Overview
HTTP Ledger provides built-in security features to prevent sensitive data from appearing in logs. The primary security mechanism is field masking, which automatically replaces sensitive values with masked placeholders.
maskFields
Array of field names to mask in request bodies, response bodies, headers, and query parameters. Matching is case-insensitive.
Basic Usage
app . use ( logger ({
maskFields: [ 'password' , 'token' , 'secret' , 'apiKey' ]
}));
How Field Masking Works
When a field name matches an entry in maskFields, its value is replaced with "***MASKED***":
Original Request:
Logged Output:
Nested Field Masking
Field masking works recursively on nested objects:
app . use ( logger ({
maskFields: [ 'password' , 'creditCard' , 'ssn' ]
}));
Original Data:
{
"user" : {
"name" : "John Doe" ,
"credentials" : {
"password" : "secret123"
}
},
"payment" : {
"creditCard" : "4111-1111-1111-1111"
}
}
Logged Output:
{
"user" : {
"name" : "John Doe" ,
"credentials" : {
"password" : "***MASKED***"
}
},
"payment" : {
"creditCard" : "***MASKED***"
}
}
Common Sensitive Fields
Always mask authentication credentials, personal identifiable information (PII), and financial data.
app . use ( logger ({
maskFields: [
// Authentication
'password' ,
'passwd' ,
'pwd' ,
'token' ,
'accessToken' ,
'refreshToken' ,
'apiKey' ,
'api_key' ,
'secret' ,
'secretKey' ,
'privateKey' ,
// Financial
'creditCard' ,
'cardNumber' ,
'cvv' ,
'ssn' ,
'bankAccount' ,
// Personal
'birthdate' ,
'dob' ,
'phone' ,
'address'
]
}));
Masking in Different Contexts
Field masking applies to multiple parts of the request/response:
Request Bodies
app . use ( logger ({
logBody: true ,
maskFields: [ 'password' ]
}));
// POST /api/login
// Body: { "email": "[email protected] ", "password": "secret" }
// Logged: { "email": "[email protected] ", "password": "***MASKED***" }
Response Bodies
app . use ( logger ({
logResponse: true ,
maskFields: [ 'accessToken' , 'refreshToken' ]
}));
// Response: { "user": {...}, "accessToken": "eyJhbG...", "refreshToken": "def50200..." }
// Logged: { "user": {...}, "accessToken": "***MASKED***", "refreshToken": "***MASKED***" }
Query Parameters
app . use ( logger ({
logQueryParams: true ,
maskFields: [ 'api_key' , 'token' ]
}));
// GET /api/data?api_key=secret123&user=john
// Logged queryParams: { "api_key": "***MASKED***", "user": "john" }
app . use ( logger ({
maskFields: [ 'authorization' ],
excludedHeaders: [] // Don't exclude, just mask
}));
// Headers: { "authorization": "Bearer token123", "content-type": "application/json" }
// Logged: { "authorization": "***MASKED***", "content-type": "application/json" }
You can combine maskFields with excludedHeaders for defense in depth:
app . use ( logger ({
// Completely remove these headers from logs
excludedHeaders: [ 'authorization' , 'cookie' ],
// Mask these fields in bodies and query params
maskFields: [ 'password' , 'token' , 'secret' ]
}));
Use excludedHeaders when you don’t want the header logged at all. Use maskFields when you want to know the field was present but hide its value.
Production Security Example
Here’s a comprehensive security configuration for production:
const express = require ( 'express' );
const logger = require ( 'http-ledger' );
const app = express ();
app . use ( logger ({
// Exclude authentication headers entirely
excludedHeaders: [
'authorization' ,
'cookie' ,
'x-api-key' ,
'x-auth-token'
],
// Mask sensitive fields in bodies and query params
maskFields: [
'password' ,
'passwd' ,
'token' ,
'accessToken' ,
'refreshToken' ,
'apiKey' ,
'api_key' ,
'secret' ,
'secretKey' ,
'creditCard' ,
'cardNumber' ,
'cvv' ,
'ssn'
],
// Don't log bodies in production to reduce exposure
logBody: process . env . NODE_ENV === 'development' ,
logResponse: false
}));
import express from 'express' ;
import logger , { ApiLoggerOptions } from 'http-ledger' ;
const app = express ();
const securityConfig : ApiLoggerOptions = {
excludedHeaders: [
'authorization' ,
'cookie' ,
'x-api-key' ,
'x-auth-token'
],
maskFields: [
'password' ,
'passwd' ,
'token' ,
'accessToken' ,
'refreshToken' ,
'apiKey' ,
'api_key' ,
'secret' ,
'secretKey' ,
'creditCard' ,
'cardNumber' ,
'cvv' ,
'ssn'
],
logBody: process . env . NODE_ENV === 'development' ,
logResponse: false
};
app . use ( logger ( securityConfig ));
Security Best Practices
Always Mask Credentials Never log passwords, API keys, tokens, or authentication credentials in plain text
Protect PII Mask personal identifiable information like SSN, credit cards, addresses
Environment-Based Logging Disable body logging in production to minimize sensitive data exposure
Regular Audits Regularly review logs to ensure no sensitive data is leaking
Implementation Details
Field masking is implemented in src/utils/logFormatter.ts:76-98. The masking:
Works recursively on nested objects
Is case-insensitive
Applies to arrays of objects
Replaces any data type with "***MASKED***"
Occurs before custom formatters run
Field masking happens in-memory and doesn’t modify the original request/response objects. It only affects the logged output.
Basic Options Control what gets logged with logBody and excludedHeaders
Production Setup Complete production security configuration guide