| 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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 } | 195 } |
| 196 return false; | 196 return false; |
| 197 } | 197 } |
| 198 | 198 |
| 199 XSSAuditor::XSSAuditor() | 199 XSSAuditor::XSSAuditor() |
| 200 : m_isEnabled(false) | 200 : m_isEnabled(false) |
| 201 , m_xssProtection(ContentSecurityPolicy::FilterReflectedXSS) | 201 , m_xssProtection(ContentSecurityPolicy::FilterReflectedXSS) |
| 202 , m_didSendValidCSPHeader(false) | 202 , m_didSendValidCSPHeader(false) |
| 203 , m_didSendValidXSSProtectionHeader(false) | 203 , m_didSendValidXSSProtectionHeader(false) |
| 204 , m_state(Uninitialized) | 204 , m_state(Uninitialized) |
| 205 , m_scriptTagFoundInRequest(false) |
| 205 , m_scriptTagNestingLevel(0) | 206 , m_scriptTagNestingLevel(0) |
| 206 , m_encoding(UTF8Encoding()) | 207 , m_encoding(UTF8Encoding()) |
| 207 { | 208 { |
| 208 // Although tempting to call init() at this point, the various objects | 209 // Although tempting to call init() at this point, the various objects |
| 209 // we want to reference might not all have been constructed yet. | 210 // we want to reference might not all have been constructed yet. |
| 210 } | 211 } |
| 211 | 212 |
| 212 void XSSAuditor::initForFragment() | 213 void XSSAuditor::initForFragment() |
| 213 { | 214 { |
| 214 ASSERT(isMainThread()); | 215 ASSERT(isMainThread()); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 ASSERT(m_scriptTagNestingLevel); | 375 ASSERT(m_scriptTagNestingLevel); |
| 375 if (hasName(request.token, scriptTag)) { | 376 if (hasName(request.token, scriptTag)) { |
| 376 m_scriptTagNestingLevel--; | 377 m_scriptTagNestingLevel--; |
| 377 ASSERT(request.shouldAllowCDATA || !m_scriptTagNestingLevel); | 378 ASSERT(request.shouldAllowCDATA || !m_scriptTagNestingLevel); |
| 378 } | 379 } |
| 379 } | 380 } |
| 380 | 381 |
| 381 bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request) | 382 bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request) |
| 382 { | 383 { |
| 383 ASSERT(m_scriptTagNestingLevel); | 384 ASSERT(m_scriptTagNestingLevel); |
| 384 if (isContainedInRequest(m_cachedDecodedSnippet) && isContainedInRequest(dec
odedSnippetForJavaScript(request))) { | 385 if (m_scriptTagFoundInRequest && isContainedInRequest(decodedSnippetForJavaS
cript(request))) { |
| 385 request.token.eraseCharacters(); | 386 request.token.eraseCharacters(); |
| 386 request.token.appendToCharacter(' '); // Technically, character tokens c
an't be empty. | 387 request.token.appendToCharacter(' '); // Technically, character tokens c
an't be empty. |
| 387 return true; | 388 return true; |
| 388 } | 389 } |
| 389 return false; | 390 return false; |
| 390 } | 391 } |
| 391 | 392 |
| 392 bool XSSAuditor::filterScriptToken(const FilterTokenRequest& request) | 393 bool XSSAuditor::filterScriptToken(const FilterTokenRequest& request) |
| 393 { | 394 { |
| 394 ASSERT(request.token.type() == HTMLToken::StartTag); | 395 ASSERT(request.token.type() == HTMLToken::StartTag); |
| 395 ASSERT(hasName(request.token, scriptTag)); | 396 ASSERT(hasName(request.token, scriptTag)); |
| 396 | 397 |
| 397 m_cachedDecodedSnippet = decodedSnippetForName(request); | |
| 398 | |
| 399 bool didBlockScript = false; | 398 bool didBlockScript = false; |
| 400 if (isContainedInRequest(decodedSnippetForName(request))) { | 399 m_scriptTagFoundInRequest = isContainedInRequest(decodedSnippetForName(reque
st)); |
| 400 if (m_scriptTagFoundInRequest) { |
| 401 didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().
string(), SrcLikeAttribute); | 401 didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().
string(), SrcLikeAttribute); |
| 402 didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr
, blankURL().string(), SrcLikeAttribute); | 402 didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr
, blankURL().string(), SrcLikeAttribute); |
| 403 } | 403 } |
| 404 | |
| 405 return didBlockScript; | 404 return didBlockScript; |
| 406 } | 405 } |
| 407 | 406 |
| 408 bool XSSAuditor::filterObjectToken(const FilterTokenRequest& request) | 407 bool XSSAuditor::filterObjectToken(const FilterTokenRequest& request) |
| 409 { | 408 { |
| 410 ASSERT(request.token.type() == HTMLToken::StartTag); | 409 ASSERT(request.token.type() == HTMLToken::StartTag); |
| 411 ASSERT(hasName(request.token, objectTag)); | 410 ASSERT(hasName(request.token, objectTag)); |
| 412 | 411 |
| 413 bool didBlockScript = false; | 412 bool didBlockScript = false; |
| 414 if (isContainedInRequest(decodedSnippetForName(request))) { | 413 if (isContainedInRequest(decodedSnippetForName(request))) { |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 return false; | 713 return false; |
| 715 | 714 |
| 716 KURL resourceURL(m_documentURL, url); | 715 KURL resourceURL(m_documentURL, url); |
| 717 return (m_documentURL.host() == resourceURL.host() && resourceURL.query().is
Empty()); | 716 return (m_documentURL.host() == resourceURL.host() && resourceURL.query().is
Empty()); |
| 718 } | 717 } |
| 719 | 718 |
| 720 bool XSSAuditor::isSafeToSendToAnotherThread() const | 719 bool XSSAuditor::isSafeToSendToAnotherThread() const |
| 721 { | 720 { |
| 722 return m_documentURL.isSafeToSendToAnotherThread() | 721 return m_documentURL.isSafeToSendToAnotherThread() |
| 723 && m_decodedURL.isSafeToSendToAnotherThread() | 722 && m_decodedURL.isSafeToSendToAnotherThread() |
| 724 && m_decodedHTTPBody.isSafeToSendToAnotherThread() | 723 && m_decodedHTTPBody.isSafeToSendToAnotherThread(); |
| 725 && m_cachedDecodedSnippet.isSafeToSendToAnotherThread(); | |
| 726 } | 724 } |
| 727 | 725 |
| 728 } // namespace WebCore | 726 } // namespace WebCore |
| OLD | NEW |