Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Security: is storing sensitive data in a self invoking function more secure than cookies?

I know security is either non-existant or very difficult in client side JavaScript. I know my server-side code should ultimately decide who it gives data to or accepts data from.

That said, is the following okay to do. By "okay" I mean if this were the method used on some new popular trendy cool web app. Could I sleep at night knowing that I won't see "Super Cool Web App Hacked, change your passwords!" all over HN and Reddit (or any other sources of info people care about) as a result of this implementation.

If it is not secure. Why? How can that info (username and password) be obtained?

If it is secure? How sure are you? Why is it secure? What is stopping me from getting that info outside of my obvious inability to right now.

Partial answers are welcome. Just looking for a better understanding.


EDIT

I'm thinking about the case of some trying to steal a users credentials. My understanding is that cookies are insecure because 1.) other javascripts (via XSS or whatever) can access them and because 2.) they are passed in the clear. I figure SSL would take care of the second issue and lets just assume I'm able to prevent XSS. It would now seem that cookies are now secure, right?

I'm aware of some supposed browser vulnerabilities that assist in making cookies insecure. That's what made me ask this question. Given all the things that make cookies insecure, is this (code below) any better?


http://jsfiddle.net/KTastrophy/vXEjm/1/ OR see code below (Only tested in Chrome)

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <form id="login">
            <div>
                <label for="username">Username</label>
                <input id="username" name="username" type="text" />
            </div>
            <div>
                <label for="password">Password</label>
                <input id="password" name="password" type="password" />
            </div>
            <div>
                <input id="submit" name="submit" type="submit" value="Login" />
            </div>
        </form>
    </body>
    <script type="text/javascript">
        ;(function () {
            "use strict";
            var login, user = {};
            login = document.getElementById("login");
            login.onsubmit = function (event) {
                event.preventDefault();
                user.username = document.getElementById("username").value;
                user.password = document.getElementById("password").value;

                /*
                    use the username and password here to do
                    an API request over SSL using HTTP Auth
                 */
            }
        }());
    </script>
</html>
like image 676
KTastrophy Avatar asked Aug 01 '12 23:08

KTastrophy


People also ask

Is JavaScript a security risk?

One of the most common JavaScript security vulnerabilities is Cross-Site Scripting (XSS). Cross-Site Scripting vulnerabilities enable attackers to manipulate websites to return malicious scripts to visitors. These malicious scripts then execute on the client side in a manner determined by the attacker.

Is JavaScript localStorage secure?

On the downside, localStorage is potentially vulnerable to cross-site scripting (XSS) attacks. If an attacker can inject malicious JavaScript into a webpage, they can steal an access token in localStorage. Also, unlike cookies, localStorage doesn't provide secure attributes that you can set to block attacks.

Is JavaScript a secure language?

Like nearly any programming language, JavaScript is not without its share of potential security exposures. Exploiting JavaScript vulnerabilities can manipulate data, redirect sessions, modify and steal data, and much more.

How security is provided in JavaScript?

JavaScript has its own security model, but this is not designed to protect the Web site owner or the data passed between the browser and the server. The security model is designed to protect the user from malicious Web sites, and as a result, it enforces strict limits on what the page author is allowed to do.


2 Answers

When you're dealing with sensitive values stored in JavaScript, you have two primary security concerns:

  1. The sensitive value is viewable as plain text in the source.
  2. Another JS function on the page can reach into the object and pull those values (i.e., an XSS attack).

The second item above becomes much more relevant when you have apps running from multiple sources on a single page (e.g., Facebook apps). In these instances, you would have to take pre-cautions not to expose sensitive variables by using closures to namespace. You are actually already doing this: your user object is declared inside a closure. This prevents any other JS function on the page from being able to access the user object.

In your case, I'm assuming that there isn't any other code on the page except for your own and the possibility for injection is minimal--your code is safe :)

Edit: What makes storing the username and password in a cookie insecure is that it sits on your computer after you've closed the browser. If a hacker can access that cookie (through any number of ways) then you could be in trouble. What you've done above is safe because nothing is stored on the client side after the browser closes (and while the browser is open, other JS cannot access the values you've stored). If you want to put something in a cookie, it'd be better to store some sort of public/private authentication key. There's a lot of discussion on this, here is a thorough 'best practices' article on the topic: http://jaspan.com/improved_persistent_login_cookie_best_practice

like image 150
Elliot B. Avatar answered Oct 17 '22 06:10

Elliot B.


If the data you're storing appears inside the source code then no, a function's toString method can be used to turn a function body into source code.

function f() {
  var cryptoKey = "ABGASDJEOTATJKASDTNM...";
}
alert(f);

If the data is closed over instead of appearing in the source code and there's no way that function can call eval in its body, then on modern interpreters yes.

Older Netscape interpreters extended eval so that it could be used to run code inside a function via eval("nameOfLocalVariable", fnToStealFrom).

If the function calls one of its arguments then it can be stolen from as in.

var f = (function () {
  var x = "secret";
  return function (a, b) { return a(b + x.length); };
})();
f(eval, "x//");

will steal the secret on EcmaScript 3 interpreters and maybe some EcmaScript 5 interpreters.

like image 38
Mike Samuel Avatar answered Oct 17 '22 07:10

Mike Samuel