mockttp
mockttp copied to clipboard
Set authentication for accessing MockHttp and Included Credential in http-toolkit android app?
Hi @NguyenCongVN, I'm not sure exactly what this means. Can you explain more about what you're trying to do?
@pimterry In usual, we can set username and password for proxy server authentication. Are there any similar option for mockhttp server? I'm trying to use mock http server like proxy server in your toolkit but with some identification for each user.
I see. By default Mockttp can't do that for you - it acts as a transparent proxy, and tries to be as invisible as possible.
On the Mockttp side, it should be possible to build this for yourself easily though. You'd just need to some rules that checked the authentication headers, for example:
// Pass through traffic with a matching header value:
server.anyRequest().withHeaders({
"Proxy-Authorization": "Basic BASE64AUTHVALUE"
}).always().thenPassThrough({
transformRequest: {
updateHeaders: {
// Tell Mockttp to drop the proxy header when forwarding requests:
"Proxy-Authorization": undefined
}
}
});
// Close connections that send any other requests:
server.anyRequest().always().thenCloseConnection();
Does that make sense? I haven't tested this, but I think in theory that will give you an authenticating proxy. Unfortunately, that's the easy part.
Sending the authentication details from Android is harder, because the HTTP Toolkit Android app just works in terms of TCP, it doesn't know anything about HTTP and in the case of HTTPS it can't see or modify the headers at all. It redirects traffic at the TCP level, and also sets the system proxy settings, that's it, and it looks like Android completely removed system-level support for proxy authentication years ago, and so there's nothing the app can do there.
It's probably impossible to automatically set up Android devices to authenticate to a proxy in the way you're imagining. There will be alternatives though.
Can you tell me more about what you're trying to do?
- Who are these users you're trying to authenticate?
- Are all your proxy users Android devices?
- Are these rooted devices that you control, emulators, or normal phones?
- Once you know which user is which, how do you want to treat them differently?
- Do you need the an automated app to set all this up, like the HTTP Toolkit app, or is manual configuration sufficient?
There is probably a solution to this, but it depends a lot on the context.
- Who are these users you're trying to authenticate?
- For who is our current user. They all have credential pre-defined before.
- Are all your proxy users Android devices?
- Yes
- Are these rooted devices that you control, emulators, or normal phones?
- I'm trying to find a solution for normal phones ( just need for some apps)
- Once you know which user is which, how do you want to treat them differently?
- I want to set a request is allowed or denied depend on each user with different set of rules. It's done by other server , it'll receive traffic and do work automatically.
- Do you need the an automated app to set all this up, like the HTTP Toolkit app, or is manual configuration sufficient?
- An automated app.
@pimterry Can i write custom header to network layer packet to make it work?
AFAIK TCP does not support custom headers or arbitrary packet metadata like that. Even if you did manage to squeeze it into a defined TCP header field somewhere, I suspect it won't be possible to read it out from Node.js, so Mockttp won't be able to access it.
You can normal TCP packet data easily enough though, for example the remote IP is available. Would that be sufficient? If they're on your local network, you can probably use IPs to identify individual devices.
I'm also trying to implement authentication for accessing the server, there seems to be plenty of "hacky" ways to get some semblance of authentication running, but the main idea is that I want to avoid the possibility of others connecting to the proxy, period.
For now I'm going to resort to IP whitelisting, but it would be really nice to get authorization set up, somehow.
On a TCP/IP level, if you want to allow some remote clients to connect but not others then filtering by IP is your only real option to completely cut off access I'm afraid.
This isn't really a Mockttp limitation, it's a general networking issue. There's no support for authentication metadata in TCP, so there's no way to block unauthenticated clients from ever connecting at all.
You can add custom authentication to each individual rule within Mockttp if you'd like though, to block requests after connection, with something like:
server.forAnyRequest().withHeaders({
"Proxy-Authorization": "Basic BASE64AUTHVALUE"
}).then/*...*/()
That rule will only run for clients that send the expected header. You can use a rule like server.forUnmatchedRequest().thenReply(403) to reject requests from all other clients.
That blocks traffic at the HTTP level, after the connection has been accepted. Mockttp is not really designed to be used as a strict security mechanism, so I can't guarantee it'll hold up against really determined attacks, but it should make it reasonably difficult.
If you really need a strict authentication mechanism, I'd suggest putting something else in front of Mockttp and handling authentication there. Some ideas, in approximate order of security:
- Put your Mockttp server in a VPN, and authenticate access to the VPN
- Put your Mockttp server behind a TLS-terminating middlebox, and authenticate connections there using TLS client certificates
- Put your Mockttp server behind Nginx, and configure authentication based on HTTP headers there (equivalent to the above rule approach, but globally effective and Nginx is specifically designed to do this securely in production use).
@pimterry
Put your Mockttp server in a VPN, and authenticate access to the VPN
I believe this to be the best solution, it would also allow for a much more secure certificate-based authentication, which is preferable to Basic authentication.
I've been looking into how to implement this since I posted my reply by using a dockerized OpenVPN instance running on the same network as the NodeJS server running the mockttp server proxy, the nuances with available docker images and ARM architecture along with IPTable configuration is unfortunate, but I'm on the way to figuring it out.
If I remember, I'd be happy to respond here with the solution I've decided to proceed with, although I do understand this is not a limitation of mockttp in and of itself.