Skip to content

Commit

Permalink
feat(golang): add hardcoded database password (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
cfabianski authored Feb 22, 2024
1 parent c272c2d commit eaf98d0
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 0 deletions.
49 changes: 49 additions & 0 deletions rules/go/lang/hardcoded_mysql_database_password.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
patterns:
- pattern: |
$<SQL>.Config{$<!>Passwd: $<STRING_LITERAL>}
filters:
- variable: SQL
detection: go_lang_hardcoded_mysql_database_password_init
scope: cursor
- variable: STRING_LITERAL
detection: string_literal
scope: cursor
- pattern: |
$<INIT>.Open($<_>, $<STRING>)
filters:
- variable: INIT
detection: go_lang_hardcoded_mysql_database_password_sql_init
scope: cursor
- variable: STRING
string_regex: \A\w+:.+@tcp.*\z
scope: cursor
auxiliary:
- id: go_lang_hardcoded_mysql_database_password_init
patterns:
- import $<!>"github.com/go-sql-driver/mysql"
- |
import (
$<!>"github.com/go-sql-driver/mysql"
)
- id: go_lang_hardcoded_mysql_database_password_sql_init
patterns:
- import $<!>"database/sql"
- |
import (
$<!>"database/sql"
)
languages:
- go
metadata:
description: "Usage of hard-coded MySQL 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_mysql_database_password
documentation_url: https://docs.bearer.com/reference/rules/go_lang_hardcoded_mysql_database_password
49 changes: 49 additions & 0 deletions rules/go/lang/hardcoded_pg_database_password.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
patterns:
- pattern: |
$<SQL>.Options{$<!>Password: $<STRING_LITERAL>}
filters:
- variable: SQL
detection: go_lang_hardcoded_pg_database_password_init
scope: cursor
- variable: STRING_LITERAL
detection: string_literal
scope: cursor
- pattern: |
$<INIT>.Open($<_>, $<STRING>)
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
18 changes: 18 additions & 0 deletions tests/go/lang/hardcoded_mysql_database_password/test.js
Original file line number Diff line number Diff line change
@@ -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([])
})
})
90 changes: 90 additions & 0 deletions tests/go/lang/hardcoded_mysql_database_password/testdata/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Use of bearer:expected go_lang_hardcoded_mysql_database_password to flag expected findings
package main

import (
"database/sql"
"fmt"
"os"

"github.com/go-sql-driver/mysql"
)

func bad1() {
// Hard-coded credentials are a serious security risk
dbUser := "admin"
dbPassword := "admin123"
dbName := "myDatabase"
port := 3306

// Building the DSN (Data Source Name) with hard-coded credentials
dsn := fmt.Sprintf("%s:%s@tcp(localhost:%d)/%s?charset=utf8", dbUser, dbPassword, port, dbName)

// Connect to the database
// bearer:expected go_lang_hardcoded_mysql_database_password
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close()

// Database operations go here
// ...
}

func bad1() {
cfg := mysql.Config{
User: "user",
// bearer:expected go_lang_hardcoded_mysql_database_password
Passwd: "password",
Net: "tcp",
Addr: "127.0.0.1:3306",
DBName: "recordings",
}

// Connect to the database
db, err := sql.Open("mysql", cfg.FormatDSN())
if err != nil {
panic(err)
}
defer db.Close()

// Database operations go here
// ...
}

func good1() {
dbUser := os.Getenv("DB_USER")
dbPassword := os.Getenv("DB_PASSWORD") // Get the password from an environment variable
dbName := "myDatabase"

dsn := fmt.Sprintf("%s:%s@tcp(localhost:3306)/%s?charset=utf8", dbUser, dbPassword, dbName)

db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close()

// Database operations go here
// ...
}

func good2() {
cfg := mysql.Config{
User: os.Getenv("DB_USER"),
Passwd: os.Getenv("DB_PASSWORD"),
Net: "tcp",
Addr: "127.0.0.1:3306",
DBName: "myDatabase",
}

// Connect to the database
db, err := sql.Open("mysql", cfg.FormatDSN())
if err != nil {
panic(err)
}
defer db.Close()

// Database operations go here
// ...
}
18 changes: 18 additions & 0 deletions tests/go/lang/hardcoded_pg_database_password/test.js
Original file line number Diff line number Diff line change
@@ -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([])
})
})
54 changes: 54 additions & 0 deletions tests/go/lang/hardcoded_pg_database_password/testdata/main.go
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit eaf98d0

Please sign in to comment.