Closed Bug 213012 Opened 21 years ago Closed 21 years ago

relative URLs can violate cookie path restrictions


(Core :: Networking: Cookies, defect)

Not set





(Reporter: dveditz, Assigned: darin.moz)



(Keywords: fixed1.4.1)


(4 files)

Netscape received the following report from Martin O'Neal. In short, a URL like 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 

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

      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

Attachment #128080 - Flags: review?(dveditz) → review+
Comment on attachment 128429 [details] [diff] [review]
same patch as before but against 1.4

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
Closed: 21 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.

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.