diff --git a/rules/go/lang/hardcoded_mysql_database_password.yml b/rules/go/lang/hardcoded_mysql_database_password.yml index 580812c73..f8c458d8f 100644 --- a/rules/go/lang/hardcoded_mysql_database_password.yml +++ b/rules/go/lang/hardcoded_mysql_database_password.yml @@ -15,7 +15,7 @@ patterns: detection: go_lang_hardcoded_mysql_database_password_sql_init scope: cursor - variable: STRING - string_regex: \A\w+:.+@.*\z + string_regex: \A\w+:.+@tcp.*\z scope: cursor auxiliary: - id: go_lang_hardcoded_mysql_database_password_init diff --git a/rules/go/lang/hardcoded_pg_database_password.yml b/rules/go/lang/hardcoded_pg_database_password.yml new file mode 100644 index 000000000..0cf09317d --- /dev/null +++ b/rules/go/lang/hardcoded_pg_database_password.yml @@ -0,0 +1,49 @@ +patterns: + - pattern: | + $.Options{$Password: $} + filters: + - variable: SQL + detection: go_lang_hardcoded_pg_database_password_init + scope: cursor + - variable: STRING_LITERAL + detection: string_literal + scope: cursor + - pattern: | + $.Open($<_>, $) + filters: + - variable: INIT + detection: go_lang_hardcoded_pg_database_password_sql_init + scope: cursor + - variable: STRING + string_regex: \Apostgres://\w+:.+@.*\z + scope: cursor +auxiliary: + - id: go_lang_hardcoded_pg_database_password_init + patterns: + - import $"github.com/lib/pg" + - | + import ( + $"github.com/lib/pg" + ) + - id: go_lang_hardcoded_pg_database_password_sql_init + patterns: + - import $"database/sql" + - | + import ( + $"database/sql" + ) +languages: + - go +metadata: + description: "Usage of hard-coded PostgreSQL database password" + remediation_message: | + ## Description + + Hardcoded password used in database connection string detected. Code is not a safe place to store passwords like this; use environment variables or a key-management system instead. + + ## Resources + - [OWASP hardcoded passwords](https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password) + cwe_id: + - 259 + id: go_lang_hardcoded_pg_database_password + documentation_url: https://docs.bearer.com/reference/rules/go_lang_hardcoded_pg_database_password diff --git a/tests/go/lang/hardcoded_pg_database_password/test.js b/tests/go/lang/hardcoded_pg_database_password/test.js new file mode 100644 index 000000000..3adb70c35 --- /dev/null +++ b/tests/go/lang/hardcoded_pg_database_password/test.js @@ -0,0 +1,18 @@ +const { + createNewInvoker, + getEnvironment, +} = require("../../../helper.js") +const { ruleId, ruleFile, testBase } = getEnvironment(__dirname) + +describe(ruleId, () => { + const invoke = createNewInvoker(ruleId, ruleFile, testBase) + + test("hardcoded_database_password", () => { + const testCase = "main.go" + + const results = invoke(testCase) + + expect(results.Missing).toEqual([]) + expect(results.Extra).toEqual([]) + }) +}) \ No newline at end of file diff --git a/tests/go/lang/hardcoded_pg_database_password/testdata/main.go b/tests/go/lang/hardcoded_pg_database_password/testdata/main.go new file mode 100644 index 000000000..e42f28c37 --- /dev/null +++ b/tests/go/lang/hardcoded_pg_database_password/testdata/main.go @@ -0,0 +1,54 @@ +// Use of bearer:expected go_lang_hardcoded_mysql_database_password to flag expected findings +package main + +import ( + "database/sql" + "fmt" + "os" + + "github.com/lib/pg" +) + +func bad1() { + options := &pg.Options{ + Addr: ":5432", + User: "admin123", + // bearer:expected go_lang_hardcoded_pg_database_password + Password: "password", + Database: "db_name", + } + db := pg.Connect(options) +} + +func bad2() { + dsn := "postgres://admin123:password@localhost/db_name?sslmode=enable" + // bearer:expected go_lang_hardcoded_pg_database_password + db, err = sql.Open("postgres", dsn) +} + +func good1() { + dbUser := os.Getenv("DB_USER") + dbPassword := os.Getenv("DB_PASSWORD") + dbName := "myDatabase" + + dsn := fmt.Sprintf("postgres://%s:%s@localhost/%s", dbUser, dbPassword, dbName) + + db, err := sql.Open("postgres", dsn) + if err != nil { + panic(err) + } + defer db.Close() + + // Database operations go here + // ... +} + +func good2() { + options := &pg.Options{ + Addr: ":5432", + User: "admin123", + Password: os.Getenv("DB_PASSWORD"), + Database: "db_name", + } + db := pg.Connect(options) +}