Hardcoded Credentials in Source Code

HIGH

Detects credential-named variables (password, secret, api_key, token) being assigned or passed as arguments — hardcoded secrets are exposed in git history, compiled binaries, container images, and CI/CD logs.

Rule Information

Language
Go
Category
Security
Author
Shivasurya
Shivasurya
Last Updated
2026-04-13
Tags
gosecurityhardcoded-credentialssecretsapi-keytokenpasswordCWE-798CWE-259CWE-321OWASP-A07OWASP-A02
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset golang/GO-SEC-004 --project .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Cross-file analysis: 3 files

About This Rule

Understanding the vulnerability and how it is detected

Hardcoded credentials are secrets — passwords, API keys, tokens, signing keys, and connection strings — embedded directly as string literals in source code. This is one of the most frequently occurring and impactful security vulnerabilities in software development, consistently appearing in real breaches with catastrophic consequences.

**Why hardcoded secrets are permanently dangerous**:

Source code is copied, forked, backed up, and diffed far more broadly than developers realize. A secret committed to any version control system persists in the commit history indefinitely — even `git rm` and `git commit` do not remove it. An attacker with read access to any historical snapshot (via GitHub, GitLab, Bitbucket, backup, or zip export) recovers the credential. Forcing a secret into git history is effectively publishing it.

**Surface area of secret exposure beyond git**: - "**Compiled Go binaries**: Go embeds string literals directly in the binary's `.rodata`" section. The Unix `strings` command extracts all printable strings of 4+ characters. Tools like Ghidra with the "ghostrings" plugin specifically hunt for string constants that look like credentials. A hardcoded JWT secret or database password survives unchanged in every compiled artifact shipped to customers or placed in container images. - "**Container image layers**: Docker layers are union filesystem snapshots. Each layer" is a tar archive. `docker history --no-trunc` and `docker inspect` expose build-time ARG values. If a binary containing hardcoded credentials is in the image, `docker save` followed by `tar xf` and `strings` extracts them. - "**CI/CD pipeline artifacts**: Build systems cache compiled binaries and run logs. A" test output that prints a hardcoded constant, or a build artifact in a public artifact store, exposes the credential to anyone with artifact access. - "**Log files and crash dumps**: Go programs that log their configuration at startup" (common in 12-factor app patterns) may log environment variables or struct fields — including credential-named fields initialized from string literals.

**Real-world incidents involving hardcoded credentials**:

*Toyota T-Connect breach (2022–2023)*: Toyota disclosed that a contractor had accidentally published source code to a public GitHub repository containing credentials for a data server. The exposed data server contained information of approximately 296,019 Toyota T-Connect customers — names, phone numbers, and vehicle identification numbers. The credentials remained valid and exposed for approximately 4 years and 9 months before discovery. Toyota stated no financial data was accessed but could not rule out third-party access during the exposure window.

*Internet Archive breach (October 2024)*: Threat actors obtained a GitLab personal access token that was exposed in a public repository. Using this token, they accessed the Internet Archive's GitLab instance and exfiltrated configuration files. The breach exposed 31 million user records (email addresses, usernames, bcrypt-hashed passwords, and other internal data). The token, once hardcoded in the repository, became the entry point for the entire breach.

*Slack GitHub repository credential exposure (2022)*: Slack disclosed that hashed employee credentials and GitHub repository cloning tokens were exposed when an attacker gained access to a subset of Slack's GitHub repositories. The exposure included tokens that could be used to access Slack's internal systems. While Slack rotated all affected credentials immediately, the incident demonstrated how a single exposed token creates a lateral movement path from external repository access to internal infrastructure.

**Scale of the problem — GitGuardian research (2024)**: GitGuardian's "State of Secrets Sprawl" report analyzed over 1 billion commits: - 23.8 million new plaintext secrets were detected in public GitHub repositories in 2023 - 70% of secrets exposed in 2021 remain valid and active 2 years later — secret rotation after discovery is the exception, not the rule - "The most common secret types: API keys (35%), generic credentials (28%), private keys (17%)" - "Developer-to-secret ratio: approximately 1 hardcoded secret per 1,000 commits in" enterprise repositories

**Extraction techniques attackers use**: 1. `strings /path/to/binary | grep -iE "(password|secret|key|token)" | grep -v "^[[:space:]]*$"` 2. TruffleHog v3: `trufflehog git file:///path/to/repo --only-verified` — scans git history with entropy analysis and regex patterns against known-secret formats 3. Gitleaks: `gitleaks detect --source /path/to/repo` — rule-based scanning with 150+ built-in patterns for AWS keys, GitHub tokens, Stripe keys, etc. 4. Docker layer inspection: `docker save image:tag | tar xf - | find . -name "*.tar" -exec tar xf {} \; | strings | grep -i secret` 5. Ghidra ghostrings plugin: static analysis of Go binaries to identify Go string constants and cross-reference them against credential patterns

**CWE taxonomy for this vulnerability class**: - "**CWE-798** (parent): General hardcoded credentials — covers any credential type" - "**CWE-259** (child): Specifically hardcoded passwords in authentication code" - "**CWE-321** (child): Hardcoded cryptographic keys — JWT signing secrets, AES keys," HMAC secrets. These are both a credential and a cryptographic failure simultaneously.

**Go-specific remediation hierarchy** (in order of increasing security): 1. `os.Getenv("SECRET_NAME")` — environment variables; acceptable for development, simple deployments. Note: env vars are visible in `/proc/<pid>/environ`, `docker inspect`, and CI/CD log output if logged. 2. `github.com/spf13/viper` with config files excluded from git — supports env var binding, remote config (etcd, Consul), and layered config. Better than bare os.Getenv for complex apps. 3. `github.com/hashicorp/vault/sdk` — HashiCorp Vault dynamic secrets. Vault generates short-lived credentials on demand and revokes them automatically. Compromised credentials expire without requiring rotation. Vault audit logs all secret accesses. 4. AWS Secrets Manager (`github.com/aws/aws-sdk-go-v2/service/secretsmanager`) / GCP Secret Manager / Azure Key Vault — cloud-native secrets management with IAM-based access control, automatic rotation for supported services (RDS, Redshift), and CloudTrail audit logging.

**CISA Secure by Design guidance**: CISA's "Secure by Design" principles explicitly list elimination of default and hardcoded credentials as a foundational requirement. The guidance states that software manufacturers should make it technically impossible to deploy software with default credentials by requiring credential configuration as part of the installation process.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Permanent Exposure via Git History

Any secret committed to version control persists indefinitely in git history. Even `git rm` + `git push` leaves the secret in every historical clone, CI/CD artifact, and backup. Tools like TruffleHog and Gitleaks scan all commits, not just the current HEAD. The only remediation is credential rotation — the history cannot be practically sanitized once other parties have cloned the repository.

2

Binary Reverse Engineering

Go embeds string literals verbatim in compiled binaries. A database password or API key in a Go string constant appears in the binary's .rodata section readable by the `strings` command without any disassembly. Compiled binaries distributed to customers, deployed in container images, or included in GitHub releases expose credentials to anyone who downloads them.

3

Supply Chain Compromise

An attacker who compromises a developer's workstation, a CI/CD pipeline, or a source code repository recovers all hardcoded credentials with a single search. This provides immediate access to every environment — development, staging, and production — where those credentials are used. Hardcoded credentials make a single point of compromise (developer laptop) equivalent to full infrastructure compromise.

4

Credential Reuse Across Environments

Hardcoded credentials typically use the same value across all environments. When a staging environment credential is exposed, it often also works in production because developers hardcoded the same value in both. Per-environment rotation is only possible with externalized configuration.

How to Fix

Recommended remediation steps

  • 1Use os.Getenv() as a minimum for all credential values — never hardcode string literals.
  • 2Validate that required secrets are present at startup; fail fast with a clear error message.
  • 3Use HashiCorp Vault or AWS/GCP/Azure Secrets Manager for production workloads.
  • 4Add .env and config files containing secrets to .gitignore before initial commit.
  • 5Run TruffleHog or Gitleaks as a pre-commit hook and in CI to catch secrets before push.
  • 6If a credential is ever committed, rotate it immediately — assume it is compromised.
  • 7Use per-environment secrets — staging and production must never share credentials.
  • 8Store JWT signing keys with minimum 256-bit entropy (32 random bytes from crypto/rand).
  • 9Audit binary artifacts for embedded credentials using `strings binary | grep -iE 'password|secret|key|token'`.
  • 10Follow the principle of least privilege — each service should have its own credentials with minimal scope.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

Variable name pattern matching for password/secret/api_key/apikey/token/credential/passwd patterns. Produces findings on any variable with these name patterns used in function calls. Requires manual review to confirm whether the assigned value is a hardcoded literal vs a runtime value — the rule flags the variable name as a strong signal warranting review.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A07:2021 — Identification and Authentication Failures; A02:2021 — Cryptographic Failures (hardcoded crypto keys)
PCI DSS v4.0
Requirement 8.6.2 — Hardcoded credentials (passwords/passphrases) for non-console administrative access and application accounts are prohibited. Requirement 8.3 — Authenticate individual non-consumer user accounts and credentials.
NIST SP 800-53 Rev 5
IA-5 — Authenticator Management: prohibits embedded/hardcoded authenticators in software and requires unique authenticators per environment. SA-15 — Development Process, Standards, and Tools: secure coding practices must prohibit hardcoded credentials.
NIST SP 800-57 Part 1
Key Management: cryptographic keys must have defined lifecycle with generation, distribution, storage, and revocation procedures. Hardcoded keys violate all lifecycle requirements.
CWE Top 25 (2024)
CWE-798 — Use of Hard-coded Credentials (ranked in CWE/SANS Top 25)
HIPAA Security Rule
§164.312(d) — Person or entity authentication; hardcoded credentials undermine authentication integrity
CISA Secure by Design
Hardcoded default and embedded credentials are explicitly called out as an insecure-by-design pattern that software manufacturers must eliminate. Deployment must require credential configuration rather than accepting embedded defaults. URL: https://www.cisa.gov/resources-tools/resources/secure-by-design

References

External resources and documentation

Similar Rules

Explore related security rules for Go

Frequently Asked Questions

Common questions about Hardcoded Credentials in Source Code

Hardcoded credentials are secrets — passwords, API keys, tokens, signing keys, and connection strings — embedded directly as string literals in source code. This is one of the most frequently occurring and impactful security vulnerabilities in software development, consistently appearing in real breaches with catastrophic consequences. **Why hardcoded secrets are permanently dangerous**: Source code is copied, forked, backed up, and diffed far more broadly than developers realize. A secret committed to any version control system persists in the commit history indefinitely — even `git rm` and `git commit` do not remove it. An attacker with read access to any historical snapshot (via GitHub, GitLab, Bitbucket, backup, or zip export) recovers the credential. Forcing a secret into git history is effectively publishing it. **Surface area of secret exposure beyond git**: - "**Compiled Go binaries**: Go embeds string literals directly in the binary's `.rodata`" section. The Unix `strings` command extracts all printable strings of 4+ characters. Tools like Ghidra with the "ghostrings" plugin specifically hunt for string constants that look like credentials. A hardcoded JWT secret or database password survives unchanged in every compiled artifact shipped to customers or placed in container images. - "**Container image layers**: Docker layers are union filesystem snapshots. Each layer" is a tar archive. `docker history --no-trunc` and `docker inspect` expose build-time ARG values. If a binary containing hardcoded credentials is in the image, `docker save` followed by `tar xf` and `strings` extracts them. - "**CI/CD pipeline artifacts**: Build systems cache compiled binaries and run logs. A" test output that prints a hardcoded constant, or a build artifact in a public artifact store, exposes the credential to anyone with artifact access. - "**Log files and crash dumps**: Go programs that log their configuration at startup" (common in 12-factor app patterns) may log environment variables or struct fields — including credential-named fields initialized from string literals. **Real-world incidents involving hardcoded credentials**: *Toyota T-Connect breach (2022–2023)*: Toyota disclosed that a contractor had accidentally published source code to a public GitHub repository containing credentials for a data server. The exposed data server contained information of approximately 296,019 Toyota T-Connect customers — names, phone numbers, and vehicle identification numbers. The credentials remained valid and exposed for approximately 4 years and 9 months before discovery. Toyota stated no financial data was accessed but could not rule out third-party access during the exposure window. *Internet Archive breach (October 2024)*: Threat actors obtained a GitLab personal access token that was exposed in a public repository. Using this token, they accessed the Internet Archive's GitLab instance and exfiltrated configuration files. The breach exposed 31 million user records (email addresses, usernames, bcrypt-hashed passwords, and other internal data). The token, once hardcoded in the repository, became the entry point for the entire breach. *Slack GitHub repository credential exposure (2022)*: Slack disclosed that hashed employee credentials and GitHub repository cloning tokens were exposed when an attacker gained access to a subset of Slack's GitHub repositories. The exposure included tokens that could be used to access Slack's internal systems. While Slack rotated all affected credentials immediately, the incident demonstrated how a single exposed token creates a lateral movement path from external repository access to internal infrastructure. **Scale of the problem — GitGuardian research (2024)**: GitGuardian's "State of Secrets Sprawl" report analyzed over 1 billion commits: - 23.8 million new plaintext secrets were detected in public GitHub repositories in 2023 - 70% of secrets exposed in 2021 remain valid and active 2 years later — secret rotation after discovery is the exception, not the rule - "The most common secret types: API keys (35%), generic credentials (28%), private keys (17%)" - "Developer-to-secret ratio: approximately 1 hardcoded secret per 1,000 commits in" enterprise repositories **Extraction techniques attackers use**: 1. `strings /path/to/binary | grep -iE "(password|secret|key|token)" | grep -v "^[[:space:]]*$"` 2. TruffleHog v3: `trufflehog git file:///path/to/repo --only-verified` — scans git history with entropy analysis and regex patterns against known-secret formats 3. Gitleaks: `gitleaks detect --source /path/to/repo` — rule-based scanning with 150+ built-in patterns for AWS keys, GitHub tokens, Stripe keys, etc. 4. Docker layer inspection: `docker save image:tag | tar xf - | find . -name "*.tar" -exec tar xf {} \; | strings | grep -i secret` 5. Ghidra ghostrings plugin: static analysis of Go binaries to identify Go string constants and cross-reference them against credential patterns **CWE taxonomy for this vulnerability class**: - "**CWE-798** (parent): General hardcoded credentials — covers any credential type" - "**CWE-259** (child): Specifically hardcoded passwords in authentication code" - "**CWE-321** (child): Hardcoded cryptographic keys — JWT signing secrets, AES keys," HMAC secrets. These are both a credential and a cryptographic failure simultaneously. **Go-specific remediation hierarchy** (in order of increasing security): 1. `os.Getenv("SECRET_NAME")` — environment variables; acceptable for development, simple deployments. Note: env vars are visible in `/proc/<pid>/environ`, `docker inspect`, and CI/CD log output if logged. 2. `github.com/spf13/viper` with config files excluded from git — supports env var binding, remote config (etcd, Consul), and layered config. Better than bare os.Getenv for complex apps. 3. `github.com/hashicorp/vault/sdk` — HashiCorp Vault dynamic secrets. Vault generates short-lived credentials on demand and revokes them automatically. Compromised credentials expire without requiring rotation. Vault audit logs all secret accesses. 4. AWS Secrets Manager (`github.com/aws/aws-sdk-go-v2/service/secretsmanager`) / GCP Secret Manager / Azure Key Vault — cloud-native secrets management with IAM-based access control, automatic rotation for supported services (RDS, Redshift), and CloudTrail audit logging. **CISA Secure by Design guidance**: CISA's "Secure by Design" principles explicitly list elimination of default and hardcoded credentials as a foundational requirement. The guidance states that software manufacturers should make it technically impossible to deploy software with default credentials by requiring credential configuration as part of the installation process.
Use Code Pathfinder to scan your codebase: pathfinder scan --ruleset golang/GO-SEC-004 --project .
This vulnerability is rated as HIGH severity.
Yes! Code Pathfinder allows you to customize rules. Modify detection patterns, adjust severity levels, add custom sanitizers, and configure the rule to fit your organization's security policies.

New feature

Get these findings posted directly on your GitHub pull requests

The Hardcoded Credentials in Source Code rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works