← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Hardcoded Credentials

security PHP 5.0+ Beginner
debt(d5/e5/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep, trufflehog, and gitleaks — all specialist SAST/secret-scanning tools. These are not default linters and won't catch the issue in a standard IDE or compile step, but they are well-established tools for this exact problem. Plain code review may catch obvious cases, but the credential may already be deep in git history before review happens.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says move credentials to environment variables or a secrets manager and update .gitignore. However, common_mistakes highlight that rotating the credential without purging git history is insufficient — git filter-repo or BFG must be run, .env must be retroactively excluded, and all deployment configs (docker-compose, Kubernetes manifests) must be audited. This is more than a one-line patch but typically stays within one codebase/component rather than being a cross-cutting architectural rework.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The hardcoded credential itself is a localised problem — typically one or a few files are affected. However, the remediation burden (purging git history, rotating the credential externally, updating CI/CD and deployment secrets) imposes a persistent but bounded tax. It does not reshape the entire codebase or impose an ongoing structural cost on every future maintainer once properly resolved.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The canonical misconception is that private repositories are safe for storing secrets. This is a widely held and plausible belief — private repos feel restricted and secure — but it is wrong because repos can be breached, forked, accidentally made public, or accessed by former employees. This directly contradicts the developer's intuition about access control providing security, making it a serious cognitive trap rather than a mere edge case.

About DEBT scoring →

Also Known As

hardcoded password hardcoded API key credential in source

TL;DR

Passwords, API keys, or tokens written directly into source code — permanently exposed to anyone with repository access and impossible to rotate without a code change.

Explanation

Hardcoded credentials appear in source code, config files committed to git, docker images, and CI/CD logs. Once in git history they are permanent — even deleting the file does not remove the commit. Secret scanning tools (GitHub, GitLab, truffleHog) automatically detect patterns like API keys and alert providers. The correct approach is runtime injection via environment variables or a secrets manager, never compile-time embedding.

Common Misconception

Private repositories are safe for storing secrets — private repos are breached, forked, accidentally made public, or accessed by former employees; secrets must never be in code regardless of visibility.

Why It Matters

A single hardcoded credential in a git repository — even a private one — is a breach waiting to happen; once committed it is effectively permanent and can be found by anyone who gains repo access.

Common Mistakes

  • Committing .env files to version control — add .env to .gitignore before the first commit.
  • Hardcoding credentials in docker-compose.yml or Kubernetes manifests committed to git.
  • Using placeholder credentials that 'get replaced in production' but never do.
  • Rotating the credential without removing it from git history — use git filter-repo or BFG.

Code Examples

✗ Vulnerable
// Hardcoded in source — permanent exposure:
$pdo = new PDO('mysql:host=db', 'root', 'supersecret123');

$client = new StripeClient('sk_live_abc123realkey');

define('ADMIN_PASS', 'letmein');
✓ Fixed
// Runtime injection via environment variables:
$pdo = new PDO(
    'mysql:host=' . getenv('DB_HOST'),
    getenv('DB_USER'),
    getenv('DB_PASS')
);

$client = new StripeClient(getenv('STRIPE_SECRET_KEY'));

// Or from a secrets manager:
$secret = $vault->getSecret('prod/stripe');

Added 16 Mar 2026
Edited 22 Mar 2026
Views 29
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Perplexity 7 Amazonbot 7 Google 3 Unknown AI 3 Ahrefs 2 SEMrush 2 Majestic 1
crawler 23 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Low
⚡ Quick Fix
Move credentials to environment variables (getenv()) or a secrets manager; add .env to .gitignore immediately
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
$password = ' or $apiKey = ' or $secret = ' as string literals in source files
Auto-detectable: ✓ Yes semgrep trufflehog gitleaks
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: High Context: File
CWE-798 CWE-259

✓ schema.org compliant