I have a single page web app that I made using (html5, bootstrap, and) angularjs. I want to be able to securely register and sign in to the web page, and then I would have access to the information associated with my account on MySQL. Can someone give me a good starting point? I feel like I could do it myself but I'd make a mistake, and thus create a security loophole. It also seems to me as this would already be done in angularjs.
Note: I don't need anything fancy with different permission levels. Each user simply has full control over his/her own data.
Not sure about the technology you will be using on the server side. This is important to know as this is where the authentication / authorization "magic" will take place.
One possibility is to use Bearer Token authentication scenario, which works roughly as follows:
The client send a request to an authentication end point on the server (for instance, sending username and password)
The server authenticate and sends him back a authentication token, if the user has been successfully authenticated.
Any subsequent request made to the server should include the bearer token in the request header that the server will verify before giving access to the resources.
The above is an overly simplified summary but should give you a starting point for reading as you requested.
Please note that:
1- No authentication should be made on the client side as this can easily be hacked.
2- Authorization to resources could be made on the client side to improve user experience, but MUST also be made on the server side for the same reasons as 1
3- Make sure that all transactions are made with https protocol, otherwise any effort could be vain.
Hope this helps getting you started
Related
So there's a few things I'm confused about with connecting a frontend to a backend part of a website, and I can't seem to find anything online about it.
Say you have a backend API, which if you had a endpoint which deletes a user, for if they want their account deleted, then what's stopping an attacker from just pinging the end point with a user ID and then it'll delete the user? I've heard that you can use like a password or something similar to stop fake attacks, but what's stopping somebody from just looking through the source code to find the code that is sent along with the request? Do you just use a user ID that would be hard to guess? But if so, why couldn't they just brute force user ID's?
Should the backend be run on the same domain as the frontend? Should you just have to use https://example.com:3000, or should you have to use the ip of the server and send data to https://000.000.000.00:3000?
Any help would be appreciated. I don't know that much about full stack development since I'm just now starting to learn, however what people say seems to be a really insecure way of doing it.
1 - You can safe your backend with a JWT signed by User/Password to ensure that only signed users are calling to your API BACKEND, in your server you can use a service of DDOS and a Firewall to avoid this kind of attack.
2 - a Backend/Frontend of a website can be anywhere in web separated or not, in a home computer or in a cloud service, you must ensure that your Frontend can reach your backend wherever it is. Ofcourse you can do it in a single webserver, and its better for many reasons, such as process of deploy, performance of the website and safety.
and you can always learn more in documentations.
https://laravel.com/docs/9.x/csrf
There are a csrf token stops unauthorized requests from passing .
a good example in Laravel Documentation
I hope it was useful !
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.
The Problem:
Serving a secure API to a client side app using only a local authentication strategy. The red arrows are part of the knowledge gap.
Context:
That is --- client.example.com is making a POST to api.example.com/login where on success client.example.com can gain access to a GET service like api.example.com/secret.
An idea!
Implimentation of OAuth 2.0 with hybrid grant type sitting in front of API.
Why hybrid?
It wouldn't be an Implicit Grant Flow aka Client-Side Web Applications Flow because there is no redirection to API server too grant access token. (i.e.) "Is it ok for so-and-so to access your data?"
It wouldn't be a Resource Owner Password Flow because a Client ID and Client Secret are passed along with the request so it's assumed the client app is server-side.
OK... so what about a little bit of both?
What if we used a CRSF token on page load of client-side app, and POST it with user credentials too OAuth 2.0 authentication endpoint to exchange for access token? You would authenticate each subsequent request with the access token and CRSF token after a successful login.
A good Node.js OAuth 2.0 library I found:
https://github.com/ammmir/node-oauth2-provider
Help Me!
I can not find a working example of an authentication measure that solves this problem! Point me in the right direction?
Ultimately, the goal here is too authenticate a client side app to a REST api using CORS with a local strategy --- i.e. username & password --- even if the convention above isn't possible.
To Accommodate Bounty:
This is a client side app, so let's stay trendy.
I'm looking for a working example using the Node.js OAuth 2.0 seed above for the API/Auth server and a front end framework like Angular.js or Backbone.js to make requests.
The example should match the context described above.
I'm working on an app with a pretty similar architecture though the services are .NET Web API rather than Node and we're using DotNetOpenAuth for the OAuth provider. Rather than the hybrid approach you're suggesting we're doing the following:
x.com serves up a login page
login page POSTs back credentials to x.com
server side logic at x.com combines client_id and client_secret with the credentials to submit a token request (resource owner password credentials grant that you've
mentioned above) receiving back both a temporary access token and a
refresh token
the refresh token is encrypted into a cookie issued by x.com
both the cookie (with encrypted refresh token) and the temporary access token are then sent to the browser
the client app (angular in my case) can now use the access token to hit api.x.com for services (It appears you're well aware of the limitations of CORS... we hacked a version of angular's $resource to facilitate this but it wasn't pretty since we wanted to use all HTTP verbs and support IE9)
when the access token expires, the client side app can request a new access token from x.com
server-side, x.com decrypts the cookie to get at the refresh token and issues another oauth call for a new access token
This is fairly high-level but hopefully gives you a sense for how to tackle your situation. In my case, and it appears in yours, we didn't want to use session state or a database to store the refresh token but obviously exposing that to the browser introduces security concerns so the encryption of the refresh token is important (among other security considerations) and the use of the cookie eliminates the need for session state or other persistent storage on x.com.
Not an answer running for the prize. Just my 2 cents :)
On my web server,
I do my authentication through a rest call with login/password with basic authentication over https. This call delivers a key to the client (a one page web app).
Then every subsequent REST call is signed with the key. The server checks that the signature is correct and everything still happen in https.
This mechanism is quite used I believe.
I don't see the issue with cross domain. I have a single source anf if I need something from another source, I'd use JSONP.
I use nginx as an https->http forwarder.
Not sure how it competes with an OAuth2 solution.
I've built this example using Node and PassportJS to show how to authenticate the users with Facebook or Local Strategy. Both sides are on different domains as you described and it requires CORS enabled.
GitHub: https://github.com/pablodenadai/Corsnection
Live demo: http://corsnection-client.herokuapp.com/
I can't promise that I have time to write working example but I can show you 2 paths :)
The biggest deal is CORS. After you solve that problem it is easy to use $http service. So, first and probably easiest may be to configure reverse proxy in x.com webserver which points to api.x.com. I wrote article here
Second approach is better, and created for exactly this purpose, to authorise specific domain to use your resource. It involves a bit of coding in api.x.com so you don't have to change anything in new web applications served in other domains. You simply need to authorise CORS requests in api.x.com service.
Create table in database where you can manage list of authorised domains
Add in that table record "x.com"
in api.x.com add request filter/interceptor what ever tech term you use for method which should be invoked after request is handled and add in response Access-Control-Allow-Origin: x.com if request comes from x.com (in other words check in request header refer value match to any value in table above and put that value in Access-Control-Allow-Origin response header).
That is all :) After this if you know how to use $http or jQuey.ajax you will be able to POST/PUT/DELETE/... any request to api.x.com from any authorised domain in just few minutes.
I very similar idea using vinilla js web app and cross domain authentication to GAE backend or OpenID connect.
The web app is run on CDN. When click login link, it goes to respective login server and redirect back to the web app (with XSRF security token and HTTPS only cookie). Login server accept cross domain request with credentials. XSRF token has to be set (in header) with every request. cookie is set by the browser. Since it is HTTP only cookie, JS cannot read it. The technique is very secure.
Once login, you can get secure assess from login server.
For detail description, you can find here and open source repo here.
https://developers.google.com/youtube/v3/guides/authentication
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=21302922996.apps.googleusercontent.com&
client_secret=XTHhXh1SlUNgvyWGwDk1EjXB&
refresh_token=1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ&
grant_type=refresh_token
The developer documentation lists a way to refresh an access_token on the back end. Is there a way to do this with the front end javascript calls?
If you're using the client-side web applications flow, which is appropriate if you're writing code in JavaScript that runs in the browser, then there's no way to get back a refresh token and periodically refresh it to get an access token. The accounts.google.com server doesn't support CORS, for one thing, so it's not possible to send the HTTP POST refresh request from your JavaScript.
What you can take advantage of is the approval_prompt=auto parameter behavior, which means that if a user has previously authorized access to your OAuth 2 client id for the same scopes, requesting a new access token can be done without any user intervention. So you can effectively get new access tokens indefinitely.
I'd highly recommend letting the Google APIs JavaScript client library handle this for you. In addition to the samples in the docs, you can take a look at this simple example which shows how you can handle the OAuth 2 flow in a way that only requires initial authorization.
I could do with some help on my REST API. I'm writing a Node.js app which is using Express, MongoDB and has Backbone.js on the client side. I've spent the last two days trying to work out all of this and not having much luck. I've already checked out:
Securing a REST API
Securing my REST API with OAuth while still allowing authentication via third party OAuth providers (using DotNetOpenAuth)
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://tesoriere.com/2011/10/10/node.js-getting-oauth-up-and-working-using-express.js-and-railway.js/
I want to keep my backend and frontend as separate as possible so I thought about using a carefully designed REST API would be good. My thinking is that if I ever get round to developing an iPhone app (or something else like that), it could use the API to access data.
BUT, I want this to be secure. A user has logged into my web app and I want to ensure my API is secure. I read about OAuth, OAuth 2.0, OpenID, Hmac, hashes etc... I want to avoid using external logging in (Facebook/Twitter/etc) I want the registering and logging in to be on my app/server.
...but I'm still confused here. Maybe it's late at night or my brain is just fried, but I could really do with some steps on what to do here. What are the steps for me to create a secure API?
Any help, any information, any examples, steps or anything would be great. Please help!
In order of increasing security / complexity:
Basic HTTP Auth
Many API libraries will let you build this in (Piston in Django for example) or you can let your webserver handle it. Both Nginx and Apache can use server directives to secure a site with a simple b64encoded password. It's not the most secure thing in the world but it is at least a username and password!
If you're using Nginx you can add a section to your host config like so:
auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;
(Put it in your location / block)
Docs: http://wiki.nginx.org/HttpAuthBasicModule
You'll need to get the python script to generate that password and put the output into a file: http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt
The location of the file doesn't matter too much as long as Nginx has access to it.
HTTPS
Secure the connection from your server to the app, this is the most basic and will prevent man in the middle attacks.
You can do this with Nginx, the docs for it are very comprehensive: http://wiki.nginx.org/HttpSslModule
A self-signed certificate for this would be fine (and free!).
API Keys
These could be in any format you like but they give you the benefit of revoking access should you need to. Possibly not the perfect solution for you if you're developing both ends of the connection. They tend to be used when you have third parties using the API, eg Github.
OAuth
OAuth 2.0 is the one to go with here. While I don't know the underlying workings of the spec it's the defacto standard for most authentication now (Twitter, Facebook, Google, etc.) and there are a ton of libraries and docs to help you get those implemented. That being said, it's usually used to authenticate a user by asking a third party service for the authentication.
Given that you doing the development both ends it would probably be enough to put your API behind Basic HTTP Auth and serve it over HTTPS, especially if you don't want to waste time messing around with OAuth.
Here's a different way of thinking about it:
Let's suppose for a moment that you're not using an API. Your user logs into the app, providing some credentials, and you give a cookie or similar token of some sort to the user, which you use to identify that user has logged in. The user then requests a page containing restricted information (or creating/modifying/deleting it), so you check that this token to ensure that the user is allowed to view that information.
Now, it sounds to me that the only thing you're changing here is the way that information is delivered. Instead of delivering the information as rendered HTML, you're returning the information as JSON and rendering it on the client side. Your AJAX requests to the server will carry that same logged-in token as before, so I suggest just checking that token, and restricting the information down to 'just what the user is allowed to know' in the same way.
Your API is now as secure as your login is - if anyone was to know the token necessary for accessing the api, they would also be logged into the site and have access to all the information anyway. Best bit is, if you've already implemented login, you've not really had to do any more work.
The point of systems such as OAuth is to provide this 'logging in' method, usually from a third party application and as a developer. This would potentially be a good solution for an iPhone app or similar, but that's in the future. Nothing wrong with the API accepting more than one authentication method!
The answers so far do a great job of explaining, but don't give any actual steps. I came across this blog post that goes into great detail about how to create and manage tokens securely with Node + Passport.
http://aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/
Tips valid for securing any web application
If you want to secure your application, then you should definitely start by using HTTPS instead of HTTP, this ensures a creating secure channel between you & the users that will prevent sniffing the data sent back & forth to the users & will help keep the data exchanged confidential.
You can use JWTs (JSON Web Tokens) to secure RESTful APIs, this has many benefits when compared to the server-side sessions, the benefits are mainly:
1- More scalable, as your API servers will not have to maintain sessions for each user (which can be a big burden when you have many sessions)
2- JWTs are self contained & have the claims which define the user role for example & what he can access & issued at date & expiry date (after which JWT won't be valid)
3- Easier to handle across load-balancers & if you have multiple API servers as you won't have to share session data nor configure server to route the session to same server, whenever a request with a JWT hit any server it can be authenticated & authorized
4- Less pressure on your DB as well as you won't have to constantly store & retrieve session id & data for each request
5- The JWTs can't be tampered with if you use a strong key to sign the JWT, so you can trust the claims in the JWT that is sent with the request without having to check the user session & whether he is authorized or not, you can just check the JWT & then you are all set to know who & what this user can do.
Node.js specific libraries to implement JWTs:
Many libraries provide easy ways to create & validate JWTs, for example: in node.js one of the most popular is jsonwebtoken, also for validating the JWTs you can use the same library or use express-jwt or koa-jwt (if you are using express/koa)
Since REST APIs generally aims to keep the server stateless, so JWTs are more compatible with that concept as each request is sent with Authorization token that is self contained (JWT) without the server having to keep track of user session compared to sessions which make the server stateful so that it remembers the user & his role, however, sessions are also widely used & have their pros, which you can search for if you want.
One important thing to note is that you have to securely deliver the JWT to the client using HTTPS & save it in a secure place (for example in local storage).
You can learn more about JWTs from this link