diff --git a/rules/python/security/python-redis-empty-password-python.yml b/rules/python/security/python-redis-empty-password-python.yml new file mode 100644 index 00000000..a3984583 --- /dev/null +++ b/rules/python/security/python-redis-empty-password-python.yml @@ -0,0 +1,71 @@ +id: python-redis-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: + redis.Redis(..., password="...",...): + kind: call + all: + - has: + stopBy: neighbor + kind: attribute + pattern: redis.Redis + - 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: end + kind: string_content + - not: + has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$ + - has: + stopBy: neighbor + kind: string + has: + stopBy: end + kind: string_content +rule: + kind: call + matches: redis.Redis(..., password="...",...) + all: + - not: + has: + stopBy: end + kind: ERROR + - not: + inside: + stopBy: end + kind: ERROR \ No newline at end of file diff --git a/rules/python/security/python-redis-hardcoded-secret-python.yml b/rules/python/security/python-redis-hardcoded-secret-python.yml new file mode 100644 index 00000000..98a1f92e --- /dev/null +++ b/rules/python/security/python-redis-hardcoded-secret-python.yml @@ -0,0 +1,70 @@ +id: python-redis-hardcoded-secret-python +severity: warning +language: python +message: >- + A secret is hard-coded in the application. Secrets stored in source + code, such as credentials, identifiers, and other types of sensitive data, + can be leaked and used by internal or external malicious actors. Use + environment variables to securely provide credentials and other secrets or + retrieve them from a secure vault or Hardware Security Module (HSM). +note: >- + [CWE-798] Use of Hard-coded Credentials. + [REFERENCES] + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + +ast-grep-essentials: true + +utils: + redis.Redis(..., password="...",...): + kind: call + all: + - has: + stopBy: neighbor + kind: attribute + pattern: redis.Redis + - 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: end + 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: redis.Redis(..., 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-redis-empty-password-python-snapshot.yml b/tests/__snapshots__/python-redis-empty-password-python-snapshot.yml new file mode 100644 index 00000000..aefbe6fc --- /dev/null +++ b/tests/__snapshots__/python-redis-empty-password-python-snapshot.yml @@ -0,0 +1,46 @@ +id: python-redis-empty-password-python +snapshots: + ? | + redis_client = redis.Redis( + host='localhost', + port=6379, + password='', + db=5 + ) + : labels: + - source: |- + redis.Redis( + host='localhost', + port=6379, + password='', + db=5 + ) + style: primary + start: 15 + end: 84 + - source: redis.Redis + style: secondary + start: 15 + end: 26 + - source: password + style: secondary + start: 63 + end: 71 + - source: '''''' + style: secondary + start: 72 + end: 74 + - source: password='' + style: secondary + start: 63 + end: 74 + - source: |- + ( + host='localhost', + port=6379, + password='', + db=5 + ) + style: secondary + start: 26 + end: 84 diff --git a/tests/__snapshots__/python-redis-hardcoded-secret-python-snapshot.yml b/tests/__snapshots__/python-redis-hardcoded-secret-python-snapshot.yml new file mode 100644 index 00000000..50c4f423 --- /dev/null +++ b/tests/__snapshots__/python-redis-hardcoded-secret-python-snapshot.yml @@ -0,0 +1,50 @@ +id: python-redis-hardcoded-secret-python +snapshots: + ? |- + redis_client = redis.Redis( + host='localhost', + port=6379, + password="abc", + db=5 + ) + : labels: + - source: |- + redis.Redis( + host='localhost', + port=6379, + password="abc", + db=5 + ) + style: primary + start: 15 + end: 87 + - source: redis.Redis + style: secondary + start: 15 + end: 26 + - source: password + style: secondary + start: 63 + end: 71 + - source: abc + style: secondary + start: 73 + end: 76 + - source: '"abc"' + style: secondary + start: 72 + end: 77 + - source: password="abc" + style: secondary + start: 63 + end: 77 + - source: |- + ( + host='localhost', + port=6379, + password="abc", + db=5 + ) + style: secondary + start: 26 + end: 87 diff --git a/tests/python/python-redis-empty-password-python-test.yml b/tests/python/python-redis-empty-password-python-test.yml new file mode 100644 index 00000000..c0cff62c --- /dev/null +++ b/tests/python/python-redis-empty-password-python-test.yml @@ -0,0 +1,17 @@ +id: python-redis-empty-password-python +valid: + - | + redis_client = redis.Redis( + host='localhost', + port=6379, + password=os.getenv('REDIS_PASSWORD', ''), + db=5 + ) +invalid: + - | + redis_client = redis.Redis( + host='localhost', + port=6379, + password='', + db=5 + ) diff --git a/tests/python/python-redis-hardcoded-secret-python-test.yml b/tests/python/python-redis-hardcoded-secret-python-test.yml new file mode 100644 index 00000000..9bc1b57b --- /dev/null +++ b/tests/python/python-redis-hardcoded-secret-python-test.yml @@ -0,0 +1,17 @@ +id: python-redis-hardcoded-secret-python +valid: + - | + redis_client = redis.Redis( + host='localhost', + port=6379, + password=os.getenv('REDIS_PASSWORD', 'password'), + db=5 + ) +invalid: + - | + redis_client = redis.Redis( + host='localhost', + port=6379, + password="abc", + db=5 + ) \ No newline at end of file