HTTP Man In The Middle (MITM) Proxy
http-mitm-proxy is a robust Node.js-based HTTP and HTTPS Man In The Middle (MITM) proxy designed for intercepting, inspecting, and modifying network traffic, including WebSocket communications. It provides granular control over requests and responses through its event-driven API, allowing developers to implement custom filters and handlers. A key feature is its automatic generation of SSL certificates using `node-forge`, which facilitates transparent interception of encrypted HTTPS connections, requiring users to trust a generated root CA certificate. The current stable version is 1.1.0, which was published approximately two years ago. While the library is still widely used and downloaded, its maintenance status is currently considered inactive, with no new releases in the past year and limited recent activity on its GitHub repository. Key differentiators include its pure Node.js implementation, bundled TypeScript definitions, and a modular API for extending functionality with various request and response filters.
Common errors
-
Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE
cause The client system or browser does not trust the self-signed root CA certificate generated by the proxy for HTTPS interception.fixManually install the `ca.pem` certificate from the proxy's `sslCaDir` into your client's operating system or browser's trusted root certificate store. -
Error: proxy error: certificate has expired
cause The generated SSL certificates (either the root CA or an intermediate certificate) have expired according to the client's system clock.fixEnsure your system's date and time are correct. If the issue persists, delete the contents of the `sslCaDir` directory to force the proxy to regenerate new CA and host certificates. -
ERR_CERT_COMMON_NAME_INVALID
cause The requested hostname does not match the 'Common Name' or 'Subject Alternative Names' (SANs) in the generated SSL certificate, which can happen with certain strict clients or configurations.fixEnsure the `sslCaDir` is correctly set up and the CA is trusted. For specific or complex hostname scenarios, consider using the `proxy.onCertificateRequired` hook to provide custom certificates that exactly match the target host.
Warnings
- breaking The `engines` field in `package.json` specifies Node.js `>=16`, which is stricter than the `README`'s mention of testing starting from Node.js 12.x. Users on Node.js versions below 16 may encounter installation issues or unexpected runtime behavior. Always adhere to the `engines` field for compatibility.
- gotcha To successfully intercept HTTPS traffic without browser or client warnings, the root CA certificate generated by `http-mitm-proxy` must be explicitly installed and trusted by the client's operating system or browser. This certificate is typically found at `options.sslCaDir + '/certs/ca.pem'` after the proxy starts. Failure to do so will result in SSL/TLS errors and security warnings.
- deprecated The `http-mitm-proxy` project is currently in a state of inactive maintenance. According to recent analysis, there have been no new npm releases in the past year and minimal recent activity on its GitHub repository. While still functional, critical bug fixes, security patches, or new feature development may not be actively pursued.
- breaking While not explicitly documented in the provided excerpt, a major version bump from 0.x to 1.x typically introduces breaking API changes. Users migrating from pre-1.0 versions should thoroughly review the project's commit history and examples for any API alterations that may not be backward compatible.
Install
-
npm install http-mitm-proxy -
yarn add http-mitm-proxy -
pnpm add http-mitm-proxy
Imports
- Proxy
const Proxy = require('http-mitm-proxy');import { Proxy } from 'http-mitm-proxy'; - Proxy.gunzip
import { gunzip } from 'http-mitm-proxy';import { Proxy } from 'http-mitm-proxy'; const { gunzip } = Proxy; - Context
import Context from 'http-mitm-proxy/Context';
import { Context } from 'http-mitm-proxy';
Quickstart
import { Proxy } from 'http-mitm-proxy';
const proxy = new Proxy();
proxy.onError(function(ctx, err) {
console.error('Proxy error for URL:', ctx?.clientToProxyRequest?.url || 'N/A', 'Error:', err);
});
proxy.onRequest(function(ctx, callback) {
// Example: Modify Google search results
if (ctx.clientToProxyRequest.headers.host === 'www.google.com' && ctx.clientToProxyRequest.url.startsWith('/search')) {
ctx.use(Proxy.gunzip); // Decompress gzipped responses
ctx.onResponseData(function(ctx, chunk, callback) {
// Replace all h3 titles with "Pwned!"
chunk = Buffer.from(chunk.toString().replace(/<h3.*?<\/h3>/g, '<h3>Pwned!</h3>'));
return callback(null, chunk);
});
}
return callback();
});
console.log('HTTP MITM Proxy listening on port 8081');
proxy.listen({ port: 8081 });