CWE-312 in APIs
- CWE ID
- CWE-312
- Category
- Data Exposure
- Severity
- HIGH
- Short Name
- Cleartext Storage
What is CWE-312?
CWE-312 refers to Clear Text Storage of Sensitive Information. This weakness occurs when an application stores sensitive data in an unencrypted format, making it accessible to anyone who can access the storage medium. The weakness allows unauthorized parties to read, modify, or exfiltrate sensitive information without needing any special access rights.
The core issue is that data which should be protected (such as passwords, API keys, personal information, or financial data) is stored in a format that can be easily read by anyone with access to the storage system. This might include database records, log files, configuration files, or even memory dumps.
CWE-312 is particularly dangerous because it violates the fundamental principle of data protection: sensitive information should only be accessible to authorized parties. When data is stored in clear text, it creates a broad attack surface where any breach of the storage system immediately compromises all sensitive data within it.
CWE-312 in API Contexts
In API environments, CWE-312 manifests in several specific ways that are particularly relevant to developers and security teams. APIs often handle sensitive data throughout their request-response lifecycle, and improper storage practices can create significant vulnerabilities.
Database Storage: APIs frequently store user credentials, authentication tokens, personal information, and business data in databases. When this data is stored without encryption, a database breach exposes all sensitive information. For example, storing user passwords in plain text rather than hashed and salted formats is a classic CWE-312 violation.
Log Files: API logging is essential for debugging and monitoring, but logs often contain sensitive data like authentication headers, query parameters, or request bodies. When logs are stored unencrypted, anyone with access to log storage can extract sensitive information. This includes API keys, personal data, and authentication credentials that appear in request/response logs.
Configuration Files: API services often store configuration data including database connection strings, API keys for third-party services, and encryption keys. When these configuration files are stored in clear text, they provide attackers with the credentials needed to compromise the entire system.
Cache Storage: APIs use caching mechanisms to improve performance, but cached responses might contain sensitive user data. If cache storage is not properly secured, cached sensitive information becomes accessible to unauthorized parties.
Session Storage: Many APIs store session tokens or authentication state in databases or cache systems. When session data is stored unencrypted, attackers who gain access to storage can hijack user sessions and impersonate legitimate users.
Detection
Detecting CWE-312 requires both manual code review and automated scanning tools. For API developers, several approaches can identify clear text storage vulnerabilities:
Code Review: Manual inspection of code that handles sensitive data is essential. Look for database queries that store passwords without hashing, logging statements that output sensitive data, or configuration files that contain unencrypted credentials. Pay special attention to authentication and authorization code paths.
Database Schema Analysis: Review database schemas for columns that should contain sensitive data but lack encryption. Look for password fields, social security numbers, credit card information, and personal identification data stored in VARCHAR or TEXT columns without encryption indicators.
Log Analysis: Examine log configuration and output to identify sensitive data exposure. Check for debug logging in production environments, log levels that include request/response bodies, and logging of authentication headers or tokens.
Configuration File Auditing: Review all configuration files for unencrypted credentials, API keys, and connection strings. Look for files in version control that contain sensitive information, and check for default credentials or weak encryption practices.
Automated Scanning with middleBrick: middleBrick provides comprehensive CWE-312 detection through its 12-point security scanning framework. The scanner identifies clear text storage vulnerabilities by analyzing API endpoints for data exposure patterns, checking for proper authentication mechanisms, and validating encryption practices.
The middleBrick CLI makes detection straightforward: middlebrick scan https://api.example.com performs a comprehensive security assessment in 5-15 seconds, identifying CWE-312 vulnerabilities along with other API security issues. The scanner tests unauthenticated attack surfaces and provides a security risk score with prioritized findings.
For continuous detection, the middleBrick GitHub Action can be integrated into CI/CD pipelines to automatically scan APIs before deployment. This ensures that CWE-312 vulnerabilities are caught early in the development lifecycle rather than discovered in production.
Remediation
Remediating CWE-312 requires a multi-layered approach that addresses both technical implementation and development practices. Here are specific code-level fixes for common API scenarios:
Password Storage: Never store passwords in clear text. Use strong, adaptive hashing algorithms like bcrypt, Argon2, or PBKDF2 with appropriate work factors. Here's a Node.js example using bcrypt:
const bcrypt = require('bcrypt');
// Hashing passwords before storage
async function createUser(password) {
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);
return db.users.create({ password: hashedPassword });
}
// Verifying passwords during authentication
async function authenticateUser(inputPassword, storedHash) {
return await bcrypt.compare(inputPassword, storedHash);
}
Database Encryption: Use application-layer encryption for sensitive data stored in databases. Encrypt data before it enters the database and decrypt it only when needed. Here's a Python example using cryptography:
from cryptography.fernet import Fernet
import base64
import os
class DatabaseEncryptor:
def __init__(self, key):
self.cipher = Fernet(key)
def encrypt_data(self, data):
return self.cipher.encrypt(data.encode())
def decrypt_data(self, encrypted_data):
return self.cipher.decrypt(encrypted_data).decode()
# Usage
key = os.environ.get('DB_ENCRYPTION_KEY')
encryptor = DatabaseEncryptor(key.encode())
# Encrypt before storing
encrypted_ssn = encryptor.encrypt_data('123-45-6789')
# Decrypt when needed
plain_ssn = encryptor.decrypt_data(encrypted_ssn)Log Sanitization: Implement log filtering to remove sensitive data before it's written to logs. Create middleware that inspects log messages and redacts sensitive information:
const sensitivePatterns = [
/(?<=Bearer\s)[^\s]+/gi, // JWT tokens
/password=([^&]+)/gi, // Query parameters
/"password":"[^"]+"/gi // JSON bodies
];
function sanitizeLog(message) {
return sensitivePatterns.reduce((msg, pattern) => {
return msg.replace(pattern, '[REDACTED]');
}, message);
}
// Express middleware for request logging
app.use((req, res, next) => {
const sanitizedHeaders = { ...req.headers };
delete sanitizedHeaders.authorization;
delete sanitizedHeaders.cookie;
console.log(`Request: ${req.method} ${req.path}`, {
headers: sanitizedHeaders,
body: sanitizeLog(JSON.stringify(req.body))
});
next();
});
Configuration Security: Store configuration secrets in environment variables or secure secret management systems rather than in configuration files. Use libraries like dotenv for local development and integrate with cloud secret managers in production:
import os
from pydantic import BaseSettings
class Settings(BaseSettings):
DATABASE_URL: str = os.getenv('DATABASE_URL')
API_KEY: str = os.getenv('API_KEY')
JWT_SECRET: str = os.getenv('JWT_SECRET')
class Config:
env_file = '.env'
settings = Settings()
# Never commit .env files to version control
# Use production secret managers in deployment
Session Management: Store session data securely using signed, encrypted cookies or secure server-side storage. Never store sensitive session data in clear text:
const session = require('express-session');
const FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore({
secret: process.env.SESSION_SECRET,
encrypt: true, // Encrypt session data on disk
ttl: 86400
}),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'strict'
}
}));
API Key Management: Implement proper API key rotation and storage. Use secure key vaults, avoid hardcoding keys in source code, and implement key expiration policies:
package main
import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"time"
)
func GenerateAPIKey() (string, error) {
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(key), nil
}
// Store in secure vault rather than config
// Implement key rotation every 90 days
middleBrick's scanning capabilities can verify that these remediation measures are properly implemented. The scanner checks for proper authentication mechanisms, validates encryption practices, and ensures sensitive data is not exposed in API responses or logs.