summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp69
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.
}
}