Created attachment 40919 [details] Example JavaScript URLs that are URL encoded via FrameLoader::completeURL are not properly decoded before eventually being passed to both the XSSAuditor and ScriptController::evaluate, because the method KURL::decodeURLEscapeSequences is NOT the inverse function of KURL::parse(). In particular, this occurs in FrameLoader::requestFrame: http://trac.webkit.org/browser/trunk/WebCore/loader/FrameLoader.cpp#L348 where the completeURL() is called on |scriptURL| before it is passed to frame->loader()->executeIfJavaScriptURL(). Remarks: The call flow of FrameLoader::completeURL is: FrameLoader::completeURL -> Document::completeURL -> KURL::KURL(const KURL& base, const String& relative, ...) -> KURL::init - > KURL::parse The issue is that KURL::parse uses the method KURL::appendEscapingBadChars, which as its name implies escapes only bad characters. One such bad character is the space character. Consider the JavaScript URL, "javascript: '%0A'" (*). Calling KURL::parse on this (directly or implicitly via one of the functions in the above call chain) will result in a KURL object that represents the URL, "javascript:%20'%46'" (**). Notice, this result differs from the fully URL encoded result of "javascript:%20%27%2546%27". Decoding the string form of (**) using KURL::decodeURLEscapeSequences produces the result: "javascript: 'F'". Clearly, this is not the inverse of the (**).
(*) should be "javascript: '%46'" (In reply to comment #0) > Created an attachment (id=40919) [details] > Example > > JavaScript URLs that are URL encoded via FrameLoader::completeURL are not > properly decoded before eventually being passed to both the XSSAuditor and > ScriptController::evaluate, because the method KURL::decodeURLEscapeSequences > is NOT the inverse function of KURL::parse(). > > In particular, this occurs in FrameLoader::requestFrame: > http://trac.webkit.org/browser/trunk/WebCore/loader/FrameLoader.cpp#L348 > where the completeURL() is called on |scriptURL| before it is passed to > frame->loader()->executeIfJavaScriptURL(). > > Remarks: > The call flow of FrameLoader::completeURL is: > FrameLoader::completeURL -> Document::completeURL -> KURL::KURL(const KURL& > base, const String& relative, ...) -> KURL::init - > KURL::parse > > The issue is that KURL::parse uses the method KURL::appendEscapingBadChars, > which as its name implies escapes only bad characters. > > One such bad character is the space character. Consider the JavaScript URL, > "javascript: '%0A'" (*). Calling KURL::parse on this (directly or implicitly > via one of the functions in the above call chain) will result in a KURL object > that represents the URL, "javascript:%20'%46'" (**). Notice, this result > differs from the fully URL encoded result of "javascript:%20%27%2546%27". > Decoding the string form of (**) using KURL::decodeURLEscapeSequences produces > the result: "javascript: 'F'". Clearly, this is not the inverse of the (**).
This bug is fixed in the new architecture.