admin管理员组

文章数量:1330379

Well it's not some huge security risk, though it reveals some potential interference at least.

Suppose we have those very well closed JavaScript modules that is loaded into my page without knowing about each other. They are from "trusted" however some developer in lib2 made a mistake, see the code.

Lib1 /libs/the-famous-important-lib1.js

setInterval(function(){
   alert('I am doing some important stuff');
}, 1000);

Lib2 /libs/the-cool-lib2.js

var i = setInterval(function(){}, 0);
for(; i >= 0; i-=1) {
    clearInterval(i);
}

My HTML

<script src="/libs/the-famous-important-lib1.js" type="text/javascript"></script>
<script src="/libs/the-cool-lib2.js" type="text/javascript"></script>

In a browser or at least on Firefox, loading Lib2 would actually break Lib1 totally. Some might say this is not important, and how silly to make such mistake.

I consider that as a bad behavior. Since we are loading more and more third party libs in our websites. Maybe a proper solution is that setInterval, and setTimeout should return an object to be really unique and un-fakeable, instead of just numeric auto increment ID.

Someone might e up with a real-world exploitation for this (still didn't test if it is cross frames, I doubt it really).

The question is: Is it? And does strict mode in ES5 overe that?

Well it's not some huge security risk, though it reveals some potential interference at least.

Suppose we have those very well closed JavaScript modules that is loaded into my page without knowing about each other. They are from "trusted" however some developer in lib2 made a mistake, see the code.

Lib1 http://good.example/libs/the-famous-important-lib1.js

setInterval(function(){
   alert('I am doing some important stuff');
}, 1000);

Lib2 http://not-excelent.example/libs/the-cool-lib2.js

var i = setInterval(function(){}, 0);
for(; i >= 0; i-=1) {
    clearInterval(i);
}

My HTML

<script src="http://good.example/libs/the-famous-important-lib1.js" type="text/javascript"></script>
<script src="http://not-excelent.example/libs/the-cool-lib2.js" type="text/javascript"></script>

In a browser or at least on Firefox, loading Lib2 would actually break Lib1 totally. Some might say this is not important, and how silly to make such mistake.

I consider that as a bad behavior. Since we are loading more and more third party libs in our websites. Maybe a proper solution is that setInterval, and setTimeout should return an object to be really unique and un-fakeable, instead of just numeric auto increment ID.

Someone might e up with a real-world exploitation for this (still didn't test if it is cross frames, I doubt it really).

The question is: Is it? And does strict mode in ES5 overe that?

Share Improve this question edited Jan 2 at 19:18 dumbass 27.3k4 gold badges37 silver badges74 bronze badges asked Jan 12, 2012 at 9:19 Omar Al-IthawiOmar Al-Ithawi 5,1705 gold badges38 silver badges48 bronze badges 5
  • 1 clearing others' setIntervals? Sure it'll break things, but nothing catastrophic can happen. – Sergio Tulentsev Commented Jan 12, 2012 at 9:21
  • easy solution.. don't use other peoples rubbish code ;) – musefan Commented Jan 12, 2012 at 9:24
  • 3 @SergioTulentsev I have however seen a website whose paywall is triggered by a setTimeout(). If that timer is cleared, non-paying customers don't get thrown out. Utterly lousy security design... – Alnitak Commented Jan 12, 2012 at 9:26
  • 3 I don't think it is a security vulnerability here. It is a developer responsibility to test scripts he use. Allowing malicious scripts to be executed is a vulnerability, but is is another story. – Andrey M. Commented Jan 12, 2012 at 11:08
  • 1 @AndreyM. Really? I don't think anyone who read the whole code Facebook SDK or Google Maps before using it. And those people using really advanced techniques to take as much as they can from the browser, so when you load a 3rd party lib you just accept lots of risks. At least I do. – Omar Al-Ithawi Commented Jan 12, 2012 at 16:14
Add a ment  | 

3 Answers 3

Reset to default 3

Does strict mode in es5 overes that?

No. setInterval and setTimeout are part of the DOM bindings -- they are not EcmaScript builtins so are not specified in any version of EcmaScript. Nothing in strict mode specifically affects them.

This will probably change in the next version of EcmaScript since the TC39 mittee thinks that concurrency is a core language feature that needs to be specified and will probably retain event loop concurrency.

Those changes are unlikely to affect the problem you raise though. Caja / Secure EcmaScript (SES) does make sure that interval and timeout ids are not guessable.

Interesting point.

Since interval/timeout ids are sequential, you can (as you've shown us) clear all intervals/timeouts by getting yourself next interval id, and than trying to clear any ids lower than one you got.

However, I don't see any security threat there. Any web application, that would base their security solely on interval and/or timeout in Javascript is as good as hacked anyway.

As Sergio Tulentsev already mented - abusing clearInterval/clearTimeout is going to break things - for sure - but (99% of the time) that won't pose any security threat for web application.

This is indeed something of a problem. Calling it a security issue is probably a stretch, though – given that most non-pathological timer-handling code will probably treat timer IDs as entirely opaque values anyway, never perform any arithmetic on them, and never pass untrusted input (or, in fact, any input other than the direct, literal contents of a variable meant specifically to store a timer ID and nothing else) to clearInterval or clearTimeout, if a malicious actor is capable of cancelling arbitrary timers, it is probably by virtue of being capable of executing entirely arbitrary code; in other words, if it’s ever a security issue, you have bigger problems.

Nevertheless, this design flaw does mean that once a malicious party gains the ability to execute code within your page, their capabilities to break any running scripts are larger than they would be otherwise. Though if you are considering implementing mitigations against the impact of arbitrary code execution vulnerabilities, protecting timer IDs will probably not be your top priority – instead, you might want to limit access to APIs like document.cookie, window.localStorage or window.sessionStorage. Unexpected cancelling of a timer is probably a lockup or denial of service at worst, and even then, you should already assume that your code may stop running at any moment without advance notice because the user has shut down their browser.

Still, if you insist: as mentioned in another answer, strict mode will not help you here. Instead you could replace setTimeout and setInterval with your own versions that call the original function and return a symbol or an object (which may even be a Number object wrapper, making numeric IDs transparent, but no longer forgeable), which a WeakMap then maps back to the actual numeric ID, while clearInterval and clearTimeout look those up to verify object identity before calling the original. If written well, much code calling those wrappers – fulfilling some reasonable assumptions – will probably never notice a difference.

本文标签: