Strip Sensitive Data Using Axios Interceptors
Axios request interceptors allow developers to inspect, modify, or sanitize HTTP requests before they are transmitted over the network. This article demonstrates how to implement an Axios request interceptor to automatically detect and strip sensitive user information—such as passwords, credit card numbers, or personally identifiable information (PII)—from request payloads, headers, and query parameters to ensure secure communication.
Understanding Axios Request Interceptors
An interceptor acts as middleware between your application code and
the network layer. When an outgoing request is initiated, Axios passes
the request configuration object (config) through any
registered request interceptors before executing the HTTP call.
To set up an interceptor, use the
axios.interceptors.request.use() method:
axios.interceptors.request.use(
(config) => {
// Modify config before request is sent
return config;
},
(error) => {
return Promise.reject(error);
}
);Creating a Data Sanitizer Function
To remove sensitive fields consistently, create a helper function that traverses data objects recursively and deletes or masks blacklisted keys.
const SENSITIVE_KEYS = ['password', 'confirmPassword', 'ssn', 'creditCard', 'cvv'];
function sanitizeData(data) {
if (!data || typeof data !== 'object') {
return data;
}
// Handle Arrays
if (Array.isArray(data)) {
return data.map(item => sanitizeData(item));
}
// Clone object to avoid mutating the original reference
const sanitized = { ...data };
for (const key of Object.keys(sanitized)) {
if (SENSITIVE_KEYS.includes(key.toLowerCase())) {
delete sanitized[key];
} else if (typeof sanitized[key] === 'object') {
sanitized[key] = sanitizeData(sanitized[key]);
}
}
return sanitized;
}Implementing the Interceptor
Once the sanitization logic is defined, attach it to your Axios
instance to process config.data (request body) and
config.params (URL query parameters).
import axios from 'axios';
// Create a dedicated Axios instance
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// Register the request interceptor
apiClient.interceptors.request.use(
(config) => {
// Sanitize JSON request bodies
if (config.data && typeof config.data === 'object' && !(config.data instanceof FormData)) {
config.data = sanitizeData(config.data);
}
// Sanitize URL query parameters
if (config.params && typeof config.params === 'object') {
config.params = sanitizeData(config.params);
}
// Optionally sanitize or remove specific sensitive headers
if (config.headers && config.headers['X-Internal-Secret']) {
delete config.headers['X-Internal-Secret'];
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default apiClient;Best Practices
- Avoid Direct Mutation: Always clone objects before modifying them to prevent unexpected side effects in other parts of the application relying on the same data reference.
- Handle Special Payload Types: Ensure your logic
accounts for non-plain objects, such as
FormData,URLSearchParams, orBlob, which require specialized parsing methods. - Combine with Schema Validation: Use interceptors as a safety net in addition to robust client-side validation libraries like Zod or Yup.