I'm trying to protect my Django restful api.
I got two clients :
my Django Front end application (Ajax requests on my server)
a python application using httplib to make its own requests
For now I'm using HTTP Basic Authentication to allow a client to consume a resource.
A basic username/password on a auth method managing a cookie session.
In production I ensure that my API is only available over https.
I tried to implement HMAC construction (because I don't want to put my password on the wire, but I have to store the secret at both ends). This work well with my other python application, but not with my Django Front end application since any user can see the javascript code.
I tried to implement an other authentication method because I don't want to really maintain a session state (not really REST).
curl -H "PERSONAL_SECRET_API_KEY: TokenKeyxxxxxxxxxx" https://localhost:8000/api/resource/
Here my questions:
What are the weaknesses of the basic Authentication System ?
Is there another method which suit my purposes ?
Thank you
Being prone to repeat attack is in my opinion the largest weakness of basic authentication.
Have you considered public/private key infrastructure? Client apps create public/private key pairs. Public keys are stored on the server. Client app encrypts its request with private key, server can decrypt it with client app's public key and send the response the same way.
Related
I have this question. I am quite new in this area.
I have web app.
This consist of services deployed on Docker engine.
The main services/containers are:
Frontend : React on Nginx web server
Backend (API) : Django, DRF on gunicorn on Nginx
For frontend I use Auth0 provider. It works as expected. If user is not authenticated/authorized it is redirected to login page.
Now I want also to "secure" my backend that it only would accept authenticated connections from frontend.
For backend (Django) I also have CORS enabled (django-cors-headers package), but I still can connect from my browser my-site/api/ and get the response.
Does anybody know which strategy should I use.
Should I somehow secure it using JWT tokens. Somehow pass it to backend in my request?
There is various ways of authorizing API calls from your front-end applications to execute actions on your back-end. These will tend to vary in a few aspects:
Complexity
Needing to know who sent the request
Access surfaces
Duration of access
Roles
and so on...
In this case if you have authenticated users on your front-end using AuthO then a JWT could make sense since using this method you can encode specific user data that will allow you to make the decision on your backend as to if that user should have access to that action at that time.
Here is an article explaining a few popular methods of authentication
I am making an Android application with a Django based backend.
The Django server has a REST API to serve user data which I want to protect. I only want my users to log in via Google (or FB which I'm going to implement in the future).
I am using django-rest-framework-social-auth to implement the authorization in the backend.
So the flow as I understand is like this:
The client (my android application), does the whole Google OAuth2.0
flow and obtains the access token
The the client then wants to
convert the Google access token with one with which it can access my
backend server API endpoints. To do this it calls the convert-token
API endpoint implemented in django-rest-framework-social-auth
Now that it has the API access token, it can include that in the header of all further API calls and receive the private data.
Now my concern is, the django-rest-framework-social-auth convert-token endpoint also needs the client-id and client-secret generated by django-oauth for the application. So I will have to store the client-secret somewhere in my mobile app, which entirely defeats the purpose of authenticating whether the request came from the app or not, because someone can decompile the apk and get the app and make token exchange requests on my app's behalf.
Is there any way around this? Is there a "standard" way to implement this which I don't know?
I am developing several Web Services that will be accessed by a mobile application. I have several requirements:
Each user will need to sign in with their own User ID and Password (the same User ID and Password they use to sign into the website).
Every Web Service request will need to be authenticated to ensure that the request is coming from the mobile app(s).
Every Web Service request will need to authenticate the user, since there is user-specific fucntionality built in, and access will need to be blocked if the user's account is disabled.
Let's assume that OAuth is not an option.
In order to ensure that Web Service requests are coming only from the mobile app(s), I am planning to use HTTP Basic Authentication in IIS (the mobile app(s) will need to have a User Account setup in Windows Server and the mobile app will need to store the User Name & Password and pass these in the header).
Next is the User Authentication for each Web Service request. Would it be suitable to encrypt the User ID, Password, and some shared secret key (a "pepper", of sort) with AES-256, pass that encrypted string as a parameter with each request (over HTTPS, of course), and then decrypt and parse it on the server to authenticate? This is the existing plan, but something just doesnt seem right about it - like it's not "secure enough".
What else can I do to properly authenticate users for Web Service requests?
I recently went through this problem and asked opinions from a group of senior people about how they solve the problem. Opinions were varied, but one consistent feeling is that your level of security depends on the use case of your application. Are you doing online banking or storing medical records? Then your security needs may be quite high. Social networking? Maybe not so much.
Basic Authentication is generally fine when encrypted over SSL, ColdFusion works well with it. If you use Basic Auth, make sure to encrypt your traffic with 1024-bit keys or better. Don't authenticate every request with username/password - that's unnecessary. Authenticate the first request, set a session token, and rely on the session token for your identification of users.
Set a polling mechanism from the client to the server to keep the session alive - set the session timeout to 30 minutes and the polling frequency at 25 minutes, for example. Otherwise you may need to re-authenticate expired sessions. Again, how you approach this part of the solution depends on your paranoia level, which depends on what kind of data/app you are dealing with.
Cookies, and therefore sessions, should work fine in iOS apps. If you use sessions to verify identity after authentication, make sure your session cookies are memory-only (set at the server level).
Check the SSL implementation of your server against the Qualysis SSL Test:
https://www.ssllabs.com/ssltest/
The report will give you a surprising amount of detail about the strength of your SSL implementation.
Lastly, consider implementing two-factor authentication to combat password theft.
If you ignore the SSL advice and plan on encrypting your password and communicating over an insecure channel, look at the Kerberos protocol for a well-known example of how to authenticate securely:
http://en.wikipedia.org/wiki/Kerberos_%28protocol%29
Yes, you can use Basic Authentication but that means the client will need to store the username/password in plain text, and also send them over in plain text. Sending part is sort of fine if it's under HTTPS, but storing username/password in plain text may not be a good idea, unless you're using some secure key store.
Let's assume you have decided that Basic Authentication is the way to go, and you want to make use of the official CF way of supporting that, then you can use CFLOGIN.name & CFLOGIN.password. You may also check out Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion. In the remote cfc side, always validate the username/password, or return some sort of token and asks the client to use that token going forward. The token can be cfid+cftoken if you like, or even roll your own that never expires. If you use cfid+cftoken, and send them over as cookie or in body along with your web service call, I believe you can resume the session if you so choose.
We have a central RESTful webservices application that exposes data to many different clients (parsers, web applications, touch applications, etc). The clients have different means for authenticating users, some LDAP, others not. Regardless, the RESTful application leaves the authentication of the end-user to the client, and simply authenticates the client making the request. The client will have a username and password in LDAP, along with a list of acceptable IP addresses from which the client can access the RESTful application.
Here is the tricky part: the RESTful application must audit every request with the end-user's username. Furthermore, in certain circumstances (depending on the client) the RESTful application will need the end-user's username and password for accessing a third-party application. So, every request from the client will have authentication credentials for the client itself and the end-user accessing the client.
Here comes the question. Would it be best to put the client's credentials in Basic Auth, and pass the end-user's credentials via an encrypted SALT request parameter? Or, should the client put both sets of credentials in the Basic Auth (i.e. system~username:systempwd~userpwd) and parse them out into two sets of tokens that are then authenticated. Or, another solution that is better than either of these two?
This sounds pretty much like OAuth2's "Resource Owner Password Credentials Grant" - see https://www.rfc-editor.org/rfc/rfc6749#section-4.3. You pass application/client credentials in the Authorization header and client information in the body encoded using x-www-url-encoded. Do that once at the beginning of the session and then depend on a bearer token in the authorization header after that. All of that is described in the RFC. Remember to use SSL/TLS to encrypt the credentials.
This is a similar situation to the one raised in this question:
Javascript Calling a Rest API with App Name and App Password - How Can i Secure it
Here is the architecture overview:
The site is Html5/jquerymobile
It contacts what I call a "Wrapper" service.... This is a REST API I wrote in C#, to contact another 3rd party REST API. I do this because there are credentials in the Header and the API uses Basic Authentication. Credentials are therefore not publicized as they are only known server-side.
My "Wrapper" service does not currently implement any additional security. It is currently accessible from anywhere. The easiest and quickest way to lock it down is to restrict by IP, so no other IP anywhere except the server can actually contact my wrapper service.
The questions:
Is the locking by IP the only way to ensure that the API won't get hammered if it was otherwise accessible from anywhere?
If I convert this using Phonegap (which I have... and deployed successfully on Android), obviously the native app won't work if the web service is restricted.
Is there a way around this so I can allow traffic only from the mobile app, and not from any other source? I'm thinking along the lines of MD5 hash or something that could be sent to the wrapper API.. but unfortunately I'm thinking that info can easily be "sniffed".
Is my only viable option here to release the app as a web app, forcing browser use, thereby removing any concerns about allowing my web service to be hammered??
I believe the answer to this is a combination of a user token and encrypting the message through SSL.
The server can issue a valid user a token so we can identify him in future requests.
Encrypting it via SSL will ensure that this token cannot be sniffed.
https://security.stackexchange.com/questions/12531/ssl-with-get-and-post