How to Encrypt password for REST API authentication - javascript

There is a lot resources about how to secure REST API access, but this not what I am looking for. I am going to use provided REST API with Basic Authentication (and this cannot be changed easily :( ).
Obviously I can go with:
var requestOptions = {
hostname: "rest.api.url.com",
path: "/path/",
auth: "username:password"
};
var req = http.request(requestOptions, function (res) {
// some code here
});
Is there a way to not provide password in plain text in the script?

Is there a way to not provide password in plain text in the [JavaScript]?
Client-side JavaScript will always be vulnerable to tampering and modification, including reversing any "encrypted" passwords you store in the client-side script. You can obfuscate your code all you like, but if the password is present in any form in your client script, it is accessible.
I am going to use a provided REST API with Basic Authentication (and this cannot be changed easily
Since you can't change the REST API to use something like tokens or SSL, one solution that comes to mind is to have an intermediary between your server and the REST API which does use SSL. Communicate securely with some server-side script on your server, and have this script proxy the requests and responses from the REST API.
Resources:
How to encrypt data in javascript and decrypt in php?
Secure communication between JavaScript and a Web service in PHP
How to secure the password while it being sent using AJAX?

You can encode it with whatever encryption you like, however your encryption technique will still exist on the client side. The proper thing to do here is to setup a SSL certificate so that your requests become encrypted with the certificate.
Furthermore, to reduce the need to send passwords around you may want to look at using some sort of token based authentication.

Related

signing api calls from frontend to backend

I am implementing a secure way for the frontend to communicate with the backend using a secret key. The backend is a sensitive service (mobile banking.)
First I was thinking JWT, but the token-based approach has two disadvantages:
a) the front-end has to obtain the token, this means it has to send some auth data to the back-end - and if the front-end can do this, anyone can do this.
b) even if there is some secure way of obtaining the token, anyone can fire up Chrome dev tools and use it while it's not expired.
So the alternative approach is to sign each request from a front-end with a secret key. The key is known to back-end and front-end the front-end is bundled and uglified so as to keep the key secret. We concatenate the request URL and its payload, encrypt them with a secret key and send the resulting hash in a header. The back-end gets the request, does the same encryption and compares the headers; if they are equal - it makes the request.
This leads me to three questions:
Does this really mean that even if the request is sniffed it cannot be reproduced unless the url+payload is the same? Is there something i'm missing?
Is there a JS library implementing this approach? (or maybe something for the backend too - I am using Django)
Is there a better approach?
Bundle as you want, if your security key which authorizes request is inside js i will be able to un-uglify (beautify) and get it. Use SSL to encrypt connection and just use JWT ;)
http://jsbeautifier.org/
You will have to authorize user somehow anyways, so it means sending private data to establish the "session". Let it be username, email, password or some "secret" token.

RESTful API write security

I've recently started using modern front end technologies like React/Angular and as a result have started using tools like JSON Server to recreate dummy restful db interactions.
My understanding is that most rest api's authenticate via some kind of token and secret that is either passed as part of the url or as a header. This seems fine for retrieving data, but is it not risky exposing these login credentials in a front end language like JS when writing is possible?
My thinking is that all it would take is a simple view source for somebody to steal my token/secret and potentially start populating my db with data.
In the problem that you describe the client (browser) has the login credentials because the server provide them. There is no "exposing" as the credentials are already exposed. Exposing your credentials to every client means that there is no security.
When we talk about security we consider as a client the browser not the real person that operates the browser. As you said, the real person can access all the browser's data.
To secure your API the secret key must be kept secret. This means that each client has a different key and uses it to get their data/services from your RESTfull server.
In a simple senario this key can be used/managed like the session id.
The client should first pass through an authorization process (login maybe) and then a temporary key can be generated for the client's session.
Generally, a key is converted to rights. If every client by default has the key, everyone has the default rights, so you may also remove the key and set the default rights to every request.
A client that you don't want to have full access to your db should have a key that gives him limited access to your db.
On the other hand, if the client provides the key, this is secure. For example a php code on a server that uses the secret key for accessing your API.

POST Call to Authenticate User to Front end Application

I've been tasked with creating an LDAP authentication on a front-end Javascript application.
I am extremely limited on time and have a very small toolset. The toolset is the front-end javascript application and an available C# application which I can make post and get requests to.
I was thinking I could simply make a call such as https://mybackend.com/authenticate
Where I would post a username and password.
And on the backend this would return whether or not the user was valid in the AD. Which I can then use on the front-end to ensure the user has logged in.
Is this approach extremely unsecure or does it have flaws? I'm thinking that if I am posting to the backend above not much will be exposed.
Any tips would be immensely helpful.
Is this approach extremely unsecure or does it have flaws?
This is not insecure, it's the normal way you would do it. One could add more security by adding a CSRF token, which would be validated on the server for any form submit.
And yes, you should send all the data over HTTPS, this will encrypt the payload.
What you are doing is normal for front-end JavaScript framework like Angular. As long as you use Https, you should be ok.
Only issue is how you will handle the subsequence page requests.
There are two ways to handle it –
Easiest way is to use ASP.Net MVC as login page, and use Cookie Owin Middleware. Since same cookie is sent back to server on API calls, you do not need to do any extra works. You can download my sample code at GitHub - OwinAuthenticationService.
Another way is to use Bearer Token in which you will have to send the same token back to server on every page request.
All method are insecure.
Especially without HTTPS.
But you can put the Authentications in the header of message and use a token generated with a key that only server know.

webapi backend with pure javascript frontend, security

So now I am pretty much sold to the idea of having pure html+js front end where all processing happens at client side browser and the backend provides all the data in JSON/xml/other format and so on.
Here's the dilemma,
For authentication, I am using OAuth2 Bearer token which gets generated when user authenticate using username and password (for e.g. at login stage).
There is an extra security for which clientside application (i.e.a front end web server or mobile app) that is making request to this WebAPI. When it makes the initial request, it passes "client_id " and "client_secret" to make sure the client is app is authorized to make this request to back end server.
In traditional .NET way I would store the encrypted clientid and key in web.config and my C# (Or VB.NET) code would retrieve it and send it over SSL to the server. So in the manner the client_id and client_secret is not exposed in rendered HTML (for e.g.) to the client side browser.
In pure javascript environment how can I secure my client_id and client_secret (or any other sensitive data for that matter)?
Thanks
I don't think you can secure your "secrets".
HTML5/JS code is pure text, anyone with a text editor can see it. What people normally try to do is obfuscate their code by using javascript minifiers/compressors; see here for a good discussion. The practice is called Security through Obscurity. But note that obfuscation is not security. Given time and effort, a determined "hacker" will eventually find your secrets. Another step you can take to deter, delay and frustrate such attacks is to spread bits of your secrets in the code, in different modules, etc. Having said that, you'll need to write code to assemble them at some point, so again, no real security.
I have a similar problem because I wanted to use a "shared secret" with the server so I can hash my client requests such that they are tamper-proof and can't be recreated without the attacher knowing the shared secret. Unfortunately I had to give up on the idea, since I realised I couldn't keep it secret enough.

Javascript asymmetric encryption and authentication

Some of the guys here are developing an application which incorporates some 'secure areas' accessible by logging in. In the past, the login form and subsequent 'secure' pages were all plain text transmitted over http, as it's an application that goes out for use on shared servers where there is little chance of being able to use SSL (think WordPress and the like). Most people just shrugged their shoulders as that's all they expected - it's hardly a national bank.
We are now thinking of writing the next version using a JavaScript front end, with the advantage of loading all the images & CSS once, then writing HTML into the DOM thereafter with extJS (or maybe jQuery). We'd like to encrypt user input at the client before being sent to the server, then decrypt server output at the browser before being rendered to HTML so as to introduce some sort of security for users. There are also gains to be had with reducing page loading times, as we're only sending gzipped JSON back and forth.
While playing around, we realised that the method we were looking at to encrypt the basic stuff also doubled up as an authentication mechanism for login in the first place.
For simplicity...:
The user connects to the login page over standard http, where the browser downloads the JavaScript package containing the hashing and encryption algorithms (SHA-256 and AES for example).
User enters username, password and secret into a login form.
The browser JavaScript sends a hash of username and password to the server via AJAX. The secret is only stored in JavaScript and is never sent across the internet.
The server looks up the hash and retrieves username and secret from the database.
The server sends a hash (same algorithm as the browser) of username and secret back to the browser.
The browser JavaScript creates a hash of username and secret and compares it to the hash sent back from the server.
If they are the same, the browser JavaScript encrypts response with secret and sends the message back to the server.
The server decrypts the message with secret to find the expected response and starts a new session.
Subsequent communications are encrypted and decrypted both ways with secret.
There seem to be a few advantages of this type of system, but are we right in thinking:
The user knows they are talking to their server if the server manages to create a hash of username and secret, proving the server knows and understands username and secret.
The server knows the user is genuine if they manage to encrypt response with secret, proving the user knows secret.
At no time is secret ever transmitted in plain text, or is it possible to determine secret from the hash.
A sniffer will only ever find out the 'secure' URL and detect compressed hashes and encryptions in the query string. If they send a request to to the URL that is malformed, no response is given. If they somehow manage to guess an appropriate request, they still have to be able to decrypt it.
It all seems quick enough as to be imperceptible to the user. Can anyone see through this, as we all just assumed we shouldn't be playing with JavaScript encryption!
Don't do this. Please use SSL/TLS. See Javascript Cryptography Considered Harmful.
If you can provide a single SSL site to deliver your JavaScript securely (to avoid the attack mentioned above), then you can use the opensource Forge library to provide cross-domain TLS connections to your other sites after generating self-signed certificates for them. The Forge library also provides other basic crypto stuff if you opt to go in a different direction. Forge has an XMLHttpRequest wrapper that is nearly all JavaScript, with a small piece that leverages Flash's socket API to enable cross-domain communication.
http://digitalbazaar.com/2010/07/20/javascript-tls-1/
https://github.com/digitalbazaar/forge

Categories

Resources