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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 | 260 |
261 if (document->decoder()) | 261 if (document->decoder()) |
262 m_encoding = document->decoder()->encoding(); | 262 m_encoding = document->decoder()->encoding(); |
263 | 263 |
264 m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding); | 264 m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding); |
265 if (m_decodedURL.find(isRequiredForInjection) == notFound) | 265 if (m_decodedURL.find(isRequiredForInjection) == notFound) |
266 m_decodedURL = String(); | 266 m_decodedURL = String(); |
267 | 267 |
268 String httpBodyAsString; | 268 String httpBodyAsString; |
269 if (DocumentLoader* documentLoader = document->frame()->loader()->documentLo
ader()) { | 269 if (DocumentLoader* documentLoader = document->frame()->loader()->documentLo
ader()) { |
270 DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, (ASCIILiteral("X-XSS-Pr
otection"))); | 270 DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection")); |
271 String headerValue = documentLoader->response().httpHeaderField(XSSProte
ctionHeader); | 271 String headerValue = documentLoader->response().httpHeaderField(XSSProte
ctionHeader); |
272 String errorDetails; | 272 String errorDetails; |
273 unsigned errorPosition = 0; | 273 unsigned errorPosition = 0; |
274 String reportURL; | 274 String reportURL; |
275 KURL xssProtectionReportURL; | 275 KURL xssProtectionReportURL; |
276 | 276 |
277 // Process the X-XSS-Protection header, then mix in the CSP header's val
ue. | 277 // Process the X-XSS-Protection header, then mix in the CSP header's val
ue. |
278 ContentSecurityPolicy::ReflectedXSSDisposition xssProtectionHeader = par
seXSSProtectionHeader(headerValue, errorDetails, errorPosition, reportURL); | 278 ContentSecurityPolicy::ReflectedXSSDisposition xssProtectionHeader = par
seXSSProtectionHeader(headerValue, errorDetails, errorPosition, reportURL); |
279 m_didSendValidXSSProtectionHeader = xssProtectionHeader != ContentSecuri
tyPolicy::ReflectedXSSUnset && xssProtectionHeader != ContentSecurityPolicy::Ref
lectedXSSInvalid; | 279 m_didSendValidXSSProtectionHeader = xssProtectionHeader != ContentSecuri
tyPolicy::ReflectedXSSUnset && xssProtectionHeader != ContentSecurityPolicy::Ref
lectedXSSInvalid; |
280 if ((xssProtectionHeader == ContentSecurityPolicy::FilterReflectedXSS ||
xssProtectionHeader == ContentSecurityPolicy::BlockReflectedXSS) && !reportURL.
isEmpty()) { | 280 if ((xssProtectionHeader == ContentSecurityPolicy::FilterReflectedXSS ||
xssProtectionHeader == ContentSecurityPolicy::BlockReflectedXSS) && !reportURL.
isEmpty()) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request) | 509 bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request) |
510 { | 510 { |
511 ASSERT(request.token.type() == HTMLToken::StartTag); | 511 ASSERT(request.token.type() == HTMLToken::StartTag); |
512 ASSERT(hasName(request.token, buttonTag)); | 512 ASSERT(hasName(request.token, buttonTag)); |
513 | 513 |
514 return eraseAttributeIfInjected(request, formactionAttr, blankURL().string()
, SrcLikeAttribute); | 514 return eraseAttributeIfInjected(request, formactionAttr, blankURL().string()
, SrcLikeAttribute); |
515 } | 515 } |
516 | 516 |
517 bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
quest) | 517 bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
quest) |
518 { | 518 { |
519 DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, (ASCIILiteral("javascript:voi
d(0)"))); | 519 DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, ("javascript:void(0)")); |
520 | 520 |
521 bool didBlockScript = false; | 521 bool didBlockScript = false; |
522 for (size_t i = 0; i < request.token.attributes().size(); ++i) { | 522 for (size_t i = 0; i < request.token.attributes().size(); ++i) { |
523 const HTMLToken::Attribute& attribute = request.token.attributes().at(i)
; | 523 const HTMLToken::Attribute& attribute = request.token.attributes().at(i)
; |
524 bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.name); | 524 bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.name); |
525 // FIXME: It would be better if we didn't create a new String for every
attribute in the document. | 525 // FIXME: It would be better if we didn't create a new String for every
attribute in the document. |
526 String strippedValue = stripLeadingAndTrailingHTMLSpaces(String(attribut
e.value)); | 526 String strippedValue = stripLeadingAndTrailingHTMLSpaces(String(attribut
e.value)); |
527 bool valueContainsJavaScriptURL = (!isInlineEventHandler && protocolIsJa
vaScript(strippedValue)) || (isSemicolonSeparatedAttribute(attribute) && semicol
onSeparatedValueContainsJavaScriptURL(strippedValue)); | 527 bool valueContainsJavaScriptURL = (!isInlineEventHandler && protocolIsJa
vaScript(strippedValue)) || (isSemicolonSeparatedAttribute(attribute) && semicol
onSeparatedValueContainsJavaScriptURL(strippedValue)); |
528 if (!isInlineEventHandler && !valueContainsJavaScriptURL) | 528 if (!isInlineEventHandler && !valueContainsJavaScriptURL) |
529 continue; | 529 continue; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 } | 717 } |
718 | 718 |
719 bool XSSAuditor::isSafeToSendToAnotherThread() const | 719 bool XSSAuditor::isSafeToSendToAnotherThread() const |
720 { | 720 { |
721 return m_documentURL.isSafeToSendToAnotherThread() | 721 return m_documentURL.isSafeToSendToAnotherThread() |
722 && m_decodedURL.isSafeToSendToAnotherThread() | 722 && m_decodedURL.isSafeToSendToAnotherThread() |
723 && m_decodedHTTPBody.isSafeToSendToAnotherThread(); | 723 && m_decodedHTTPBody.isSafeToSendToAnotherThread(); |
724 } | 724 } |
725 | 725 |
726 } // namespace WebCore | 726 } // namespace WebCore |
OLD | NEW |