Bug 101683 - Merge isViewSource checks in ScriptController::executeIfJavaScriptURL and ScriptController::canExecuteScripts.
Summary: Merge isViewSource checks in ScriptController::executeIfJavaScriptURL and Scr...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore JavaScript (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mike West
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-11-08 18:32 PST by Alexey Proskuryakov
Modified: 2013-01-25 09:50 PST (History)
4 users (show)

See Also:


Attachments
Patch (2.13 KB, patch)
2012-11-11 22:47 PST, Mike West
no flags Details | Formatted Diff | Diff
Patch (5.33 KB, patch)
2013-01-25 02:46 PST, Mike West
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Proskuryakov 2012-11-08 18:32:11 PST
Most of these checks are there, so perhaps the CSP one should be there, too?

Notably, isViewSource check seems to be duplicated in these locations... But one looks in Frame, and another in Document!
Comment 1 Adam Barth 2012-11-08 18:36:18 PST
> Most of these checks are there, so perhaps the CSP one should be there, too?

In CSP, you can have JavaScript URLs turned off but have script (more generally) turned on.  CSP treats JavaScript URLs like inline script (e.g., <script>...</script>), the idea being that JavaScript URLs can be injected by attackers (e.g., <a href="$userSuppliedString">...</a>).

The view-source bits do look dodgy though.
Comment 2 Alexey Proskuryakov 2012-11-09 14:34:41 PST
Thank you Adam, reusing the bug to track the second issue then.
Comment 3 Mike West 2012-11-09 23:42:47 PST
I'll take a look at the isViewSource checks.
Comment 4 Mike West 2012-11-10 00:15:39 PST
Can JavaScript URLs ever execute if JavaScript is disabled? That is, could I simply replace some of the logic in executeIfJavaScriptURL with a call to canExecuteScripts?
Comment 5 Mike West 2012-11-10 00:17:09 PST
(In reply to comment #4)
> Can JavaScript URLs ever execute if JavaScript is disabled? That is, could I simply replace some of the logic in executeIfJavaScriptURL with a call to canExecuteScripts?

For instance, executeIfJavaScriptURL doesn't check settings, nor does it check sandbox status. It seems like it should do both.
Comment 6 Adam Barth 2012-11-10 11:45:55 PST
> Can JavaScript URLs ever execute if JavaScript is disabled?

Nope.

> That is, could I simply replace some of the logic in executeIfJavaScriptURL with a call to canExecuteScripts?

Yes, but we'll need the extra CSP check for 'unsafe-inline'.
Comment 7 Mike West 2012-11-10 15:25:39 PST
(In reply to comment #6)
> > That is, could I simply replace some of the logic in executeIfJavaScriptURL with a call to canExecuteScripts?
> 
> Yes, but we'll need the extra CSP check for 'unsafe-inline'.

Right. I've put a patch together that simply replaces the viewsource check with a call to canExecuteScripts. That works correctly, so far as I can tell, but I'm having trouble identifying a testable change in behavior. The two missing tests (settings and sandbox) seem both to be taken care of somewhere else in the code; I haven't had any luck constructing a test that failed without the patch.

Do you see anything relevant?
Comment 8 Adam Barth 2012-11-11 15:20:08 PST
I don't expect there will be any change in behavior.
Comment 9 Mike West 2012-11-11 22:47:47 PST
Created attachment 173563 [details]
Patch
Comment 10 Adam Barth 2012-11-12 15:12:36 PST
Comment on attachment 173563 [details]
Patch

I'm looking at the call site in FrameLoader::urlSelected.  Is there some way that was checking that JavaScript was disabled before?  I don't see where that check would have been.

data:text/html,<iframe sandbox srcdoc="<a href=javascript:alert(1)>click me</a>"><iframe>

That doesn't seem to execute when clicked....
Comment 11 Adam Barth 2012-11-12 15:14:25 PST
I see, the check is in ScriptController::executeScript, which is called by executeIfJavaScriptURL
Comment 12 Adam Barth 2012-11-12 15:16:45 PST
Comment on attachment 173563 [details]
Patch

So, this does the wrong thing for view-source documents.  It's too bad we don't have a test for that.  (We should add one.)

Notice that ScriptController::canExecuteScripts returns true when isViewSource, but executeIfJavaScriptURL used to abort execution if inViewSourceMode
Comment 13 Adam Barth 2012-11-12 15:21:15 PST
As for the relation between isViewSource and inViewSourceMode, it looks like the Document freezes the inViewSourceMode from the Frame on creation (i.e., in DocumentWriter::createDocument).  The inViewSourceMode is at the mercy of the frame's attributes (i.e., in HTMLFrameElementBase::parseAttribute).

That means this teh call site in executeIfJavaScriptURL should use isViewSource from the Document rather than inViewSourceMode from the frame.  The way to write a test is to create a frame with a javascript URL in it, after the frame loads, set the viewsource attribute on the frame, then try to execute the javascript URL.  Currently, the javascript URL will be blocked (the Frame is in view source mode but the document is not), but there isn't any reason that it should be blocked.
Comment 14 Mike West 2013-01-25 02:21:47 PST
(In reply to comment #13)
> As for the relation between isViewSource and inViewSourceMode, it looks like the Document freezes the inViewSourceMode from the Frame on creation (i.e., in DocumentWriter::createDocument).  The inViewSourceMode is at the mercy of the frame's attributes (i.e., in HTMLFrameElementBase::parseAttribute).
> 
> That means this teh call site in executeIfJavaScriptURL should use isViewSource from the Document rather than inViewSourceMode from the frame.  The way to write a test is to create a frame with a javascript URL in it, after the frame loads, set the viewsource attribute on the frame, then try to execute the javascript URL.  Currently, the javascript URL will be blocked (the Frame is in view source mode but the document is not), but there isn't any reason that it should be blocked.

Sorry, I missed this response way back in November.

Given that executeIfJavaScriptURL ends up calling canExecuteScripts (via executeScript), I think we can safely drop the isViewSource check from the former entirely. I'll attach a patch in a moment that does just that, and adds a small test to verify that the document's viewsource bit is checked.
Comment 15 Mike West 2013-01-25 02:46:01 PST
Created attachment 184709 [details]
Patch
Comment 16 Adam Barth 2013-01-25 09:25:37 PST
Comment on attachment 184709 [details]
Patch

Ok
Comment 17 WebKit Review Bot 2013-01-25 09:50:23 PST
Comment on attachment 184709 [details]
Patch

Clearing flags on attachment: 184709

Committed r140839: <http://trac.webkit.org/changeset/140839>
Comment 18 WebKit Review Bot 2013-01-25 09:50:28 PST
All reviewed patches have been landed.  Closing bug.