Changeset 49434 in webkit
- Timestamp:
- Oct 11, 2009 11:50:09 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r49433 r49434 1 2009-10-11 Daniel Bates <dbates@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 https://bugs.webkit.org/show_bug.cgi?id=30242 6 7 Tests that JavaScript URLs that are twice URL encoded do not bypass the XSSAuditor. 8 9 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode-expected.txt: Added. 10 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode.html: Added. 11 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode2-expected.txt: Added. 12 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode2.html: Added. 13 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode3-expected.txt: Added. 14 * http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode3.html: Added. 15 1 16 2009-10-11 Dan Bernstein <mitz@apple.com> 2 17 -
trunk/WebCore/ChangeLog
r49432 r49434 1 2009-10-11 Daniel Bates <dbates@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 https://bugs.webkit.org/show_bug.cgi?id=30242 6 7 Fixes an issue where JavaScript URLs that are URL-encoded twice can 8 bypass the XSSAuditor. 9 10 JavaScript URLs that are completed by method Document::completeURL have added 11 URL-encoded characters such that a direct comparison with the URL-decoded 12 outgoing HTTP parameters is not sufficient. Instead, the URL-decoded outgoing 13 HTTP parameters must be URL-decoded before comparison. 14 15 Tests: http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode.html 16 http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode2.html 17 http/tests/security/xssAuditor/iframe-javascript-url-twice-url-encode3.html 18 19 * bindings/ScriptControllerBase.cpp: 20 (WebCore::ScriptController::executeIfJavaScriptURL): Modified to pass XSSAuditor 21 the URL-decoded source code for the JavaScript URL. 22 * page/XSSAuditor.cpp: 23 (WebCore::isIllegalURICharacter): Minor syntactical change to the comment. 24 (WebCore::XSSAuditor::CachingURLCanonicalizer::canonicalizeURL): Added 25 parameter decodeURLEscapeSequencesTwice. 26 (WebCore::XSSAuditor::canEvaluateJavaScriptURL): 27 (WebCore::XSSAuditor::decodeURL): Ditto. 28 (WebCore::XSSAuditor::findInRequest): Ditto. 29 * page/XSSAuditor.h: 30 (WebCore::XSSAuditor::CachingURLCanonicalizer::CachingURLCanonicalizer): Ditto. 31 1 32 2009-10-11 Dominic Cooney <dominicc@google.com> 2 33 -
trunk/WebCore/bindings/ScriptControllerBase.cpp
r49372 r49434 64 64 const int javascriptSchemeLength = sizeof("javascript:") - 1; 65 65 66 String script = url.string().substring(javascriptSchemeLength);66 String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength)); 67 67 ScriptValue result; 68 68 if (xssAuditor()->canEvaluateJavaScriptURL(script)) 69 result = executeScript( decodeURLEscapeSequences(script), userGesture);69 result = executeScript(script, userGesture); 70 70 71 71 String scriptResult; -
trunk/WebCore/page/XSSAuditor.cpp
r48961 r49434 66 66 // 67 67 // If the request does not contain these characters then we can assume that no inline scripts have been injected 68 // into response page, because it is impossible to write an inline script of the form <script>...</script>68 // into the response page, because it is impossible to write an inline script of the form <script>...</script> 69 69 // without "<", ">". 70 70 return (c == '\'' || c == '"' || c == '<' || c == '>'); 71 71 } 72 72 73 String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities) 74 { 75 if (decodeEntities == m_decodeEntities && encoding == m_encoding && url == m_inputURL) 73 String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, 74 bool decodeURLEscapeSequencesTwice) 75 { 76 if (decodeEntities == m_decodeEntities && decodeURLEscapeSequencesTwice == m_decodeURLEscapeSequencesTwice 77 && encoding == m_encoding && url == m_inputURL) 76 78 return m_cachedCanonicalizedURL; 77 79 78 m_cachedCanonicalizedURL = canonicalize(decodeURL(url, encoding, decodeEntities ));80 m_cachedCanonicalizedURL = canonicalize(decodeURL(url, encoding, decodeEntities, decodeURLEscapeSequencesTwice)); 79 81 m_inputURL = url; 80 82 m_encoding = encoding; 81 83 m_decodeEntities = decodeEntities; 84 m_decodeURLEscapeSequencesTwice = decodeURLEscapeSequencesTwice; 82 85 return m_cachedCanonicalizedURL; 83 86 } … … 116 119 return true; 117 120 118 if (findInRequest(code )) {121 if (findInRequest(code, true, false, true)) { 119 122 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); 120 123 m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); … … 183 186 } 184 187 185 String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeEntities )188 String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeEntities, bool decodeURLEscapeSequencesTwice) 186 189 { 187 190 String result; … … 194 197 if (!decodedResult.isEmpty()) 195 198 result = decodedResult; 199 if (decodeURLEscapeSequencesTwice) { 200 result = decodeURLEscapeSequences(result); 201 utf8Url = result.utf8(); 202 decodedResult = encoding.decode(utf8Url.data(), utf8Url.length()); 203 if (!decodedResult.isEmpty()) 204 result = decodedResult; 205 } 196 206 if (decodeEntities) 197 207 result = decodeHTMLEntities(result); … … 236 246 } 237 247 238 bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters) const 248 bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 249 bool decodeURLEscapeSequencesTwice) const 239 250 { 240 251 bool result = false; 241 252 Frame* parentFrame = m_frame->tree()->parent(); 242 253 if (parentFrame && m_frame->document()->url() == blankURL()) 243 result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters );254 result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); 244 255 if (!result) 245 result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters );256 result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); 246 257 return result; 247 258 } 248 259 249 bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters) const 260 bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 261 bool decodeURLEscapeSequencesTwice) const 250 262 { 251 263 ASSERT(frame->document()); … … 286 298 if (string.length() < pageURL.length()) { 287 299 // The string can actually fit inside the pageURL. 288 String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities );300 String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); 289 301 290 302 if (allowRequestIfNoIllegalURICharacters && (!formDataObj || formDataObj->isEmpty()) … … 303 315 // code is less than or equal to the length of the url-encoded 304 316 // string. 305 String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities );317 String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); 306 318 if (decodedFormData.find(canonicalizedString, 0, false) != -1) 307 319 return true; // We found the string in the POST data. -
trunk/WebCore/page/XSSAuditor.h
r48961 r49434 103 103 { 104 104 public: 105 CachingURLCanonicalizer() : m_decodeEntities(false) { } 106 String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities); 105 CachingURLCanonicalizer() : m_decodeEntities(false), m_decodeURLEscapeSequencesTwice(false) { } 106 String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, 107 bool decodeURLEscapeSequencesTwice); 107 108 108 109 private: … … 111 112 TextEncoding m_encoding; 112 113 bool m_decodeEntities; 114 bool m_decodeURLEscapeSequencesTwice; 113 115 114 116 // The cached result. … … 117 119 118 120 static String canonicalize(const String&); 119 static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities); 121 static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, 122 bool decodeURLEscapeSequencesTwice = false); 120 123 static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true); 121 124 122 bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false) const; 123 bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false) const; 125 bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 126 bool decodeURLEscapeSequencesTwice = false) const; 127 bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 128 bool decodeURLEscapeSequencesTwice = false) const; 124 129 125 130 // The frame to audit.
Note: See TracChangeset
for help on using the changeset viewer.