Inclusion of Sensitive Information in Source Code Comments
Description
Inclusion of Sensitive Information in Source Code Comments occurs when developers leave sensitive information in code comments that get deployed to production. This includes passwords, API keys, internal URLs, database connection strings, security notes, TODO items revealing vulnerabilities, and personal information. While comments may seem harmless, they can be exposed through source maps, client-side code, version control, or server misconfigurations.
Risk
Comments in client-side code (JavaScript, HTML) are directly visible to users. Server-side comments may leak through source code disclosure vulnerabilities. Version control history preserves comments even after removal. Source maps expose original code including comments. Comments describing security weaknesses guide attackers. Internal URLs and credentials enable further attacks. Compliance violations may occur from PII in comments.
Solution
Establish policies against sensitive data in comments. Use automated scanning to detect credentials in code. Store secrets in secure configuration management systems. Remove debug comments before deployment. Configure build processes to strip comments from production code. Review code for sensitive comments during security audits. Train developers on secure commenting practices.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Credential Exposure Passwords and API keys in comments are exposed. |
| Security | Scope: Attack Surface Security notes guide attackers to vulnerabilities. |
| Privacy | Scope: Information Disclosure Personal data and internal details leaked. |
Example Code + Solution Code
Vulnerable Code
<!-- VULNERABLE: HTML comments with sensitive info -->
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<!-- TODO: Remove debug credentials before production
Admin login: admin / Admin123! -->
<!-- Database server: db-internal.corp.local:5432 -->
</head>
<body>
<!-- Author: [email protected], ext 4521 -->
<form action="/login" method="POST">
<!-- Form validation bypass: add ?debug=true to URL -->
<input type="text" name="username" />
<input type="password" name="password" />
</form>
</body>
</html>
// VULNERABLE: JavaScript with sensitive comments
const API_KEY = 'sk_live_abc123'; // Production key
// TODO: This validation is weak, attacker can bypass with SQL injection
function validateUser(username) {
// Old code: const query = "SELECT * FROM users WHERE name = '" + username + "'";
// Still vulnerable, just uses different injection point
return db.query(`SELECT * FROM users WHERE name = '${username}'`);
}
// Debug: admin panel at /secret-admin-panel-2024
// Backup admin: backup_admin / B@ckup2024!
/*
* API Endpoints (internal use):
* Production: https://api.internal.corp/v2
* Staging: https://staging-api.corp:8443
* Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
*/
// John's notes: The encryption here is weak, using MD5
// We should fix this but deadline is tomorrow
function hashPassword(password) {
return md5(password); // FIXME: Use bcrypt
}
// VULNERABLE: Java with sensitive comments
public class UserService {
// Database credentials - DO NOT COMMIT
// private static final String DB_PASSWORD = "Pr0duct10n_P@ss!";
/*
* SECURITY NOTE: This method has a race condition
* that allows duplicate transactions. Exploit by
* sending requests within 100ms window.
*/
public void processTransaction(Transaction t) {
// Temporary bypass for QA: if (user.isQA()) return true;
validateTransaction(t);
}
// TODO: Remove before release - allows any password
// if (password.equals("master_override")) return true;
/**
* Author: jsmith
* Phone: 555-123-4567
* SSN: 123-45-6789 (for payroll integration testing)
*/
public void updateEmployee(Employee e) {
// ...
}
}
# VULNERABLE: Python with sensitive comments
import hashlib
# AWS credentials for deployment
# AWS_ACCESS_KEY = 'AKIA...'
# AWS_SECRET_KEY = 'wJalrXUtnFEMI...'
# Database connection (prod)
# postgresql://admin:[email protected]:5432/main
def authenticate(username, password):
# Known vulnerability: timing attack possible here
# See internal ticket SEC-2023-0142
stored_hash = get_password_hash(username)
input_hash = hashlib.md5(password.encode()).hexdigest()
return stored_hash == input_hash # FIXME: Use constant-time compare
# Debug backdoor - remove before release!
# if username == 'debug_user': return True
"""
Internal API documentation:
- /api/admin/users - requires X-Admin-Token: admin_token_12345
- /api/debug/dump - dumps all user data (disable in prod!)
"""
Fixed Code
<!-- SAFE: No sensitive information in comments -->
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="/login" method="POST">
<input type="text" name="username" />
<input type="password" name="password" />
</form>
</body>
</html>
// SAFE: Credentials loaded from secure configuration
const config = require('./config'); // Not in version control
function validateUser(username) {
// Use parameterized queries
return db.query('SELECT * FROM users WHERE name = ?', [username]);
}
// Use proper documentation systems, not code comments
// Security issues tracked in separate issue tracker
function hashPassword(password) {
return bcrypt.hashSync(password, 10);
}
// Build process strips comments from production bundle
// Comments here are for development only
// SAFE: No sensitive data in comments
public class UserService {
@Value("${database.password}") // Loaded from secure config
private String dbPassword;
/**
* Processes a transaction with proper validation.
* @param t The transaction to process
* @throws TransactionException if validation fails
*/
public void processTransaction(Transaction t) throws TransactionException {
validateTransaction(t);
}
/**
* Updates employee information.
* @param e The employee to update
*/
public void updateEmployee(Employee e) {
// Implementation
}
}
# SAFE: Secrets managed externally
import os
import bcrypt
from config import get_secret # Secure secret management
def authenticate(username, password):
"""Authenticate user with secure password comparison."""
stored_hash = get_password_hash(username)
return bcrypt.checkpw(password.encode(), stored_hash)
# Security issues tracked in separate system (JIRA, etc.)
# No sensitive URLs or credentials in code
// SAFE: Build configuration to strip comments
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false, // Remove all comments
},
},
extractComments: false,
}),
],
},
};
# SAFE: Pre-commit hook to detect secrets
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
- repo: https://github.com/trufflesecurity/trufflehog
rev: v3.0.0
hooks:
- id: trufflehog
# SAFE: Automated comment scanning
import re
import sys
SENSITIVE_PATTERNS = [
r'password\s*[:=]\s*["\']',
r'api_?key\s*[:=]\s*["\']',
r'secret\s*[:=]\s*["\']',
r'token\s*[:=]\s*["\']',
r'\b[A-Z0-9]{20}\b', # AWS-style keys
r'TODO.*password',
r'FIXME.*security',
]
def scan_for_sensitive_comments(file_path):
"""Scan file for potentially sensitive comments."""
issues = []
with open(file_path) as f:
for line_num, line in enumerate(f, 1):
for pattern in SENSITIVE_PATTERNS:
if re.search(pattern, line, re.IGNORECASE):
issues.append({
'line': line_num,
'content': line.strip(),
'pattern': pattern
})
return issues
# Run as part of CI/CD pipeline
if __name__ == '__main__':
issues = scan_for_sensitive_comments(sys.argv[1])
if issues:
print(f"Found {len(issues)} potential sensitive comments")
sys.exit(1)
Exploited in the Wild
API Key Exposure
API keys in JavaScript comments were harvested for abuse.
Database Credential Leaks
Connection strings in comments led to database breaches.
Vulnerability Disclosure
TODO comments describing security weaknesses guided targeted attacks.
Tools to test/exploit
-
git-secrets — prevents secrets in commits.
-
truffleHog — scans repos for secrets.
-
detect-secrets — pre-commit secret detection.
-
Browser view source — examine client-side comments.
CVE Examples
-
CVEs from credentials exposed in source comments.
-
Data breaches from leaked internal documentation.
References
-
MITRE. "CWE-615: Inclusion of Sensitive Information in Source Code Comments." https://cwe.mitre.org/data/definitions/615.html
-
OWASP. "Information Exposure Through Comments." https://owasp.org/