[webkit-dev] Best way to disable JavaScript

2013-03-17 Thread Geoffrey Garen
Hi folks.

Currently, we have two different ways to disable JavaScript execution:

(1) Paste / Drag n Drop / editing: Remove script elements and script attributes 
from untrusted source markup at parse time.

(2) JavaScript disabled setting / Content Security Policy: Check settings 
and/or CSP at runtime.

There are problems with mode (2):

* It breaks features that are implemented in JavaScript.

The Web Inspector, bookmarklets, extensions, Safari Reader, and Safari autofill 
all run JavaScript. This means that they break when users disable JavaScript.

As a defense against phishing attacks, mail clients and other web content 
readers disable JavaScript. This means that they can't implement pieces of 
their UI in JavaScript.

(FWIW, WebKit violates the CSP specification in this regard: Enforcing a CSP 
policy should not interfere with the operation of user-supplied scripts such as 
third-party user-agent add-ons and JavaScript bookmarklets.)

* It subjects users to XSS attacks.

Runtime checking mode leaves inert JavaScript in the untrusted document. This 
is a risky proposition. Operations that clone or adopt nodes from the untrusted 
document unwittingly re-vivify that inert JavaScript, subjecting the user to 
attack. Experience shows that this is a difficult programming model to get 
right.

* It's hard to verify.

We have 18 different call sites to canExecuteScripts() in WebKit, not counting 
the call sites that pertain to plug-ins. Are you confident we've caught all the 
right places? Do you know if the feature you just added needs to call 
canExecuteScripts()?

* It's two different ways to do the same thing.

Simplicity is a goal of the WebKit project.


Proposal:

If -- for any reason -- JavaScript is disabled in a given document, the 
document parser will elide all JavaScript. This means that runtime checks can 
be removed.

One potential downside to this proposal is that it changes the document's 
internal structure. Since the changes are not generally observable, since they 
only take place when we're already making much bigger changes by preventing 
whole scripts from running, and since we haven't seen any compatibility 
problems from our paste / drag n drop / editing behavior in this regard, I 
think this downside is acceptable.

Another potential downside is that CSP errors will be reported at parse time 
instead of runtime. FWIW, some authors might see this as an upside.

Any objections?

Thanks,
Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] Best way to disable JavaScript

2013-03-17 Thread Adam Barth
Unfortunately, you can't implement CSP that way.  Consider the case of
two same-origin iframes A and B.  Suppose A has a restrictive CSP
policy (say that bans everything) and B doesn't.  If B uses the DOM to
insert a script element into A, then CSP should block that script
element from executing.  Stripping script tags at parse time won't.

Adam


On Sun, Mar 17, 2013 at 8:26 PM, Geoffrey Garen gga...@apple.com wrote:
 Hi folks.

 Currently, we have two different ways to disable JavaScript execution:

 (1) Paste / Drag n Drop / editing: Remove script elements and script 
 attributes from untrusted source markup at parse time.

 (2) JavaScript disabled setting / Content Security Policy: Check settings 
 and/or CSP at runtime.

 There are problems with mode (2):

 * It breaks features that are implemented in JavaScript.

 The Web Inspector, bookmarklets, extensions, Safari Reader, and Safari 
 autofill all run JavaScript. This means that they break when users disable 
 JavaScript.

 As a defense against phishing attacks, mail clients and other web content 
 readers disable JavaScript. This means that they can't implement pieces of 
 their UI in JavaScript.

 (FWIW, WebKit violates the CSP specification in this regard: Enforcing a CSP 
 policy should not interfere with the operation of user-supplied scripts such 
 as third-party user-agent add-ons and JavaScript bookmarklets.)

 * It subjects users to XSS attacks.

 Runtime checking mode leaves inert JavaScript in the untrusted document. This 
 is a risky proposition. Operations that clone or adopt nodes from the 
 untrusted document unwittingly re-vivify that inert JavaScript, subjecting 
 the user to attack. Experience shows that this is a difficult programming 
 model to get right.

 * It's hard to verify.

 We have 18 different call sites to canExecuteScripts() in WebKit, not 
 counting the call sites that pertain to plug-ins. Are you confident we've 
 caught all the right places? Do you know if the feature you just added needs 
 to call canExecuteScripts()?

 * It's two different ways to do the same thing.

 Simplicity is a goal of the WebKit project.


 Proposal:

 If -- for any reason -- JavaScript is disabled in a given document, the 
 document parser will elide all JavaScript. This means that runtime checks can 
 be removed.

 One potential downside to this proposal is that it changes the document's 
 internal structure. Since the changes are not generally observable, since 
 they only take place when we're already making much bigger changes by 
 preventing whole scripts from running, and since we haven't seen any 
 compatibility problems from our paste / drag n drop / editing behavior in 
 this regard, I think this downside is acceptable.

 Another potential downside is that CSP errors will be reported at parse time 
 instead of runtime. FWIW, some authors might see this as an upside.

 Any objections?

 Thanks,
 Geoff
 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 https://lists.webkit.org/mailman/listinfo/webkit-dev
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev