diff --git a/rules/rust/security/empty-password-rust.yml b/rules/rust/security/empty-password-rust.yml new file mode 100644 index 00000000..a00a3943 --- /dev/null +++ b/rules/rust/security/empty-password-rust.yml @@ -0,0 +1,1059 @@ +id: empty-password-rust +language: rust +severity: warning +message: >- + The application uses an empty credential. This can lead to unauthorized + access by either an internal or external malicious actor. It is + recommended to rotate the secret and retrieve them from a secure secret + vault or Hardware Security Module (HSM), alternatively environment + variables can be used if allowed by your company policy. +note: >- + [CWE-87]: Improper Authentication + [REFERENCES] + - https://docs.rs/sqlx/latest/sqlx/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures +ast-grep-essentials: true +utils: + + MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + + PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + + sqlx::mysql::MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + + sqlx::postgres::PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + + $PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + - has: + kind: arguments + + $MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + - has: + kind: arguments + + $MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + $PgConnectOption::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^PgConnectOption::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + sqlx::postgres::PgConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + sqlx::mysql::MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + PgConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + - has: + kind: arguments + + let $OPTS = sqlx::postgres::PgConnectOptions::new(...): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + not: + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + + let $OPTS = sqlx::postgres::PgConnectOptions::new(...)_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + + let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...)_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + not: + has: + kind: string_content + +rule: + any: + - matches: MySqlConnectOptions::new(...). ... .password("") + - matches: PgConnectOptions::new(...). ... .password("") + - matches: sqlx::mysql::MySqlConnectOptions::new(...). ... .password("") + - matches: sqlx::postgres::PgConnectOptions::new(...). ... .password("") + - matches: $PgConnectOptions::new(...). ... .password("") + - matches: $MySqlConnectOptions::new(...). ... .password("") + - matches: $MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: $PgConnectOption::new(...). ... .password("")_with_Instance + - matches: sqlx::postgres::PgConnectOptions::new(...). ... .password("")_with_Instance + - matches: sqlx::mysql::MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: PgConnectOptions::new(...). ... .password("")_with_Instance + - matches: MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...) + - matches: let $OPTS = sqlx::postgres::PgConnectOptions::new(...) + - matches: let $OPTS = sqlx::postgres::PgConnectOptions::new(...)_with_Instance + - matches: let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...)_with_Instance \ No newline at end of file diff --git a/rules/rust/security/hardcoded-password-rust.yml b/rules/rust/security/hardcoded-password-rust.yml new file mode 100644 index 00000000..21161486 --- /dev/null +++ b/rules/rust/security/hardcoded-password-rust.yml @@ -0,0 +1,1036 @@ +id: hardcoded-password-rust +language: rust +severity: warning +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. It is + recommended to rotate the secret and retrieve them from a secure secret + vault or Hardware Security Module (HSM), alternatively environment + variables can be used if allowed by your company policy. +note: >- + [CWE-798]: Use of Hard-coded Credentials + [REFERENCES] + - https://docs.rs/sqlx/latest/sqlx/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures +ast-grep-essentials: true +utils: + + MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + + PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + + sqlx::mysql::MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + + sqlx::postgres::PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + + $PgConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + - has: + kind: arguments + + $MySqlConnectOptions::new(...). ... .password(""): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + - has: + kind: arguments + + $MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + $PgConnectOption::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $INSTANCE + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $INSTANCE + nthChild: 1 + - has: + kind: call_expression + nthChild: 2 + all: + - has: + kind: scoped_identifier + regex: ^PgConnectOption::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + sqlx::postgres::PgConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + sqlx::mysql::MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + PgConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: identifier + regex: ^PgConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres$ + - has: + kind: use_list + has: + kind: identifier + regex: ^PgConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + MySqlConnectOptions::new(...). ... .password("")_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: scoped_identifier + regex: ^MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: use_declaration + has: + kind: scoped_identifier + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: identifier + regex: ^MySqlConnectOptions$ + - kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql$ + - has: + kind: use_list + has: + kind: identifier + regex: ^MySqlConnectOptions$ + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + - has: + kind: arguments + + let $OPTS = sqlx::postgres::PgConnectOptions::new(...): + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + + let $OPTS = sqlx::postgres::PgConnectOptions::new(...)_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::postgres::PgConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + + let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...)_with_Instance: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + stopBy: end + kind: field_expression + has: + kind: identifier + nthChild: 1 + pattern: $SQL + - has: + kind: field_identifier + regex: ^password$ + - has: + kind: arguments + has: + kind: identifier + pattern: $STR + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + precedes: + kind: arguments + - has: + kind: arguments + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $SQL + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + regex: ^sqlx::mysql::MySqlConnectOptions::new$ + - has: + kind: arguments + - inside: + stopBy: end + follows: + stopBy: end + any: + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $STR + - has: + kind: string_literal + has: + kind: string_content + +rule: + any: + - matches: MySqlConnectOptions::new(...). ... .password("") + - matches: PgConnectOptions::new(...). ... .password("") + - matches: sqlx::mysql::MySqlConnectOptions::new(...). ... .password("") + - matches: sqlx::postgres::PgConnectOptions::new(...). ... .password("") + - matches: $PgConnectOptions::new(...). ... .password("") + - matches: $MySqlConnectOptions::new(...). ... .password("") + - matches: $MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: $PgConnectOption::new(...). ... .password("")_with_Instance + - matches: sqlx::postgres::PgConnectOptions::new(...). ... .password("")_with_Instance + - matches: sqlx::mysql::MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: PgConnectOptions::new(...). ... .password("")_with_Instance + - matches: MySqlConnectOptions::new(...). ... .password("")_with_Instance + - matches: let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...) + - matches: let $OPTS = sqlx::postgres::PgConnectOptions::new(...) + - matches: let $OPTS = sqlx::postgres::PgConnectOptions::new(...)_with_Instance + - matches: let $OPTS = sqlx::mysql::MySqlConnectOptions::new(...)_with_Instance \ No newline at end of file diff --git a/rules/rust/security/secrets-reqwest-hardcoded-auth-rust.yml b/rules/rust/security/secrets-reqwest-hardcoded-auth-rust.yml new file mode 100644 index 00000000..4f703ca4 --- /dev/null +++ b/rules/rust/security/secrets-reqwest-hardcoded-auth-rust.yml @@ -0,0 +1,302 @@ +id: secrets-reqwest-hardcoded-auth-rust +language: rust +severity: warning +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. It is + recommended to rotate the secret and retrieve them from a secure secret + vault or Hardware Security Module (HSM), alternatively environment + variables can be used if allowed by your company polic +note: >- + [CWE-798]: Use of Hard-coded Credentials + [REFERENCES] + - https://docs.rs/reqwest/latest/reqwest/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures +ast-grep-essentials: true +utils: + MATCH_PATTERN_ONE.basic_auth: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: field_identifier + regex: ^basic_auth$ + - has: + stopBy: end + kind: arguments + not: + has: + nthChild: + position: 3 + ofRule: + not: + kind: line_comment + has: + stopBy: neighbor + kind: call_expression + nthChild: + position: 2 + ofRule: + not: + kind: line_comment + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^Some$ + - has: + stopBy: neighbor + kind: arguments + has: + stopBy: neighbor + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + all: + - follows: + stopBy: end + kind: let_declaration + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: call_expression + pattern: reqwest::Client::new($$$) + # - inside: + # stopBy: end + # kind: block + + + MATCH_PATTERN_TWO.bearer_auth: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: field_identifier + regex: ^bearer_auth$ + - inside: + stopBy: end + follows: + stopBy: end + kind: let_declaration + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: call_expression + pattern: reqwest::Client::new($$$) + - has: + stopBy: neighbor + kind: arguments + has: + stopBy: neighbor + kind: string_literal + nthChild: + position: 1 + ofRule: + not: + kind: line_comment + has: + stopBy: neighbor + kind: string_content + not: + has: + nthChild: 2 + - not: + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^Some$ + - has: + stopBy: neighbor + kind: arguments + has: + stopBy: neighbor + kind: identifier + + MATCH_PATTERN_ONE.basic_auth_Instance: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: field_identifier + regex: ^basic_auth$ + - has: + stopBy: end + kind: arguments + not: + has: + nthChild: + position: 3 + ofRule: + not: + kind: line_comment + has: + stopBy: neighbor + kind: call_expression + nthChild: + position: 2 + ofRule: + not: + kind: line_comment + all: + - has: + stopBy: neighbor + kind: identifier + regex: ^Some$ + - has: + stopBy: neighbor + kind: arguments + has: + stopBy: neighbor + kind: identifier + pattern: $PASSWORD + - inside: + stopBy: end + all: + - follows: + stopBy: end + kind: let_declaration + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: call_expression + pattern: reqwest::Client::new($$$) + - follows: + stopBy: end + kind: let_declaration + all: + - has: + kind: identifier + pattern: $PASSWORD + nthChild: + position: 1 + ofRule: + not: + kind: line_comment + - has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + kind: block + + MATCH_PATTERN_TWO.bearer_auth_Instance: + kind: call_expression + all: + - has: + stopBy: neighbor + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: field_identifier + regex: ^bearer_auth$ + - inside: + stopBy: end + all: + - follows: + stopBy: end + kind: let_declaration + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $C + - has: + stopBy: neighbor + kind: call_expression + pattern: reqwest::Client::new($$$) + - follows: + stopBy: end + kind: let_declaration + all: + - has: + kind: identifier + pattern: $PASSWORD + nthChild: 1 + - has: + kind: string_literal + has: + kind: string_content + - inside: + stopBy: end + kind: block + - has: + stopBy: end + kind: arguments + has: + stopBy: neighbor + kind: identifier + pattern: $PASS + nthChild: + position: 1 + ofRule: + not: + kind: line_comment + not: + has: + nthChild: 2 + + +rule: + kind: call_expression + any: + - matches: MATCH_PATTERN_ONE.basic_auth + - matches: MATCH_PATTERN_TWO.bearer_auth + - matches: MATCH_PATTERN_ONE.basic_auth_Instance + - matches: MATCH_PATTERN_TWO.bearer_auth_Instance + not: + all: + - has: + stopBy: end + kind: ERROR + - inside: + stopBy: end + kind: ERROR diff --git a/tests/__snapshots__/empty-password-rust-snapshot.yml b/tests/__snapshots__/empty-password-rust-snapshot.yml new file mode 100644 index 00000000..12bf0bbc --- /dev/null +++ b/tests/__snapshots__/empty-password-rust-snapshot.yml @@ -0,0 +1,179 @@ +id: empty-password-rust +snapshots: + ? | + use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + async fn test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } + : labels: + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + style: primary + start: 139 + end: 219 + - source: () + style: secondary + start: 163 + end: 165 + - source: MySqlConnectOptions::new + style: secondary + start: 139 + end: 163 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + style: secondary + start: 139 + end: 204 + - source: password + style: secondary + start: 207 + end: 215 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password + style: secondary + start: 139 + end: 215 + - source: '""' + style: secondary + start: 216 + end: 218 + - source: ("") + style: secondary + start: 215 + end: 219 + - source: sqlx::mysql + style: secondary + start: 4 + end: 15 + - source: MySqlConnectOptions + style: secondary + start: 18 + end: 37 + - source: '{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}' + style: secondary + start: 17 + end: 80 + - source: sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode} + style: secondary + start: 4 + end: 80 + - source: use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + style: secondary + start: 0 + end: 81 + - source: use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + style: secondary + start: 0 + end: 81 + ? |- + use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + async fn test3() -> Result<(), sqlx::Error> { + let pg = PgConnectOptions::new(); + let conn = pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + + use_connection(conn); + Ok(()) + } + : labels: + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + style: primary + start: 164 + end: 237 + - source: pg + style: secondary + start: 164 + end: 166 + - source: password + style: secondary + start: 225 + end: 233 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password + style: secondary + start: 164 + end: 233 + - source: '""' + style: secondary + start: 234 + end: 236 + - source: ("") + style: secondary + start: 233 + end: 237 + - source: sqlx::postgres + style: secondary + start: 4 + end: 18 + - source: PgConnectOptions + style: secondary + start: 21 + end: 37 + - source: '{PgConnectOptions, PgConnection, PgPool, PgSslMode}' + style: secondary + start: 20 + end: 71 + - source: sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode} + style: secondary + start: 4 + end: 71 + - source: use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + style: secondary + start: 0 + end: 72 + - source: use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + style: secondary + start: 0 + end: 72 + - source: pg + style: secondary + start: 123 + end: 125 + - source: PgConnectOptions::new + style: secondary + start: 128 + end: 149 + - source: () + style: secondary + start: 149 + end: 151 + - source: PgConnectOptions::new() + style: secondary + start: 128 + end: 151 + - source: let pg = PgConnectOptions::new(); + style: secondary + start: 119 + end: 152 + - source: let pg = PgConnectOptions::new(); + style: secondary + start: 119 + end: 152 diff --git a/tests/__snapshots__/hardcoded-password-rust-snapshot.yml b/tests/__snapshots__/hardcoded-password-rust-snapshot.yml new file mode 100644 index 00000000..abd2b0de --- /dev/null +++ b/tests/__snapshots__/hardcoded-password-rust-snapshot.yml @@ -0,0 +1,187 @@ +id: hardcoded-password-rust +snapshots: + ? | + use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + async fn test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("password") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } + : labels: + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("password") + style: primary + start: 139 + end: 227 + - source: () + style: secondary + start: 163 + end: 165 + - source: MySqlConnectOptions::new + style: secondary + start: 139 + end: 163 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + style: secondary + start: 139 + end: 204 + - source: password + style: secondary + start: 207 + end: 215 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password + style: secondary + start: 139 + end: 215 + - source: password + style: secondary + start: 217 + end: 225 + - source: '"password"' + style: secondary + start: 216 + end: 226 + - source: ("password") + style: secondary + start: 215 + end: 227 + - source: sqlx::mysql + style: secondary + start: 4 + end: 15 + - source: MySqlConnectOptions + style: secondary + start: 18 + end: 37 + - source: '{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}' + style: secondary + start: 17 + end: 80 + - source: sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode} + style: secondary + start: 4 + end: 80 + - source: use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + style: secondary + start: 0 + end: 81 + - source: use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + style: secondary + start: 0 + end: 81 + ? |- + use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + async fn test3() -> Result<(), sqlx::Error> { + let pg = PgConnectOptions::new(); + let conn = pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("secret-password") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + + use_connection(conn); + Ok(()) + } + : labels: + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("secret-password") + style: primary + start: 164 + end: 252 + - source: pg + style: secondary + start: 164 + end: 166 + - source: password + style: secondary + start: 225 + end: 233 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password + style: secondary + start: 164 + end: 233 + - source: secret-password + style: secondary + start: 235 + end: 250 + - source: '"secret-password"' + style: secondary + start: 234 + end: 251 + - source: ("secret-password") + style: secondary + start: 233 + end: 252 + - source: sqlx::postgres + style: secondary + start: 4 + end: 18 + - source: PgConnectOptions + style: secondary + start: 21 + end: 37 + - source: '{PgConnectOptions, PgConnection, PgPool, PgSslMode}' + style: secondary + start: 20 + end: 71 + - source: sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode} + style: secondary + start: 4 + end: 71 + - source: use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + style: secondary + start: 0 + end: 72 + - source: use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + style: secondary + start: 0 + end: 72 + - source: pg + style: secondary + start: 123 + end: 125 + - source: PgConnectOptions::new + style: secondary + start: 128 + end: 149 + - source: () + style: secondary + start: 149 + end: 151 + - source: PgConnectOptions::new() + style: secondary + start: 128 + end: 151 + - source: let pg = PgConnectOptions::new(); + style: secondary + start: 119 + end: 152 + - source: let pg = PgConnectOptions::new(); + style: secondary + start: 119 + end: 152 diff --git a/tests/__snapshots__/secrets-reqwest-hardcoded-auth-rust-snapshot.yml b/tests/__snapshots__/secrets-reqwest-hardcoded-auth-rust-snapshot.yml new file mode 100644 index 00000000..354314f6 --- /dev/null +++ b/tests/__snapshots__/secrets-reqwest-hardcoded-auth-rust-snapshot.yml @@ -0,0 +1,118 @@ +id: secrets-reqwest-hardcoded-auth-rust +snapshots: + ? "use reqwest::Client; \nasync fn test1() -> Result<(), reqwest::Error> {\nlet client = reqwest::Client::new();\nlet resp = client.delete(\"http://httpbin.org/delete\")\n.basic_auth(\"admin\", Some(\"hardcoded-password\"))\n.send()\n.await?;\nprintln!(\"body = {:?}\", resp);\nOk(())\n}\n" + : labels: + - source: |- + client.delete("http://httpbin.org/delete") + .basic_auth("admin", Some("hardcoded-password")) + style: primary + start: 119 + end: 210 + - source: client + style: secondary + start: 119 + end: 125 + - source: basic_auth + style: secondary + start: 163 + end: 173 + - source: |- + client.delete("http://httpbin.org/delete") + .basic_auth + style: secondary + start: 119 + end: 173 + - source: Some + style: secondary + start: 183 + end: 187 + - source: hardcoded-password + style: secondary + start: 189 + end: 207 + - source: '"hardcoded-password"' + style: secondary + start: 188 + end: 208 + - source: ("hardcoded-password") + style: secondary + start: 187 + end: 209 + - source: Some("hardcoded-password") + style: secondary + start: 183 + end: 209 + - source: ("admin", Some("hardcoded-password")) + style: secondary + start: 173 + end: 210 + - source: client + style: secondary + start: 75 + end: 81 + - source: reqwest::Client::new() + style: secondary + start: 84 + end: 106 + - source: let client = reqwest::Client::new(); + style: secondary + start: 71 + end: 107 + - source: |- + let resp = client.delete("http://httpbin.org/delete") + .basic_auth("admin", Some("hardcoded-password")) + .send() + .await?; + style: secondary + start: 108 + end: 227 + ? "use reqwest::Client; \nasync fn test2() -> Result<(), reqwest::Error> {\nlet client = reqwest::Client::new();\nlet resp = client.put(\"http://httpbin.org/delete\")\n.bearer_auth(\"hardcoded-token\")\n.send()\n.await?;\nprintln!(\"body = {:?}\", resp);\nOk(())\n}" + : labels: + - source: |- + client.put("http://httpbin.org/delete") + .bearer_auth("hardcoded-token") + style: primary + start: 119 + end: 190 + - source: client + style: secondary + start: 119 + end: 125 + - source: bearer_auth + style: secondary + start: 160 + end: 171 + - source: |- + client.put("http://httpbin.org/delete") + .bearer_auth + style: secondary + start: 119 + end: 171 + - source: client + style: secondary + start: 75 + end: 81 + - source: reqwest::Client::new() + style: secondary + start: 84 + end: 106 + - source: let client = reqwest::Client::new(); + style: secondary + start: 71 + end: 107 + - source: let client = reqwest::Client::new(); + style: secondary + start: 71 + end: 107 + - source: hardcoded-token + style: secondary + start: 173 + end: 188 + - source: '"hardcoded-token"' + style: secondary + start: 172 + end: 189 + - source: ("hardcoded-token") + style: secondary + start: 171 + end: 190 diff --git a/tests/rust/empty-password-rust-test.yml b/tests/rust/empty-password-rust-test.yml new file mode 100644 index 00000000..11c27ab3 --- /dev/null +++ b/tests/rust/empty-password-rust-test.yml @@ -0,0 +1,42 @@ +id: empty-password-rust +valid: + - | + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("password") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } +invalid: + - | + use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + async fn test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } + - | + use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + async fn test3() -> Result<(), sqlx::Error> { + let pg = PgConnectOptions::new(); + let conn = pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + + use_connection(conn); + Ok(()) + } \ No newline at end of file diff --git a/tests/rust/hardcoded-password-rust-test.yml b/tests/rust/hardcoded-password-rust-test.yml new file mode 100644 index 00000000..f639f33f --- /dev/null +++ b/tests/rust/hardcoded-password-rust-test.yml @@ -0,0 +1,42 @@ +id: hardcoded-password-rust +valid: + - | + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("password") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } +invalid: + - | + use sqlx::mysql::{MySqlConnectOptions, MySqlConnection, MySqlPool, MySqlSslMode}; + async fn test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("password") + .database("db") + .connect().await?; + + use_connection(conn); + Ok(()) + } + - | + use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + async fn test3() -> Result<(), sqlx::Error> { + let pg = PgConnectOptions::new(); + let conn = pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("secret-password") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + + use_connection(conn); + Ok(()) + } \ No newline at end of file diff --git a/tests/rust/secrets-reqwest-hardcoded-auth-rust-test.yml b/tests/rust/secrets-reqwest-hardcoded-auth-rust-test.yml new file mode 100644 index 00000000..df5952cd --- /dev/null +++ b/tests/rust/secrets-reqwest-hardcoded-auth-rust-test.yml @@ -0,0 +1,36 @@ +id: secrets-reqwest-hardcoded-auth-rust +valid: + - | + use reqwest::Client; + async fn test1() -> Result<(), reqwest::Error> { + let client = reqwest::Client::new(); + let resp = client.delete("http://httpbin.org/delete") + .basic_auth("admin", Some(hardcoded-password)) + .send() + .await?; + println!("body = {:?}", resp); + Ok(()) + } +invalid: + - | + use reqwest::Client; + async fn test1() -> Result<(), reqwest::Error> { + let client = reqwest::Client::new(); + let resp = client.delete("http://httpbin.org/delete") + .basic_auth("admin", Some("hardcoded-password")) + .send() + .await?; + println!("body = {:?}", resp); + Ok(()) + } + - | + use reqwest::Client; + async fn test2() -> Result<(), reqwest::Error> { + let client = reqwest::Client::new(); + let resp = client.put("http://httpbin.org/delete") + .bearer_auth("hardcoded-token") + .send() + .await?; + println!("body = {:?}", resp); + Ok(()) + } \ No newline at end of file