diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp | 69 |
1 files changed, 35 insertions, 34 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp index 5dfc963..70b691b 100644 --- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp @@ -46,9 +46,14 @@ using namespace WTF; namespace WebCore { -static bool isNonNullControlCharacter(UChar c) +static bool isNonCanonicalCharacter(UChar c) { - return (c > '\0' && c < ' ') || c == 127; + // Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character. + // Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the + // adverse effect that we remove any legitimate zeros from a string. + // + // For instance: new String("http://localhost:8000") => new String("http://localhost:8"). + return (c == '\\' || c == '0' || c < ' ' || c == 127); } XSSAuditor::XSSAuditor(Frame* frame) @@ -66,12 +71,12 @@ bool XSSAuditor::isEnabled() const return (settings && settings->xssAuditorEnabled()); } -bool XSSAuditor::canEvaluate(const String& sourceCode) const +bool XSSAuditor::canEvaluate(const String& code) const { if (!isEnabled()) return true; - if (findInRequest(sourceCode, false, true, false)) { + if (findInRequest(code, false)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -84,7 +89,7 @@ bool XSSAuditor::canEvaluateJavaScriptURL(const String& code) const if (!isEnabled()) return true; - if (findInRequest(code, false, false, true, true)) { + if (findInRequest(code)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -123,7 +128,7 @@ bool XSSAuditor::canLoadObject(const String& url) const if (!isEnabled()) return true; - if (findInRequest(url, false, false)) { + if (findInRequest(url)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -145,11 +150,16 @@ bool XSSAuditor::canSetBaseElementURL(const String& url) const return true; } -String XSSAuditor::decodeURL(const String& str, const TextEncoding& encoding, bool allowNullCharacters, - bool allowNonNullControlCharacters, bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched) +String XSSAuditor::canonicalize(const String& string) +{ + String result = decodeHTMLEntities(string); + return result.removeCharacters(&isNonCanonicalCharacter); +} + +String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeHTMLentities) { String result; - String url = str; + String url = string; url.replace('+', ' '); result = decodeURLEscapeSequences(url); @@ -157,20 +167,13 @@ String XSSAuditor::decodeURL(const String& str, const TextEncoding& encoding, bo if (!decodedResult.isEmpty()) result = decodedResult; if (decodeHTMLentities) - result = decodeHTMLEntities(result, leaveUndecodableHTMLEntitiesUntouched); - if (!allowNullCharacters) - result = StringImpl::createStrippingNullCharacters(result.characters(), result.length()); - if (!allowNonNullControlCharacters) { - decodedResult = result.removeCharacters(&isNonNullControlCharacter); - if (!decodedResult.isEmpty()) - result = decodedResult; - } + result = decodeHTMLEntities(result); return result; } -String XSSAuditor::decodeHTMLEntities(const String& str, bool leaveUndecodableHTMLEntitiesUntouched) +String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodableHTMLEntitiesUntouched) { - SegmentedString source(str); + SegmentedString source(string); SegmentedString sourceShadow; Vector<UChar> result; @@ -193,7 +196,7 @@ String XSSAuditor::decodeHTMLEntities(const String& str, bool leaveUndecodableHT if (entity > 0xFFFF) { result.append(U16_LEAD(entity)); result.append(U16_TRAIL(entity)); - } else if (!leaveUndecodableHTMLEntitiesUntouched || entity != 0xFFFD){ + } else if (entity && (!leaveUndecodableHTMLEntitiesUntouched || entity != 0xFFFD)){ result.append(entity); } else { result.append('&'); @@ -205,22 +208,18 @@ String XSSAuditor::decodeHTMLEntities(const String& str, bool leaveUndecodableHT return String::adopt(result); } -bool XSSAuditor::findInRequest(const String& string, bool matchNullCharacters, bool matchNonNullControlCharacters, - bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched) const +bool XSSAuditor::findInRequest(const String& string, bool decodeHTMLentities) const { bool result = false; Frame* parentFrame = m_frame->tree()->parent(); if (parentFrame && m_frame->document()->url() == blankURL()) - result = findInRequest(parentFrame, string, matchNullCharacters, matchNonNullControlCharacters, - decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched); + result = findInRequest(parentFrame, string, decodeHTMLentities); if (!result) - result = findInRequest(m_frame, string, matchNullCharacters, matchNonNullControlCharacters, - decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched); + result = findInRequest(m_frame, string, decodeHTMLentities); return result; } -bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool matchNullCharacters, bool matchNonNullControlCharacters, - bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched) const +bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeHTMLentities) const { ASSERT(frame->document()); String pageURL = frame->document()->url().string(); @@ -236,11 +235,14 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool matchNul if (string.isEmpty()) return false; + String canonicalizedString = canonicalize(string); + if (canonicalizedString.isEmpty()) + return false; + if (string.length() < pageURL.length()) { // The string can actually fit inside the pageURL. - String decodedPageURL = decodeURL(pageURL, frame->document()->decoder()->encoding(), matchNullCharacters, - matchNonNullControlCharacters, decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched); - if (decodedPageURL.find(string, 0, false) != -1) + String decodedPageURL = canonicalize(decodeURL(pageURL, frame->document()->decoder()->encoding(), decodeHTMLentities)); + if (decodedPageURL.find(canonicalizedString, 0, false) != -1) return true; // We've found the smoking gun. } @@ -252,9 +254,8 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool matchNul // the url-encoded POST data because the length of the url-decoded // code is less than or equal to the length of the url-encoded // string. - String decodedFormData = decodeURL(formData, frame->document()->decoder()->encoding(), matchNullCharacters, - matchNonNullControlCharacters, decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched); - if (decodedFormData.find(string, 0, false) != -1) + String decodedFormData = canonicalize(decodeURL(formData, frame->document()->decoder()->encoding(), decodeHTMLentities)); + if (decodedFormData.find(canonicalizedString, 0, false) != -1) return true; // We found the string in the POST data. } } |