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>
Perfectly fine to save the value of an input box in a javascript value because since the user entered it, they obviously know about it.
However! It is usually frowned upon to store user passwords as plain text anywhere.
Edit
SSL will make it very hard (not impossible given enough time, but enough that this is what most of the web uses as secure) for a malicious observer to intercept and recreate a message. Temporarily storing a single password in a javascript variable that was entered on that page is okay. But, do not send it from the server in plain text or you will wake up with the bad headlines.
When you're dealing with sensitive values stored in JavaScript, you have two primary security concerns:
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 theuser
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
No. What you can and need to do is:
In the clientside javascript code there can be no security. The user enters all data as plain text, and as such it can be accessed by every script running in your page. Therefore, you will need to prevent XSS. Sure, cookies are directly available to every script running on your domain while data hidden in the scope of some functions is not a "global variable", but every malicious script can access it just as your own application does.
@your code: It's true, no one can access the
user
object from outside. But everyone can access the password input element, and everyone can highjack browser objects to spy into the api request.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.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 viaeval("nameOfLocalVariable", fnToStealFrom)
.If the function calls one of its arguments then it can be stolen from as in.
will steal the secret on EcmaScript 3 interpreters and maybe some EcmaScript 5 interpreters.
As your example has it you are perfectly safe.
This does not, however, replace cookies. In your example you are storing the password in code locally, but unlike cookies these values can never be used later.
It would be better to not store the value at all, and use traditional http authentication over ssl.