Closed Bug 998456 Opened 10 years ago Closed 6 years ago

can't disable javascript even from about:config for an already-loaded page

Categories

(Core :: XPConnect, defect)

28 Branch
defect
Not set
normal

Tracking

()

RESOLVED INACTIVE

People

(Reporter: phr-mozilla, Unassigned)

References

Details

(Keywords: regression)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0 (Beta/Release)
Build ID: 20140319073243

Steps to reproduce:

1. Visit http://ov3y.github.io/2048-AI/ with JS enabled
2. Press "auto-run" and watch game play itself for a few moments
3. Disable JS from prefbar or about:config



Actual results:

Game keeps playing itself, eating your cpu.  You have to wait for it to finish or close the tab to make it stop.


Expected results:

Disabling JS should stop any JS that is already running.  Instead it only prevents JS from running .  This worked til recently, behavior seems to have changed in 28 or slightly earlier.

This is NOT a dup of #879610 which was only about a UI preference being removed (which is bad enough).  It used to be possible to kill running JS from the prefbar/config but now it's not possible.  As another consequence it's no longer possible to disable obnoxious rollovers, status bar overrides, etc. that way.  This isn't nice.
Can't seem to edit initial post.  Somehow it got garbled: it should say, disabling JS only prevents JS from running on pages that you load after disabling.  It leaves it enabled on any pages where it is already loaded.  This is wrong.  Disable means disable, it should not be enabled anywhere if you disable it.
All the UI preference did was toggle the same preference you're toggling in about:config, so that part is completely orthogonal.

As for the change in behaviour, I'm not sure it's worth fixing. Under what scenario is the current behaviour actually problematic? Surely closing or reloading the tab isn't that much of an effort?

If you think it's absolutely paramount that the toggle is immediate, it would be useful if you could figure out when the behaviour changed. You can use mozregression for this: https://harthur.wordpress.com/2010/09/13/mozregression-update/ .
Component: Untriaged → General
OS: Linux → All
Product: Firefox → Core
Hardware: x86_64 → All
This changed with bug 840488.

Bobby, do we want to go through the Scriptability objects for all globals when this pref changes and the SSM has updated its state and update mScriptBlockedByPolicy?
Blocks: 840488
Status: UNCONFIRMED → NEW
Component: General → XPConnect
Ever confirmed: true
Flags: needinfo?(bobbyholley)
Summary: can't disable javascript even from about:config → can't disable javascript even from about:config for an already-loaded page
Gijs, yes, it's a nuisance in lots of situations:

1) many pages now can't even be read with JS turned off, e.g. because they populate the screen from xmlhttp etc.  So turning off JS before loading the page isn't helpful.

2) Sometimes buggy script on a page goes into a loop (detected by the laptop fan turning on).  It's useful to be able to stop that.    

3) Many pages nowadays start popping side-loading banners and other such ****, after you've been looking at the page for a while.  It was nice to be able to turn that off while continuing to read the page (removing banners with HTML Inspector).

4) Many pages including Google search results overwrite the browser status bar, so that hovering the mouse over a link displays where you expect the link to point, but it actually points somewhere else.  I.e. Google rewrites result links to point back to their own server so they can intercept your clicks.  Turning off JS used to restore the normal function of the status bar so you could see where the link actually went.

5) I've even heard of banner ads with scripts that mine bitcoins on the user's computer.

I could go on but you probably get the picture.
Bug 61098 is mostly about looping modal dialogs, but more discussion about the need to be able to turn off JS.
(In reply to Boris Zbarsky [:bz] from comment #3)
> This changed with bug 840488.
> 
> Bobby, do we want to go through the Scriptability objects for all globals
> when this pref changes and the SSM has updated its state and update
> mScriptBlockedByPolicy?

If we were to do something like that, it would make more sense to just modify xpc::Scriptability::Allowed() to check a global variable.

But those seem like the wrong semantics anyhow. In general, I think prefs like this shouldn't perturb already-loaded content. If people want to turn off JS midway dynamically, they shouldn't be doing it with a pref at all - they should be using an add-on (or just a browser-chrome web console / scratchpad) to invoke Cu.blockScriptForGlobal on the global they want to block.
Flags: needinfo?(bobbyholley)
I can understand the idea that prefs aren't the ideal interface, but IMHO there really does need to be a convenient way to stop rampant or obnoxious scripts.   The pref setting worked for a long time for that, and apparently changed by accident.  That is functionality that shouldn't be removed casually.

I'm generally pained by the offloading of important functionality to third party add-ons.  I do use a few add-ons, but I try to minimize the number and I only use well-recognized ones.  The browser is a security product and it shouldn't have a culture that encourages users to install dozens of pieces of unvetted code from unknown developers, that can all access private data inside the browser.  The flow of functionality should be from the add-on ecosystem into the browser (as stuff from add-ons gets recognized as important), rather than the other way around.  The password manager, pdf viewer, and development console are all examples that started out as add-ons or plug-ins.  I'd be happy if prefbar-like functionality also became "official".
(In reply to Paul Rubin from comment #7)
> I can understand the idea that prefs aren't the ideal interface

Definitely not.

> but IMHO
> there really does need to be a convenient way to stop rampant or obnoxious
> scripts.

Different people have vastly different interests and needs in this area, so this kind of thing is unlikely to go into the default Firefox frontend. The platform provides the ability to do it, and there are various extensions that hook into those APIs. NoScript is a big one. If it and the others don't fit your use-case, you can write an extension, and publish it on AMO so that others can benefit from your work.

> The pref setting worked for a long time for that, and apparently
> changed by accident

It wasn't an accident. Bug 913734 removed it explicitly, because the code was insane, and prefs aren't the ideal interface (see above). Note that bug 840488 (which landed a cycle earlier) also included a new API for addons to hook into.

> That is functionality that shouldn't be removed
> casually.

It wasn't casual. It was planned for several years.

> I'm generally pained by the offloading of important functionality to third
> party add-ons.

The concept of "important" is very subjective. User experience research suggests that the majority of users find this kind of feature more confusing than beneficial. There are certainly some users for whom this stuff is really important - and that's why we have add-ons.

> I do use a few add-ons, but I try to minimize the number and
> I only use well-recognized ones.  The browser is a security product and it
> shouldn't have a culture that encourages users to install dozens of pieces
> of unvetted code from unknown developers

This isn't really true. AMO does code review on all addons, and watches out for security issues.

> , that can all access private data
> inside the browser.  The flow of functionality should be from the add-on
> ecosystem into the browser (as stuff from add-ons gets recognized as
> important), rather than the other way around.  The password manager, pdf
> viewer, and development console are all examples that started out as add-ons
> or plug-ins.  I'd be happy if prefbar-like functionality also became
> "official".

Maintaining a front-end on three different platforms is hard. Having hidden, seldom-used features is really cumbersome, and is one of the biggest sources of security vulnerabilities (because the code doesn't get a lot of eyes on it). So it's generally considered to be good engineering practice to drop existing support for these kinds of things, and only add new features if it's clear that a large portion of users will use them. We just don't have the resources to build a product that is secure, easy-to-use, and the union of everybody's feature wishlist all at the same time. :-(
(In reply to :Gijs Kruitbosch from comment #2)

> As for the change in behaviour, I'm not sure it's worth fixing. Under what
> scenario is the current behaviour actually problematic? Surely closing or
> reloading the tab isn't that much of an effort?

It is (much of an effort). When you have many tabs with JavaScript. 

Now I understand better. 
At home, in Firefox Mac, I have many pages open, and I often get one of them jumping in and asking : 
"A script is running slowly. Do you want to stop it ?" 
But this happens also when JavaScript is supposed to be turned off - thanks to the extension QuickJS. 

It would be really nicer if turning JavaScript off really turned JavaScript off. It would save energy, and euros. Even when I leave him alone, my Mac blows a lot, and Firefox is almost the only big app running.
(In reply to Nicolas Barbulesco from comment #9)

> It would be really nicer if turning JavaScript off really turned JavaScript
> off. It would save energy, and euros. Even when I leave him alone, my Mac
> blows a lot, and Firefox is almost the only big app running.

Well, in fact, Firefox *is* the responsible of the CPU running at more than 100 % (in Activity Monitor). Even when JS is supposed to be turned off. This is the sign of a problem.
Note that Chrome works as we'd like Firefox to work here; i.e. toggling the "Disable JavaScript" checkbox off does stop all JS on the site. It's a really nice feature for reasons outlined in comment #4.
Bobby, I agree that an extension could easily disable script on a given window, but disabling on all windows seems like it would be pretty annoying to get right.

Maybe what we should do is add a hidden pref, for use by such extensions, and have scriptability watch a bool cache for that pref?
Flags: needinfo?(bobbyholley)
(In reply to Boris Zbarsky [:bz] from comment #12)
> Bobby, I agree that an extension could easily disable script on a given
> window, but disabling on all windows seems

Well, it would just involve using the window enumerator.

> like it would be pretty annoying to get right.

I still don't understand the use case in which both of the following are important:
* disabling javascript UA-wide
* having that take effect immediately, for already-loaded pages
 
> Maybe what we should do is add a hidden pref, for use by such extensions,
> and have scriptability watch a bool cache for that pref?

If somebody actually wants to write and maintain an extension, I'm happy to provide them any reasonable platform pieces that they need. But as noted above, I don't think platform support is really needed at all.
Flags: needinfo?(bobbyholley)
If sb wants to have a toggle to disable JS in all tabs in the current window/in all windows, that's separate issue, let's not mix them. This one is about stopping all JS in-progress in the tab DevTools are inspecting and it is very useful (see comment #4).
(In reply to Michał Gołębiowski [:m_gol] from comment #14)
> If sb wants to have a toggle to disable JS in all tabs in the current
> window/in all windows, that's separate issue, let's not mix them. This one
> is about stopping all JS in-progress in the tab DevTools are inspecting and
> it is very useful (see comment #4).

Maybe devtools should provide a feature to disable JS on pages under inspection? All they need to do is call Cu.blockScriptForGlobal(contentWindow). This is also trivial to do from an addon (or even from the browser console), FWIW.
Flags: needinfo?(rcampbell)
IMO wherever any global stopping of JS execution (whether it's limited to window, all inspected tabs etc.) option is introduced, it's still extremely useful to be able to stop JS only on the currently inspected tab and leave it everywhere else.
(In reply to Michał Gołębiowski [:m_gol] from comment #14)

> If sb wants to have a toggle to disable JS in all tabs in the current
> window/in all windows, that's separate issue, let's not mix them. This one
> is about stopping all JS in-progress in the tab DevTools are inspecting and
> it is very useful (see comment #4).

See comment 1 from Paul Rubin.

This bug file is about Firefox not stopping all JavaScript (in all tabs of all windows) when this is set in Firefox at the application level. As far as I understand, this is a regression of the feature which was working correctly in quite recent versions.

I too encounter this annoying bug when I use the (life saver) extension QuickJS. I turn off JavaScript (globally), but then I keep getting jumping alerts "A script is running slowly..."
(In reply to Bobby Holley (:bholley) from comment #15)
> (In reply to Michał Gołębiowski [:m_gol] from comment #14)
> > If sb wants to have a toggle to disable JS in all tabs in the current
> > window/in all windows, that's separate issue, let's not mix them. This one
> > is about stopping all JS in-progress in the tab DevTools are inspecting and
> > it is very useful (see comment #4).
> 
> Maybe devtools should provide a feature to disable JS on pages under
> inspection? All they need to do is call
> Cu.blockScriptForGlobal(contentWindow). This is also trivial to do from an
> addon (or even from the browser console), FWIW.

We already have an option in the Toolbox' Options panel (checkbox at the end of the page, Disable JavaScript*) that reloads the page without JS loaded.

This calls a reconfigure() method on our debug-client which does this:

http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/webbrowser.js#875

we set docShell.allowJavascript to false and reload.

This is obviously not what you're looking for.

We could either alter the behavior of that checkbox to do the thing you suggest above (possibly with other side-effects that prevent our debugger from working) or create a command or other control to disable the JavaScript in the currently-loaded page.

Also possible via a short add-on but that seems to be unpalatable.

Honestly running the Cu.blockScriptForGlobal is a good enough work around for the number of users likely to be interested in this feature.
Flags: needinfo?(rcampbell)
Being able to stop JS in a specific tab without turning it off in the rest of the browser sounds useful and I'd be ok with that (giving finer grain control is arguably an improvement), but the current situation of being unable to stop it at all is definitely a regression.  

I tried installing noscript as Bobby suggested: I found it to be a clumsy add-on that does more than it needs to, and I spotted an apparent security bug within a minute of reading the help screens (it claims to translate POST data into HTTP GET which means confidential info can be left in the httpd log for something like an online chat program), so I uninstalled it.  More to the point though, it also didn't seem to have any way to stop a running script without disturbing the page.  It is able to turn off JS and reload the page, which is nowhere near as useful.  When I tried it on the example I gave in the initial report (run the 2048 autoplay and get it to stop in mid-game leaving the screen in that mid-game state), it isn't able to do that, at least in the current implementation.  

I appreciate the lengths to which the FF maintainers went to keep the noscript add-on working, but prefbar is also a great add-on and now it's broken (at least regarding turning off JS while it's running).
To anyone who misses this functionality: you can just open up a browser console [1] and type: gBrowser.docShell.allowJavascript = false

At which point javascript on the page should be disabled (no reload required). Maybe somebody could write a devtools addon to add a handy button for this?



[1] https://developer.mozilla.org/en-US/docs/Tools/Browser_Console
Like others, I also sometimes need to disable JavaScript because I have many tabs, so that Firefox takes much CPU time, making my laptop hot and noisy (due to the fan). However this is just a workaround: this wouldn't be needed if Firefox could optionally limit the CPU resources taken by JS in background tabs.

(In reply to Bobby Holley (:bholley) from comment #20)
> To anyone who misses this functionality: you can just open up a browser
> console [1]

One also needs to enable the command line interpreter by toggling devtools.chrome.enabled to true.

> and type: gBrowser.docShell.allowJavascript = false

It doesn't have any effect on all pages.
(In reply to Vincent Lefevre from comment #21)
> Like others, I also sometimes need to disable JavaScript because I have many
> tabs, so that Firefox takes much CPU time, making my laptop hot and noisy
> (due to the fan). However this is just a workaround: this wouldn't be needed
> if Firefox could optionally limit the CPU resources taken by JS in
> background tabs.
> 
> (In reply to Bobby Holley (:bholley) from comment #20)
> > To anyone who misses this functionality: you can just open up a browser
> > console [1]
> 
> One also needs to enable the command line interpreter by toggling
> devtools.chrome.enabled to true.
> 
> > and type: gBrowser.docShell.allowJavascript = false
> 
> It doesn't have any effect on all pages.

You could enumerate them with nsIWindowMediator [1].

[1] https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator#getEnumerator%28%29
Per this article, it looks like Noscript is a joke:

http://thehackerblog.com/the-noscript-misnomer-why-should-i-trust-vjs-zendcdn-net/

Meanwhile, the web is sucking more and more, now that browsers have made JS all but mandatory.
Per policy at https://wiki.mozilla.org/Bug_Triage/Projects/Bug_Handling/Bug_Husbandry#Inactive_Bugs. If this bug is not an enhancement request or a bug not present in a supported release of Firefox, then it may be reopened.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → INACTIVE
You need to log in before you can comment on or make changes to this bug.