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 !
Related
Frontend is Vue and my backend is an express rest api that pulls data from mysql. I want to secure both the frontend (login form) and backend api, but without limiting use of the api to just my frontend. I may want to use this api for other projects in the future.
What I'm strugging with is understanding how to have a user log in on the frontend but also give them access to the api without preventing future access to the api from other projects. I know I could set a JWT, but recently there seems to be a lot of "DON'T USE JWT!" articles out there, and I can understand why they might think this. Using cookies and sessions doesn't seem practical either without needing to create a session/cookie for each frontend and backend. Then I thought maybe using cookie/sessions for frontend, and having the frontend be authenticated with an API key to the backend API. This might allow other web applications to access the api while protecting it from unauthorized access.
Apologies for the lack of knowledge and seemingly rambling. I've been stuck on this aspect of my project for a while now. I know it's due to my poverty of knowledge on the subject. Any resources and points in the right direction will be greatly appreciated.
There is nothing wrong with JWTs, though it can depend on the implementation. The simplest way of doing it is just signing the JSON string with a private key. A little more complicated is base64 encoding it, encrypting it and signing only after that with a different key. And ofc. you need to send it through SSL. You need to add expiration time to it. Probably bind it to IP, browser, language, location, etc. too. If you want to revoke it, then you need to maintain a very small global revoked JWT database and remove it after it expired. You can add a JWT verification cache too, which spares you checking the signature for every request and which can be local too. If you want to avoid accessing it from Javascript code and probably leak it with XHR, then add it to a httpOnly cookie, though if you do so, then you need a CSRF token too. So I think all of the security issues are solveable with JWT too.
We need stateless communication between the REST client and the REST service, so if your frontend has a server side REST client, which uses for example JWT or any other method with Auhorization header, then it is perfectly fine from statelessness constraint perspective to do server side sessions with your frontend. As of the constraint itself, statelessness is needed for massive services with countless users global scale where handling server side sessions is an issue on its own, so better to move the stuff to the clients. These are typically social media services, search engines, global webshops, etc. If you have a limited user number, then you probably don't need this feature. Though using server side sessions between REST client and service would violate the statelessness constraint, which means you would not have a REST service. I don't think this is an issue. I mean it would be still a service, just not a REST service, it would work, would not scale as well as a REST service, but if this is what you need and it is simpler for you to implement it securely, then go on.
You can use API keys if you have some sort of revoke mechanism for those too. And keep in mind that API keys are server side stuff, so for mobile clients and in-browser application they are not good for identification, because they can be easily stolen by the users, so don't access your service directly from those with API keys just through a server. Another way is checking IP and using SSL to identify the clients, which is similar to using API keys, just more standard and the secret does not go through the communication channel. It really depends on your needs. If you have 3rd party clients, then you'll need OAuth too and let the users decide if they trust them.
Not sure if this helps.
By far the best thing you can do is adopt OAuth2. It has all the necessary components solve your problem and has ton of implementations.
The issue with JWT is that lots of people get it wrong. inf3rno does a good job accidentally pointing out many of the issues.
I'm using Firestore as a database for my website to store my data. I'd like to use Firebase cloud functions to use the cache, in order to limit my reading requests which are limited to 50000 per day.
The fact is, my users don't need to be authenticated to fetch some basic datas, and I'd like to know if you could figure out a way to proceed endpoint calls from only authorized application.
So far I've been thinking of creating my own "secret key" to pass as a parameter in my request and this is the only solution I found on the subject, but I know this isnt a real security as far as you can see the body of the request in the console. The only other solutions I found on the web would be to make sure users are authenticated to check their token, but I don't want to force them to get logged in to use my website.
I'm kind of disappointed that there are no clear ways to identify my application as a trusted one through firebase ecosystem... If you have any clue, it would be very helpfull.
It's not possible to fully protect an HTTP function to be called from just your app. Here's why:
Client devices should be considered compromised and under full control of a malicious user. As such, you can't trust any code on them, even if it came with your own app.
If you can't trust the code, then can't trust any information held in memory by that code.
If you can't trust what's in memory, then you can't trust anything passed to your backend. This means you really have no way of protecting it from malicious use at all.
Cloud Functions doesn't offer any solutions here, because there are no 100% bulletproof solutions that can be deployed with application code that sits on a user's device. What you're doing now might be "good enough" to prevent casual hacking, but bear in mind that anyone could get a hold of that token for the purpose of spoofing calls, and you'd never know that was happening.
This is why developers use Firebase Auth or some other auth mechanism, as a way to have an independent source verify the identity of the end user that can't be compromised by malicious client code, or at least not for more than 1 hour after an ID token is leaked.
I'm currently working on a mobile app that is built primarily with HTML and css, then run with phonegap. Part of the app requires that the user logs in and sync data with a backend. I want it done in such a way that once the user is logged in on their device they will remain logged in until they manually log out; they should only have to enter their information once. I've found some decent information when working with native code, but not so much that applies to my situation.
Right now, I'm not sure how to properly do this in a way that is secure. My first idea was to handle the login normally, then pass back a secret code that is stored both in local storage on the device, as well as in the database under the user that was authenticated with it. On subsequent requests it would pass this and allow access to the user that had a matching secret code. My question is whether this is secure enough to be practical?
I've also done a bit of research and it appears JWT is similar to what I'm looking for? My two concerns for this approach are:
How do I maintain the persistent login with this method.
What prevents someone from spoofing a connection? From what I know there's a secret string that is passed with each request to verify it. But, since the code in my app would be visible to someone who knew how to access it what is to prevent them from learning what the secret is and spoofing a connection?
I assume my questions with JWT are due to me misunderstanding some fundamentals of how it works. If it satisfies what I'm looking to do I'd much rather use a more standardized process like JWT as opposed to writing my own solution.
Am I on the right track with what I'm thinking above or am I way off base?
Your idea is correct and this is how it's usually done. It is a combination of cookie and session concepts. A 'session' is started on the server once the user logs in. The session is identified by a string (e.g. md5 format) and passed back to the client. The string is saved in a cookie on the client, and since cookie info is sent in each HTTP request, the server can assign that request to the session, thus considering your user as logged in. The signout process later basically consists of removing your cookie, and / or sending a request to the server to remove the session object.
In most HTTP server side frameworks there is an API used for sessions, so you don't have to reinvent the wheel. And yes, it is secure enough, as you don't usually base your security on this layer of transport, but rather on a lower layer by introducing https.
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
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