Shopify / toxiproxy

:alarm_clock: :fire: A TCP proxy to simulate network and system conditions for chaos and resiliency testing
https://github.com/shopify/toxiproxy
MIT License
10.62k stars 445 forks source link

Toxiproxy API access from browser #219

Open xthexder opened 6 years ago

xthexder commented 6 years ago

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-

jpittis commented 6 years ago

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.

JackMc commented 6 years ago

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.

xthexder commented 6 years ago

@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.

JackMc commented 6 years ago

Hey, sorry for the delay but this is the actual hackerone report related to this: https://hackerone.com/reports/236349

nsidhaye commented 3 years ago

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

dentarg commented 1 year ago

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).