Closed Bug 213012 Opened 22 years ago Closed 22 years ago

relative URLs can violate cookie path restrictions

Categories

(Core :: Networking: Cookies, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: dveditz, Assigned: darin.moz)

References

Details

(Keywords: fixed1.4.1)

Attachments

(4 files)

Netscape received the following report from Martin O'Neal. In short, a URL like http://x.com/victim/%2E%2E/evil/hack.html is incorrectly able to read cookies with the path set to "/victim". If a literal ".." is used then Mozilla coalesces the path before matching against cookies, with the result that "/victim" will not match "/evil". Some servers (Netscape's NES, for example) will not accept %2E%2E as a relative path, but others (e.g. Apache) do. We should not depend on the server implementation for our security, the coalescing code should treat %2e as a '.' On the other hand, our Same-origin policy means /evil/hack.html could open /victim/target.html in a frame and take the cookies through the DOM. But the described hack does not require javascript. ----------Report follows----------------- Issue details: -- Overview -- The cookie specifications detail a path argument that can be used to restrict the areas of a host that will be exposed to a cookie. By using standard encoding techniques this functionality can be subverted, potentially exposing the cookie to scrutiny and use in further attacks. -- Analysis -- The cookie standard is formally defined in RFC2965 [1]. This makes reference to the optional path argument that allows a cookie originator to specify “the subset of URLs on the origin server to which this cookie applies” [1]. Many of the user agents appear to function by simply matching the initial part of the requested URL, so by using a combination of relative paths and standard encoding techniques the path restriction functionality can be subverted. Where this becomes useful is in conducting attacks against the session cookies of an application that does not suffer from any exploitable input validation flaws, but that shares the same server environment with one that does. -- Example -- For this example we shall imagine that our secure application shares a host with some sample files that were installed at the same time as the web server. Obviously, this would never happen in a live production environment (pauses to insert tongue firmly in cheek). The secure application is located within the “/secure” folder and sets the cookie path argument to “/secure” which is intended to restrict the cookie information from being exposed elsewhere on the same host. The attacker knows that the secure application has no useable vulnerabilities in itself and can also see that the cookie that it sets has the path restricted. They also know that the sample files have an exploitable XSS flaw that would give them access to the all-important session cookies (if they can get a valid user to access it; a completely different problem to solve). By using a crafted URL they can bypass the path restriction intended by the originator and get the valid users browser to expose the session cookie to the sample application. -- Recommendations -- The cookie path functionality of the affected user agents should be revised to ensure that they work as intended and cannot be bypassed by encoding techniques. -- Escalation -- >From initial analysis, it appears this style of flaw might be widespread across various agents. If this is confirmed as being so, then we will most likely need to coordinate a public release across vendors.
I'm wondering if this is really a cookie bug, or something we should fix in the various implementations of nsIURI... currently, cookies just calls nsIURI::GetPath and then matches that against a stored string. So, if the nsIURI impls coalesced the path in this case, I don't think there'd be a problem. Comments? thanks for filing this dveditz!
I'm getting a feeling of deja vu here - haven't we seen this before? theres bug 114018, but I thought we had something on the .. thing too. Maybe I'm misremembering.
dveditz and i thought about making net_CoalesceDirsAbs (in nsURLHelper.cpp) treat %2E equivalently to a simple unescaped '.'
Should we also watch out for %2F==/ just in case? The two servers we tested wouldn't act on that equivalence, and it *is* in the restricted set (unlike '.') so arguably we shouldn't have to.
bbaetz: bug 114018 doesn't seem relevant, did you mean another?
Now that I have access to this bug (bugzilla is strange sometimes) repeating what I mailed before: RFC 2396 says: 2.3. Unreserved Characters Data characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include upper and lower case letters, decimal digits, and a limited set of punctuation marks and symbols. unreserved = alphanum | mark mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" Unreserved characters can be escaped without changing the semantics of the URI, but this should not be done unless the URI is being used in a context that does not allow the unescaped character to appear. A "." can be escaped without changing the semantics of the url. For that reason I think we should change CoalesceDirs in a way that it also recognizes %2E and %2e as . For example we can do a replace of %2E or %2e to "." at the beginning of CoalesceDirs and then use the usual algorithm. But please do not watch out for %2F .. doing so would change the semantics of the url, usually %2F is used to hide a slash that is for example part of a directory or filename. Looking for %2F would have really strange effects.
Searching bugzilla comments for %2e%2e turned up bug 41571 and bug 182176.
Should we not do the same thing in net_CoalesceDirsAbs?
That function does not exist anymore, see bug 207298 for details or update your tree ;-)
But of course, if you want this fix in 1.4x or 1.5a you must do this patch on net_coalesceDirsAbs and net_coalesceDirsRel instead.
Comment on attachment 128080 [details] [diff] [review] quick and dirty patch, replaces %2E or %2e in the path with . and then does the usual stuff since no one instantly objected to this quick fix, requesting reviews
Attachment #128080 - Flags: superreview?(darin)
Attachment #128080 - Flags: review?(dveditz)
Comment on attachment 128080 [details] [diff] [review] quick and dirty patch, replaces %2E or %2e in the path with . and then does the usual stuff this looks good to me. thanks andreas! sr=darin
Attachment #128080 - Flags: superreview?(darin) → superreview+
Attachment #128429 - Flags: superreview?(darin)
Attachment #128429 - Flags: review?(dveditz)
Attachment #128429 - Flags: superreview?(darin) → superreview+
There is a potential i18n problem with this change. If the URL contained escaped multibyte-sequences, the straightforward-conversion of %2E to '.' might corrupt the URL. A multibyte-sequence starts with a non-ASCII character, but the trailing bytes can be 7-bit ASCII and therefore one of them might be 0x2E. This can probably be prevented if the URL will be unescaped as whole.
The conversion shouldn't affect the intepretation -- the server gets %2e and converts it to '.', or we send it the '.' directly. Either way if it's part of a multi-byte sequence it should be combinable with the previous character. We only strip out the dots if after conversion there are one or two in a row bounded by slashes which is never going to be a multibyte sequence.
Comment on attachment 128080 [details] [diff] [review] quick and dirty patch, replaces %2E or %2e in the path with . and then does the usual stuff r=dveditz
Attachment #128080 - Flags: review?(dveditz) → review+
Comment on attachment 128429 [details] [diff] [review] same patch as before but against 1.4 r=dveditz
Attachment #128429 - Flags: review?(dveditz) → review+
I agree with Dan here. If %2E would be "IsDBCSLeadByte" we would have a problem, but as far as I know it isn't.
Comment on attachment 128429 [details] [diff] [review] same patch as before but against 1.4 should this also be fixed for 1.0.x?
Attachment #128429 - Flags: approval1.4.x?
Thinking again about what Asaf Amit said, if the first byte is "IsDBCSLeadByte" and the following chars are "%2E" ("%" being the other byte) we would destroy that by replacing "%2E" with ".". Does this make sense?
hmm... when net_CoalesceDirs is called from BuildNormalizedSpec, the input string will have any non-ASCII characters (or possibly non-UTF8 characters depending on preferences) URL-escaped. so, there cannot be an unescaped DBCS lead byte passed to net_CoalesceDirs when invoked from BuildNormalizedSpec. likewise, since the input/output of nsIURI::resolve must be a UTF-8 string, the input to net_CoalesceDirs will not contain an unescaped DBCS lead byte. so, i think the original patches are i18n safe.
In return this would mean that that code in coalesceDirs is old cruft that can be removed when conveniant.
literal '%' is not a valid URL character. If you were really trying to enter a path with "<2ndByte-%>2e" in it you should escape it as %252e.
fix checked in on trunk
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Comment on attachment 128429 [details] [diff] [review] same patch as before but against 1.4 Please check the appropriate patch into 1.4. Thanks
Attachment #128429 - Flags: approval1.4.x? → approval1.4.x+
fix also checked in into the 1.4 branch
Keywords: fixed1.4.1
Blocks: 224532
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: