-
Notifications
You must be signed in to change notification settings - Fork 324
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
Block subresource requests whose URLs include credentials. #465
base: main
Are you sure you want to change the base?
Conversation
Hard-coding credentials into subresource requests (e.g. `https://user:pass@host/`) is problematic from a security perspective, as it's allowed folks to brute-force credentials in the past, enables session fixation attacks for sites using basic auth, and can allow attackers access to well-known, poorly-coded devices (such as users' routers). Moreover, the ability to hard-code credentials leads to inadvertant leakage via XSS on the one hand, and poor development practice on the other. Sifting through HTTPArchive, for example, yields a number of credentials for test servers and other internal architecture. Usage of the `http://user:pass@host/` pattern has [declined significantly in the last few years][1]; given that low usage, closing this small security hole seems quite reasonable. [1]: https://www.chromestatus.com/metrics/feature/timeline/popularity/532 [2]: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/lx-U_JR2BF0
If we do this we can simplify https://fetch.spec.whatwg.org/#concept-http-redirect-fetch as well (the "includes credentials" pieces) since CORS requests are always subresource requests. |
I haven't verified this in Edge, but I'm told that MS hasn't supported this for years: https://support.microsoft.com/en-us/help/834489/internet-explorer-does-not-support-user-names-and-passwords-in-web-site-addresses-http-or-https-urls |
Note also that the way the standard does HTTP authentication at the moment is by using this syntax. So if we can no longer use this syntax, that would also have to change somehow. Search for 401 in https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch. |
It's a bit complicated, so I might be misreading, but I don't think the suggested change breaks that bit of the algorithm. By putting the check at the top of main fetch, we're dealing with the URL that comes from a page (or redirect). The implementation detail of HTTP-network-or-cache fetch doesn't call back into main fetch, but calls into itself (in 24.4). |
Fair. What about XMLHttpRequest? https://xhr.spec.whatwg.org/#the-open()-method also uses this and does call into fetch. Or would you stop honoring those parameters? |
I'd suggest blocking those as well; they're included in the Chrome metric noted above, and they have similar properties from a security perspective. Basically, I think basic/digest auth is ~fine as a browser-mediated mechanism of allowing users to sign into sites and maintain state in some way. I think it's significantly less fine when the credentials are controlled by the page. |
Currently, requests have a 'destination' property, which provides some clarity about the type of request that's being made. For navigation requests, however, we need a little more granularity in order to support suggestions like #464 and #465. In particular, we need to distinguish between navigation requests that target a new top-level browsing context, and those that target nested browsing contexts (as the latter are treated as subresource requests in the context of some policy decisions). This patch adds a new 'target browsing context' property to requests which will be populated from HTML's navigation algorithm in order to support these kinds of policies.
@youennf any thoughts from WebKit on this? @travisleithead any thoughts from Edge? @mcmanus @valenting any thoughts from Gecko/Necko? |
FYI: I'm pretty sure Edge (and IE) already implement this. See https://groups.google.com/a/chromium.org/d/msg/blink-dev/lx-U_JR2BF0/dxXzIYjwBwAJ and https://support.microsoft.com/en-us/help/834489/internet-explorer-does-not-support-user-names-and-passwords-in-web-site-addresses-http-or-https-urls. @travisleithead can, I'm sure, confirm that. |
IE/Edge restricts it to HTTP(S) URLs, which is a little different, though I suspect in practice that only affects FTP. |
Indeed. Also, let's kill FTP (in #464). :) |
Firefox changes tracked in bug 1340200 |
@mikewest same questions as for the |
This one I can certainly write tests for, so let's let me do that before we land the spec patch. I plan to land this change in Chrome after the next branch point, and I'm not sure there's much point upstreaming tests before any implementation passes. Perhaps we can put this on hold for a week or three? I'll file bugs against Safari and Edge to ensure they're aware. Edge shouldn't have much work to do. |
I'm happy to wait three weeks. We'll also need to rebase as this probably conflicts with the FTP change. |
What about the case when receiving error/challenge 401 with (WWW-Authenticate: Basic realm=...) for a URL for which the browser already has the credentials cached. |
I found this via the message
Chrome 60.0.3095.5 gave me when visiting a site with Basic-authentication. When loading the resources it contains (which do not have authentication information in their URLs in the markup) Chrome will not load them giving the explanation quoted above. Like @ykraynov I wonder whether this is what you have in mind here or whether Chrome may be overdoing it here. |
I'm developing Selenium Tests with Cucumber. We have a test environment with Basic Authentication. Unfortunately Chrome completes relative URLs on the Website with the full Authentication URL, I expect, after Chrome has been authentificated by the URL, adding only the URL without authentification information to relative links and not to block them, e.g. In my opinion it doesn't make sense, that Chrome completes URLs with information that is not allowed by itself. If this case is not considered in the specs, other browsers may implement it the same way in the future. I think we need to specify, that after auth, relative links are completed without authentication. |
Same issue here. I have a local bookmark https://user:[email protected] and it doesn't work since all subresource requests are blocked (all using relative URL's). Seems like a bug to me. |
FYI: Relating to the Chrome Bug, I have created an issue: |
When can we expect a fix on this? It has messed up all my test cases. |
Until the fix is released, you can use the switch
to run your tests. |
I have a couple log viewer apps that are behind a vpn that I am now not able to access because of this.
is wrong. Just because you're not getting it in your analytics doesn't mean it's not happening. I personally just don't allow you to collect these analytics, and I'd wager a bet there are many more like me. How about instead of a breaking change, and pushing your opinions on others, you just issue a warning about it when it happens, and allow the warning to be dismissed? This is a feature people use, and you just took it away without just cause IMHO. I think the most frustrating part is you page: states:
I'm a Web Developer, and part of a company of 100+ others, we want this feature back without a launch flag. Hope that's a clear enough signal for ya. |
This is the wrong place to complain about Chrome's behavior. You want https://bugs.chromium.org/p/chromium/issues/detail?id=731618 most likely. |
Thanks @annevk! will go complain there as well Is this the right place to complain about a change to the browser standard? Because I think getting rid of this feature is a mistake. So to be perfectly clear, if I auth once, all requests to that domain should use that same auth until my browser session/window closes. This is how browsers have worked for ages, please keep it that way. |
Constructive feedback on the proposed change is welcome, yes. And although HTTP authentication and credentials in a URL are related in some cases (e.g., with XMLHttpRequest), they're also different. |
I guess I'm a little confused as to what the road block is then. So I'm going to write out what I think is going on, maybe you can steer me in the right direction. Let's say I have a page requested at <html>
<head>
<link rel="stylesheet" href="/a.css">
<link rel="stylesheet" href="http://user:[email protected]/b.css">
<link rel="stylesheet" href="http://user2:[email protected]/c.css">
<script>
// JS code that adds a link to a style sheet
addStyleLink('/d.css');
addStyleLink('http:/user:[email protected]/e.css');
addStyleLink('http://user2:[email protected]/f.css');
</script>
</head>
.... Under the proposed rule "Block subresource requests whose URLs include credentials", I think the following would happen:
Not sure how this should all play out in what should/should not be blocked from happening. I'd prefer, and I think you'd step on a lot less peoples toes, if you just notified people they are doing something wrong, or it's a bad practice. At the end of the day, I think you'd get the results you want(steering people away from this practice), but not block peoples legitimate use(in their eyes) of this feature of the URL spec. |
The bad practice is including credentials in URLs. I'm surprised you have code like that, since as far as I know Internet Explorer (and now Edge) has never supported it (at least not from IE6 onward). |
I have code like I'm just trying to flesh out what exactly is being suggested here, because it's not clear(to me) what you are blocking. |
If your code doesn't embed credentials in URLs it shouldn't be affected. |
From http://httpwg.org/specs/rfc7230.html#http.uri --
Background: |
Safari is currently supporting user info for both top resources and sub resources. I am not sure how backward compatible it is to remove support of userinfo for things like XHR. |
Some types of artifacts need sandboxing: for example an HTML report can contain JavaScript and for both security and robustness reasons we don't want the report's scripts to have access to the Control Center state. One of the states a sandboxed artifact is denied access to is the session cookie. While that is good to protect a user's login from being abused by malicious scripting in a report, it also means that the Control Center has no way to decide whether a report is allowed to load additional resources, since it doesn't know on behalf of which user the request is made. To solve this, a temporary URL namespace is created: 'sandbox/<key>', where the key is a secure random string. This URL exists long enough for page loading to finish, but not much longer than that: currently it is set to half a minute. If the sandbox URL has expired, the CC redirects the request to a non-sandboxed version, which then verifies the user's permissions and creates a new sandboxed URL. This way, expired URLs are automatically renewed. I tried hiding the sandbox key from the browser's location bar using the "user:pass@" syntax in the sandboxed URL, but modern web browsers will only accept that syntax directly from the user, not from a site: whatwg/fetch#465 A more secure approach would be to serve artifacts from a separate origin (scheme + hostname + port), but that would significantly complicate the setup of a Control Center, so I didn't want to require that. It might be something to implement as an option in the future, if there are projects with very strict security requirements.
What's the status of this @mikewest? https://wpt.fyi/results/xhr/send-authentication-competing-names-passwords.htm suggests that XMLHttpRequest still works in Chrome. |
I think we had to roll this back for XHR. I'll try to dig up the details. |
I think we landed in a place where we block subresource loads whose URLs contain userinfo (https://codereview.chromium.org/2651943002), unless either: a) The subresource is being loaded via XHR (https://codereview.chromium.org/2808753003), or |
@mikewest your last comment describes Chrome's behavior for URI that contain a userinfo. Can you confirm what is Chrome's behavior if URI does not contain a userinfo? |
@mikewest Can you also share with us what the Chrome behavior in case of |
Hi @ddragana! I'm sorry, but I don't understand the question. The change discussed in this PR was only related to URLs that do contain userinfo, with the carveouts described above. What aspect of Chromium's behavior regarding URLs that don't contain userinfo are you interested in understanding? |
What I am interested in is slightly related to this PR, but not completely. (I did not have a better place to ask the question therefore I asked here) Some more explanation: |
I found this code in Chromium https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc;l=94;drc=a432cd59d51281057ba2a2673ca645a9600bb927 which seems to strip usernames and passwords from some requests... looking at the call sites, it appears the list of requests is somewhat random, including mostly CORS subresources, but also prefetches and preloads? We are trying to determine whether to emulate this pattern for new CORS subresource requests... if this is in specs somewhere and I missed it, please let me know. |
I suspect what you are observing is an alternative implementation of the "use-URL-credentials flag" that ends up being observable in at least service workers and therefore technically is a specification violation. Probably worthy of a new issue. |
Hello @annevk, do you see any problem here? |
This PR needs rebasing and OP needs to be updated to include (and fill out) https://github.com/whatwg/fetch/blob/main/PULL_REQUEST_TEMPLATE.md. If that's done and there are tests indicating this is what's implemented in Chromium and planned to be implemented by Gecko I don't see a reason not to merge this. |
Hello @mikewest , I am trying to match Firefox's behaviour with Chrome for URLs with credentials described in this PR. It would be great if we could merge this PR and standardize the behavior. If you don't have time to do the remaining tasks mentioned above to merge this, I would be happy to do them for you. Kindly let me know. Thanks |
@MayyaSunil I would be thrilled for you to pick this up and get it landed. It's been a few years since I looked at any of this, but I can certainly help track down behavioral differences if you come across them. |
Hard-coding credentials into subresource requests (e.g.
https://user:pass@host/
) is problematic from a security perspective,as it's allowed folks to brute-force credentials in the past, enables
session fixation attacks for sites using basic auth, and can allow
attackers access to well-known, poorly-coded devices (such as users'
routers). Moreover, the ability to hard-code credentials leads to
inadvertant leakage via XSS on the one hand, and poor development
practice on the other. Sifting through HTTPArchive, for example, yields
a number of credentials for test servers and other internal
architecture.
Usage of the
http://user:pass@host/
pattern has declined significantlyin the last few years; given that low usage, closing this small
security hole seems quite reasonable.
Preview | Diff