[snarfs coffee]... wait, What are you doing?

Published 27 November 07 08:13 AM | Billy 

While reading through an article about Firefox 3 on Security Focus today I snarfed my drink when I read the following passage:

The group also rewrote the Password Manager in JavaScript from C++ to eliminate memory errors, Schroepfer said.

Digging a little deeper I find an article talking about how OS keychain tools can interact with Firefox 3's JavaScript password manager. In the comments of the article is the following tidbit:

The JS portions mostly handle DOM interaction and file IO for signons2.txt. The two main reasons for switching to JS are simpler code and increased security (eg, no buffer overflows possible). Most of the Firefox frontend is already JS, so this isn’t exactly a radical change. But, in any case, the actual encryption of logins continues to be done be a C++ component (using Triple-DES).

 There are numerous things about this that concern me:

  1. JavaScript code is *not* simple. It is highly dynamic, loosely typed, with late bindings. This means short of a syntax error, all your errors are runtime errors. Not fun to debug regardless of how awesome Firebug is. In fact, we have an entire chapter in our  Ajax Security book about nuances of JavaScript (variable scoping and declaration, oddly performing functions, deadlocks/race conditions/live locks with no mutexs, etc) that make it tricky to develop JavaScript. Dumping one language for another solely to improve readability of your code is admitting you are a poor software architect and, frankly, rather of lame.
  2. Moving to JavaScript because most of Firefox/chrome is JavaScript kind of makes sense. Moving to JavaScript from C++ to "fix" buffer overflows and memory problems is a horrible reason. You are admitting you are incapable of solving a very well known problem and the only solution was to move to a language/runtime that removed the problem for you.
  3. Is this JavaScript interface accessible from plugins or other chrome controls? Please don't tell me you just increased what can be done with Cross Zone Scripting attacks.
  4. As is pointed out in the comments of the second article, programs must be very careful when freeing memory that contains passwords. In C you can blast the buffer with junk before a free(). You have to be extremely careful with passwords in memory for managed languages like C# or Java where strings are immutable. JavaScript? No control what-so-ever over how string data is stored and destroyed. Does Spidermoney or Rhino handle JavaScript strings securely? Hmmmm...
All and all, this is a scary jolt first thing in the morning.

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# DigDug said on November 27, 2007 12:01 PM:
I think you're overreacting a bit. The JS code is simpler for Firefox because its an XPCom component. Simply put, writing anything in C++ XPCom involves a lot of reference counting and whatnot, and the code gets messy real fast. Not impossible to read but messy. Easier to read code is (usually) easier to fix if a problem is found. Its also one solution to the buffer overflow problem. No one is discounting that there are others. Just that it is one and they used it. Cross Zone Scripting attacks would be a problem either way. If a site has access to chrome, then the site can do dig through anything the user has access to. It doesn't really matter if the component is JS or C++. That said, if you use a master password, then the login manager requires it before it will give out any info. I also have no idea how passwords are stored in memory though.
# TrackBack said on November 27, 2007 1:38 PM:
# Justin Dolske said on November 27, 2007 7:05 PM:

The simplicity gains from moving to JS are not imaginary here. For example, the password manager does a lot of interaction with a page's DOM, and that's well known to be clunky with C++ in the Mozilla code base. [Mozilla 2 will be receiving a significant amount of rework to help rectify that in a general way, but that wasn't an option for the codebase used in Firefox 3.]

I gave an example of this in a comment to my original post on the subject: http://blog.mozilla.com/dolske/2007/02/05/password-manager-changes/

If the old password manager hadn't been so poorly designed and implemented, we probably would have just fixed the existing C++ code. Unfortunately, it needed a LOT of work, and so it made sense to switch to JS in the process. Yes, just blindly tossing out established code for $LANGUAGE_OF_THE_DAY is a classic rookie mistake, but that wasn't the case here.

The password manager is a XPCOM component, and so the JS version is accessible/inaccessible from exactly the same places the C++ version was. [To be explicit: only privileged code has direct access. Javascript code running in a web page can't do anything with it.]

# The SPI laboratory said on November 28, 2007 7:15 AM:

Just a quick update from yesterday's post . It appears that Rhino uses Java's String object to

# Ben Bucksch said on November 28, 2007 7:23 AM:

> JavaScript code is *not* simple.

Actually, it is. We're not talking about webpage-JS coders here, but proper software development, many people with C++ background.

I am in a big project (2 million users) right now and the whole frontend and overall logic control is in JS. If done properly, it is very effective (several times less code size, but doing the same), reliable (even more so than C++, lack of pointers, crashes etc.) and secure (no buffer overflows, easy security checking). It must be done properly and designed for reliability and cleaniness from the start though. You also need to take care to "check all your inputs" etc..

Looking at my actual experiences with big projects, in C++, Java and JavaScript, XUL+JS was a serious success.

> all your errors are runtime errors

Yes, but with discipline, this is not a major problem. You *do* get proper exception, with stack trace, though, in runtime, instead of e.g. crashing for a null pointer in C++. In combination with assertions, this is very helpful in getting problems resolved quickly.

> > buffer overflows and memory problems

> You are admitting you are incapable of solving a very well known problem

A problem that most current C++ software is still suffering from, and which simply does not exist in JS and Java.

This is the old "if you can't handle it, you're a loser" argument, which is very old and was not true then and is not true now, because even those people who state that have had buffer overflows and null pointers - repeatedly.

> Is this JavaScript interface accessible from plugins or other chrome controls?

Given that they run with system privileges and can do *anything* on the machine, including keylogging and reading the signon2.txt file, that's not a major concern.

# Billy said on November 28, 2007 7:59 AM:

Comments inlined

> JavaScript code is *not* simple.
Actually, it is.

C++ is not simple and JavaScript is not simple, they are different. Each language has different nuances that need to be be understood to build scalable and secure applications. To simply say "JavaScript doesn't have X Y or Z and C++ does" ignores the fact that C++ doesn't have E, F, or G and JavaScript does. Instead of tracking pointers you are tracking data types. Its a trade off.

It must be done properly and designed for reliability and cleaniness from the start though. You also need to take care to "check all your inputs" etc..

 100% agreed.

> You are admitting you are incapable of solving a very well known
> problem
A problem that most current C++ software is still suffering from

Quoth the Ben: "Yes, but with discipline, this is not a major problem" :-)

Perhaps I came on strong here, but my point was it seems silly to me that a major reason to re-implement an existing (and already battle hardened) feature in a new language is because it removes the ability to accidentally shoot yourself in the foot. Especially when it is fairly widely known how not to shoot yourself in the foot.

Whether people actually follow the advice is a different story (checks Full-Disclosure/BugTraq...) ... apparently not so many disciplined C++ coders out there writing all these heap overflows.  I suppose that because we're talking about proper software development and not webpage-JS coders. :-)

I suppose its just a matter of priorities. I would not have used memory management as such a major reason to refactor to an new language. It seems that you would.

Given that they run with system privileges and can do *anything* on the machine, including keylogging and reading the signon2.txt file, that's not a major concern.

Good point I'm not super familiar with the capabilities of Mozilla plugins, (if they could only read/write to certain paths, only listen for certain events, etc).

Leave a Comment

(required) 
(optional)
(required) 

About Billy

Billy Hoffman is the lead researcher for SPI Labs.