safe user authentification without javascript - javascript

I consider Javascript a security risk, therefore I would like to allow users of my website to login without having to have Javascript enabled.
This brings me to another problem. Without client-side-scripting I have no idea how I can hash the users password at the client side so to avoid plaintext password transmission.
How can "pure HTML+CSS" allow me to have a password hashed.
At present it seems to me the only safe option (without Javascript) would be to have a secure(encrypted) ssl/https connection and send password as plaintext?
Anyhow: Is there some way to hash the users password as to avoid to send it over the internet in plaintext.? Is this possible only using client-side-scripting?
[update]
I am aware that SSL is maybe the most close to ideal way. (as mentioned in the comments) Anyhow. It would be already an security improvement when at no time a plaintext username and plaintext password would be send via an unsafe channel. The hashes can be sniffed as well and no safty (i.e encryption) can be there. BUT at no time a sniffer will be able to get the unhased version of the username and password. => advantage would be that users will not make public their username/password combination (potentially used elsewhere).
After all it seems like there is no "scripting disabled"-way of (spice)hashing some input-field values. So I assume my question is unsolveable.

First of all, if you are using SSL, then the password is not being sent in plain text. Everything beyond the initial handshake is encrypted, and quite securely at that. Consider that this is the security that banks, the military, government all over the world rely upon daily. I'm not saying that you should trust it just because everyone else does (argument from authority) - I'm just saying that if there were a problem with it, we'll hear about it right away.
Second of all, you don't ever really gain anything by client side hashing. The basic attack you're trying to prevent is a man-in-the-middle (MITM) attack. Whether its someone eavesdropping on the connection, sniffing the password for a replay attack, or actively hijacking the session (i.e. pretending to be the server and the client to opposite ends of the connection), you can't really prevent it through additional security.
If you assume that the attacker can break through your SSL encryption, then any other token that relies on something the client software is doing or something that the server is sending along can be compromised. If its some client-side hash function, then the attacker can either learn what the function is by inspecting the webpage the server sends down or just sniff the hashed value and use it to impersonate the client when the attacker communicates with the server. If there is some secure key or token the server sends down for the client to use and respond with, the attacker can just intercept that.
I think what you're looking for is two-factor authentication.

Related

SSL alternative for secure handshake?

I'm curious if there's any way that a server can validate a client without knowing that the client is entirely "friendly" code that isn't monitoring 1) the user's input or 2) network requests.
The only way I could conceive of this is if browsers have a built-in, secure, isolated shell / scope that can hash and send data (which can be verified with a complimenting server unhashing / lookup script).
Is there any browser-supported (non-DOM) input/hashing method that can also be installed on the server to identify the authenticity or user input? I want to avoid Chrome Extensions and potential keylogging in general, but I'm not sure any browser supports this feature.
Thanks
EDIT
I think some form of 2-step auth in a separate window would be the closest, but I don't have SSL, and I don't like the presentation of random "popup" windows
If I understand your question correctly you are asking for a proof that the data entered into a form are neither manipulated nor generated by malicious software. But you (as operator of the server) don't have control of the client.
This is impossible as long as you don't have control of the client because it is impossible to distinguish user generated data from software generated data on the network level, and that's all you get at the server. Even the output generated by a browser extension can be faked.
I think some form of 2-step auth would be the closest
2FA is relevant for authentication of the client only and provides no way of making user generated data tamper resistant.
SSL alternative for secure handshake?
SSL only protects the transport and does not prevent modification of the user input within a malicious browser extension or similar. It also does not protect against malicious man in the middle on the clients machine (i.e. Superfish or similar).

Maintaining private key between https and http

I'm working on a new site that utilizes a service-oriented architecture, with pure JavaScript on the front-end, accessing web services for data via RESTful AJAX calls.
It shouldn't be of particular importance but my stack is:
javascriptMVC
jQuery
Bootsrap
ASP.NET Web API (C# on .NET 4.0)
MS SQL
From this article I've figured out some good ways of securing my web service calls once I have a private key shared between the client (JavaScript) and server (REST services via Web API). However, I'm struggling with how to establish the private key to be used for encryption.
Bad Idea #1
The initial though was to set it at log in which would occur over HTTPS, then store it on the client in a cookie for reuse. The problem is that our SSL cert is for https://secure.example.com, while our site is on http://www.example.com - so I wouldn't be able to access the secure.example.com cookie from www.example.com.
Bad Idea #2
My next thought was to pass it encrypted and signed via a URL parameter from the HTTPS login to the HTTP post-login page like so:
http://www.example.com/processLogin?key=[encryptedKey]&sig=[encryptedSig]&user=[userid]
encryptedKey and encryptedSig would both be encrypted with another private key that only exists just for that transaction. It would be created at log-in and assigned to that user in the database. On the HTTP side, all of this gets passed to the server which decrypts it, validates the signature, removes that private key (to guard against replay attacks - essentially a nonce) and returns the decrypted private key ([encryptedKey] decrypted).
From then on out, the decrypted value of [encryptedKey] would be used for all future transactions. The problem is that the decrypted private key would have to be sent over the line via HTTP, which sucks.
Bad Idea #3
It also briefly occurred to me to have a hard-coded key in the JavaScript that's used to decrypt this value but no matter how I try and obfuscate it, it could be found and used by a hacker.
Bad Idea #4
I've also considered some sort of key exchange using Public-key cryptography at the initial handshake, but as noted elsewhere, you can't really be confident on the client-side that there isn't tampering during this initial handshake unless it's over SSL - putting me back at square one.
The Big Question
So, how do you guys manage such things without everything going over HTTPS? Do I have to have the same domain name for my HTTP and HTTPS so that I can store this private key in a cookie?
Note that the non-SSL portions of the site wouldn't be sharing credit card or login information or the like. I just don't want to leave this sucker wide open.
You can not have secure and encrypted communication between a javascript client and a server without implementing SSL. It is impossible. If what you really want to accomplish is not to encrypt the traffic but simply insure the client you are talking to has been authorized to make the request and that the client is not an impersonator, then OAuth may be sufficient. See http://www.dotnetopenauth.net/ for the standard OAuth .net implementation.
If OAuth is not what you want to get involved in and you simply want to build on what you already have built, you should distribute a token and a public and a private key to the javascript client. The public key and the token is what gets sent back and forth for every request while the private key is never sent back and forth and is instead used to generate some type of signature hash. Every request should have this signature and a time-based nonce to prevent replays. You should also expire the token on a very frequent basis and require the client to request a "refresh" token with their sig and their public key. In essence, what I have described is OAuth 1.0a, and if you do want to take this route, I would refer back to DotNet OpenAuth instead of trying to roll it yourself.
However, to reiterate, without SSL, you will still be vulnerable to other types of attacks. Also, unless you SSL encrypt the initial token request, a hacker could always sniff the initial delivery of the token/public/private key pair, therefore, eliminating all your hard work to make things secure in the first place.
An alternative to the above is to have a proxy server sitting between your client and the REST API. Requests to the API can only go through the proxy server. The client logs in and gets a cookie from https://secure.example.com using basic auth. The client then continues to make requests to secure.example.com and secure.example.com then makes requests to your API and returns the data back to the client.
Anyway, hopefully enough info to give you food for thought.
You can view how to work with sub domains and cookies by checking out this answer: Creating a javascript cookie on a domain and reading it across sub domains
Regarding Bad Idea #3:
I've known for awhile that I can use http://jsbeautifier.org to deobfuscate anything that is obfuscated using http://dean.edwards.name/packer/ with the "Shrink variables" checkbox &/or the "Base62 encode" checkbox. So JavaScript is totally insecure & shouldn't be relied upon for saving any sort of SSL encryption, nor user auth tokens, nor editable account stats in the browser. Otherwise someone would simply try to edit their game account & give themselves +10 million game coins.
When everything goes over SSL it only protects against "man-in-the-middle" attacks. It's really a "server-bot-in-the-middle" attack. It doesn't prevent the end-user from being a hacker themselves.
In this next illustration, SSL would prevent servers a through e from seeing any data that's being passed from the client to the terminus server, but without SSL server C would steal data. This is how server hops work, without encryption, where the client + all servers can read the data:
client > a > b > server c's bot sniffs http traffic > d > e > terminus server
Server c's bot logs a credit card number, which is an encrypted bank account number. (Most people don't realize that a credit card number is an encrypted & transformed bank account number. If the credit card number is compromised, it's easy for a bank to re-issue a new encrypted CC# from a bank account number & send out a new card in the mail. They don't have to change the original bank account number nor printing new checks, which have the bank account number printed on the bottom of them.)
Server hops with TLS/SSL/https encryption would work like this, where only the client & server could read anything:
client > all servers from a-e are blind & pass the data through > terminus server
Server c's bot sees junk like: as65a89as7df08 instead of 1234-5678-9012-..., if they can read anything at all using SSL.
What's cool about iOS, is that it makes it harder to read the JS code when it's used with HTML 5 & CSS. User can't right-click to inspect on their iPhone, like they can in a desktop browser. It's easy to hide a password in the terminus server using a back-end language.
It's currently impossible to prevent JavaScript from being hacked by the end-user (client). Every end-user can be a hacker. If I figure something else out, I can post it here for future developers to read.

practical use of cryptico.js

Cryptico seems like a super slick RSA encryption library.
cryptico.wwwtyro.net
In regards to JavaScript applications, suppose I want to send data to the client, have them do something to the data, and pass it back. How can I use RSA to ensure that the data clients send back to the server is not tampered with? Since JavaScript is easily reverse-engineered, is there any practical client-side application of cryptico?
Do you - by your example - mean that you want to hide from the user what his client is doing with the data? If so - it's impossible.
You should never trust any data which comes from the client.
If you send encrypted data to the client to process - you must assume that the user knows (or will know if he wants) the encryption key, otherwise it will be impossible to process. In other words there is no secure way to hide from the user what his client processes. Obfuscation - like you've noticed can always be cracked no matter what language you use.
I think that the most common and practical client-side application for this library would be encrypting user's data and sending them to server or vice-versa. There may be some cases you can't use SSL. Moreover, you can make -for example- an encrypted post on facebook which only your friend will be able to decrypt (because he knows the key).
There is a solution to what you seek (I'm sure there is more than one). My answer requires two non-conventional approaches to what we call a 'secure connection' and how you receive the 'client code'.
You need a physically pre-shared key that initiates a secure connection, and because it's pre-shared it doesn't have to be RSA, which then opens up speed opportunities and higher levels of encryption security for you.
Physically pre-share your client code in a similar manner, i.e., download the code from a cd in a magazine or from a pre-paid card sold in a market. This stops the MITM from sending you tampered and exploited clients, which ssl allows. Once client is known to be secure, and a real secure connection, mentioned in (1), is established, the client code can be updated.
With the combination of a pre-shared key that develops a secure connection and client code that can pass a checksum, you can achieve what you are after.
Ideally, we should have pre-shared secure connection keys available in the market now, but we don't. So, for you to do it alone, would require to implement something similar for you website specifically until people in this country get their act together with some real security. You would have to give them keys over your phone, through the mail, etc. And your client code would most likely have to be a browser extension to install it due to cross domain security issues.

Is passing password from server to browser in javascript variable over https secure?

Following is our page flow,
User is at Login page accessing via https.
User enters password and page is submitted (POST method).
User credentials is not authenticated now instead server response with some polling page(https).
In order to retain the password on poll page, password is passed from server to browser via Javascript variable and onsubmit of poll page, password is passed via POST method. Now server authenticates the user credentials.
Question:
Is passing password from server to browser in javascript variable over https secure?
My opinion
Entire transaction between the
browser and server is via https and
password is passed via POST method -
so password is SECURE.
The password is visible via "view
page source" since it is assigned to
a javascript variable - NOT SECURE if
browser plug-in has access to the
page content. But if browser plug-in
has access to page content then it
can even access the password while user enters it, so NO new
threat is introduced by this flow.
Note
I know their is better way to handle
this flow. But I am interested in
whether our existing flow is secure
or not.
Any reference to security tips will
be helpful.
The bigger issue is best practice - you just don't need to do it, and it's bad practice. This would indicate a poor understanding of security overall - it's a best practice to not store the password in plaintext ever. If your programmer coworkers do not give proper credence to this concept, then I would suggest they may have other areas they are lax in observing, security-wise.
Security is a mindset, not a lowest common denominator. It's about giving as few opportunities for compromise as possible, giving as little wedge room as possible.
Not storing plaintext passwords is what you should do, not "store them when we want unless someone can prove it's bad".
This interest in "harmless failures" –
cases where an adversary can cause an
anomalous but not directly harmful
outcome – is another hallmark of the
security mindset. Not all "harmless
failures" lead to big trouble, but
it's surprising how often a clever
adversary can pile up a stack of
seemingly harmless failures into a
dangerous tower of trouble. Harmless
failures are bad hygiene. We try to
stamp them out when we can.
http://freedom-to-tinker.com/blog/felten/security-mindset-and-harmless-failures
The transmission would be secure. But it would be inadvisable to send it with a response because browsers would cache the value with the page. Someone could maliciously view source of the page and view the password.
Could you do this by passing a server session key?
Sure, the transactions themselves may be secure from some forms of interception, but you're opening yourself up to a number of other attacks that don't rely on intercepting the request/response activity. What if some page of your site is susceptible to cross side scripting and some malicious javascript gets on your page?

How do I encode passwords in web forms without javascript?

It's not that I don't have access to javascript, of course. In most of my CS Web Development courses, we are taught a little bit about server-side validation, and then as soon as javascript is introduced, server-side validation is thrown out the window.
I choose not to just rely on javascript, as the client-side is never a secure place. I have gotten into the habit of writing both the client and server-side code for such things. However, for a web application that I am writing that has optional AJAX, I do not want the password to be send plaintext over the wire if someone has javascript turned off.
I realize I may be asking a catch-22 situation, so let me just ask this: how do we know our users' passwords will be secure (enough) from malicious users on the same network when all we can rely on is server-side scripting. On that first request from the login page, is there any way to have the browser encrypt a data field?
SSL Solves this problem. For the record, passwords should never be "encrypted" or "encoded", this employs that there is a method of "Decoding" or "Decrypting" which is a clear violation if CWE-257. Passwords must be hashed, SHA-256 is a great choice, but this is not meant for transmission, only storage. When you transit secrets there is a long list of things that can go wrong, SSL is by far the best choice for solving these issues.
If the attacker can sniff the traffic then they will be able to see the session id and use it immediately, so its a moot point. You have to use SSL to protect the authenticated session anyway.
The easy solution is SSL.
I think you're mixing up a couple of concepts. The browser does not encrypt individual fields. Client-side scripting, server-side scripting and AJAX are not means to defend against eavesdropping.
As others have said, SSL is the technology that encrypts the data. The entire request and response, including the fields and scripts are contained within the SSL session.
You can also use Digest HTTP Authentication.

Categories