Introduction
Section titled “Introduction”CWE-210: Self-generated Error Message Containing Sensitive Information occurs when the product identifies an error condition and creates its own diagnostic or error messages that contain sensitive information. When that output includes Personally Identifiable Information (PII), the risks of misuse are significantly heightened.
This article discusses the risks associated with PII exposure through CWE-210 and provides remediation techniques, along with coding examples in Java, JavaScript, and Python.
Understanding the Risks
Section titled “Understanding the Risks”Direct Risks
Section titled “Direct Risks”-
Identity Theft: Exposure of personal identifiers can lead directly to identity theft.
-
Fraud: Exposed financial information, like credit card numbers or account details, can lead to fraudulent transactions.
-
Unauthorized Access: Sensitive information such as passwords or security answers can be used to gain unauthorized access to systems.
Indirect Risks
Section titled “Indirect Risks”-
Reputational Damage: Incidents of PII exposure can harm the organization’s reputation, potentially leading to customer loss.
-
Regulatory Penalties: Non-compliance with data protection laws (GDPR, HIPAA, etc.) can result in significant fines.
-
Operational Distractions: Managing the fallout from a data breach can consume significant time and resources.
Remediation Techniques
Section titled “Remediation Techniques”Mitigating the risk of PII exposure in self-generated information involves careful management of what data is included in output streams. Techniques include omitting unnecessary data, masking sensitive details, and encrypting outputs to secure potentially sensitive information.
1. Omitting Data
Section titled “1. Omitting Data”Avoid logging sensitive data unless absolutely necessary.
public class LogUtility { public void logMessage(String message) { // Ensure that no sensitive PII is logged System.out.println("Log: " + message); }}function logMessage(message) { // Avoid logging sensitive PII console.log("Log:", message);}def log_message(message): # Do not log sensitive PII print(f"Log: {message}")2. Masking Data
Section titled “2. Masking Data”If data must be included in logs or other outputs, ensure it is sufficiently masked.
public class User { public String maskEmail(String email) { int atIndex = email.indexOf("@"); return email.substring(0, 1) + "****" + email.substring(atIndex - 1); }}function maskEmail(email) { const atIndex = email.indexOf('@'); return email[0] + '****' + email[atIndex - 1] + email.substring(atIndex);}def mask_email(email): atIndex = email.index('@') return email[0] + '****' + email[atIndex - 1] + email[atIndex:]3. Encrypting Data
Section titled “3. Encrypting Data”When storing or transmitting data that could be logged or intercepted, use encryption.
import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.spec.GCMParameterSpec;import java.nio.ByteBuffer;import java.nio.charset.StandardCharsets;import java.security.SecureRandom;
public class EncryptionUtility { // secretKey is supplied by the caller, sourced from your KMS or secret store public static String encrypt(String data, SecretKey secretKey) throws Exception { byte[] iv = new byte[12]; new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, iv)); byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
byte[] payload = ByteBuffer.allocate(iv.length + encrypted.length).put(iv).put(encrypted).array(); return java.util.Base64.getEncoder().encodeToString(payload); }}const crypto = require('crypto');
// key: 32-byte Buffer loaded from your KMS or secret storefunction encrypt(data, key) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); const encrypted = Buffer.concat([cipher.update(data, 'utf8'), cipher.final()]); return iv.toString('hex') + ':' + encrypted.toString('hex');}from cryptography.fernet import Fernet
# key: Fernet key loaded from your secret store, never generated per calldef encrypt(data, key): cipher = Fernet(key) encrypted = cipher.encrypt(data.encode()) return encrypted.decode()Conclusion
Section titled “Conclusion”To effectively manage CWE-210 risks, developers and system administrators must be vigilant in controlling the content of output generated by applications, especially when handling PII. Implementing practices such as omitting, masking, and encrypting sensitive data can greatly reduce the likelihood of inadvertent exposure. This ensures compliance with privacy laws and helps maintain trust and security.
