James Williams
A08: Sensitive data exposure occurs when applications don't properly protect sensitive information
A09: Insufficient logging allows attackers to persist undetected
Impact: Data breaches, regulatory fines, reputation damage
<!-- VULNERABLE: Plaintext storage -->
CREATE TABLE users (
id INT,
username VARCHAR(50),
password VARCHAR(50), -- Plaintext
ssn VARCHAR(20), -- Plaintext
credit_card VARCHAR(20) -- Plaintext
);
<!-- SECURE: Encrypted storage -->
CREATE TABLE users (
id INT,
username VARCHAR(50),
password_hash VARCHAR(255), -- Hashed
ssn_encrypted BLOB, -- Encrypted
credit_card_encrypted BLOB -- Encrypted
);
<!-- VULNERABLE: Weak encryption -->
MD5(password) // Easily cracked
DES(data) // 56-bit key
<!-- SECURE: Strong encryption -->
bcrypt(password, 12) // Adaptive hashing
AES-256-GCM(data) // Strong encryption
<!-- Data classification levels -->
PUBLIC: No restrictions
INTERNAL: Company use only
CONFIDENTIAL: Limited access
RESTRICTED: Highest security
<!-- Implementation -->
if (data.classification === 'RESTRICTED') {
requireStrongAuthentication();
requireEncryption();
logAccess(data, user);
}
<!-- VULNERABLE: No security logging -->
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (authenticate(username, password)) {
res.json({ success: true });
} else {
res.json({ success: false });
}
});
<!-- SECURE: Comprehensive logging -->
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (authenticate(username, password)) {
logger.info('Successful login', { username, ip: req.ip });
res.json({ success: true });
} else {
logger.warn('Failed login attempt', { username, ip: req.ip });
res.json({ success: false });
}
});
<!-- VULNERABLE: Log injection -->
logger.info('User action: ' + userInput);
<!-- Malicious input -->
userInput = 'admin\n[ERROR] System compromised'
<!-- SECURE: Sanitized logging -->
logger.info('User action: %s', sanitize(userInput));
<!-- SECURE: Structured logging -->
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'security.log' })
]
});
logger.info('Security event', {
event: 'login_attempt',
user: username,
ip: req.ip,
success: false
});
<!-- SECURE: Log rotation -->
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.DailyRotateFile({
filename: 'logs/security-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '14d'
})
]
});
<!-- SECURE: Database encryption -->
const crypto = require('crypto');
function encryptData(data, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipher('aes-256-gcm', key);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
encrypted,
iv: iv.toString('hex')
};
}
function decryptData(encryptedData, key, iv) {
const decipher = crypto.createDecipher('aes-256-gcm', key);
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
<!-- SECURE: Field-level encryption -->
// Store encrypted SSN
const encryptedSSN = encryptData(user.ssn, process.env.ENCRYPTION_KEY);
await db.users.create({
username: user.username,
ssn_encrypted: encryptedSSN.encrypted,
ssn_iv: encryptedSSN.iv
});
// Retrieve and decrypt
const user = await db.users.findById(id);
const decryptedSSN = decryptData(user.ssn_encrypted, process.env.ENCRYPTION_KEY, user.ssn_iv);
Skills Needed: Data protection, Privacy regulations, Encryption, Compliance
Our OS³ Studio provides hands-on experience with:
Access: Available through university portal
Lesson: Misconfigured logging can lead to massive data exposure
Use OS³ Studio to identify data exposure vulnerabilities and insufficient logging in the lab environment.
Time: 45 minutes
Focus on systematic testing and thorough documentation
Take a break, ask questions, or catch up on the previous task.
Next: Secure implementation and Task 2
<!-- SECURE: Database encryption -->
// Enable Transparent Data Encryption (TDE)
ALTER DATABASE MyDatabase
SET ENCRYPTION ON;
// Column-level encryption
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50),
ssn VARBINARY(MAX), -- Encrypted
credit_card VARBINARY(MAX) -- Encrypted
);
<!-- SECURE: Data masking -->
function maskSensitiveData(data) {
if (data.type === 'ssn') {
return data.value.replace(/(\d{3})\d{4}(\d{3})/, '$1-****-$2');
}
if (data.type === 'credit_card') {
return data.value.replace(/(\d{4})\d{8}(\d{4})/, '$1-********-$2');
}
return data.value;
}
<!-- SECURE: Security logging -->
const winston = require('winston');
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'security.log' })
]
});
// Log security events
securityLogger.warn('Failed login attempt', {
username: username,
ip: req.ip,
userAgent: req.headers['user-agent'],
timestamp: new Date().toISOString()
});
<!-- SECURE: Log monitoring -->
// Monitor for suspicious patterns
const suspiciousPatterns = [
/failed login/i,
/unauthorized access/i,
/privilege escalation/i
];
function analyzeLogs(logEntry) {
for (const pattern of suspiciousPatterns) {
if (pattern.test(logEntry.message)) {
alertSecurityTeam(logEntry);
}
}
}
<!-- SECURE: RBAC implementation -->
const roles = {
admin: ['read', 'write', 'delete'],
user: ['read'],
guest: []
};
function checkPermission(userRole, action) {
return roles[userRole].includes(action);
}
app.get('/sensitive-data', (req, res) => {
if (!checkPermission(req.user.role, 'read')) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(sensitiveData);
});
<!-- SECURE: Data anonymization -->
function anonymizeData(data) {
return {
id: hashId(data.id),
age: data.age,
gender: data.gender,
// Remove PII
// name: data.name,
// email: data.email
};
}
<!-- SECURE: GDPR compliance -->
// Right to be forgotten
app.delete('/user/:id', async (req, res) => {
const userId = req.params.id;
await anonymizeUserData(userId);
await deleteUserData(userId);
res.json({ message: 'User data deleted' });
});
// Data portability
app.get('/user/:id/export', async (req, res) => {
const userData = await getUserData(req.params.id);
res.json(userData);
});
<!-- SECURE: Audit trail -->
function logDataAccess(userId, dataType, action) {
auditLogger.info('Data access', {
userId: userId,
dataType: dataType,
action: action,
timestamp: new Date().toISOString(),
ip: req.ip
});
}
<!-- SECURE: Real-time monitoring -->
const monitoring = {
failedLogins: 0,
lastReset: Date.now()
};
function checkSecurityMetrics() {
if (monitoring.failedLogins > 10) {
alertSecurityTeam('High failed login rate');
monitoring.failedLogins = 0;
}
}
setInterval(checkSecurityMetrics, 60000); // Every minute
Use OS³ Studio to implement secure data protection and logging practices.
Time: 45 minutes
Focus on implementing industry-standard data protection practices
For students with additional time, explore the source code to understand:
Deliverable: Code review report with data protection recommendations