-
Notifications
You must be signed in to change notification settings - Fork 4
Sensitive Data Handling Guidelines
Proper handling of sensitive data is critical to maintaining security and privacy in web applications. This guide covers best practices for identifying, protecting, and managing sensitive information throughout its lifecycle.
Sensitive data includes any information that could harm individuals, organizations, or systems if improperly disclosed or modified. Common categories include:
- Full names
- Addresses
- Phone numbers
- Email addresses
- Social security/tax identification numbers
- Date of birth
- Government-issued ID numbers
- Credit card numbers
- Bank account details
- Payment records
- Financial statements
- Tax information
- Passwords
- API keys
- Access tokens
- Session identifiers
- Private keys
- Trade secrets
- Business strategies
- Proprietary algorithms
- Customer lists
- Internal communications
Implementing a data classification system helps determine appropriate protection levels:
Classification | Description | Examples | Protection Level |
---|---|---|---|
Public | Information that can be freely disclosed | Marketing materials, public documentation | Basic security controls |
Internal | For internal use, limited sensitivity | Employee directory, project plans | Standard security controls |
Confidential | Sensitive data with access restrictions | Customer records, financial data | Enhanced security controls |
Restricted | Highly sensitive information | Health records, authentication secrets | Highest security controls |
- Conduct regular security assessments
- Use static analysis tools to detect hardcoded secrets
- Implement dynamic scanning to identify sensitive data leakage
- Perform penetration testing with focus on data protection
- OWASP Sensitive Data Exposure
- NIST Guidelines for Media Sanitization
- PCI Security Standards
- GDPR Official Text
Proper handling of sensitive data is critical to maintaining security and privacy in web applications. This guide covers best practices for identifying, protecting, and managing sensitive information throughout its lifecycle.
Sensitive data includes any information that could harm individuals, organizations, or systems if improperly disclosed or modified. Common categories include:
- Full names
- Addresses
- Phone numbers
- Email addresses
- Social security/tax identification numbers
- Date of birth
- Government-issued ID numbers
- Credit card numbers
- Bank account details
- Payment records
- Financial statements
- Tax information
- Passwords
- API keys
- Access tokens
- Session identifiers
- Private keys
- Trade secrets
- Business strategies
- Proprietary algorithms
- Customer lists
- Internal communications
Implementing a data classification system helps determine appropriate protection levels:
Classification | Description | Examples | Protection Level |
---|---|---|---|
Public | Information that can be freely disclosed | Marketing materials, public documentation | Basic security controls |
Internal | For internal use, limited sensitivity | Employee directory, project plans | Standard security controls |
Confidential | Sensitive data with access restrictions | Customer records, financial data | Enhanced security controls |
Restricted | Highly sensitive information | Health records, authentication secrets | Highest security controls |
- Collect only necessary data (data minimization principle)
- Implement privacy by design principles
- Regularly review data necessity and delete unneeded information
Store secrets in environment variables:
# .env file example
DATABASE_URL=postgresql://username:password@localhost:5432/mydb
API_KEY=sk_live_51H3k2k...
JWT_SECRET=eyJhbGciOiJIUz...
Never commit .env
files to version control:
# .gitignore example
.env
.env.local
.env.*.local
For production environments, consider dedicated secret management solutions:
- AWS Secrets Manager: Managed service for storing and retrieving secrets
- HashiCorp Vault: Open-source secrets management with extensive features
- Google Secret Manager: GCP's secret storage service
- Azure Key Vault: Microsoft's cloud-based secret storage
Protect stored data:
- Database-level encryption
- File system encryption
- Backup encryption
Protect data moving between systems:
- HTTPS/TLS for all web traffic
- Secure protocols for API communications
- VPN for administrative access
For highest security requirements:
- Encrypt data before storing in your system
- Only allow decryption by authorized end users
- Your system never has access to unencrypted data
- Implement strict RBAC for sensitive data access
- Use the principle of least privilege
- Require additional authentication for sensitive operations
- Log and monitor all access to sensitive data
Using Node.js and dotenv:
// Load environment variables from .env file
require('dotenv').config();
// Access secrets via environment variables
const dbConnection = {
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};
// Never log secrets
console.log('Connected to database:', dbConnection.host);
// NOT: console.log('Database connection:', dbConnection);
Keep secrets server-side only:
// API route with authentication
app.get('/api/user-data', authenticateUser, (req, res) => {
// Use API key server-side only
const apiKey = process.env.EXTERNAL_API_KEY;
// Make authenticated request to external service
fetch('https://api.example.com/data', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
})
.then(response => response.json())
.then(data => {
// Return only necessary data to client
res.json({
username: data.username,
preferences: data.preferences
// Do NOT include API key or other sensitive data
});
});
});
Using Node.js crypto module:
const crypto = require('crypto');
// Encrypt data
function encryptData(text, secretKey) {
// Generate random initialization vector
const iv = crypto.randomBytes(16);
// Create cipher
const cipher = crypto.createCipheriv(
'aes-256-gcm',
Buffer.from(secretKey, 'hex'),
iv
);
// Encrypt data
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
// Get auth tag for GCM mode
const authTag = cipher.getAuthTag().toString('hex');
// Return everything needed for decryption
return {
iv: iv.toString('hex'),
encrypted,
authTag
};
}
// Decrypt data
function decryptData(encryptedData, secretKey) {
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
Buffer.from(secretKey, 'hex'),
Buffer.from(encryptedData.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));
let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
- Use parameterized queries to prevent SQL injection:
// Using prepared statements with parameterized queries
const { Pool } = require('pg');
const pool = new Pool(/* connection details */);
async function getUserData(userId) {
// SAFE: Uses parameterized query
const query = 'SELECT name, email FROM users WHERE id = $1';
const result = await pool.query(query, [userId]);
return result.rows[0];
}
// UNSAFE - DO NOT DO THIS:
// const query = `SELECT name, email FROM users WHERE id = ${userId}`;
- Column-level encryption for sensitive fields:
-- Store encrypted data in database
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
-- Encrypted columns
ssn_encrypted BYTEA,
ssn_iv BYTEA,
credit_card_encrypted BYTEA,
credit_card_iv BYTEA,
-- Non-sensitive data
email TEXT
);
- Database user permissions with least privilege:
-- Create application-specific database user with limited permissions
CREATE USER app_user WITH PASSWORD 'strong_password';
-- Grant only necessary permissions
GRANT SELECT, INSERT, UPDATE ON customers TO app_user;
GRANT USAGE, SELECT ON SEQUENCE customers_id_seq TO app_user;
-- Deny direct table deletion
REVOKE DELETE ON customers FROM app_user;
- Show generic error messages to users
- Log detailed errors server-side only
- Sanitize sensitive data from logs
// Error handling middleware
app.use((err, req, res, next) => {
// Log error details (server-side only)
console.error('Error details:', {
message: err.message,
stack: err.stack,
// Sanitize any sensitive data
request: sanitizeRequestData(req)
});
// Return generic error to client
res.status(500).json({
error: 'An unexpected error occurred'
// Don't include detailed error information
});
});
// Sanitize sensitive data from request
function sanitizeRequestData(req) {
const sanitized = {...req.body};
// Remove sensitive fields
delete sanitized.password;
delete sanitized.creditCard;
delete sanitized.ssn;
// Mask partial values if needed for debugging
if (sanitized.email) {
sanitized.email = maskEmail(sanitized.email);
}
return sanitized;
}
Different regulations have specific requirements for handling sensitive data:
Regulation | Region | Key Requirements |
---|---|---|
GDPR | European Union | Explicit consent, right to erasure, data portability |
CCPA/CPRA | California, USA | Disclosure requirements, opt-out rights, data deletion |
HIPAA | USA (Healthcare) | PHI protection, technical safeguards, breach notification |
PCI DSS | Global (Payment) | Secure transmission, restricted access, regular testing |
SOX | USA (Financial) | Data integrity, audit controls, retention requirements |
- Conduct regular security assessments
- Use static analysis tools to detect hardcoded secrets
- Implement dynamic scanning to identify sensitive data leakage
- Perform penetration testing with focus on data protection
- [OWASP Sensitive Data Exposure](https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure)
- [NIST Guidelines for Media Sanitization](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-88r1.pdf)
- [PCI Security Standards](https://www.pcisecuritystandards.org/)
- [GDPR Official Text](https://gdpr-info.eu/)