Angular and secret keys - javascript

I have been learning angular 2 and have been doing research on how to protect data within my app.
How, if possible, can you obstruct data from the front end of the app? Is it possible to serve the angular app through a node server, say using Universal Angular, which would mean variable values can be hidden from the user on the front end.
I am essentially looking for the solution of hiding private keys which will give the app access to various APIs/creating auth headers/paths. I've read a solution is to have an API bridge for the app - so I would connect to that to retrieve the data/keys - but then how do I protect that from access? Since that endpoint would then be exposed and could be abused, or if getting keys the response is visible. The idea of locking down to domain I have read is unreliable due to spoofing and locking to IP wouldn't work as its front end or through an app?
I feel there is a glaringly obvious answer that I am missing something.

You must assume that everything that is held in your frontend is visible to anybody that can access your frontend.
All JS variables, storage (local, session), network requests, etc. in your front end are unsecured from users of your frontend.
You can (and should) use SSL to make hide data from anybody in between your server and the browser, but there is just no way to secure data held in your frontend from users of your frontend. (At least if your frontend is available on "regular" browser as opposed to some tightened kiosk mode installations.)

It's simple, when the server sends the data as response to a request, then the data can be accessed from the outside.
If you don't want that, then don't send the data.
You didn't mention what problem you actually try to solve. For API keys you can for example do the request to the API on the server and provide an API on your own server for your clients and then make the server forward the requests to the actual API server.

Related

Preventing CSRF with an Express API and a React frontend

I have been reading around CSRF for the past few days and feel like I have a good grasp on what it is and how to prevent it. I am building a small Express/React application that will have a secure admin area for updating the app content and I want it to be protected from CSRF.
I understand that it is common for the server to generate the CSRF token and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag). However, my Express API does not serve HTML, it is a REST API that only returns JSON data. The UI is built with React, running on a different port from the server.
My question is; Where do I securely store a token generated on the server?
For example, if I log in as admin by hitting '/api/login', generate a token, and send it back to the client in the API response, what should I do with it now?
The original plan was to use Redux to store the token but from reading this post Is Redux secure?, this does not sound ideal.
I considered using React env variables but have also read that these are exposed in the build.
Obviously localStorage is also a bad idea...
I am really struggling to find a solution to this problem using the tools I am implementing i.e. Express/React
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
I understand that it is common for the server to generate the CSRF token
The server needs to generate two CSRF tokens
and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag).
One token is commonly sent as a cookie, another can be sent as HTTP header. It doesn't need to be sent inside HTML body as a HTML form input tag (or any other part of the body) though it can be sent this way.
My question is; Where do I securely store a token generated on the server?
You don't have to store a token on the server. You can but you don't need to.
The original plan was to use Redux to store the token
The Redux store is on the client, in browser's memory. In theory one React component (that extracts the second CSRF token from server response) can temporarily store the token in the store so that another React component can get it from there and put into the next request before it's sent to the server.
Obviously localStorage is also a bad idea...
Yes
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
Links
With Express is very common to use this middleware. The steps can be found here.
Criticisms
This is strictly speaking off topic in the context of CSRF related Q/A, but ...
The UI is built with React, running on a different port from the server.
That hints to the possibility of using react-scripts which start webpack-dev-server. It's fine for development, not good for deployment in production. However this is a separate topic, serving React app's build artifacts (.html file, script bundles) to webclients has nothing to do with CSRF attack and its mitigation.
I want to learn to build apps with security in mind
Then you might consider using one webserver instead of two (frontend to serve React app and backend to serve API responses). Using one server results in production deployment which is not only less complex and costly, but also more secure because two servers have larger attack surface and with one server you don't need to weaken security by using CORS.

Hiding API access credentials from an AngualrJS app

This is a design question for AngularJS websites that access a REST API. Since all the AngularJS code can be viewed from the client side (assuming obfuscation is not completely secure) how do you hide the API access credentials (the API key and password or even a JWT)?
This can be extended to a broader question about how other application logic can be hidden in an AngularJS website?
My research led me to some insights, one of which was
http://billpatrianakos.me/blog/2016/02/15/securing-api-keys-in-a-javascript-single-page-app/
But this has me more confused now, since the post suggests an SPA connecting to a REST API is not a good architecture. I thought it was and now can't figure what the right approach is.
The closest I can come to an answer is this resource:
https://developers.facebook.com/docs/facebook-login/security#appsecret
Facebook, is pretty good with their security and say:
Never include your App Secret in client-side or decompilable code.
Use unique short-term tokens on clients.
In short, do not keep API secrets on the client side
Answering the discussion in comments for sake of not being brief:
And then my question would be "what then is the correct architecture for SPAs and server side code (or database access)?".
There's no one correct architecture, it depends on the size and scope of your project. It will also depend on what frontend and backend frameworks you choose. Those choices also will depend on how many other APIs you are calling, or what other developers or you are most familiar with.
Speaking more specifically about security though, ideally you'd like to set up a session for the user which consists of a token that the user uses to identify himself. This is usually generated for each user by the server when they login. Generally this is provided by the framework you are working in, but even if it isn't, it's fairly simple to build. You will want to prevent cross origin requests (making sure the user is actually on YOUR frontend) and have secure connections (setting up SSL and https, though this can get complicated). You will generally want to run your JS code through something like Uglify to prevent it from being too easy to look through, but this does NOT guarantee that people cannot take that code and un-uglify it.
As the other answers have suggested, you should never keep API keys or any secrets in the client source code. There is no way to hide anything on the client, and obfuscation != security.
If you are looking to architect secure authentication/authorization into your app, you will want to return a JWT to the AngularJS application. You can then pass this JWT as a Bearer token to your API which will verify the validity of the token and allow the API to authorize access to the AngularJS application.
As for where to store the JWT token, you can store it in either Local Storage or in a cookie. There are serious considerations between choosing whether to store the token in either of these locations.
If security is your concern, I would look into the OAuth 2.0 Implicit Flow.
Don't put API keys in your client side source code. Keep them on your server, and have your client make a request to YOUR server, which then calls out to external APIs for data.

Securing API with Node

I'm trying to build my first API to be consumed by a mobile application built with Ionic.
Before starting I'm looking into the architecture and I can not understand exactly how to make secure my API routes.
Let's say I have an endpoint like http://myapi/v1/get-items and my application doesn't need an user to be authenticated to view those items in the mobile app.
How should I protect that route from external queries, using Postman for example?
I wish that route to be not accessible unless is not requested by the application.
Looking on Google I can find many solution using basic authentication but all of those require an user to log in... What if my app doesn't have users to log in?
I'm a bit confused but I think there is a solution and I don't know it yet...
I hope you can help me to understand it.
EDIT:
My Question is totally different from the following: How to implement a secure REST API with node.js
I'm looking for solution that DO NOT require a User Authentication.
If you don't want to use User Auth through something like Passport then you can institute a whitelist in your Node API instead. express-ipfilter is an express middleware module that allows you to filter requests based on the request IP.
Requiring a login would be the cleanest and safest way to make sure your api remains private. However, if you want to keep external users out of your services without requiring a login, you will need to "sign" your requests. By that I mean doing something like encrypting a current timestamp on the client using a key known to both the server and the client app, adding that encrypted string as a header, receiving that header in your server, decrypting it and checking that it's not too old of a timestamp before you return a response.
It's not really safe (if someone can see the code they can see the encryption key) but it's an obstacle and it down't require logging in. See this for an example on encryption/decryption

How to Secure ASP.NET Web API with Cross Domain AJAX Calls?

I want to create an API at www.MyDomain.com that is accessible from public websites www.Customer1.com and www.Customer2.com. These public websites display each customers inventory and do not have any login features. They will use AJAX calls to read data from my API.
How can I secure the API so that it can be accessed via AJAX from different domains but no one can access the API to be able to scrape all of my customers data and all of their inventory?
I have tried thinking of different solutions on my own but they would all either require people to login to the public websites (which isn't an option) or it would require some secret "key" to be displayed publicly in the browser source code which could then be easily stolen.
Any ideas would be greatly appreciated.
Thanks!
P.S. Are their any obstacles that I am going to run into using Javascript & CORS that I need to look into now?
Anything that is accessible without authentication from a browser is by definition insecure, so you can't stop that. Your best bet is to have to have a relationship with the owner of customer1.com and customer2.com - the server apps for those two websites would make an HTTP call to you and authenticate with your service. Going this way also avoids the CORS issues you're talking about.
If you've already designed the client functionality, you can still probably do it without much change to the javascript - have it point to customer1.com for its AJAX call instead of your API, and customer1.com would accept this request and just act as a proxy to your API. Aside from the authentication, the rest of the request and response could just be pass-throughs to your API.
You can use Microsoft.AspNet.WebApi.Cors.
It's just need add ONE line at webapi config to use CORS in ASP.NET WEB API:
config.EnableCors("*","*","*");
View this for detail.
The simplest way to provide a minimum security here is to provide some kind of token system. Each app has its own token, or combination of tokens which it must pass to the server to be verified. How you generate this tokens is up to you and other than being linked to app's access, doesn't have to mean anything.
Provide a way for each API implementer to open an account with you. This way you will know who is accessing what and in some cases you can block/stop service.
For instance, a token can just be an MD5 hash:
7f138a09169b250e9dcb378140907378
In the database, this hash is linked to their account. On each request, they send this token with what they want. It is verified first to be valid, then the request is fore filled. If the token is invalid, then you can decide how to deal with it. Either don't return anything or return an "access denied" (or anything you want).
One thing to avoid is having a single token for everyone, though this can be a starting point. The reason for this is if some unauthorized app gets a hold of this token and exploits it, you have to change the token for everyone, not just the app that somehow leaked the token. You also can't control if someone has access to something or not.
Since you listed ASP.NET, I can also point you to WCF, which is fairly complex but has all the tools that you need to setup a comprehensive web service to service both you and your clients.
I hope this gives you a starting point!
EDIT:
There are security concerns here in the case that someone leaks their token key somehow. Make sure that you setup a way in which the app/your service do not expose the the token in anyway. Also have a flexible way of blocking a token, both by your clients in you, if it so happens that a token is exploited.

Keep an API call private/protected

I'm working on a web app that is mostly static - just HTML/CSS/JS + assets. I'm using a Rack server (Thin, actually) to serve it.
While the app is mostly static, there are a couple of server-side needs that have cropped up along the way. Since the app needs to interact with those needs via JavaScript, I've added Sinatra to the stack to allow me to easily set up some routes to serve as a simple API.
One such API call is to send an email - the web app needs a way to send an email to users. I set up a route (/api/mail) that can be called with a POST that includes a JSON object, and Ruby will fire off an email (via SendGrid).
Here's my issue - by nature, these API calls are public. Most of the time, that is fine - but with the email API, I want to protect it so that nobody can just start sending malicious emails with a simple POST, posing as my app.
Problem is, I'm not quite sure how to authenticate this. The web app itself is the client, not the user, so a password or API key seems worthless, since anyone could just sniff out the POST header and grab the credentials that the app is posting to the API.
Is encrypting everything via SSL my only option, or am I missing some glaringly obvious solution?
At the end of the day, anything you do can easily be scraped. I would do some aggressive rate limiting by ip and session, don't think if anything else would be possible (or effective)

Categories