From fccc01523001f043bed3f87109a5de303a046ffc Mon Sep 17 00:00:00 2001 From: Sakshis Date: Wed, 11 Dec 2024 12:18:23 +0000 Subject: [PATCH 1/2] empty-password-rust --- rules/rust/security/empty-password-rust.yml | 309 +++++++++ .../empty-password-rust-snapshot.yml | 643 ++++++++++++++++++ tests/rust/empty-password-rust-test.yml | 54 ++ 3 files changed, 1006 insertions(+) create mode 100644 rules/rust/security/empty-password-rust.yml create mode 100644 tests/__snapshots__/empty-password-rust-snapshot.yml create mode 100644 tests/rust/empty-password-rust-test.yml diff --git a/rules/rust/security/empty-password-rust.yml b/rules/rust/security/empty-password-rust.yml new file mode 100644 index 00000000..2b002079 --- /dev/null +++ b/rules/rust/security/empty-password-rust.yml @@ -0,0 +1,309 @@ +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-287]: Improper Authentication + [REFERENCES] + - https://docs.rs/sqlx/latest/sqlx/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures +utils: + match_call_expression_with_mysqlconnections: + kind: call_expression + all: + - has: + kind: field_expression + field: function + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: scoped_identifier + all: + - has: + stopBy: end + kind: identifier + field: path + regex: "^MySqlConnectOptions$" + - has: + stopBy: end + field: name + kind: identifier + regex: "^new$" + - has: + kind: arguments + - has: + kind: arguments + has: + kind: string_literal + inside: + kind: field_expression + has: + kind: field_identifier + field: field + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: field_expression + has: + kind: field_identifier + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: await_expression + inside: + kind: try_expression + inside: + kind: let_declaration + inside: + stopBy: end + kind: function_item + follows: + stopBy: end + kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + field: path + all: + - has: + kind: identifier + field: path + regex: "^sqlx$" + - has: + kind: identifier + field: name + regex: "^mysql$" + - has: + kind: use_list + field: list + all: + - has: + kind: identifier + regex: "^MySqlConnectOptions$" + - has: + kind: identifier + regex: "^MySqlConnection$" + - has: + kind: identifier + regex: "^MySqlPool$" + - has: + kind: identifier + regex: "^MySqlSslMode$" + match_call_expression_with_PgConnectOptions: + kind: call_expression + all: + - has: + stopBy: end + kind: field_expression + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: scoped_identifier + all: + - has: + stopBy: end + kind: identifier + field: path + regex: "^PgConnectOptions$" + - has: + stopBy: end + field: name + kind: identifier + regex: "^new$" + - has: + kind: arguments + - has: + kind: arguments + not: + has: + stopBy: end + kind: string_literal + has: + stopBy: end + kind: string_content + inside: + kind: field_expression + has: + kind: field_identifier + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: field_expression + has: + kind: field_identifier + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: await_expression + inside: + kind: try_expression + inside: + kind: let_declaration + inside: + stopBy: end + kind: function_item + follows: + stopBy: end + kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + field: path + all: + - has: + kind: identifier + field: path + regex: "^sqlx$" + - has: + kind: identifier + field: name + regex: "^postgres$" + - has: + kind: use_list + field: list + all: + - has: + kind: identifier + regex: "^PgConnectOptions$" + - has: + kind: identifier + regex: "^PgConnection$" + - has: + kind: identifier + regex: "^PgPool$" + - has: + kind: identifier + regex: "^PgSslMode$" + match_call_expression_with_instance_PgConnectOptions: + kind: call_expression + all: + - has: + kind: field_expression + all: + - has: + kind: call_expression + has: + kind: field_expression + all: + - has: + stopBy: end + kind: identifier + field: value + pattern: $PG + - has: + kind: field_identifier + - has: + kind: field_identifier + - has: + kind: arguments + inside: + kind: field_expression + has: + kind: field_identifier + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: field_expression + has: + kind: field_identifier + inside: + kind: call_expression + has: + kind: arguments + inside: + kind: await_expression + inside: + kind: try_expression + inside: + kind: let_declaration + follows: + stopBy: end + kind: let_declaration + all: + - has: + kind: identifier + pattern: $PG + - has: + kind: call_expression + all: + - has: + kind: scoped_identifier + all: + - has: + kind: identifier + field: path + regex: "^PgConnectOptions$" + - has: + kind: identifier + field: name + regex: "^new$" + - has: + kind: arguments + inside: + stopBy: end + kind: function_item + follows: + stopBy: end + kind: use_declaration + has: + kind: scoped_use_list + all: + - has: + kind: scoped_identifier + field: path + all: + - has: + kind: identifier + field: path + regex: "^sqlx$" + - has: + kind: identifier + field: name + regex: "^postgres$" + - has: + kind: use_list + field: list + all: + - has: + kind: identifier + regex: "^PgConnectOptions$" + - has: + kind: identifier + regex: "^PgConnection$" + - has: + kind: identifier + regex: "^PgPool$" + - has: + kind: identifier + regex: "^PgSslMode$" + +rule: + any: + - matches: match_call_expression_with_mysqlconnections + - matches: match_call_expression_with_PgConnectOptions + - matches: match_call_expression_with_instance_PgConnectOptions diff --git a/tests/__snapshots__/empty-password-rust-snapshot.yml b/tests/__snapshots__/empty-password-rust-snapshot.yml new file mode 100644 index 00000000..e36c017e --- /dev/null +++ b/tests/__snapshots__/empty-password-rust-snapshot.yml @@ -0,0 +1,643 @@ +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: 216 + - source: MySqlConnectOptions + style: secondary + start: 139 + end: 158 + - source: new + style: secondary + start: 160 + end: 163 + - source: MySqlConnectOptions::new + style: secondary + start: 139 + end: 163 + - source: ("root") + style: secondary + start: 194 + end: 202 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + style: secondary + start: 139 + end: 202 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password + style: secondary + start: 139 + end: 212 + - source: '""' + style: secondary + start: 213 + end: 215 + - source: ("") + style: secondary + start: 212 + end: 216 + - source: sqlx + style: secondary + start: 4 + end: 8 + - source: mysql + style: secondary + start: 10 + end: 15 + - source: sqlx::mysql + style: secondary + start: 4 + end: 15 + - source: MySqlConnectOptions + style: secondary + start: 18 + end: 37 + - source: MySqlConnection + style: secondary + start: 39 + end: 54 + - source: MySqlPool + style: secondary + start: 56 + end: 65 + - source: MySqlSslMode + style: secondary + start: 67 + end: 79 + - 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: |- + async fn test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await?; + use_connection(conn); + Ok(()) + } + style: secondary + start: 82 + end: 284 + - source: |- + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await?; + style: secondary + start: 128 + end: 251 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await? + style: secondary + start: 139 + end: 250 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect().await + style: secondary + start: 139 + end: 249 + - source: () + style: secondary + start: 241 + end: 243 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect() + style: secondary + start: 139 + end: 243 + - source: connect + style: secondary + start: 234 + end: 241 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + .connect + style: secondary + start: 139 + end: 241 + - source: ("db") + style: secondary + start: 226 + end: 232 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database("db") + style: secondary + start: 139 + end: 232 + - source: database + style: secondary + start: 218 + end: 226 + - source: |- + MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password("") + .database + style: secondary + start: 139 + end: 226 + ? | + use sqlx::postgres::{PgConnectOptions, PgConnection, PgPool, PgSslMode}; + async fn test2() -> Result<(), sqlx::Error> { + let conn = PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + use_connection(conn); + Ok(()) + } + : labels: + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + style: primary + start: 130 + end: 225 + - source: PgConnectOptions + style: secondary + start: 130 + end: 146 + - source: new + style: secondary + start: 148 + end: 151 + - source: PgConnectOptions::new + style: secondary + start: 130 + end: 151 + - source: ("secret-user") + style: secondary + start: 196 + end: 211 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + style: secondary + start: 130 + end: 211 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password + style: secondary + start: 130 + end: 221 + - source: ("") + style: secondary + start: 221 + end: 225 + - source: sqlx + style: secondary + start: 4 + end: 8 + - source: postgres + style: secondary + start: 10 + end: 18 + - source: sqlx::postgres + style: secondary + start: 4 + end: 18 + - source: PgConnectOptions + style: secondary + start: 21 + end: 37 + - source: PgConnection + style: secondary + start: 39 + end: 51 + - source: PgPool + style: secondary + start: 53 + end: 59 + - source: PgSslMode + style: secondary + start: 61 + end: 70 + - 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: |- + async fn test2() -> Result<(), sqlx::Error> { + let conn = PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + use_connection(conn); + Ok(()) + } + style: secondary + start: 73 + end: 306 + - source: |- + let conn = PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + style: secondary + start: 119 + end: 275 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await? + style: secondary + start: 130 + end: 274 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await + style: secondary + start: 130 + end: 273 + - source: () + style: secondary + start: 264 + end: 266 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + style: secondary + start: 130 + end: 266 + - source: connect + style: secondary + start: 257 + end: 264 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect + style: secondary + start: 130 + end: 264 + - source: (PgSslMode::Require) + style: secondary + start: 235 + end: 255 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + style: secondary + start: 130 + end: 255 + - source: ssl_mode + style: secondary + start: 227 + end: 235 + - source: |- + PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode + style: secondary + start: 130 + end: 235 + ? | + 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: username + style: secondary + start: 200 + end: 208 + - source: |- + pg.host("secret-host") + .port(2525) + .username + style: secondary + start: 164 + end: 208 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + style: secondary + start: 164 + end: 223 + - 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: 233 + end: 237 + - source: sqlx + style: secondary + start: 4 + end: 8 + - source: postgres + style: secondary + start: 10 + end: 18 + - source: sqlx::postgres + style: secondary + start: 4 + end: 18 + - source: PgConnectOptions + style: secondary + start: 21 + end: 37 + - source: PgConnection + style: secondary + start: 39 + end: 51 + - source: PgPool + style: secondary + start: 53 + end: 59 + - source: PgSslMode + style: secondary + start: 61 + end: 70 + - 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: |- + 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(()) + } + style: secondary + start: 73 + end: 318 + - source: pg + style: secondary + start: 123 + end: 125 + - source: PgConnectOptions + style: secondary + start: 128 + end: 144 + - source: new + style: secondary + start: 146 + end: 149 + - 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 conn = pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await?; + style: secondary + start: 153 + end: 287 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await? + style: secondary + start: 164 + end: 286 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + .await + style: secondary + start: 164 + end: 285 + - source: () + style: secondary + start: 276 + end: 278 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect() + style: secondary + start: 164 + end: 278 + - source: connect + style: secondary + start: 269 + end: 276 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .connect + style: secondary + start: 164 + end: 276 + - source: (PgSslMode::Require) + style: secondary + start: 247 + end: 267 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + style: secondary + start: 164 + end: 267 + - source: ssl_mode + style: secondary + start: 239 + end: 247 + - source: |- + pg.host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode + style: secondary + start: 164 + end: 247 diff --git a/tests/rust/empty-password-rust-test.yml b/tests/rust/empty-password-rust-test.yml new file mode 100644 index 00000000..e6578be8 --- /dev/null +++ b/tests/rust/empty-password-rust-test.yml @@ -0,0 +1,54 @@ +id: empty-password-rust +valid: + - | + async fn ok_test1() -> Result<(), sqlx::Error> { + let conn = MySqlConnectOptions::new() + .host("localhost") + .username("root") + .password(env!("pwd")) + .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 test2() -> Result<(), sqlx::Error> { + let conn = PgConnectOptions::new() + .host("secret-host") + .port(2525) + .username("secret-user") + .password("") + .ssl_mode(PgSslMode::Require) + .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(()) + } From 40ccf7f9ca8e3d330d67bfdd250a759f8b8ed055 Mon Sep 17 00:00:00 2001 From: Sakshis Date: Wed, 11 Dec 2024 12:22:31 +0000 Subject: [PATCH 2/2] ruby-cassandra-empty-password-ruby --- .../ruby-cassandra-empty-password-ruby.yml | 131 ++++++++++++++++++ ...cassandra-empty-password-ruby-snapshot.yml | 112 +++++++++++++++ ...uby-cassandra-empty-password-ruby-test.yml | 12 ++ 3 files changed, 255 insertions(+) create mode 100644 rules/ruby/security/ruby-cassandra-empty-password-ruby.yml create mode 100644 tests/__snapshots__/ruby-cassandra-empty-password-ruby-snapshot.yml create mode 100644 tests/ruby/ruby-cassandra-empty-password-ruby-test.yml diff --git a/rules/ruby/security/ruby-cassandra-empty-password-ruby.yml b/rules/ruby/security/ruby-cassandra-empty-password-ruby.yml new file mode 100644 index 00000000..cb6d61c9 --- /dev/null +++ b/rules/ruby/security/ruby-cassandra-empty-password-ruby.yml @@ -0,0 +1,131 @@ +id: ruby-cassandra-empty-password-ruby +language: ruby +severity: warning +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 +utils: + Cassandra.cluster(): + # Cassandra.cluster(..., password: "", ...) + kind: call + all: + - has: + stopBy: neighbor + kind: constant + regex: ^Cassandra$ + - has: + stopBy: neighbor + regex: ^.$ + - has: + stopBy: neighbor + kind: identifier + regex: ^cluster$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: pair + all: + - has: + stopBy: neighbor + kind: hash_key_symbol + regex: ^password$ + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: neighbor + kind: string_content + - inside: + stopBy: end + kind: program + has: + stopBy: end + kind: call + pattern: require 'cassandra' + Cassandra.cluster()_with_instance: + # Cassandra.cluster(..., password: "", ...) + kind: call + all: + - has: + stopBy: neighbor + kind: constant + regex: ^Cassandra$ + - has: + stopBy: neighbor + regex: ^.$ + - has: + stopBy: neighbor + kind: identifier + regex: ^cluster$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: pair + all: + - has: + stopBy: neighbor + kind: hash_key_symbol + regex: ^password$ + - has: + stopBy: neighbor + kind: identifier + pattern: $SECRET + - inside: + stopBy: end + kind: program + has: + stopBy: end + kind: call + pattern: require 'cassandra' + - any: + - follows: + stopBy: end + kind: assignment + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SECRET + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: neighbor + kind: string_content + - inside: + stopBy: end + kind: assignment + follows: + stopBy: end + kind: assignment + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SECRET + - has: + stopBy: neighbor + kind: string + not: + has: + stopBy: neighbor + kind: string_content +rule: + kind: call + any: + - matches: Cassandra.cluster() + - matches: Cassandra.cluster()_with_instance diff --git a/tests/__snapshots__/ruby-cassandra-empty-password-ruby-snapshot.yml b/tests/__snapshots__/ruby-cassandra-empty-password-ruby-snapshot.yml new file mode 100644 index 00000000..fe1f26fd --- /dev/null +++ b/tests/__snapshots__/ruby-cassandra-empty-password-ruby-snapshot.yml @@ -0,0 +1,112 @@ +id: ruby-cassandra-empty-password-ruby +snapshots: + ? | + require 'cassandra' + cluster = Cassandra.cluster(username: 'user',password: '') + : labels: + - source: 'Cassandra.cluster(username: ''user'',password: '''')' + style: primary + start: 30 + end: 78 + - source: Cassandra + style: secondary + start: 30 + end: 39 + - source: . + style: secondary + start: 39 + end: 40 + - source: cluster + style: secondary + start: 40 + end: 47 + - source: password + style: secondary + start: 65 + end: 73 + - source: '''''' + style: secondary + start: 75 + end: 77 + - source: 'password: ''''' + style: secondary + start: 65 + end: 77 + - source: '(username: ''user'',password: '''')' + style: secondary + start: 47 + end: 78 + - source: require 'cassandra' + style: secondary + start: 0 + end: 19 + - source: | + require 'cassandra' + cluster = Cassandra.cluster(username: 'user',password: '') + style: secondary + start: 0 + end: 79 + ? | + require 'cassandra' + password = '' + cluster = Cassandra.cluster(username: 'user',password: password) + : labels: + - source: 'Cassandra.cluster(username: ''user'',password: password)' + style: primary + start: 44 + end: 98 + - source: Cassandra + style: secondary + start: 44 + end: 53 + - source: . + style: secondary + start: 53 + end: 54 + - source: cluster + style: secondary + start: 54 + end: 61 + - source: password + style: secondary + start: 79 + end: 87 + - source: password + style: secondary + start: 89 + end: 97 + - source: 'password: password' + style: secondary + start: 79 + end: 97 + - source: '(username: ''user'',password: password)' + style: secondary + start: 61 + end: 98 + - source: require 'cassandra' + style: secondary + start: 0 + end: 19 + - source: | + require 'cassandra' + password = '' + cluster = Cassandra.cluster(username: 'user',password: password) + style: secondary + start: 0 + end: 99 + - source: password + style: secondary + start: 20 + end: 28 + - source: '''''' + style: secondary + start: 31 + end: 33 + - source: password = '' + style: secondary + start: 20 + end: 33 + - source: 'cluster = Cassandra.cluster(username: ''user'',password: password)' + style: secondary + start: 34 + end: 98 diff --git a/tests/ruby/ruby-cassandra-empty-password-ruby-test.yml b/tests/ruby/ruby-cassandra-empty-password-ruby-test.yml new file mode 100644 index 00000000..3261b17a --- /dev/null +++ b/tests/ruby/ruby-cassandra-empty-password-ruby-test.yml @@ -0,0 +1,12 @@ +id: ruby-cassandra-empty-password-ruby +valid: + - | + cluster = Cassandra.cluster(username: 'user',password: '') +invalid: + - | + require 'cassandra' + cluster = Cassandra.cluster(username: 'user',password: '') + - | + require 'cassandra' + password = '' + cluster = Cassandra.cluster(username: 'user',password: password)