Bug 581629 (CVE-2010-1236)

Summary: CVE-2010-1236 webkit: leading URL bypass of cross-origin protections
Product: [Other] Security Response Reporter: Vincent Danen <vdanen>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: jreznik, stransky, than
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2010-04-23 18:39:24 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Vincent Danen 2010-04-12 20:18:18 UTC
A bug was reported in Google Chrome [1], [2] where a javascript URL with a leading NULL byte can bypass cross-origin protections.  Looking at the patch to KURLGoogle.cpp [3] and comparing it to KURL.cpp's isProtocol() function, it may be possible that this will work with other browsers besides just Google Chrome as the upstream report indicates.

For instance, in qt-everywhere-opensource-src-4.6.2/src/3rdparty/webkit/WebCore/platform/KURL.cpp we have the exact same code that was changed in KURLGoogle.cpp:

1610 bool protocolIs(const String& url, const char* protocol)
1611 {
1612     // Do the comparison without making a new string object.
1613     assertProtocolIsGood(protocol);
1614     for (int i = 0; ; ++i) {
1615         if (!protocol[i])
1616             return url[i] == ':';
1617         if (toASCIILower(url[i]) != protocol[i])
1618             return false;
1619     }
1620 }

I have verified this affects konqueror on Fedora 12:

konqueror(12458)/kio (Scheduler) KIO::SchedulerPrivate::findIdleSlave: HOLD: Reusing held slave for KUrl("http://linsec.ca/file_store/test.html")
konqueror(12458)/khtml (html) DOM::HTMLDocumentImpl::changeModes:  using compatibility parseMode
konqueror(12458)/khtml (html) DOM::HTMLDocumentImpl::changeModes:  using strict parseMode
konqueror(12458)/khtml (part) KHTMLPart::requestObject: Running new KHTMLRun for KHTMLPart(0x12ac1f0) and child= khtml::ChildFrame(0x152a650, name = "khtml_child_frame")
konqueror(12458)/kparts KParts::BrowserRun::scanFile: KUrl("http://localhost:8080/security/resources/innocent-victim.html")
konqueror(12458)/kio (KIOJob) KIO::SlaveInterface::dispatch: error  123   "localhost: Connection refused"
konqueror(12458)/kparts KParts::BrowserRun::slotBrowserScanFinished: 123

Also verified with Safari on OS X, so this is not Chrome-specific (compared to how Firefox handles the URL).  This likely affects webkitgtk and qt both.

[1] http://code.google.com/p/chromium/issues/detail?id=37383
[2] https://bugs.webkit.org/show_bug.cgi?id=35948
[3] http://trac.webkit.org/changeset/55822

Comment 2 Tomas Hoger 2010-04-20 10:22:20 UTC
This is indeed reproducible with F12 konqueror, but not with midori / webkitgtk-1.1.15.4 or arora / qt-4.6.2.  Does anyone have access to the webkit bug?

Comment 3 Than Ngo 2010-04-20 11:16:10 UTC
(In reply to comment #2)
> This is indeed reproducible with F12 konqueror, but not with midori /
> webkitgtk-1.1.15.4 or arora / qt-4.6.2.  Does anyone have access to the webkit
> bug?    

how can you reproduce it in konqueror?

Comment 4 Tomas Hoger 2010-04-20 11:47:27 UTC
(In reply to comment #3)

> how can you reproduce it in konqueror?    

Ok, I guess I should correct myself.  konqueror does execute that javascript, but it is executed inside the parent frame's domain, not inside iframe domain.  With webkitgtk and QTWebKit (and firefox too), the behaviour is as mentioned in the google bug:

http://code.google.com/p/chromium/issues/detail?id=37383#c13

Comment 5 Tomas Hoger 2010-04-23 18:39:24 UTC
I'm closing this, based on comment #4.  The behaviour of different browsers / engines differ, but none of the tested browsers executes specified javascript script inside iframe domain, but rather in the domain of the page that includes it, which does not bypass same-origin protection.