I'm working on a Single-Page-Webapp (SPA) with angularjs (JavaScript) in the frontend and a php rest api in the backend.
I do a lot of ajax calls to the server for example to submit a new story. There the security question came up. The server needs to identify the request. Since it's an SPA only one client (the frontend) should be have the permission to do this request.
I've been googleing for days to find a way to identify the client. I saw that i could send a clientid in the header of the ajax call but that would not be secure since the frontend is in JS and all the JS code can be seen by the user.
Example:
$http.post("some/url", somedata, {
headers: {
"ClientId":"someidforthisclient"
}
});
a hacker could look into the JS code and copy the ClientId. With that he could make ajax calls and the server would think this request is valid.
So my question is:
How can i identfiy the client in the server but with the guarantee that the ClientId (or a security token etc.) can not be seen by the user?
How can i identfiy the client in the server but with the guarantee that the ClientId (or a security token etc.) can not be seen by the user?
You cannot. It is absolutely impossible. For all intents and purposes, as far as the server is concerned, the client application and the user of it are one entity.
You have to trust your users, not their software.
All you need to do is expose the api of login and registration to the users. For any other api access, first you need to authenticate if user is logged in/active.
For authentication you can store user credential in session :
Now user credential will be sent to the api on each request and you will be able to authenticate before processing the request.
You should at the same time encrypt user credential being saved in session so that no one can read that from browser console.
Related
I have a CodeIgniter App that is made of 3 parts:
The API, basically is a separate entity, with its own location
The CodeIgniter back-end that renders the pages
The FrontEnd of the app, mostly jQuery.
I have a login system based on session and cookies. Basically the authentification data is stored on the client (browser).
A user authentificates with email and password. The backend looks for a authentification cookie and knows if it is logged in or not. If I make an AJAX request to the API directly, the API also knows if the user is authentificated.
Problem: I want to render some data server-side (That means I need to make a call to the API from the backend. It's a server to server communication. They are located on the same machine. ).
The API tells the backend that it's not authentificated, because obviously no cookie is set on the backend.
How do you pass authentification data from backend to api?
I might pass the userID via a secure endpoint that can be accessed only via the server to server communication, but I don't like the idea.
Any solutions to this? I read about oAuth and JWT but don't understand how they might help me.
the API should be built on top of the back-end. meaning the request is handled by API, then activates a function in the back-end and sends a response back to the client who sent the request(according to the result of the function in the back end). JWT json web token, is a token provider which means once you log in you get back a token "string" that is stored in the data base, in the request for the API you add the token to the header named Authorization instead of sending user and password everytime and you can extract the user info out of the token itself.but still there is need to check the validity of user and pass somehow at the first time.
basically you should send from client to API, API to server and then for response server to API and API to client. by server i mean back-end.
I think it's important to say that I don't have any experience in the technologies nominated below, I have some idea what is going on, I've googled a lot, but still - more I google more dumb I feel. :)
Making an app in Ionic 2, users of this app can read/write data about themself in DB.
I am using Wordpress as backend, actually users will change values in the table that was created by some Wordpress plugin.
First problem - I have no experience at all.
Second one - I must understand which user is knocking to the server.
Because user can change only his own data in DB.
I've solved it by creating a script that checks GET request from app & that request has a param with user nickname, so I have turned this script to template and assignined it to the page. ( template was first thing that went to my mind, if you have better idea - please tell me how to do it better! ).
Well now I knew who it is, but I disliked that this so unsecure!
Its only GET request with user name in it and changes to bring into DB.
NOT GOOD.
I've thought that I should send not only nickname but also some kind of a password, so I can check if the user is actually genuine user, well, you know.
But knowing nothing about security, didn't know where to start so I've started googling.
I've find out that there is 'Basic Authentication' - disliked it because password is verry simple to decode (base64) and you must send it with every request (not safe).
Then I thought about crypting pass with strong algorithm like bcrypt & then send it with the request. Disliked it too - because at the end you are always send a password even if strongly crypted.
Now I've started to look in the direction of Auth 1.0
(because saw that wordpress has a plugin for it, I know little about wp however).
But after all I am not so sure that I am doing things in the right way.
I must finish many things, but I am stuck with this security issue and I don't know if it's my paranoia and there is simplier ways to accomplish what I want to do.
Don't have much time, don't want to waste time anymore.
Please, someone who is pro in this stuff give me an advise how to do this thing in the right way!
because I am going crazy with that stuff.
The best practice is to issue an access token from your server to your (or even third-party) client application by the following steps.
A user uses a client application.
The client application asks the user whether to use your service.
The user answers "yes".
The client application opens the authorization page of your service using a web browser. In other words, the client application makes an authorization request to your authorization server.
The authorization page explains to the user that the client application is requesting some permissions and asks the user whether to approve it or not.
The user inputs his/her ID and password into the login form in the authorization page and then presses the "approve" button.
Your authorization server authenticates the user and issues an access token to the client application.
The client application accesses a Web API of your service with the access token.
The Web API of your service checks whether the presented access token is valid or not.
If the access token is valid, the Web API returns a successful response to the client application.
RFC 6749 (The OAuth 2.0 Authorization Framework) defines 4 flows to issue an access token. Check the specification.
I am currently implementing an OAuth authentication 3 legged strategy using 2.0. I have come across a problem:
What's the best way to remember the client's session when logging in using Oauth.
Currently what I'm doing is setting a cookie on the client that matches my session ID on the server. This is of course equivalent to a normal cookie session based login. Then in the session, I keep track of the access token that I got when I used the Auth Code and exchanged it for the access token.
As you can see, state is kept in sync between the client and the server via the cookie/session id, and the access token is kept only in the server and in relationship to the session id.
However I've read that this is insecure, and that OAuth should be stateless (restful) style, so cookies should not be required, especially if the client is a machine client and not a browser client. Some resources have mentioned that the client should store all the necessary credentials in order to authenticate any request to the app. Does this mean I should store the access token in the browser's header? What about the auth code from the redirect, should this be stored on the browser's header as well? (And should these codes/tokens be encrypted/signed on the browser's headers) (and how would you do this using PHP?)
Resources like this: http://sitr.us/2011/08/26/cookies-are-bad-for-you.html says a client side rich javascript app could keep track of the access token and pass it in on every XHR request? But of course not every client is a javascript app such as machine clients.
You should not store the token in a regular session.
The idea of it being stateless is that each request carries all the required validation information.
Of course this may require more work on the client side in order to ensure all requests carry all the required data.
One of the benefits of REST's statelessness is that it is simpler to have a distributed implementation. Every request has all the necessary data so you don't even need to hit the same server twice, each server can validate on its own.
I'm writing a RESTful Webservice with the Slim Microframework and use GET for reading data from a mysql database (select query) and also POST/PUT/DELETE for insert/update/delete rows in the database.
My question is now, is this not a big security issue if everybody is able to write or delete data in the database? But how could I prevent this, I thought the ST in REST stands for state transfer (so the webservice is stateless), which is a contradiction to a state like being logged in or not. And if I would pass some login data with the client which is allowed to write in the database, couldn't a bad guy catch the logindata and fake requests with it and for example delete all entries?
So, whats the normal way to go with this, the only Slim Framework examples I had found always show the route examples, but not how to secure it.
Are there also some opportunities in the Slim Framework to implement this what I need? It should be as easy as possible and the request should be responded nearly as quick as without an authentification or similar. There are no sensitive data like passwords, for me it would be enough that not everybody with a cURL commandline tool can delete all rows or things like that.
Would be great if anybody could explain me what to do and/or give some examples. I also need to know, what I maybe will need to change at the clients which are allowed to send the requests.
Lots of thanks.
Each request has to be authenticated and authorised.
People often get tied up with the word 'stateless'. This really just means that from one request to the next, the RESTful service has no prior knowledge of the users state.
BUT, the service is obviously allowed to be aware of the authenticated user that has just made a request, else how would it decide if it should allow access?
Therefore, you can 'store' the authenticated user in some variable during each request. Then it's up to you how you use this information to authorize the request.
I like to keep it simple and have all my users as a resource in my URI chain. They make requests like users/{username}/someresource.
I authenticate using http basic authentication (over SSL) and authorise based on the URI. If the request failed authentication, its a 401 Unauthorized Request. If the URI {username} and authenticated {username} do not match, the request is a 403 forbidden. If it is authenticated and authorized, the request is allowed (http code dependant on http verb)
Now that's the web service covered, now on to the web service client. This of course HAS to store state, otherwise your user would have to log in every time they make a request.
You simply store the users session in the application (as per normal session management) with the addition that you store the username and password (encrypted of course) in the session. Now every time a request is made, your web service client needs to retrieve the username and password, and send it with the request to your web service.
It will be stateless, in the sense that there won't be a session or a cookie, really. You'd normally issue out a key that would be required for INSERT/UPDATE/DELETE.
It is then up to you to pass the key with each request and to determine when a key should expire.
It would be as safe as normal http authenticated sessions. These use a cookie etc to authenticate the connected user to the stored session state.
A stateless service would be no different - the token is passed to the service just as a token is stored in a cookie for normal http. If you are worried about sniffing (IE man in the middle attacks) you would secure the link via SSL.
The authentication token generated by the service would be encrypted and would include a salt which is also verified on the server for each request. You could also limit the session time to suit your paranoia, and also check changes in source IP, user agent etc and expire the user's token if these change.
I recently ran into similar problem. As recommended by people here, I have decided to go with OAuth Authentication.
I am using HybridAuth A php wrapper for OAuth and out of the box sign in solution for Facebook, Twitter, Google, LinkedIn, etc.
I am developing a mobile application using PhoneGap which will communicate with a server(PHP) via ajax requests.
On the server side(PHP)
Something like https://example.com/retrieveData.php
will get the user id via $_POST['user_id'] and return some sensitive information about the user as JSON.
And on the client side(PhoneGap-Javascript)
that JSON output will be parsed and will be used in the application.
My concern is that if someone steals this url ( https://example.com/retrieveData.php ), he can manually send fake post requests and can steal the returned user information?
How can I secure this communication?
My concern is that if someone steals this url ( https://example.com/retrieveData.php ), he can manually send fake post requests and can steal the returned user information?
You are right to be concerned. Anybody can send a message to that URL, and get the result unless you check some part of the request that authorizes the request.
For example, you could authenticate to check that the request comes from the user and then authorize the request based on the idea that the user should have access to that info.
Alternatively, you can authorize based on something that only a valid requestor would know via a shared secret and rely on the https part of that URL to prevent shared secrets from becoming public. You give out the secret to trusted partners, and when you generate a web form via PHP (also protected via HTTPS), you include a hidden input containing the shared secret. This is how XSRF protection typically works.
You should think about the following:
Who should legitimately be able to reach this page? Logged-in users interacting via your phone app, partners who can protect a secret, web API users?
What credentials do they have for using other parts of your server? Log-in cookies? XSRF tokens? Partner tokens?
What parts of your app are sent only over secure channels like https?
If all of (1) is satisfied by some subset of credentials in (2) and those credentials are only ever sent over (3) then you just need to check (2) in your page. Otherwise, you need to rework your application architecture until that is true.
OWASP has a Guide to Authorization that might come in handy and they also have a number of pages on reviewing authorization code but most of the examples are not PHP specific.
Of course he can send any post request he wants. The only possible way to get around this is with authentication that the server knows about, i.e. the client has to send you something hard to guess and that starts a session in the server.
As other answers suggests, following is the strategy to make your webapp more secure :-
The most basic rule, use secured protocol(https)
Authenticate
your user through username and password
Most of the
features/operations of your app primarily must require user to be get
authenticated.
Apart from authentication, Maintain Access Control
List for your app, which decides authorities each user role
have(Assuming that you divides your users into different roles).
Prior to performing any operation on behalf of user, check if user is
authorized to do so.
Don't rely only on client-side validation.
Perform validation at server side also.
Send csrf_tokens along
with your response, along with session cookies.
Never send any
confidential information in cookies.
Hope it helps.