Skip to content

Add security rules for pg8000 database connection authentication #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions rules/python/security/python-pg8000-empty-password-python.yml
Original file line number Diff line number Diff line change
@@ -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="...",...)

75 changes: 75 additions & 0 deletions rules/python/security/python-pg8000-hardcoded-secret-python.yml
Original file line number Diff line number Diff line change
@@ -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


Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions tests/python/python-pg8000-empty-password-python-test.yml
Original file line number Diff line number Diff line change
@@ -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='')
7 changes: 7 additions & 0 deletions tests/python/python-pg8000-hardcoded-secret-python-test.yml
Original file line number Diff line number Diff line change
@@ -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")