node-http-mitm-proxy icon indicating copy to clipboard operation
node-http-mitm-proxy copied to clipboard

Is there an option to forward a HTTPS request without intercepting it?

Open aDu opened this issue 7 years ago • 5 comments

Let's say, my clients wants to use my proxy.

I want to only do a 'Man In The Middle' for https://example.com, but not interfere with https://google.com and so on.

So, the client would see that they will get a 'Bad certificate' error when they visit example.com, but I want it so that when they visit google.com, they get Google's real certificate (at the cost of not being able to read/modify the requests to/from Google).

In other words, is there an option to just 'not do anything' and use the 'real certificate'. Note that the client is always connected to the proxy.

Thanks in advance.

aDu avatar Jun 01 '17 10:06 aDu

https://github.com/joeferner/node-http-mitm-proxy/blob/c2305aa485ee960e61dfd6ad948cdc6e8733a412/lib/proxy.js#L287 Looks like you need a custom handler to pipe the request over. I found an example here: https://newspaint.wordpress.com/2012/11/05/node-js-http-and-https-proxy/ If you don't want to log the amount of data passing over, you can just use .pipe() to speed things up.

jspenguin2017 avatar Jun 06 '17 17:06 jspenguin2017

@jspenguin2017 thanks for that, it works! But do you have any references on how to forward requests to an upstream proxy? The example you gave works for forwarding to upstream HTTPS servers (I'd like to forward to another proxy)

I got the example working for my hard-port of mitm-proxy (rewritten for promises+typescript) but with minor tweaks you can get it working for mitm-proxy:

put this at the comment mentioned here: https://github.com/joeferner/node-http-mitm-proxy/blob/c2305aa485ee960e61dfd6ad948cdc6e8733a412/lib/proxy.js#L287


		const url = req.url;
		const httpVersion = req.httpVersion;
		let { host, port } = utils.getHostPortFromString(url, 443);
		socket.pause();
		const conn = new net.Socket();
		conn.connect(port, host, (...huh) => {
			conn.write(head);
			//tell the caller the connection was successfully established
			socket.write("HTTP/" + httpVersion + " 200 Connection established\r\n\r\n");
			// create a tunnel between the two hosts
			socket.pipe(conn);
			conn.pipe(socket);
			socket.resume();
		});

		conn.on(
			'error',
			function (err) {
				socket.write("HTTP/" + httpVersion + " 500 Connection error\r\n\r\n");
				console.log('  < ERR: %s', err);
				socket.end();
			}
		);

		socket.on(
			'error',
			function (err) {
				console.log('  > ERR: %s', err);
				conn.end();
			}
		);

you can get the code for the mentioned getHostPortFromString() function from the newspaint.wordpress.com blog that @jspenguin2017 mentioned above.

jasonswearingen avatar Jun 14 '17 14:06 jasonswearingen

@jasonswearingen If you have one specific proxy to always use, then I think you can configure Node to do that. If you want to dynamically determine whether or not the upstream proxy should be used, then I'm not very sure, I think you need to initiate a CONNECT connection with the proxy and pipe the content over.

jspenguin2017 avatar Jun 14 '17 15:06 jspenguin2017

@jasonswearingen will you be committing that feature to your port?

micaww avatar Jun 21 '17 16:06 micaww

Is it possible to achieve this using .onConnect() handler instead of modifying the source code directly? I didn't manage to do it myself.

niicojs avatar Mar 18 '18 15:03 niicojs