toxiproxy
toxiproxy copied to clipboard
Toxiproxy API access from browser
This was previously "fixed" in PR https://github.com/Shopify/toxiproxy/pull/184, but it looks like it is still possible to access Toxiproxy from a malicious page.
I was looking deeper into this, and the User-Agent
header is programmable via JS.
See: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
Generally this means a malicious page can make requests from the user's IP. The Host
header can't be set, so this isn't terribly useful to an attacker, but there's still definitely DOS possibilities, and issues around unsecured internal endpoints.
I think the main thing that needs to happen is to lock down and verify the hostname requests are being sent to. 127.0.0.1
and localhost
should be safe, but we should disallow requests to other hostnames unless explicitly set when starting the service.
CC-ing people on the original PR/issue: @JackMc @jpittis @sirupsen @EiNSTeiN-
My understanding is that you're suggesting we only allow 127.0.0.1
/ localhost
as upstreams by default? The trouble I see with this is that we likely have a bunch of users that use services which are either not on localhost, or masked by some kind of domain name. I can't see this not being a breaking change.
I think we discussed that another option would be to do some kind of fancy token exchange where a client can't add a proxy without first making a request for an identifying token which it then passes to the next request to add a proxy. I don't remember what this is called. Likely @JackMc or @EiNSTeiN- would know. I think this would be a breaking change too.
edit: I just noticed the conversation here. The token thingy I mentioned above is the header that @EiNSTeiN- mentions.
Hey @xthexder!
Thanks for pointing this out. I think that was changed after the PR shipped.
Validating the Host
header seems like a sane way to deal with this. I don't think we should worry about DoS. The PoC we received used a subdomain that pointed at the local Toxiproxy.
@jpittis This wouldn't affect the proxies at all, but we would only allow localhost for the api endpoint. Right now this is configurable via the --host
attribute when starting the server. This should work as-is for most people, but in some scenarios where it's running in docker or on a remote server, we can verify the Host
header against what toxiproxy is listening on.
The token exchange thing is something we may need to add still, but it's not useful until we start validating the hostname. Otherwise we aren't protected by Same-Origin, and any malicious code could just request its own token. I'm not sure there's a good way to patch this without requiring updates to the clients.
@JackMc The DoS thing I mentioned was more about an attacker being able to use Toxiproxy as a way to amplify traffic to some other target. I'd rather my computer wasn't used as part of a DDoS, but it's a fairly unlikely scenario, considering the number of variables for it to work. Still something that should be patched for other potential security reasons.
Hey, sorry for the delay but this is the actual hackerone report related to this: https://hackerone.com/reports/236349
It's not only browser but if I use powershell rest command then also I need to override user-agent.
Invoke-RestMethod http://localhost:8474/proxies
gives following error
Invoke-RestMethod : User agent not allowed
At line:1 char:1
+ Invoke-RestMethod http://localhost:8474/proxies
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
One need to pass empty user-agent then only you able to see response.
Invoke-RestMethod -UserAgent "" http://localhost:8474/proxies
I think this issue can be closed as browser are not allowing the User-Agent to be changed anymore, going by the comments on https://stackoverflow.com/a/44367690/525616 and the fact I couldn't make it happen in latest Firefox (tried against https://httpbin.io/user-agent).