Closed
Bug 308800
Opened 19 years ago
Closed 19 years ago
Character U+FF0F appears to allow URL spoofing
Categories
(Core :: Networking, defect)
Tracking
()
RESOLVED
DUPLICATE
of bug 316444
People
(Reporter: usenet, Assigned: darin.moz)
References
(Blocks 1 open bug)
Details
(Whiteboard: [sg:dupe 316444])
Attachments
(5 files)
1 Put www.pyth/on.info in your /etc/hosts file, mapped to 127.0.0,1.
2 Run a local Apache webserver.
3 Visit the attached HTML page. Click on the http://www.pyth/on.info link at
left (where the wide slash character is Unicode character U+FF0F, FULLWIDTH
SOLIDUS.
WHAT HAPPENS:
Apache returns:
> Bad Request
>
>Your browser sent a request that this server could not understand.
> Apache/2.0.49 (Linux/SuSE) Server at www.pyth/on.info Port 80
with the location bar reading "http://www.pyth/on.info/", with the inserted
slash character (as verified by cut-and-paste from the location bar, and hex
dumping) again being a normal ASCII 0x2f slash character. Hovering over the link
also gives the same apparent URL.
WHAT SHOULD HAPPEN:
At the very least, the page should be blocked because the hostname is malformed.
DNS labels with 0x2f in them are neither valid standard LDH domain names (per
RFC 1035), nor are they valid Punycode encodings.
RFC1035 wording:
> The labels must follow the rules for ARPANET host names. They must
> start with a letter, end with a letter or digit, and have as interior
> characters only letters, digits, and hyphen. There are also some
> restrictions on the length. Labels must be 63 characters or less.
PROBLEM:
Sniffing the packets shows that Firefox connects to the webserver at 127.0.0.1,
and sends it a request for
> GET / HTTP/1.1
> Host: www.pyth/on.info
where the / character is an ASCII 0x2f in each case.
This example uses a line in /etc/hosts to define the domain name. However,
removing this line reveals that Firefox is more than happy to attempt to resolve
this name, and will put DNS queries for names with slashes in on the wire.
Removing the line in /etc/hosts shows that Firefox actually generates DNS
requests for www.pyth/on.info (again with the slash character being an ASCII 0x2f).
POSSIBLE PHISHING EXPLOIT:
* attacker runs a Web server that does not regard hostnames with "/" in them as
an error
* attacker runs a DNS resolver at which is happy to resolve names with a "/" in
them, specifically, www,python.org/login
* attacker registers the screen.info. domain, and point its at this DNS resolver
* attacker sends out phishing messages containing "http:
//www.paypal.com/login.screen.info/login"
* waits users to click on it, see web content delivered with the location bar
saying http://www.paypal.com/login.screen.info/login"
* attacker phishes users' private information
Note that writing the name resolver / web server is easy, either by hacking
existing applications like BIND and Apache, or by writing trivial DNS and HTTP
client which almost completely ignore the content of requests, and just send out
the spoofed responses.
PROPOSED FIX:
* check within Necko that DNS names _only_ contain the characters
[A-Za-z0-9\-\.] before being looked up at low level. This check should occur
_after_ all URL processing, FQDN canonicalization, IDN processing etc. has been
performed, by performing it at the domain name resolver library entry point.
Generate an error code for all non-conforming names.
It might also be interesting to investigate why this special case gets through
the current URL/IDN/DNS processing code, but it's better to fix this at the low
level by enforcing the RFC, rather than trying to find and fix special cases
one-at-a-time.
Reporter | ||
Comment 1•19 years ago
|
||
This HTML file contains a test case for this bug. Don't forget to modify
/etc/hosts as specified in the bug report first. Try both links: you will get
different behaviour.
Reporter | ||
Comment 2•19 years ago
|
||
Proof of concept testing: This is a tiny Python web server that ignores request
headers completely, and just serves a page. You'll need to hard code the IP
address into this.
Reporter | ||
Comment 3•19 years ago
|
||
Reporter | ||
Comment 4•19 years ago
|
||
OK. After a lot of packet dumping, it looks like I was wrong about the DNS part
of this, and this is not nearly as severe as I thought.
The DNS lookup does not appear to have a slash in, as I thought (although I
could have sworn I saw it earlier; is there any way of turning off the DNS
caching?). Instead, the FQDN is terminated at the slash, and "www.pyth" is what
is looked up.
However, the reason why I came to this conclusion does appear to be caused by a
bug. When visiting the URL with the long slash in, the apparent FQDN fed to the
webserver appears to first have been normalized, converting the long slash to a
normal slash, and then passed out _including the slash_ to the web server in the
HTTP Host: header, thus:
GET / HTTP/1.1
Host: www.pyth/on.info
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8b4) Gecko/20050907
Firefox/1.4
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
HTTP/1.1 400 Bad Request
Date: Fri, 16 Sep 2005 13:49:57 GMT
Server: Apache/2.0.49 (Linux/SuSE)
Content-Length: 314
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr />
<address>Apache/2.0.49 (Linux/SuSE) Server at www.pyth/on.info Port 80</address>
</body></html>
Apache then dutifully echoes the result back, slash and all. Having the FQDN fed
to the server and the FQDN fed to the DNS system is probably a bad thing, but I
can't instantly work out an exploit based on it.
Severity: critical → major
Reporter | ||
Comment 5•19 years ago
|
||
No, it looks like I was right the first time. I hadn't removed the
www.pyth/on.info entry in my /etc/hosts. Having done so, I managed to capture
the malformed DNS requests using ethereal. So it looks like the bug may be real
after all.
Reporter | ||
Comment 6•19 years ago
|
||
Enclosed, the libpcap dump referred to in the previous comment. More to come.
Reporter | ||
Comment 7•19 years ago
|
||
OK, at the moment, it looks like if the malformed DNS request is answered,
there's no subsequent TCP connection attempt, and you don't get a page. So, it's
sort of "safe by luck". (On the other hand, if it isn't answered, do you get the
lookup of www.pyth?)
However, there are some _really strange_ things going on here, and it's going to
take some time to try all the variations.
Please can someone have a go at replicating this, by simply clicking on the left
link in the testcase, _without_ either a DNS spoofer or an /etc/hosts entry, and
capturing the packet stream generated.
I'll attach the latest version of the tiny DNS server, which now knows not to
answer queries for anything but A records, below.
Reporter | ||
Comment 8•19 years ago
|
||
See comment above.
Comment 9•19 years ago
|
||
Duplicate of bug 301694 (beyond the overly-specific summary the patch itself
includes several other characters including U+FF0F)
*** This bug has been marked as a duplicate of 301694 ***
Group: security
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → DUPLICATE
Comment 10•19 years ago
|
||
Reopening. I've misunderstood the issue, FF0F seems to be converted into a real
0x2F somewhere along the way, and according to Neil (via mail) the patch in bug
301694 does not fix the problem.
-------from mail--------
I was the person who added the patch for bug 301694. The filing of this bug was
based on _my testing of that patch:_ it blocked all of the funny characters but
one, which created very peculiar behavior. Hence the very specific mention of
that one character.
The characters specified in 301694 are all potential visual spoofs, but apart
from this one all appear to be Punycoded correctly. However, this _particular_
character, unlike the others, appears to do something really strange to the
processing of URLs and DNS requests, as witness the malformed DNS lookups
generated, and the malformed host name passed to in the Host: header of the HTTP
request. Unlike the other characters, this seems to be bypassing the IDN logic,
and ending up being converted into a slash within a DNS label. This occurs _even
after the patch for 301694 is applied_, which is unsurprising as that patch only
affects DNS display of domain name labels, not the logic of DNS processing.
See the Ethereal dump attached in comment #6 in bug 308800 as evidence.
This is bad. Note that the DNS lookup is malformed: a FQDN with a slash in it is
never valid, either in a standard ASCII lookup, or in a Punycoded lookup. See
RFC 1035. Similarly, a malformed host address should never be passed in an HTTP
call. Fortunately, at the moment, I can't get a page load to occur when the
malformed DNS entry is responded to, so at the moment it looks difficult to
exploit. But this looks like "security through luck", rather than security by
design, and there may be a real exploit possible by exploiting this or similar
behavior.
Group: security
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Whiteboard: [sg:fix]
Updated•19 years ago
|
Assignee: nobody → gerv
Status: REOPENED → NEW
Flags: blocking1.8b5?
Comment 11•19 years ago
|
||
Bug 304904 might help.
Component: Security → Networking
Product: Firefox → Core
Summary: Character U+FFOF appears to allow URL spoofing → Character U+FF0F appears to allow URL spoofing
Version: unspecified → Trunk
Updated•19 years ago
|
Flags: blocking1.8b5? → blocking1.8b5+
Updated•19 years ago
|
Whiteboard: [sg:fix] → [sg:spoof]
Comment 12•19 years ago
|
||
Why did this get assigned to me? :-)
Gerv
Comment 13•19 years ago
|
||
We now have an ASCII character blacklist which is applied before DNS resolving.
This was added in bug 304904. Here is the branch version of the patch:
+ const char* bad = net_FindCharInSet(hostname, end,
+ "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+ "\x21\x22\x23\x25\x26\x27\x28\x29"
+ "\x2a\x2b\x2c\x2f\x3b\x3c\x3d\x3e"
+ "\x3f\x40\x5c\x5e\x7b\x7c\x7e\x7f");
Even if we have bugs which allows the / character to make it through to the DNS
resolver, this should stop the lookup from happening (/ is 2f, which is on the
list). Does that deal with the security part of this bug?
Gerv
Comment 14•19 years ago
|
||
Darin, so are we covered here as far as the security concern goes, as Gerv
suggests in comment #13?
Assignee: gerv → darin
Comment 15•19 years ago
|
||
After talking with Darin, we're going to push this out to after the beta2 (first
RC).
Flags: blocking1.8b5+ → blocking1.8b5-
Reporter | ||
Comment 16•19 years ago
|
||
Whilst the particular example given here has now been fixed by refining the DNS output character filter rules, this does not yet solve the general case of the underlying problem.
Resolving bug 316444 _will_ however fix the larger problem of which this is a special case. Therefore, I'm marking what remainst of this bug as a dup of 316444.
*** This bug has been marked as a duplicate of 316444 ***
Status: NEW → RESOLVED
Closed: 19 years ago → 19 years ago
Resolution: --- → DUPLICATE
Updated•18 years ago
|
Whiteboard: [sg:spoof] → [sg:dupe 316444]
Updated•18 years ago
|
Group: security
You need to log in
before you can comment on or make changes to this bug.
Description
•