diff --git a/rules/python/security/python-mysql-empty-password-python.yml b/rules/python/security/python-mysql-empty-password-python.yml new file mode 100644 index 00000000..a3fd1fbb --- /dev/null +++ b/rules/python/security/python-mysql-empty-password-python.yml @@ -0,0 +1,202 @@ +id: python-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: + define_string: + kind: string + all: + - has: + kind: string_start + nthChild: 1 + # - has: + # kind: string_content + # nthChild: 2 + - has: + kind: string_end + nthChild: 2 + + define_password: + any: + - matches: define_string + - kind: identifier + pattern: $PWD_IDENTIFIER + inside: + stopBy: end + follows: + stopBy: end + kind: expression_statement + has: + stopBy: end + kind: assignment + nthChild: 1 + all: + - has: + nthChild: 1 + kind: identifier + field: left + pattern: $PWD_IDENTIFIER + - has: + nthChild: 2 + matches: define_string + +rule: + any: + - kind: call + any: + - kind: call + has: + kind: identifier + regex: ^connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: dotted_name + regex: ^connect$ + - kind: call + any: + - kind: call + has: + kind: identifier + pattern: $SASL_ALIAS + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: aliased_import + all: + - has: + kind: dotted_name + nthChild: 1 + regex: ^connect$ + - has: + kind: identifier + field: alias + nthChild: 2 + pattern: $SASL_ALIAS + - kind: call + any: + - kind: call + has: + kind: attribute + all: + - has: + kind: identifier + field: object + nthChild: 1 + pattern: $MYSQL_ALIAS + - has: + kind: identifier + field: attribute + nthChild: 2 + regex: ^connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_statement + has: + nthChild: 1 + kind: aliased_import + all: + - has: + nthChild: 1 + kind: dotted_name + field: name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: identifier + pattern: $MYSQL_ALIAS + - kind: call + any: + - kind: call + has: + kind: attribute + field: function + nthChild: 1 + regex: ^mysql.connector.connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password diff --git a/rules/python/security/python-mysql-hardcoded-secret-python.yml b/rules/python/security/python-mysql-hardcoded-secret-python.yml new file mode 100644 index 00000000..fa9e5456 --- /dev/null +++ b/rules/python/security/python-mysql-hardcoded-secret-python.yml @@ -0,0 +1,204 @@ +id: python-mysql-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: + define_string: + kind: string + all: + - has: + kind: string_start + nthChild: 1 + - has: + kind: string_content + nthChild: 2 + - has: + kind: string_end + nthChild: 3 + + define_password: + any: + - matches: define_string + - kind: identifier + pattern: $PWD_IDENTIFIER + inside: + stopBy: end + follows: + stopBy: end + kind: expression_statement + has: + stopBy: end + kind: assignment + nthChild: 1 + all: + - has: + nthChild: 1 + kind: identifier + field: left + pattern: $PWD_IDENTIFIER + - has: + nthChild: 2 + matches: define_string + +rule: + any: + - kind: call + any: + - kind: call + has: + kind: identifier + regex: ^connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: dotted_name + regex: ^connect$ + - kind: call + any: + - kind: call + has: + kind: identifier + pattern: $SASL_ALIAS + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: aliased_import + all: + - has: + kind: dotted_name + nthChild: 1 + regex: ^connect$ + - has: + kind: identifier + field: alias + nthChild: 2 + pattern: $SASL_ALIAS + - kind: call + any: + - kind: call + has: + kind: attribute + all: + - has: + kind: identifier + field: object + nthChild: 1 + pattern: $MYSQL_ALIAS + - has: + kind: identifier + field: attribute + nthChild: 2 + regex: ^connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + inside: + stopBy: end + follows: + stopBy: end + kind: import_statement + has: + nthChild: 1 + kind: aliased_import + all: + - has: + nthChild: 1 + kind: dotted_name + field: name + regex: ^mysql.connector$ + precedes: + stopBy: end + kind: identifier + pattern: $MYSQL_ALIAS + - kind: call + any: + - kind: call + has: + kind: attribute + field: function + nthChild: 1 + regex: ^mysql.connector.connect$ + precedes: + kind: argument_list + has: + stopBy: end + kind: keyword_argument + all: + - has: + nthChild: 1 + kind: identifier + regex: ^(password|passwd)$ + - has: + nthChild: 2 + matches: define_password + + diff --git a/rules/python/security/python-neo4j-empty-password-python.yml b/rules/python/security/python-neo4j-empty-password-python.yml new file mode 100644 index 00000000..443b0a2d --- /dev/null +++ b/rules/python/security/python-neo4j-empty-password-python.yml @@ -0,0 +1,217 @@ +id: python-neo4j-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: + define_string: + kind: string + all: + - has: + kind: string_start + nthChild: 1 + - has: + kind: string_end + nthChild: 2 + + define_password: + any: + - matches: define_string + - kind: identifier + pattern: $PWD_IDENTIFIER + inside: + stopBy: end + follows: + stopBy: end + kind: expression_statement + has: + stopBy: end + kind: assignment + nthChild: 1 + all: + - has: + nthChild: 1 + kind: identifier + field: left + pattern: $PWD_IDENTIFIER + - has: + nthChild: 2 + matches: define_string + +rule: + any: + # basic_auth and custom_auth + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: attribute + regex: ^(neo4j.custom_auth|neo4j.basic_auth)$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^basic_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^basic_auth$ + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^custom_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^custom_auth$ + + # kerberos_auth and bearer_auth + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: attribute + regex: ^(neo4j.kerberos_auth|neo4j.bearer_auth)$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^kerberos_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^kerberos_auth$ + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^bearer_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^bearer_auth$ diff --git a/rules/python/security/python-neo4j-hardcoded-secret-auth-python.yml b/rules/python/security/python-neo4j-hardcoded-secret-auth-python.yml new file mode 100644 index 00000000..bf603abc --- /dev/null +++ b/rules/python/security/python-neo4j-hardcoded-secret-auth-python.yml @@ -0,0 +1,219 @@ +id: python-neo4j-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: + define_string: + kind: string + all: + - has: + kind: string_start + nthChild: 1 + - has: + kind: string_content + nthChild: 2 + - has: + kind: string_end + nthChild: 3 + + define_password: + any: + - matches: define_string + - kind: identifier + pattern: $PWD_IDENTIFIER + inside: + stopBy: end + follows: + stopBy: end + kind: expression_statement + has: + stopBy: end + kind: assignment + nthChild: 1 + all: + - has: + nthChild: 1 + kind: identifier + field: left + pattern: $PWD_IDENTIFIER + - has: + nthChild: 2 + matches: define_string + +rule: + any: + # basic_auth and custom_auth + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: attribute + regex: ^(neo4j.custom_auth|neo4j.basic_auth)$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^basic_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^basic_auth$ + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^custom_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 2 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^custom_auth$ + + # kerberos_auth and bearer_auth + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: attribute + regex: ^(neo4j.kerberos_auth|neo4j.bearer_auth)$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^kerberos_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^kerberos_auth$ + - kind: call + any: + - kind: call + has: + nthChild: 1 + kind: identifier + regex: ^bearer_auth$ + precedes: + kind: argument_list + has: + nthChild: + position: 1 + ofRule: + not: + kind: comment + matches: define_password + + inside: + stopBy: end + follows: + stopBy: end + kind: import_from_statement + all: + - has: + nthChild: 1 + kind: dotted_name + field: module_name + regex: ^neo4j$ + precedes: + stopBy: end + kind: dotted_name + regex: ^bearer_auth$ diff --git a/tests/__snapshots__/python-mysql-empty-password-python-snapshot.yml b/tests/__snapshots__/python-mysql-empty-password-python-snapshot.yml new file mode 100644 index 00000000..18c7ac76 --- /dev/null +++ b/tests/__snapshots__/python-mysql-empty-password-python-snapshot.yml @@ -0,0 +1,157 @@ +id: python-mysql-empty-password-python +snapshots: + ? | + PASSWORD1 = "" + conn = mysql.connector.connect(password=PASSWORD1) + : labels: + - source: mysql.connector.connect(password=PASSWORD1) + style: primary + start: 22 + end: 65 + - source: password + style: secondary + start: 46 + end: 54 + - source: PASSWORD1 + style: secondary + start: 0 + end: 9 + - source: '"' + style: secondary + start: 12 + end: 13 + - source: '"' + style: secondary + start: 13 + end: 14 + - source: '""' + style: secondary + start: 12 + end: 14 + - source: PASSWORD1 = "" + style: secondary + start: 0 + end: 14 + - source: PASSWORD1 = "" + style: secondary + start: 0 + end: 14 + - source: PASSWORD1 = "" + style: secondary + start: 0 + end: 14 + - source: PASSWORD1 + style: secondary + start: 55 + end: 64 + - source: password=PASSWORD1 + style: secondary + start: 46 + end: 64 + - source: (password=PASSWORD1) + style: secondary + start: 45 + end: 65 + - source: mysql.connector.connect + style: secondary + start: 22 + end: 45 + ? |- + import mysql.connector as mysql123 + mysql123.connect(host="localhost",user="root",passwd="",database="aaa") + : labels: + - source: mysql123.connect(host="localhost",user="root",passwd="",database="aaa") + style: primary + start: 35 + end: 106 + - source: mysql123 + style: secondary + start: 35 + end: 43 + - source: connect + style: secondary + start: 44 + end: 51 + - source: passwd + style: secondary + start: 81 + end: 87 + - source: '"' + style: secondary + start: 88 + end: 89 + - source: '"' + style: secondary + start: 89 + end: 90 + - source: '""' + style: secondary + start: 88 + end: 90 + - source: passwd="" + style: secondary + start: 81 + end: 90 + - source: (host="localhost",user="root",passwd="",database="aaa") + style: secondary + start: 51 + end: 106 + - source: mysql123.connect + style: secondary + start: 35 + end: 51 + - source: mysql123 + style: secondary + start: 26 + end: 34 + - source: mysql.connector + style: secondary + start: 7 + end: 22 + - source: mysql.connector as mysql123 + style: secondary + start: 7 + end: 34 + - source: import mysql.connector as mysql123 + style: secondary + start: 0 + end: 34 + - source: import mysql.connector as mysql123 + style: secondary + start: 0 + end: 34 + ? | + mysql.connector.connect(password="") + : labels: + - source: mysql.connector.connect(password="") + style: primary + start: 0 + end: 36 + - source: password + style: secondary + start: 24 + end: 32 + - source: '"' + style: secondary + start: 33 + end: 34 + - source: '"' + style: secondary + start: 34 + end: 35 + - source: '""' + style: secondary + start: 33 + end: 35 + - source: password="" + style: secondary + start: 24 + end: 35 + - source: (password="") + style: secondary + start: 23 + end: 36 + - source: mysql.connector.connect + style: secondary + start: 0 + end: 23 diff --git a/tests/__snapshots__/python-mysql-hardcoded-secret-python-snapshot.yml b/tests/__snapshots__/python-mysql-hardcoded-secret-python-snapshot.yml new file mode 100644 index 00000000..aa616f55 --- /dev/null +++ b/tests/__snapshots__/python-mysql-hardcoded-secret-python-snapshot.yml @@ -0,0 +1,169 @@ +id: python-mysql-hardcoded-secret-python +snapshots: + ? | + PASSWORD1 = "password" + conn = mysql.connector.connect(password=PASSWORD1) + : labels: + - source: mysql.connector.connect(password=PASSWORD1) + style: primary + start: 30 + end: 73 + - source: password + style: secondary + start: 54 + end: 62 + - source: PASSWORD1 + style: secondary + start: 0 + end: 9 + - source: '"' + style: secondary + start: 12 + end: 13 + - source: password + style: secondary + start: 13 + end: 21 + - source: '"' + style: secondary + start: 21 + end: 22 + - source: '"password"' + style: secondary + start: 12 + end: 22 + - source: PASSWORD1 = "password" + style: secondary + start: 0 + end: 22 + - source: PASSWORD1 = "password" + style: secondary + start: 0 + end: 22 + - source: PASSWORD1 = "password" + style: secondary + start: 0 + end: 22 + - source: PASSWORD1 + style: secondary + start: 63 + end: 72 + - source: password=PASSWORD1 + style: secondary + start: 54 + end: 72 + - source: (password=PASSWORD1) + style: secondary + start: 53 + end: 73 + - source: mysql.connector.connect + style: secondary + start: 30 + end: 53 + ? |- + import mysql.connector as mysql123 + mysql123.connect(host="localhost",user="root",passwd="password",database="aaa") + : labels: + - source: mysql123.connect(host="localhost",user="root",passwd="password",database="aaa") + style: primary + start: 35 + end: 114 + - source: mysql123 + style: secondary + start: 35 + end: 43 + - source: connect + style: secondary + start: 44 + end: 51 + - source: passwd + style: secondary + start: 81 + end: 87 + - source: '"' + style: secondary + start: 88 + end: 89 + - source: password + style: secondary + start: 89 + end: 97 + - source: '"' + style: secondary + start: 97 + end: 98 + - source: '"password"' + style: secondary + start: 88 + end: 98 + - source: passwd="password" + style: secondary + start: 81 + end: 98 + - source: (host="localhost",user="root",passwd="password",database="aaa") + style: secondary + start: 51 + end: 114 + - source: mysql123.connect + style: secondary + start: 35 + end: 51 + - source: mysql123 + style: secondary + start: 26 + end: 34 + - source: mysql.connector + style: secondary + start: 7 + end: 22 + - source: mysql.connector as mysql123 + style: secondary + start: 7 + end: 34 + - source: import mysql.connector as mysql123 + style: secondary + start: 0 + end: 34 + - source: import mysql.connector as mysql123 + style: secondary + start: 0 + end: 34 + ? | + mysql.connector.connect(password="password") + : labels: + - source: mysql.connector.connect(password="password") + style: primary + start: 0 + end: 44 + - source: password + style: secondary + start: 24 + end: 32 + - source: '"' + style: secondary + start: 33 + end: 34 + - source: password + style: secondary + start: 34 + end: 42 + - source: '"' + style: secondary + start: 42 + end: 43 + - source: '"password"' + style: secondary + start: 33 + end: 43 + - source: password="password" + style: secondary + start: 24 + end: 43 + - source: (password="password") + style: secondary + start: 23 + end: 44 + - source: mysql.connector.connect + style: secondary + start: 0 + end: 23 diff --git a/tests/__snapshots__/python-neo4j-empty-password-python-snapshot.yml b/tests/__snapshots__/python-neo4j-empty-password-python-snapshot.yml new file mode 100644 index 00000000..8720890f --- /dev/null +++ b/tests/__snapshots__/python-neo4j-empty-password-python-snapshot.yml @@ -0,0 +1,260 @@ +id: python-neo4j-empty-password-python +snapshots: + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + password = "" + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) + : labels: + - source: basic_auth(username, password) + style: primary + start: 143 + end: 173 + - source: password + style: secondary + start: 83 + end: 91 + - source: '"' + style: secondary + start: 94 + end: 95 + - source: '"' + style: secondary + start: 95 + end: 96 + - source: '""' + style: secondary + start: 94 + end: 96 + - source: password = "" + style: secondary + start: 83 + end: 96 + - source: password = "" + style: secondary + start: 83 + end: 96 + - source: password = "" + style: secondary + start: 83 + end: 96 + - source: password + style: secondary + start: 164 + end: 172 + - source: (username, password) + style: secondary + start: 153 + end: 173 + - source: basic_auth + style: secondary + start: 143 + end: 153 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, "")) + : labels: + - source: basic_auth(username, "") + style: primary + start: 127 + end: 151 + - source: '"' + style: secondary + start: 148 + end: 149 + - source: '"' + style: secondary + start: 149 + end: 150 + - source: '""' + style: secondary + start: 148 + end: 150 + - source: (username, "") + style: secondary + start: 137 + end: 151 + - source: basic_auth + style: secondary + start: 127 + end: 137 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = GraphDatabase.driver(uri, auth=bearer_auth("")) + : labels: + - source: bearer_auth("") + style: primary + start: 122 + end: 137 + - source: '"' + style: secondary + start: 134 + end: 135 + - source: '"' + style: secondary + start: 135 + end: 136 + - source: '""' + style: secondary + start: 134 + end: 136 + - source: ("") + style: secondary + start: 133 + end: 137 + - source: bearer_auth + style: secondary + start: 122 + end: 133 + - source: bearer_auth + style: secondary + start: 47 + end: 58 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? "from neo4j import (\nbasic_auth,\nkerberos_auth,\nbearer_auth,\nAsyncGraphDatabase,\n)\nuri = \"neo4j://example.com:7687\" \ndriver = GraphDatabase.driver(uri, auth=kerberos_auth(\"\"))\n" + : labels: + - source: kerberos_auth("") + style: primary + start: 156 + end: 173 + - source: '"' + style: secondary + start: 170 + end: 171 + - source: '"' + style: secondary + start: 171 + end: 172 + - source: '""' + style: secondary + start: 170 + end: 172 + - source: ("") + style: secondary + start: 169 + end: 173 + - source: kerberos_auth + style: secondary + start: 156 + end: 169 + - source: kerberos_auth + style: secondary + start: 32 + end: 45 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 diff --git a/tests/__snapshots__/python-neo4j-hardcoded-secret-auth-python-snapshot.yml b/tests/__snapshots__/python-neo4j-hardcoded-secret-auth-python-snapshot.yml new file mode 100644 index 00000000..110188d4 --- /dev/null +++ b/tests/__snapshots__/python-neo4j-hardcoded-secret-auth-python-snapshot.yml @@ -0,0 +1,276 @@ +id: python-neo4j-hardcoded-secret-python +snapshots: + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + password = "NEO4J_PASSWORD" + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) + : labels: + - source: basic_auth(username, password) + style: primary + start: 157 + end: 187 + - source: password + style: secondary + start: 83 + end: 91 + - source: '"' + style: secondary + start: 94 + end: 95 + - source: NEO4J_PASSWORD + style: secondary + start: 95 + end: 109 + - source: '"' + style: secondary + start: 109 + end: 110 + - source: '"NEO4J_PASSWORD"' + style: secondary + start: 94 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password + style: secondary + start: 178 + end: 186 + - source: (username, password) + style: secondary + start: 167 + end: 187 + - source: basic_auth + style: secondary + start: 157 + end: 167 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, "NEO4J_PASSWORD")) + : labels: + - source: basic_auth(username, "NEO4J_PASSWORD") + style: primary + start: 127 + end: 165 + - source: '"' + style: secondary + start: 148 + end: 149 + - source: NEO4J_PASSWORD + style: secondary + start: 149 + end: 163 + - source: '"' + style: secondary + start: 163 + end: 164 + - source: '"NEO4J_PASSWORD"' + style: secondary + start: 148 + end: 164 + - source: (username, "NEO4J_PASSWORD") + style: secondary + start: 137 + end: 165 + - source: basic_auth + style: secondary + start: 127 + end: 137 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = GraphDatabase.driver(uri, auth=bearer_auth("token")) + : labels: + - source: bearer_auth("token") + style: primary + start: 122 + end: 142 + - source: '"' + style: secondary + start: 134 + end: 135 + - source: token + style: secondary + start: 135 + end: 140 + - source: '"' + style: secondary + start: 140 + end: 141 + - source: '"token"' + style: secondary + start: 134 + end: 141 + - source: ("token") + style: secondary + start: 133 + end: 142 + - source: bearer_auth + style: secondary + start: 122 + end: 133 + - source: bearer_auth + style: secondary + start: 47 + end: 58 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? "from neo4j import (\nbasic_auth,\nkerberos_auth,\nbearer_auth,\nAsyncGraphDatabase,\n)\nuri = \"neo4j://example.com:7687\" \ndriver = GraphDatabase.driver(uri, auth=kerberos_auth(\"token\"))\n" + : labels: + - source: kerberos_auth("token") + style: primary + start: 156 + end: 178 + - source: '"' + style: secondary + start: 170 + end: 171 + - source: token + style: secondary + start: 171 + end: 176 + - source: '"' + style: secondary + start: 176 + end: 177 + - source: '"token"' + style: secondary + start: 170 + end: 177 + - source: ("token") + style: secondary + start: 169 + end: 178 + - source: kerberos_auth + style: secondary + start: 156 + end: 169 + - source: kerberos_auth + style: secondary + start: 32 + end: 45 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 diff --git a/tests/__snapshots__/python-neo4j-hardcoded-secret-python-snapshot.yml b/tests/__snapshots__/python-neo4j-hardcoded-secret-python-snapshot.yml new file mode 100644 index 00000000..110188d4 --- /dev/null +++ b/tests/__snapshots__/python-neo4j-hardcoded-secret-python-snapshot.yml @@ -0,0 +1,276 @@ +id: python-neo4j-hardcoded-secret-python +snapshots: + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + password = "NEO4J_PASSWORD" + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) + : labels: + - source: basic_auth(username, password) + style: primary + start: 157 + end: 187 + - source: password + style: secondary + start: 83 + end: 91 + - source: '"' + style: secondary + start: 94 + end: 95 + - source: NEO4J_PASSWORD + style: secondary + start: 95 + end: 109 + - source: '"' + style: secondary + start: 109 + end: 110 + - source: '"NEO4J_PASSWORD"' + style: secondary + start: 94 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password = "NEO4J_PASSWORD" + style: secondary + start: 83 + end: 110 + - source: password + style: secondary + start: 178 + end: 186 + - source: (username, password) + style: secondary + start: 167 + end: 187 + - source: basic_auth + style: secondary + start: 157 + end: 167 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, "NEO4J_PASSWORD")) + : labels: + - source: basic_auth(username, "NEO4J_PASSWORD") + style: primary + start: 127 + end: 165 + - source: '"' + style: secondary + start: 148 + end: 149 + - source: NEO4J_PASSWORD + style: secondary + start: 149 + end: 163 + - source: '"' + style: secondary + start: 163 + end: 164 + - source: '"NEO4J_PASSWORD"' + style: secondary + start: 148 + end: 164 + - source: (username, "NEO4J_PASSWORD") + style: secondary + start: 137 + end: 165 + - source: basic_auth + style: secondary + start: 127 + end: 137 + - source: basic_auth + style: secondary + start: 20 + end: 30 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = GraphDatabase.driver(uri, auth=bearer_auth("token")) + : labels: + - source: bearer_auth("token") + style: primary + start: 122 + end: 142 + - source: '"' + style: secondary + start: 134 + end: 135 + - source: token + style: secondary + start: 135 + end: 140 + - source: '"' + style: secondary + start: 140 + end: 141 + - source: '"token"' + style: secondary + start: 134 + end: 141 + - source: ("token") + style: secondary + start: 133 + end: 142 + - source: bearer_auth + style: secondary + start: 122 + end: 133 + - source: bearer_auth + style: secondary + start: 47 + end: 58 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + ? "from neo4j import (\nbasic_auth,\nkerberos_auth,\nbearer_auth,\nAsyncGraphDatabase,\n)\nuri = \"neo4j://example.com:7687\" \ndriver = GraphDatabase.driver(uri, auth=kerberos_auth(\"token\"))\n" + : labels: + - source: kerberos_auth("token") + style: primary + start: 156 + end: 178 + - source: '"' + style: secondary + start: 170 + end: 171 + - source: token + style: secondary + start: 171 + end: 176 + - source: '"' + style: secondary + start: 176 + end: 177 + - source: '"token"' + style: secondary + start: 170 + end: 177 + - source: ("token") + style: secondary + start: 169 + end: 178 + - source: kerberos_auth + style: secondary + start: 156 + end: 169 + - source: kerberos_auth + style: secondary + start: 32 + end: 45 + - source: neo4j + style: secondary + start: 5 + end: 10 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 + - source: |- + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + style: secondary + start: 0 + end: 81 diff --git a/tests/python/python-mysql-empty-password-python-test.yml b/tests/python/python-mysql-empty-password-python-test.yml new file mode 100644 index 00000000..697d5d91 --- /dev/null +++ b/tests/python/python-mysql-empty-password-python-test.yml @@ -0,0 +1,13 @@ +id: python-mysql-empty-password-python +valid: + - | + mysql.connector.connect(password=test) +invalid: + - | + mysql.connector.connect(password="") + - | + PASSWORD1 = "" + conn = mysql.connector.connect(password=PASSWORD1) + - | + import mysql.connector as mysql123 + mysql123.connect(host="localhost",user="root",passwd="",database="aaa") \ No newline at end of file diff --git a/tests/python/python-mysql-hardcoded-secret-python-test.yml b/tests/python/python-mysql-hardcoded-secret-python-test.yml new file mode 100644 index 00000000..7e11e163 --- /dev/null +++ b/tests/python/python-mysql-hardcoded-secret-python-test.yml @@ -0,0 +1,13 @@ +id: python-mysql-hardcoded-secret-python +valid: + - | + mysql.connector.connect(password=test) +invalid: + - | + mysql.connector.connect(password="password") + - | + PASSWORD1 = "password" + conn = mysql.connector.connect(password=PASSWORD1) + - | + import mysql.connector as mysql123 + mysql123.connect(host="localhost",user="root",passwd="password",database="aaa") \ No newline at end of file diff --git a/tests/python/python-neo4j-empty-password-python-test.yml b/tests/python/python-neo4j-empty-password-python-test.yml new file mode 100644 index 00000000..0357ad00 --- /dev/null +++ b/tests/python/python-neo4j-empty-password-python-test.yml @@ -0,0 +1,40 @@ +id: python-neo4j-empty-password-python +valid: + - | + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) +invalid: + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + password = "" + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, "")) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + uri = "neo4j://example.com:7687" + driver = GraphDatabase.driver(uri, auth=kerberos_auth("")) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = GraphDatabase.driver(uri, auth=bearer_auth("")) + \ No newline at end of file diff --git a/tests/python/python-neo4j-hardcoded-secret-python-test.yml b/tests/python/python-neo4j-hardcoded-secret-python-test.yml new file mode 100644 index 00000000..492af97b --- /dev/null +++ b/tests/python/python-neo4j-hardcoded-secret-python-test.yml @@ -0,0 +1,39 @@ +id: python-neo4j-hardcoded-secret-python +valid: + - | + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) +invalid: + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + password = "NEO4J_PASSWORD" + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, password)) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = AsyncGraphDatabase.driver(url, auth=basic_auth(username, "NEO4J_PASSWORD")) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + uri = "neo4j://example.com:7687" + driver = GraphDatabase.driver(uri, auth=kerberos_auth("token")) + - | + from neo4j import ( + basic_auth, + kerberos_auth, + bearer_auth, + AsyncGraphDatabase, + ) + driver = GraphDatabase.driver(uri, auth=bearer_auth("token")) \ No newline at end of file