Closed
Bug 36117
Opened 24 years ago
Closed 24 years ago
Assignment of getter bypasses security checks
Categories
(Core :: Security, defect, P3)
Tracking
()
VERIFIED
FIXED
M17
People
(Reporter: norrisboyd, Assigned: security-bugs)
References
()
Details
(Keywords: js1.5)
Attachments
(2 files)
5.34 KB,
patch
|
Details | Diff | Splinter Review | |
4.54 KB,
patch
|
Details | Diff | Splinter Review |
The following mail thread shows some of the syntax of getters and setters. According to Brendan, these accesses currently bypass per-property security checks. Subject: Re: getters and setters Date: Mon, 17 Apr 2000 15:41:35 -0700 From: Brendan Eich <brendan@meer.net> To: Lynn Davidson <lynn@lynndavidson.com> CC: norris@netscape.com References: 1 Lynn Davidson wrote: Norris or Brendan - I assume that the new getter and setter capabilities apply only to properties of objects that the JavaScript developer creates herself, that she cannot use it to create getters and setters for predefined core objects. Or am I assuming incorrectly? Incorrect -- getters and setters may be defined on any object that allows new properties to be added. (Norris: there is nothing to prevent a getter or setter from being defined in place of an existing readonly and/or permanent property--this sounds like a security hole to me!) All native objects support getters and setters, so for example: var d = Date.prototype; d.year getter= function() { return this.getFullYear(); }; d.year setter= function(y) { return this.setFullYear(y); }; is legit, and adds a handy year property to all instances of the Date class: var now = new Date; print(now.year); // 2000 now.year = 2001; // timewarp print(now); // prints 4/17/2001's localized Date string /be
Comment 2•24 years ago
|
||
Patch coming up. /be
Comment 3•24 years ago
|
||
Comment 4•24 years ago
|
||
The fix changed more than just the JSOP_GETTER/JSOP_SETTER prefix-bytecode cases in jsinterp.c. I took advantage of the common OBJ_LOOKUP_PROPERTY call that always must precede the old revision's calls to CheckRedeclaration, pushing that call down into the subroutine. That required an out param telling whether the property was found predeclared, but compatibly declared, for JSOP_DEFVAR (cuz 'var x' in JS does not alter a pre-defined x property in the variables object). I also tidied unrelated indentation in jsscope.h, found while reviewing getter and setter logic and error cases. Norris, can you try this patch out and give me an r=? Thanks. /be
Reporter | ||
Comment 5•24 years ago
|
||
I've built the patch on Windows. Let's say a malicious script tries to replace a victim's window.location with a setter of its own choosing. Does this patch attempt to stop such an attack? How is that accomplished?
Comment 6•24 years ago
|
||
First, the malicious setter would run with malicious.org's principals, so that should stop some amount of mischief (seeing form field values, e.g.). Second, the patch protects only against properties that are JSPROP_READONLY or JSPROP_PERMANENT (or both) from being replaced by getter/setter pairs, or just by setters (it's illegal to have only a getter and no setter -- see jsscope.h in the patch). So if window.location is not predefined as permanent and readonly (usually it makes no sense to be just permanent, unless you want to enforce the value too), the patch offers no further defense than the usual principals (point 1 above). Whaddya think? /be /be
Reporter | ||
Comment 7•24 years ago
|
||
So it sounds like there are no protections against changing a property in another protection domain to be a getter/setter that you own. It seems like a script should be able to monitor writes to objects that it cannot itself write to.
Comment 8•24 years ago
|
||
Yeah, script variables (non-consts) are vulnerable, just as user-defined functions have always been wrap-able or hijack-able. Not sure this is more serious than the status quo ante. Thoughts? /be
Reporter | ||
Comment 9•24 years ago
|
||
I think this is more serious than status quo ante. (BTW, I've restricted access to top-level user variables and functions across domains for the past several milestones and have heard no complaints about broken scripts. IE 5 implements a similar policy, so perhaps offending scripts have been changed.) Test case that demonstrates vulnerability is in URL field above. It is the following two files: 36117.html: <script> function f() { w.location getter = function() { alert("getting"); } w.location setter = function(a) { alert("setting to " + a); } } w = window.open("http://makeda/tests/mocha/norris/mozilla/36117a.html"); setTimeout(f, 5000); </script> 36117a.html: <script> function f() { alert('hi'); window.location='http://www.yahoo.com'; } </script> <a href="about:blank" onclick="f()">click here</a>
Comment 10•24 years ago
|
||
Ok, sold -- and thanks for patching up the loose old same-origin policy to cover user-defined properties. So the problem with getters and setters is that they must be defined (create new property, replacing any old one). That says to me we need a checkAccess call in the JSOP_GETTER: JSOP_SETTER: case in jsinterp.c. I could treat defining a setter and/or getter exactly like adding a watchpoint. That looks like it would do the trick. Patch coming up, let me know if it works for you. Thanks, /be
Comment 11•24 years ago
|
||
Reporter | ||
Comment 12•24 years ago
|
||
I still get information leakage with the new fix. The problem appears to be the asymetric usage of the location object: you get a window's URI by reading window.location.href, but you can set a new href by assignment to window.location. So the addition of a call to checkAccess attempts a read of window.location, which is allowed, and the attacking script is allowed to attach a setter to the victim's location property. IE 5 enforces same origin for read access to window.location. Should we do the same? I believe that would fix this problem.
Keywords: beta2
Comment 13•24 years ago
|
||
Yeah, we must protect window.location because that property's value is an object whose toString() method yields the currently loaded URL (or should -- could be a separate Mozilla bug here). I checked in the revised patch. Norris, off to you for window.location lock-up! /be
Assignee: brendan → norris
Status: ASSIGNED → NEW
Reporter | ||
Updated•24 years ago
|
Status: NEW → ASSIGNED
Reporter | ||
Comment 14•24 years ago
|
||
Didn't get to this. Reassign to mstoltz.
Assignee: norris → mstoltz
Status: ASSIGNED → NEW
Comment 18•24 years ago
|
||
Assigning QA to czhang
Assignee | ||
Comment 19•24 years ago
|
||
Brendan, This exploit is still working. What more needs to be done to fix it? We have security checks on all of the properties of window.location, are these still being bypassed?
Group: netscapeconfidential?
Assignee | ||
Comment 20•24 years ago
|
||
Marking nsbeta3, removing nsbeta2+. Exploit still exists, but it's not public, so it's not a beta stopper.
Comment 21•24 years ago
|
||
The JS engine does the right thing. The DOM code does implement checkAccess. What's left? Is the problem here that certain DOM properties are not permanent (may be deleted, either via delete or by getter/setter=)? I think we should disclose bugs like this. It's not as if they won't be found out anyway, soon enough. Better yet, let's just fix the DOM to use permanence.
Assignee | ||
Comment 22•24 years ago
|
||
I think the problem described in this bug is fixed (I verified this with Roger today.) There is a related exploit (bug 38959), but the problem there is not with the CheckAccess callback from the JS engine; that works as it should. Marking FIXED and reopening to the public.
Group: netscapeconfidential?
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•