OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Adam Barth. All Rights Reserved. | 2 * Copyright (C) 2011 Adam Barth. All Rights Reserved. |
3 * Copyright (C) 2011 Daniel Bates (dbates@intudata.com). | 3 * Copyright (C) 2011 Daniel Bates (dbates@intudata.com). |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 else if (hasName(request.token, metaTag)) | 437 else if (hasName(request.token, metaTag)) |
438 didBlockScript |= filterMetaToken(request); | 438 didBlockScript |= filterMetaToken(request); |
439 else if (hasName(request.token, baseTag)) | 439 else if (hasName(request.token, baseTag)) |
440 didBlockScript |= filterBaseToken(request); | 440 didBlockScript |= filterBaseToken(request); |
441 else if (hasName(request.token, formTag)) | 441 else if (hasName(request.token, formTag)) |
442 didBlockScript |= filterFormToken(request); | 442 didBlockScript |= filterFormToken(request); |
443 else if (hasName(request.token, inputTag)) | 443 else if (hasName(request.token, inputTag)) |
444 didBlockScript |= filterInputToken(request); | 444 didBlockScript |= filterInputToken(request); |
445 else if (hasName(request.token, buttonTag)) | 445 else if (hasName(request.token, buttonTag)) |
446 didBlockScript |= filterButtonToken(request); | 446 didBlockScript |= filterButtonToken(request); |
| 447 else if (hasName(request.token, linkTag)) |
| 448 didBlockScript |= filterLinkToken(request); |
447 | 449 |
448 return didBlockScript; | 450 return didBlockScript; |
449 } | 451 } |
450 | 452 |
451 void XSSAuditor::filterEndToken(const FilterTokenRequest& request) | 453 void XSSAuditor::filterEndToken(const FilterTokenRequest& request) |
452 { | 454 { |
453 ASSERT(m_scriptTagNestingLevel); | 455 ASSERT(m_scriptTagNestingLevel); |
454 m_state = FilteringTokens; | 456 m_state = FilteringTokens; |
455 if (hasName(request.token, scriptTag)) { | 457 if (hasName(request.token, scriptTag)) { |
456 m_scriptTagNestingLevel--; | 458 m_scriptTagNestingLevel--; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 } | 595 } |
594 | 596 |
595 bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request) | 597 bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request) |
596 { | 598 { |
597 ASSERT(request.token.type() == HTMLToken::StartTag); | 599 ASSERT(request.token.type() == HTMLToken::StartTag); |
598 ASSERT(hasName(request.token, buttonTag)); | 600 ASSERT(hasName(request.token, buttonTag)); |
599 | 601 |
600 return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigi
n, SrcLikeAttributeTruncation); | 602 return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigi
n, SrcLikeAttributeTruncation); |
601 } | 603 } |
602 | 604 |
| 605 bool XSSAuditor::filterLinkToken(const FilterTokenRequest& request) |
| 606 { |
| 607 ASSERT(request.token.type() == HTMLToken::StartTag); |
| 608 ASSERT(hasName(request.token, linkTag)); |
| 609 |
| 610 size_t indexOfAttribute = 0; |
| 611 if (!findAttributeWithName(request.token, relAttr, indexOfAttribute)) |
| 612 return false; |
| 613 |
| 614 const HTMLToken::Attribute& attribute = request.token.attributes().at(indexO
fAttribute); |
| 615 if (!equalIgnoringCase(String(attribute.value), "import")) |
| 616 return false; |
| 617 |
| 618 return eraseAttributeIfInjected(request, hrefAttr, kURLWithUniqueOrigin, Src
LikeAttributeTruncation, AllowSameOriginHref); |
| 619 } |
| 620 |
603 bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
quest) | 621 bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
quest) |
604 { | 622 { |
605 DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, ("javascript:void(0)")); | 623 DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, ("javascript:void(0)")); |
606 | 624 |
607 bool didBlockScript = false; | 625 bool didBlockScript = false; |
608 for (size_t i = 0; i < request.token.attributes().size(); ++i) { | 626 for (size_t i = 0; i < request.token.attributes().size(); ++i) { |
609 bool eraseAttribute = false; | 627 bool eraseAttribute = false; |
610 bool valueContainsJavaScriptURL = false; | 628 bool valueContainsJavaScriptURL = false; |
611 const HTMLToken::Attribute& attribute = request.token.attributes().at(i)
; | 629 const HTMLToken::Attribute& attribute = request.token.attributes().at(i)
; |
612 // FIXME: Don't create a new String for every attribute.value in the doc
ument. | 630 // FIXME: Don't create a new String for every attribute.value in the doc
ument. |
(...skipping 13 matching lines...) Expand all Loading... |
626 if (!eraseAttribute) | 644 if (!eraseAttribute) |
627 continue; | 645 continue; |
628 request.token.eraseValueOfAttribute(i); | 646 request.token.eraseValueOfAttribute(i); |
629 if (valueContainsJavaScriptURL) | 647 if (valueContainsJavaScriptURL) |
630 request.token.appendToAttributeValue(i, safeJavaScriptURL); | 648 request.token.appendToAttributeValue(i, safeJavaScriptURL); |
631 didBlockScript = true; | 649 didBlockScript = true; |
632 } | 650 } |
633 return didBlockScript; | 651 return didBlockScript; |
634 } | 652 } |
635 | 653 |
636 bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, con
st QualifiedName& attributeName, const String& replacementValue, TruncationKind
treatment) | 654 bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, con
st QualifiedName& attributeName, const String& replacementValue, TruncationKind
treatment, HrefRestriction restriction) |
637 { | 655 { |
638 size_t indexOfAttribute = 0; | 656 size_t indexOfAttribute = 0; |
639 if (!findAttributeWithName(request.token, attributeName, indexOfAttribute)) | 657 if (!findAttributeWithName(request.token, attributeName, indexOfAttribute)) |
640 return false; | 658 return false; |
641 | 659 |
642 const HTMLToken::Attribute& attribute = request.token.attributes().at(indexO
fAttribute); | 660 const HTMLToken::Attribute& attribute = request.token.attributes().at(indexO
fAttribute); |
643 if (!isContainedInRequest(canonicalize(snippetFromAttribute(request, attribu
te), treatment))) | 661 if (!isContainedInRequest(canonicalize(snippetFromAttribute(request, attribu
te), treatment))) |
644 return false; | 662 return false; |
645 | 663 |
646 if (threadSafeMatch(attributeName, srcAttr)) { | 664 if (threadSafeMatch(attributeName, srcAttr) || (restriction == AllowSameOrig
inHref && threadSafeMatch(attributeName, hrefAttr))) { |
647 if (isLikelySafeResource(String(attribute.value))) | 665 if (isLikelySafeResource(String(attribute.value))) |
648 return false; | 666 return false; |
649 } else if (threadSafeMatch(attributeName, http_equivAttr)) { | 667 } else if (threadSafeMatch(attributeName, http_equivAttr)) { |
650 if (!isDangerousHTTPEquiv(String(attribute.value))) | 668 if (!isDangerousHTTPEquiv(String(attribute.value))) |
651 return false; | 669 return false; |
652 } | 670 } |
653 | 671 |
654 request.token.eraseValueOfAttribute(indexOfAttribute); | 672 request.token.eraseValueOfAttribute(indexOfAttribute); |
655 if (!replacementValue.isEmpty()) | 673 if (!replacementValue.isEmpty()) |
656 request.token.appendToAttributeValue(indexOfAttribute, replacementValue)
; | 674 request.token.appendToAttributeValue(indexOfAttribute, replacementValue)
; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 | 823 |
806 bool XSSAuditor::isSafeToSendToAnotherThread() const | 824 bool XSSAuditor::isSafeToSendToAnotherThread() const |
807 { | 825 { |
808 return m_documentURL.isSafeToSendToAnotherThread() | 826 return m_documentURL.isSafeToSendToAnotherThread() |
809 && m_decodedURL.isSafeToSendToAnotherThread() | 827 && m_decodedURL.isSafeToSendToAnotherThread() |
810 && m_decodedHTTPBody.isSafeToSendToAnotherThread() | 828 && m_decodedHTTPBody.isSafeToSendToAnotherThread() |
811 && m_httpBodyAsString.isSafeToSendToAnotherThread(); | 829 && m_httpBodyAsString.isSafeToSendToAnotherThread(); |
812 } | 830 } |
813 | 831 |
814 } // namespace blink | 832 } // namespace blink |
OLD | NEW |