You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js实现MITM:接收GET/POST请求时如何获取CONNECT请求头?

解决MITM代理中GET/POST请求获取对应CONNECT请求头的优雅方案

核心思路是利用TCP连接的唯一性:后续的HTTPS请求(GET/POST)是基于CONNECT建立的同一个socket连接发送的,因此可以直接将CONNECT请求的头信息挂载到对应的socket实例上,在request事件中直接读取,无需依赖端口关联这种不可靠的方式。

修改后的完整代码

const { createServer } = require('http');
const net = require('net');

const httpsServer = createServer();

httpsServer.on('request', (req, res) => {
    // 从socket中获取对应的CONNECT请求头
    const connectHeaders = req.socket.connectHeaders;
    if (connectHeaders) {
        console.log('对应的CONNECT请求头:', connectHeaders);
        // 这里处理你的业务逻辑
    } else {
        // 处理异常情况:没有找到对应CONNECT头的请求
        res.writeHead(400);
        res.end('Invalid request');
    }
});

httpsServer.on('connect', (req, clientSocket, head) => {
    const connectHeaders = req.headers;
    // 把CONNECT请求头挂载到socket上
    clientSocket.connectHeaders = connectHeaders;

    const mitmClientSocket = net.connect({
        port: 9999, 
        host: '127.0.0.1', 
        // timeout: 15000
    }, () => {
        if (!mitmClientSocket.destroyed && !clientSocket.destroyed) {
            if (!clientSocket.writableEnded) {
                clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                                    'Proxy-agent: MITM-proxy\r\n' +
                                    '\r\n');
            }
            if (!mitmClientSocket.writableEnded) {
                mitmClientSocket.write(head);
            }
            mitmClientSocket.pipe(clientSocket);
            clientSocket.pipe(mitmClientSocket);
        }
    });

    // 可选:socket销毁时清理挂载的属性,避免内存泄漏
    clientSocket.on('close', () => {
        delete clientSocket.connectHeaders;
    });
});

httpsServer.listen(9999, () => {
    const address = httpsServer.address();
    console.log(`MITM代理监听在 ${address.address}:${address.port}`);
});

方案优势

  • 可靠性高:直接通过socket实例绑定数据,避免了端口复用、端口冲突等场景下的关联错误
  • 逻辑清晰:数据和对应的连接实例直接绑定,代码可读性和维护性更强
  • 性能更好:无需额外的端口映射存储和查找逻辑,减少不必要的开销

注意事项

  • 如果代理支持HTTP keep-alive,同一个socket可能会处理多个请求,但MITM场景下每个CONNECT隧道的socket只会对应目标服务器的请求,因此不会出现头信息混乱的问题
  • 建议在socket的close事件中清理挂载的connectHeaders属性,避免长期运行导致的内存泄漏

内容的提问来源于stack exchange,提问作者Just Intuition

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:47:36