diff --git a/rules/python/security/python-peewee-mysql-empty-password-python.yml b/rules/python/security/python-peewee-mysql-empty-password-python.yml new file mode 100644 index 00000000..e5d4bee5 --- /dev/null +++ b/rules/python/security/python-peewee-mysql-empty-password-python.yml @@ -0,0 +1,56 @@ +id: python-peewee-mysql-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: + $DB(..., password="...",...): + # $DB(..., password="...",...) + kind: call + all: + - has: + stopBy: neighbor + pattern: $DB + regex: ^MySQLDatabase$|^peewee.MySQLDatabase$|^MySQLConnectorDatabase$|^playhouse.mysql_ext.MySQLConnectorDatabase$|^MariaDBConnectorDatabase$|^playhouse.mysql_ext.MariaDBConnectorDatabase$|^PooledMySQLDatabase$|^playhouse.pool.PooledMySQLDatabase$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$|^passwd$ + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: neighbor + kind: string_content +rule: + kind: call + matches: $DB(..., password="...",...) + not: + all: + - has: + stopBy: end + kind: ERROR + - inside: + stopBy: end + kind: ERROR + diff --git a/rules/python/security/python-peewee-mysql-hardcoded-secret-python.yml b/rules/python/security/python-peewee-mysql-hardcoded-secret-python.yml new file mode 100644 index 00000000..40c8c338 --- /dev/null +++ b/rules/python/security/python-peewee-mysql-hardcoded-secret-python.yml @@ -0,0 +1,54 @@ +id: python-peewee-mysql-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: + $DB(..., password="...",...): + # $DB(..., password="...",...) + kind: call + all: + - has: + stopBy: neighbor + pattern: $DB + regex: ^MySQLDatabase$|^peewee.MySQLDatabase$|^MySQLConnectorDatabase$|^playhouse.mysql_ext.MySQLConnectorDatabase$|^MariaDBConnectorDatabase$|^playhouse.mysql_ext.MariaDBConnectorDatabase$|^PooledMySQLDatabase$|^playhouse.pool.PooledMySQLDatabase$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: keyword_argument + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^password$|^passwd$ + - has: + stopBy: neighbor + kind: string + has: + stopBy: neighbor + kind: string_content +rule: + kind: call + matches: $DB(..., password="...",...) + not: + all: + - has: + stopBy: end + kind: ERROR + - inside: + stopBy: end + kind: ERROR + diff --git a/tests/__snapshots__/python-peewee-mysql-empty-password-python-snapshot.yml b/tests/__snapshots__/python-peewee-mysql-empty-password-python-snapshot.yml new file mode 100644 index 00000000..74b6c268 --- /dev/null +++ b/tests/__snapshots__/python-peewee-mysql-empty-password-python-snapshot.yml @@ -0,0 +1,28 @@ +id: python-peewee-mysql-empty-password-python +snapshots: + ? "mysql_db1 = MySQLDatabase('my_app', user='app', password='', host='10.1.0.8', port=3306) \n" + : labels: + - source: MySQLDatabase('my_app', user='app', password='', host='10.1.0.8', port=3306) + style: primary + start: 12 + end: 88 + - source: MySQLDatabase + style: secondary + start: 12 + end: 25 + - source: password + style: secondary + start: 48 + end: 56 + - source: '''''' + style: secondary + start: 57 + end: 59 + - source: password='' + style: secondary + start: 48 + end: 59 + - source: ('my_app', user='app', password='', host='10.1.0.8', port=3306) + style: secondary + start: 25 + end: 88 diff --git a/tests/__snapshots__/python-peewee-mysql-hardcoded-secret-python-snapshot.yml b/tests/__snapshots__/python-peewee-mysql-hardcoded-secret-python-snapshot.yml new file mode 100644 index 00000000..ff63f255 --- /dev/null +++ b/tests/__snapshots__/python-peewee-mysql-hardcoded-secret-python-snapshot.yml @@ -0,0 +1,32 @@ +id: python-peewee-mysql-hardcoded-secret-python +snapshots: + 'mysql_db1 = MySQLDatabase(''my_app'', user=''app'', password=''db_password'', host=''10.1.0.8'', port=3306) ': + labels: + - source: MySQLDatabase('my_app', user='app', password='db_password', host='10.1.0.8', port=3306) + style: primary + start: 12 + end: 99 + - source: MySQLDatabase + style: secondary + start: 12 + end: 25 + - source: password + style: secondary + start: 48 + end: 56 + - source: db_password + style: secondary + start: 58 + end: 69 + - source: '''db_password''' + style: secondary + start: 57 + end: 70 + - source: password='db_password' + style: secondary + start: 48 + end: 70 + - source: ('my_app', user='app', password='db_password', host='10.1.0.8', port=3306) + style: secondary + start: 25 + end: 99 diff --git a/tests/python/python-peewee-mysql-empty-password-python-test.yml b/tests/python/python-peewee-mysql-empty-password-python-test.yml new file mode 100644 index 00000000..fa84c49f --- /dev/null +++ b/tests/python/python-peewee-mysql-empty-password-python-test.yml @@ -0,0 +1,8 @@ +id: python-peewee-mysql-empty-password-python +valid: + - | + mysql_db1 = MySQLDatabe('my_app', user='app', password=os.env['pass'], host='10.1.0.8', port=3306) +invalid: + - | + mysql_db1 = MySQLDatabase('my_app', user='app', password='', host='10.1.0.8', port=3306) + \ No newline at end of file diff --git a/tests/python/python-peewee-mysql-hardcoded-secret-python-test.yml b/tests/python/python-peewee-mysql-hardcoded-secret-python-test.yml new file mode 100644 index 00000000..ad3c1035 --- /dev/null +++ b/tests/python/python-peewee-mysql-hardcoded-secret-python-test.yml @@ -0,0 +1,7 @@ +id: python-peewee-mysql-hardcoded-secret-python +valid: + - | + mysql_db1 = MySQLDatabe('my_app', user='app', password=os.env['password'], host='10.1.0.8', port=3306) +invalid: + - | + mysql_db1 = MySQLDatabase('my_app', user='app', password='db_password', host='10.1.0.8', port=3306) \ No newline at end of file