Changeset 97715 in webkit
- Timestamp:
- Oct 17, 2011 9:37:22 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r97713 r97715 1 2011-10-17 Tom Sepez <tsepez@chromium.org> 2 3 XSSAuditor bypass with remote script ending in ? character 4 https://bugs.webkit.org/show_bug.cgi?id=70255 5 6 Reviewed by Daniel Bates. 7 8 Fix XSSAuditor bypass where unterminated src="" attribute could pick up 9 text from page causing failed XSS detection. Constrain match to domain 10 portions of src attribute only. 11 12 * http/tests/security/xssAuditor/script-tag-with-source-unterminated-expected.txt: Added. 13 * http/tests/security/xssAuditor/script-tag-with-source-unterminated.html: Added. 14 1 15 2011-10-17 Kent Tamura <tkent@chromium.org> 2 16 -
trunk/Source/WebCore/ChangeLog
r97714 r97715 1 2011-10-17 Tom Sepez <tsepez@chromium.org> 2 3 XSSAuditor bypass with remote script ending in ? character 4 https://bugs.webkit.org/show_bug.cgi?id=70255 5 6 Reviewed by Daniel Bates. 7 8 Fix XSSAuditor bypass where unterminated src="" attribute could pick up 9 text from page causing failed XSS detection. Constrain match to domain 10 portions of src attribute only. 11 12 Test: http/tests/security/xssAuditor/script-tag-with-source-unterminated.html 13 14 * html/parser/XSSAuditor.cpp: 15 (WebCore::XSSAuditor::filterScriptToken): 16 (WebCore::XSSAuditor::filterObjectToken): 17 (WebCore::XSSAuditor::filterParamToken): 18 (WebCore::XSSAuditor::filterEmbedToken): 19 (WebCore::XSSAuditor::filterAppletToken): 20 (WebCore::XSSAuditor::filterIframeToken): 21 (WebCore::XSSAuditor::eraseAttributeIfInjected): 22 (WebCore::XSSAuditor::decodedSnippetForAttribute): 23 * html/parser/XSSAuditor.h: 24 1 25 2011-10-17 Adam Klein <adamk@chromium.org> 2 26 -
trunk/Source/WebCore/html/parser/XSSAuditor.cpp
r96440 r97715 354 354 ASSERT(hasName(token, scriptTag)); 355 355 356 if (eraseAttributeIfInjected(token, srcAttr, blankURL().string() ))356 if (eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute)) 357 357 return true; 358 358 … … 370 370 bool didBlockScript = false; 371 371 372 didBlockScript |= eraseAttributeIfInjected(token, dataAttr, blankURL().string() );372 didBlockScript |= eraseAttributeIfInjected(token, dataAttr, blankURL().string(), SrcLikeAttribute); 373 373 didBlockScript |= eraseAttributeIfInjected(token, typeAttr); 374 374 didBlockScript |= eraseAttributeIfInjected(token, classidAttr); … … 393 393 return false; 394 394 395 return eraseAttributeIfInjected(token, valueAttr, blankURL().string() );395 return eraseAttributeIfInjected(token, valueAttr, blankURL().string(), SrcLikeAttribute); 396 396 } 397 397 … … 404 404 bool didBlockScript = false; 405 405 406 didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string() );406 didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute); 407 407 didBlockScript |= eraseAttributeIfInjected(token, typeAttr); 408 408 … … 418 418 bool didBlockScript = false; 419 419 420 didBlockScript |= eraseAttributeIfInjected(token, codeAttr );420 didBlockScript |= eraseAttributeIfInjected(token, codeAttr, String(), SrcLikeAttribute); 421 421 didBlockScript |= eraseAttributeIfInjected(token, objectAttr); 422 422 … … 430 430 ASSERT(hasName(token, iframeTag)); 431 431 432 return eraseAttributeIfInjected(token, srcAttr );432 return eraseAttributeIfInjected(token, srcAttr, String(), SrcLikeAttribute); 433 433 } 434 434 … … 503 503 } 504 504 505 bool XSSAuditor::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& attributeName, const String& replacementValue )505 bool XSSAuditor::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& attributeName, const String& replacementValue, AttributeKind treatment) 506 506 { 507 507 size_t indexOfAttribute; 508 508 if (findAttributeWithName(token, attributeName, indexOfAttribute)) { 509 509 const HTMLToken::Attribute& attribute = token.attributes().at(indexOfAttribute); 510 if (isContainedInRequest(decodedSnippetForAttribute(token, attribute ))) {510 if (isContainedInRequest(decodedSnippetForAttribute(token, attribute, treatment))) { 511 511 if (attributeName == srcAttr && isSameOriginResource(String(attribute.m_value.data(), attribute.m_value.size()))) 512 512 return false; … … 529 529 } 530 530 531 String XSSAuditor::decodedSnippetForAttribute(const HTMLToken& token, const HTMLToken::Attribute& attribute )531 String XSSAuditor::decodedSnippetForAttribute(const HTMLToken& token, const HTMLToken::Attribute& attribute, AttributeKind treatment) 532 532 { 533 533 const size_t kMaximumSnippetLength = 100; … … 541 541 String decodedSnippet = fullyDecodeString(snippetForRange(token, start, end), m_parser->document()->decoder()); 542 542 decodedSnippet.truncate(kMaximumSnippetLength); 543 if (treatment == SrcLikeAttribute) { 544 int slashCount; 545 size_t currentLength; 546 // Characters following the first ?, #, or third slash may come from 547 // the page itself and can be merely ignored by an attacker's server 548 // when a remote script or script-like resource is requested. 549 for (slashCount = 0, currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) { 550 if (decodedSnippet[currentLength] == '?' || decodedSnippet[currentLength] == '#' 551 || ((decodedSnippet[currentLength] == '/' || decodedSnippet[currentLength] == '\\') && ++slashCount > 2)) { 552 decodedSnippet.truncate(currentLength); 553 break; 554 } 555 } 556 } 543 557 return decodedSnippet; 544 558 } … … 566 580 return (m_parser->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty()); 567 581 } 568 569 582 570 583 String XSSAuditor::snippetForJavaScript(const String& string) -
trunk/Source/WebCore/html/parser/XSSAuditor.h
r95901 r97715 49 49 }; 50 50 51 enum AttributeKind { 52 NormalAttribute, 53 SrcLikeAttribute 54 }; 55 51 56 void init(); 52 57 … … 65 70 66 71 bool eraseDangerousAttributesIfInjected(HTMLToken&); 67 bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&, const String& replacementValue = String() );72 bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&, const String& replacementValue = String(), AttributeKind treatment = NormalAttribute); 68 73 69 74 String snippetForRange(const HTMLToken&, int start, int end); 70 75 String snippetForJavaScript(const String&); 71 String decodedSnippetForAttribute(const HTMLToken&, const HTMLToken::Attribute& );76 String decodedSnippetForAttribute(const HTMLToken&, const HTMLToken::Attribute&, AttributeKind treatment = NormalAttribute); 72 77 73 78 bool isContainedInRequest(const String&);
Note: See TracChangeset
for help on using the changeset viewer.