Summary: | XSSAuditor is super super super slow | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | James Robinson <jamesr> | ||||||||||
Component: | New Bugs | Assignee: | Nobody <webkit-unassigned> | ||||||||||
Status: | RESOLVED FIXED | ||||||||||||
Severity: | Normal | CC: | abarth, ap, dbates, dglazkov | ||||||||||
Priority: | P2 | Keywords: | XSSAuditor | ||||||||||
Version: | 528+ (Nightly build) | ||||||||||||
Hardware: | PC | ||||||||||||
OS: | OS X 10.5 | ||||||||||||
URL: | http://tersk.intudata.com/~dbates/webkit/webkit-test-5.php | ||||||||||||
Attachments: |
|
Description
James Robinson
2010-02-24 18:12:19 PST
Created attachment 49456 [details]
shark profile of load
Created attachment 49457 [details]
test page (PHP)
Test page, from the original Chromium bug. It has directions for running it in the page. A bit messy but shows the problem clearly.
Here are the two really bad callstacks on the second load: 0.0% 91.8% WebCore WebCore::HTMLTokenizer::write(WebCore::SegmentedString const&, bool) 0.1% 91.7% WebCore WebCore::HTMLTokenizer::parseTag(WebCore::SegmentedString&, WebCore::HTMLTokenizer::State) 0.0% 91.5% WebCore WebCore::HTMLTokenizer::processToken() 0.0% 91.5% WebCore WebCore::HTMLParser::parseToken(WebCore::Token*) 0.0% 90.3% WebCore WebCore::Element::setAttributeMap(WTF::PassRefPtr<WebCore::NamedNodeMap>, WebCore::FragmentScriptingPermission) 0.0% 90.2% WebCore WebCore::StyledElement::attributeChanged(WebCore::Attribute*, bool) 0.0% 58.2% WebCore WebCore::HTMLInputElement::parseMappedAttribute(WebCore::MappedAttribute*) 0.0% 58.1% WebCore WebCore::HTMLTextFormControlElement::parseMappedAttribute(WebCore::MappedAttribute*) 0.0% 51.5% WebCore WebCore::createAttributeEventListener(WebCore::Node*, WebCore::Attribute*) 0.0% 51.5% WebCore WebCore::XSSAuditor::canCreateInlineEventListener(WebCore::String const&, WebCore::String const&) const and 0.0% 91.8% WebCore WebCore::HTMLTokenizer::write(WebCore::SegmentedString const&, bool) 0.1% 91.7% WebCore WebCore::HTMLTokenizer::parseTag(WebCore::SegmentedString&, WebCore::HTMLTokenizer::State) 0.0% 91.5% WebCore WebCore::HTMLTokenizer::processToken() 0.0% 91.5% WebCore WebCore::HTMLParser::parseToken(WebCore::Token*) 0.0% 90.3% WebCore WebCore::Element::setAttributeMap(WTF::PassRefPtr<WebCore::NamedNodeMap>, WebCore::FragmentScriptingPermission) 0.0% 90.2% WebCore WebCore::StyledElement::attributeChanged(WebCore::Attribute*, bool) 0.0% 58.2% WebCore WebCore::HTMLInputElement::parseMappedAttribute(WebCore::MappedAttribute*) 0.0% 25.5% WebCore WebCore::HTMLSelectElement::parseMappedAttribute(WebCore::MappedAttribute*) 0.0% 25.5% WebCore WebCore::createAttributeEventListener(WebCore::Node*, WebCore::Attribute*) 0.0% 25.4% WebCore WebCore::XSSAuditor::canCreateInlineEventListener(WebCore::String const&, WebCore::String const&) const They don't make sense to me - why would the XSSAuditor have to check anything coming out of the HTMLTokenizer? This is HTML served up by the server, not coming from any user-controlled data. Are you sure this warrants three supers? It looks only super super slow. > They don't make sense to me - why would the XSSAuditor have to check anything
> coming out of the HTMLTokenizer? This is HTML served up by the server, not
> coming from any user-controlled data.
The XSS auditor is checking whether the event handlers are present in the post request. If they are, it gets suspicious that there might be a reflected XSS attack.
I need to spend some time with this in the debugger to see how we can speed this up. In the worse case, we might need to build some sort of index over the post data to make substring queries faster.
Created attachment 49513 [details]
Patch
While you're thinking, could you please review this patch? Comment on attachment 49513 [details]
Patch
If you want to disable the auditor, we can do that via the Settings object. In particular, you can look in Chromium at how the --disable-xss-auditor command line switch is implemented.
Patch in hand, benchmarking. Created attachment 49593 [details]
Patch
Comment on attachment 49593 [details]
Patch
This patch needs a "why" comment explaining why it's important to use two caches.
Comment on attachment 49593 [details]
Patch
The code, not the change log.
I've added the following comment to the header: // A state store to help us avoid canonicalizing the same URL repeated. // When a page has form data, we need two caches: one to store the // canonicalized URL and another to store the cannonicalized form // data. If we only had one cache, we'd always generate a cache miss // and load some pages extremely slowly. // https://bugs.webkit.org/show_bug.cgi?id=35373 We're still slower on loading this page by a factor of four, but that's better than the factor of infinity slower we were before this patch. (Ok, it's not really infinity, I just got bored waiting for the timer to finish.) |