diff --git a/rules/python/security/python-pg8000-empty-password-python.yml b/rules/python/security/python-pg8000-empty-password-python.yml new file mode 100644 index 00000000..e567c16b --- /dev/null +++ b/rules/python/security/python-pg8000-empty-password-python.yml @@ -0,0 +1,50 @@ +id: python-pg8000-empty-password-python +severity: warning +language: python +message: >- + The application creates a database connection with an empty password. + This can lead to unauthorized access by either an internal or external + malicious actor. To prevent this vulnerability, enforce authentication + when connecting to a database by using environment variables to securely + provide credentials or retrieving them from a secure vault or HSM + (Hardware Security Module). +note: >- + [CWE-287] Improper Authentication. + [REFERENCES] + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + +ast-grep-essentials: true + +utils: + pg8000.dbapi.connect(..., password="...",...): + # pg8000.dbapi.connect(..., password="...",...) + kind: call + pattern: $CALL + all: + - has: + stopBy: neighbor + pattern: $DB + regex: ^pg8000.dbapi.connect$|^pg8000.native.Connection$ + - has: + stopBy: neighbor + kind: argument_list + all: + - has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$ + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: neighbor + kind: string_content +rule: + kind: call + matches: pg8000.dbapi.connect(..., password="...",...) + diff --git a/rules/python/security/python-pg8000-hardcoded-secret-python.yml b/rules/python/security/python-pg8000-hardcoded-secret-python.yml new file mode 100644 index 00000000..db66b30d --- /dev/null +++ b/rules/python/security/python-pg8000-hardcoded-secret-python.yml @@ -0,0 +1,75 @@ +id: python-pg8000-hardcoded-secret-python +severity: warning +language: python +message: >- + The application creates a database connection with an empty password. + This can lead to unauthorized access by either an internal or external + malicious actor. To prevent this vulnerability, enforce authentication + when connecting to a database by using environment variables to securely + provide credentials or retrieving them from a secure vault or HSM + (Hardware Security Module). +note: >- + [CWE-287] Improper Authentication. + [REFERENCES] + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + +ast-grep-essentials: true + +utils: + pg8000.dbapi.connect(..., password="...",...): + # pg8000.dbapi.connect(..., password="...",...) + kind: call + pattern: $CALL + all: + - has: + stopBy: neighbor + pattern: $DB + regex: ^pg8000.dbapi.connect$|^pg8000.native.Connection$ + - has: + stopBy: neighbor + kind: argument_list + all: + - has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$ + - has: + stopBy: neighbor + kind: string + has: + stopBy: neighbor + kind: string_content + - not: + has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$ + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: end + kind: string_content +rule: + kind: call + matches: pg8000.dbapi.connect(..., password="...",...) + all: + - not: + has: + stopBy: end + kind: ERROR + - not: + inside: + stopBy: end + kind: ERROR + + \ No newline at end of file diff --git a/tests/__snapshots__/python-pg8000-empty-password-python-snapshot.yml b/tests/__snapshots__/python-pg8000-empty-password-python-snapshot.yml new file mode 100644 index 00000000..3cfce66b --- /dev/null +++ b/tests/__snapshots__/python-pg8000-empty-password-python-snapshot.yml @@ -0,0 +1,55 @@ +id: python-pg8000-empty-password-python +snapshots: + ? | + pg8000.dbapi.connect(user="postgres", password="") + : labels: + - source: pg8000.dbapi.connect(user="postgres", password="") + style: primary + start: 0 + end: 50 + - source: pg8000.dbapi.connect + style: secondary + start: 0 + end: 20 + - source: password + style: secondary + start: 38 + end: 46 + - source: '""' + style: secondary + start: 47 + end: 49 + - source: password="" + style: secondary + start: 38 + end: 49 + - source: (user="postgres", password="") + style: secondary + start: 20 + end: 50 + ? "pg8000.dbapi.connect(user=\"postgres\", password='') \n" + : labels: + - source: pg8000.dbapi.connect(user="postgres", password='') + style: primary + start: 0 + end: 50 + - source: pg8000.dbapi.connect + style: secondary + start: 0 + end: 20 + - source: password + style: secondary + start: 38 + end: 46 + - source: '''''' + style: secondary + start: 47 + end: 49 + - source: password='' + style: secondary + start: 38 + end: 49 + - source: (user="postgres", password='') + style: secondary + start: 20 + end: 50 diff --git a/tests/__snapshots__/python-pg8000-hardcoded-secret-python-snapshot.yml b/tests/__snapshots__/python-pg8000-hardcoded-secret-python-snapshot.yml new file mode 100644 index 00000000..3207e6da --- /dev/null +++ b/tests/__snapshots__/python-pg8000-hardcoded-secret-python-snapshot.yml @@ -0,0 +1,33 @@ +id: python-pg8000-hardcoded-secret-python +snapshots: + ? | + conn = pg8000.dbapi.connect(user="postgres", password="abc") + : labels: + - source: pg8000.dbapi.connect(user="postgres", password="abc") + style: primary + start: 7 + end: 60 + - source: pg8000.dbapi.connect + style: secondary + start: 7 + end: 27 + - source: password + style: secondary + start: 45 + end: 53 + - source: abc + style: secondary + start: 55 + end: 58 + - source: '"abc"' + style: secondary + start: 54 + end: 59 + - source: password="abc" + style: secondary + start: 45 + end: 59 + - source: (user="postgres", password="abc") + style: secondary + start: 27 + end: 60 diff --git a/tests/python/python-pg8000-empty-password-python-test.yml b/tests/python/python-pg8000-empty-password-python-test.yml new file mode 100644 index 00000000..8c3e42ce --- /dev/null +++ b/tests/python/python-pg8000-empty-password-python-test.yml @@ -0,0 +1,9 @@ +id: python-pg8000-empty-password-python +valid: + - | + pg8000.dbapi.connect(user="postgres", password=get_password()) +invalid: + - | + pg8000.dbapi.connect(user="postgres", password="") + - | + pg8000.dbapi.connect(user="postgres", password='') diff --git a/tests/python/python-pg8000-hardcoded-secret-python-test.yml b/tests/python/python-pg8000-hardcoded-secret-python-test.yml new file mode 100644 index 00000000..588428ca --- /dev/null +++ b/tests/python/python-pg8000-hardcoded-secret-python-test.yml @@ -0,0 +1,7 @@ +id: python-pg8000-hardcoded-secret-python +valid: + - | + conn = pg8000.dbapi.connect(user="postgres", password=get_password()) +invalid: + - | + conn = pg8000.dbapi.connect(user="postgres", password="abc")