-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Indiscriminate injection of "Access-Control-Allow-Origin: *" is unsafe #21
Comments
This extension does not inject Thanks in advance. EDIT: re-reading your post, is your concern about local servers specifically? |
My concerns are primarily about servers in the internal network, yes. From the documentation in "Is this extension safe?":
But "GET requests that are not flagged as having credentials" are enough to do some reconnaissance on the user's internal network. This is particularly concerning in the case of home users with poorly secured "smart" devices. I may have chosen the word "indiscriminate" wrongly? Please bear with me here. Thank you |
Alright, thanks. For starters, I think it would make sense for the extension to simply ignore all requests to internal networks. I'm considering the idea of giving users the choice of doing so only when the origin server is not in an internal network, but I'm not sure if that is worthwhile or not. Probably not. As for your second point, I believe the potential risks left that are related to XHR-type requests can only happen in the scenario of making a cross-origin request to a badly designed and/or outdated server, and as stated in the documentation, those risks should be easily mitigated by using first-party isolation and/or containers. I'm all for letting users choose, but I need to draw some lines to prevent the complexity from growing to a point where it messes with user-friendliness. Also, I generally try to stick to minimalism because it makes projects maintainable, and it is the most effective way to avoid introducing bugs and vulnerabilities. From your perspective, what would be an ideal way for the extension to give you those choices? |
For the time being, I released |
I do not think there is a way to reliably discern internal networks from external networks from Firefox WebExtensions. IP addresses are the easy cases. But a hostname like "some-department.a-certain-institution.gov" might be resolved by the internal DNS server to a local address. But then, while the scenario I tested is about attack reconnaissance into the internal network, it is not the only impact of this issue, as it effectively allows a remote web server to use visiters' browsers as a kind of limited HTTP GET proxy. I propose:
Thank you |
There is. The DNS API. But not everyone would want that. In the vast majority of cases it would end up being just unnecessary overhead. EDIT: It still might be worthwhile to add it as an option (default off).
I understand the following is not your preferred way to do this, but in case anyone else is wondering, this can already be done by using the Exclusions section. For example:
Will ignore requests from any origin to any host that ends in
I still disagree. It may be a serious vulnerability to you, depending on your threat model, but for most people this would at worst be an edge case. An adversary attempting that would have to be targeting this extension specifically, and apart from that risk of giving them access to "politically sensitive" information, I can't think of many other ways for this to be exploited in the wild (assuming well-configured target servers and/or using first-party isolation/containers). As for your proposals...
Anyway, I appreciate all your valuable feedback. I will make a small release and then I'll have to do a lot of thinking. I'm sorry to say I can't promise anything, but you made some good points, so I'll try to add that functionality when I can. That being said, it wouldn't be wise for you to expect this extension to become the uMatrix of CORS, especially in terms of UI/UX. Realistically, I doubt I'll ever have the time for making fancy stuff like that. |
A brainstorm is happening in my head, but I have a question to understand better: |
Did not know about that. Learn something new each day, I guess.
I think this is acceptable.
If this extension gets popular enough (and I really hope it is, it is the only extension that specifically deals with the Origin header, as far as I know), it might turn out to be an attractive target. Elaborations below.
I agree.
That's my dream! :) @crssi No, that is not my intention. No special treatments for servers in the internal network. The scenario I started with is one where an origin in the "Internet zone" accesses an origin in the "Intranet zone", which in Firefox, would only be possible if the "Intranet zone" server replies with Access-Control-Allow-Origin set to "*" or a more permissive value. The problem is that POOP inserts that header, allowing access. Thank you |
I am really struggling to picture the scenario where you would visit an "Internet zone" page and get the additional resources over "Intranet zone" which would be harmful without the possibility for attacker to inject some content on network level as MitM. And for that, the "attacker" would already need to be on the "Intranet" network... which would anyway be a gameover and exploiting CORS would be nonsense. But, I might still not see clearly the scenario/vulnerability vector you have in your mind. |
@crssi No MITM needed. Visiting an attacker's controlled domain is enough.
Normally, step 2.3 is only possible if the fetch()ed response contains an Access-Control-Allow-Origin permitting it, which is what this bug is about. Note that www.evil-guy.com is in "Internet zone" and the URLs can be any host, either "Intranet zone" (http://some-department.a-certain-institution.gov/) or "Internet zone" (http://www.ghacks.net/). For the MITM in the local network case, it is "game over" like you said, but only for the MITMed HTTP traffic. Modern versions of Firefox, I think, block mixed content in this case by default. Hope that clarify things |
Thank you, much better for my lazy brain. 😸 By default this WE does not touch POST requests and only GET requests in a relaxed mode for Fonts and CSS.
This should be safe and mostly breakage free for a basic user. Now for the scenario where local/private IP would be used...
Please note that IPv6 in the upper list is not trough, since I have IPv6 disabled, but in my ToDo list is also revisiting IPv6 ranges to make the upper list complete (higienic)... like adding fc00::/7 and simmilar. @tartpvule could you be so kind to test your PoC (proof of concept) again, but this time adding the following into Exclusions list: If the result is good, then we can populate Exclusion list with all local/private ranges (there are not many). It could be that I have missed something or I am wrong at seeing stuff... I will be more than happy if you can, please, correct me in that case. Thank you and cheers 😄 |
First off, I made a mistake: I have been running POOP in Aggressive Mode all this time, and that turns out to be the key. This is due to (I think a bug) in /src/bg/webRequest.js.
(There is no " || isReservedAddress(target.hostname)" in the previous version) @crssi Yes, that exclusion makes fetch('http://192.168.1.1/') fail, which is a good thing.
Try using it to browse an HTTP site in the "Internet zone". No HTTPS support is implemented. |
I also wasn't aware the @claustromaniac already fixed private addresses. 😄 |
That wouldn't affect the scenarios that @tartpvule layed out.
That's what the relaxed mode is for.
There is no need for that, since
That is a bug, but it shouldn't make any difference when it comes to dealing with private addresses, because the EDIT: Damn, I didn't read @crssi's last comment before writing mine (sorry). |
Fix relaxed mode searchParam condition. Thanks @tartpvule #21 (comment)
I know... it is OT. I am saying that it would be best, if this were default checked... IMHO
😄 why "sorry", no need to be 😸 Cheers |
It is nice to have someone as @tartpvule participating. 👍
It must be late, since I am not sure that I understand correctly the "remaining problem". 😢 |
@tartpvule |
You do not normally want someone using your browser as a free proxy/bot, especially if it can be used to implement an illicit Shodan-lite. (Shodan = https://www.shodan.io/) After
That is a step in the right direction, but it is not perfect.
Yes, great project, I have been using that in my private builds of Firefox for a few years. |
So implementing DNS API matching |
I know (I was replying to @crssi, not to you), but it will take a long time for me to implement what you proposed and I haven't even decided how I'll go about doing that (assumming I even manage to squeeze the time and motivation to do it in the first place). |
That would require additional permissions and it would be unnecessary overhead like 99.9999999% percent of the time. IF I go that route, it will be optional and disabled by default (as I said above). |
Just my humble opinion: Anyway, I (possibly) will never be able to express gratitude as I feel for you @claustromaniac and for all ghacks-user.js company. I ❤️ you all. |
@crssi @claustromaniac ... There are two parts to this issue ...
I consider this part to be solved (Thanks @claustromaniac) after c0273c8 and adding exclusions as per @claustromaniac's comment:
This is an impact that I realized about two days after opening this issue, which my https://github.com/tartpvule/poc-poop-acao demonstrates. I have successfully browsed http://ghacks.net/ with this PoC proxy implementation. So this is still unsolved. Thank you |
Proof of concept:
fetch('http://192.168.1.1/').then(function(response) { return response.text(); }).then(function(text) { alert('fulfilled\n\n' + text); }).catch(function(e) { alert('rejected\n\n' + String(e)); });
In the absence of other filtering extensions (e.g. uMatrix), this extension, by default, allows an arbitrary webpage to send GET requests to and read responses from sites it should not.
While vanilla Firefox allows sending GET requests to an arbitrary URL, it only allow the responses to be accessible to the request origin if and only if the target host allows it.
(Tested on Firefox ESR 60.4.0)
The text was updated successfully, but these errors were encountered: