Are there security issues passing login credentials to REST API as data parameters in POST call? - django

I have a django web app with a RESTful API written using TastyPie. I want to allow my mobile app access to the API that uses username and api_keys, but have struggled to know what the best way to get the api_key back to the mobile client.
I am following the resource code provided here:
How can I login to django using tastypie
My question is if this is a secure method of passing a username and password as data parameters in a POST request. Should I be okay?
Here is an example of the post request:
POST to http://myapp.com/api/user/login with data { 'username' : 'me',
'password' : 'l33t' }.

While data sent over a POST request can be sniffed, that doesn't necessarily mean that you shouldn't be using it to submit user credentials to your RESTful API. So, to answer your question directly:
POSTing a username and password for authentication is not secure. It can be sniffed.
That being said, submitting user credentials in this fashion is something that in my experience is done quite often. A good practice is returning a remember token (or in your case API key) to the user once they have been authenticated. Aside from persisting sessions, the advantage is that if some malicious user gets hold of an API key, it can be reset easily without needing to reset the user's username/password (although it might be a good idea to do so anyway). Of course the downside is that remember tokens/API keys are generally stored in unsafe places like browser cookies/mistakenly in the source of some github repo.
So, is POSTing authentication credentials sniff-proof, no. Can you do it/is it done, yes.
Of course, you can see if HTTPS is an appropriate solution for you in this context if you require more security.

No, sending cleartext credentials is never secure. Anyone sniffing the traffic (including sniffing the traffic and dumping it all into a big logfile) will have the credentials.

Related

Can a user barge into django server as another user and perform operatn if he changes info in the frontend if we are using session authentication?

Hey guys I am confused and was thinking about this problem for sometime now, I am storing the current user's username in the session storage, and I have another page in which I use the stored username for an api call, it can be any requests.
Eg. a post can be deleted by its author only, suppose, the url is api/<slug>/delete and in the frontend I have enabled the delete button only for the corresponding user, what if he edits the front end page and changes it to his username or what if I use the stored username to check that condition?
And if he sends a delete request successfully from the frontend, does the django server able to determine that the user in the current session is not the real owner and has tweaked it in the frontend?
Ps. This might be a foolish question, but I am a beginner and quite confused.
Thanks.
Naturally, we would need some code to answer your question.
Will the following delete some other user's data?
A user passes a username from the client to the server
SomeModel.objects.filter(username=username).delete()
Will the above delete the user data whose username is what has been passed from the client? Yes.
You need to always verify and validate data and permissions on the server, and also you should consider using CRUD operations on the current authenticated user (since you are working with sessions), so you don't have to send the current user' username from client, if they are logged in, that can be validated with their session.
I'd advise you to read a little more on Authentication, sessions, ect. authentication in Django
Also, I see you are using A RESTful API, so I would strongly recommend using DRF

Advice how to implement a simple user login and authenication

We are in the process of building a simple Android application together with a simple back-end web server to allow the user to get some information form the server.
We need to login the user, to make sure he is authorized to view the data, but apart form that I do not think we have particular security concerns.
I need some advice on how we can implement the server to keep things as simple as possible.
For example, we could use something like this to make sure the user is authorized to see the data:
http://ourwebservice/user/password/viewsuchandsuchdata
Is that a good way of doing things?
Do you have any suggestions or comments?
There are many ways to secure web-services.
The simplest is possible "Basic Auth" (http://en.wikipedia.org/wiki/Basic_access_authentication). On every request, you send the user credentials in the "Authorization" HTTP header concatenated with ":" and base 64 encoded. To keep it safe, you need to make sure the connection to your web-server is using SSL (HTTPS), otherwise the user password could be intercepted.
Another "newer" solution is OAuth2, and in your case the "Resource Owner Credentials" flow. Instead of passing the user credentials on every request, you use them once to "exchange" them for a short-lived access token issued by your server. Then on any request to the web-service you pass that access token in lieu of authentication. The server must then verify that the token is valid and find out for which user it was issued. For more info see this article: http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified.
There are potentially many more "custom" ways of doing authentication...
Going the OAuth2 flow is probably more difficult but there are lots of open-source libraries out there to help you build a OAuth2 provider (http://oauth.net/2/). The advantage is that you don't have to store the user password on the device, which is safer (the less you touch passwords, the better).

embedded linux clients and authentication

I need to come up with a scheme for remote devices running linux to push data to a web service via https. I'm not sure how I want to handle authentication. Can anyone see any security risks by including some kind of authentication in the body of the request itself? I'm thinking of having the request body be JSON, and it would look like this:
{
'id':'some unique id',
'password':'my password',
'data':1234
}
If the id and password in the JSON don't match what is in my database, the request gets rejected.
Is there a problem with this? Is there a better way to ensure that only my clients can push data?
That scheme is primitive, but it works.
Usually a real session is preferred since it offers some advantages:
separation of authentication and request
history of requests in a session
credentials get sent only once for multiple requests
flexible change of authentication strategy
...

Authentication for Both Webapplication and WebService

I'm currently working on an application consisting both of a webapplication and client software. The client communicates via webservices, supporting both a SOAP and Protobuffer implementation.
The initial registration is done via the webapplication, which relies on username + password authentication later on.
After finishing the registration process, all features are also available via the client, which will only communicate via HTTPS. For authenticating webservice calls, I'm currently thinking about three possible approaches:
Including the username and password in every message. But is it really a good practice to include the credentials in every request, even though secured by HTTPS?
Providing the username and password in the first webservice request. The client then gets a token which is used for all future requests. (Note: It's not deemed acceptable to force the user to copy a server-generated token to the client application.) Only if the user revokes the token, he needs to send his username and password again for getting a new token. Such token based approaches seem to be quite common, for example Google, AWS and Rackspace are using them a lot. But does it really pay off in this scenario?
Hashing the password on the client sounds like a good solution. However I'd like to salt the encrypted passwords on the server-side. Adding requests only for fetching salts doesn't sound like an optimal solution or is it?
Are there any best practices or tips? I couldn't find too much information exactly for these requirements.
Currently I'd go with 2), but I'm not really convinced yet.
The project is based on Java, Apache CXF, Protobuffers and Shiro, but shouldn't have too much of an impact for the general question...
If you're only concerned by authentification and neither by confidentiality nor integrity, you can handle it by securing:
HTTP transport level, using HTTP BasicAuth (user+password on each message) + eventually HTTPS for confidentiality, however as you noticed (solution 1) it it is kind of old school and keeping user/password in local cache is not a big deal but cannot be advised.
Message level (the soap message) using Security Token for instance but I do not know Protobuffer
Application level (solution 2 and 3), that is the way Google, Amazon, Ebay and others are working. You will not ask the user to copy/paste his token, you will generate one from user/password
I would securing the application level using a token, since getting a salt from the server is almost like getting a token and does not add more security (a secured salt should be known from only you, and if channel is protected it mean getting the token from given password and username is secured as well).
A better but more complex solution would be usage of SSL certificates, available both in browser and client software.

How do I implement login in a RESTful web service?

I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.