API-Security-Checklist
API-Security-Checklist copied to clipboard
why no basic auth?
I agree. Maybe the recommendation should be, "Don't use basic auth over non-SSL connection".
I'm wondering, How to make a secure user-pass authentication with JWT?
JWT is just a token format. Assuming a non user based call.. Check out the Oauth2 Client credential grant flow (ex: Twitter ) as it defines with passing client secret to an authorization server and getting an access token (jwt). (Edit to clarify non user flow)
@felickz
OAuth2 is for Authorization, not Authentication.
There is a few issues with Basic Auth.
- The password is sent over the wire in base64 encoding.
- The password is sent repeatedly, for each request.
- There is no advanced protection ( Request Timestamp , Nonce , TTL ) to avoid popular attacks like Reply-Attack.
So using HTTPs can help , but not for so long.
The password is sent over the wire in base64 encoding.
I think that base64 encoding is just to avoid śóḿé cháŕácters
that could be broken at some point. If you are using SSL, it doesn't matter. Anyway, I agree with some other mechanism to encrypt those credentials, but it's not an issue. If your SSL certificates have been stolen or broken, you know, you will have a lot of critical problems even if you are using the strongest encryption algorithm.
The password is sent repeatedly, for each request.
Yes, you're right. I've thought basic auth in a login form and after that using some token instead of the password. Sorry, I didn't clear.
Thanks for the contribution, It'll be useful to see different viewpoints!
The password is sent repeatedly, for each request.
This is correct, but I think the downside of using basic authentication should be explained more clearly, because when an API just uses basic auth as some kind of "simple container", where API users just put in their API credentials, e.g. the password is just a token and not the "real password", basic auth IMHO might be still a suitable way (see stripe) to provide authentication to API users.
As we've recognized, that many of our customers are overwhelmed with other authentication types, we're still using basic auth, although as a "simple container" for authentication, because this reduces our support effort a lot. Unfortunately there's a number of customers who don't want to learn something new or are so lazy, that they just scan the docs, decide "...too complicated..." and send us their source files with the demand as an one liner "...integrate it for us!". With using basic authentication the chance is greater that they already know/used it.
We as developers often think "...if you don't understand it, f*** off..." but this attitude doesn't work, because the customer pays our bills and thus also me.
The password is sent over the wire in base64 encoding. The password is sent repeatedly, for each request.
Same applies for JWT, just s/password/token/
.
Same applies for JWT, just s/password/token/.
Token-based systems are generally better than repeatedly passing around passwords because they can be regularly expired and rotated, limiting their usefulness to an attacker who can eavesdrop successfully. In many situations they also have limited permissions compared to the parent account. And you get additional auditing of knowing who's making requests (or who was compromised). And if there's a compromise, you can rotate one app's token without affecting others'.
At least it is clear to me that some clarifications should be added.
I believe it is secure enough to use Basic Auth (over SSL, obviously) to trade username/password for a token only for the first time, and use the token for any subsequent requests. If even this were to be insecure, any HTML login form with username/password fields would also be insecure.
@yuki24 In the way you said it it seems ok , but no one using it like this , they use username/password combination with every request so it's a bad habit. and if you are using basic auth for only to exchange for token , you will face some challenges when it comes to token expiration and the algorithm for token generating and validating. So Its good to abandon Basic Auth and adobt more mature one.
In the way you said it it seems ok , but no one using it like this
I actually do use basic auth like this. Client sends basic authenticated POST request to /token
endpoint. The request usually includes requested scope. This endpoint returns a token which is then used as in Authorization: Bearer
header for subsequent requests.
This is almost exactly the same as how OAuth 2 Password Grant works and works quite well for m2m communication.
if you are using basic auth for only to exchange for token , you will face some challenges when it comes to token expiration and the algorithm for token generating and validating.
Can you share an example? I do not see how the transport of credentials should affect token generation in any way. That is unless the token generation is tightly coupled to some specific transport.
So Its good to abandon Basic Auth and adobt more mature one.
Basic auth has been around pretty much since the dawn of HTTP protocol so I consider it pretty mature.
I am not saying basic auth is the best choice or even correct choice for many applications. However currently there is a just a bold statement one should not use it but the provided reasoning is misleading.
Same question. A lot of big companies use Basic Auth with no problems (see AWS). If it's over HTTPS then why not? Relevant Article.
Another key point is that Basic Auth over HTTPS has built-in support almost everywhere. JWT and OAuth require relatively massive client and server libraries and, at least in the case of JWT there's fairly regular criticism of the protocol.
I think it would make be more helpful to change that section from “Don't use
In my opinion you should remove the bullet point concerning basic authentication (or at least formulate it differently) as I find it quite misleading.
There is nothing wrong with using basic authentication to exchange a username/password for an access token if you do this over a secure channel (which you absolutely should). However, it indeed is bad practice to use a username/password combination to authenticate against the API for each call you make (although I can imagine ways of doing this that are less problematic as well).
For simple API authentication I usually recommend the following:
- Use access tokens to authenticate against the API. You can e.g. pass the token as a (secure HTTP-only) cookie, HTTP header (typically the "Authorization" or "X-Authorization" header) or as a form-encoded value, but ideally not as a URL-parameter (as this might get cached).
- Give the user a way to generate access tokens through a web interface or programmatically via the API (e.g. have a "/login" endpoint where the user authenticates via username/password [and ideally 2FA] and obtains an administrative access token in return, which she can then use to generate scoped access tokens via a different endpoint [e.g. "/tokens"])
- Give the user the ability to limit the scope/power of the generated access tokens to what's absolutely necessary (and possibly provide a way to set an expiration date).
- These access tokens with limited scope can then be used to access the API without giving the owner of the tokens full administrative access. n" or "X-Authorization" header) or as a form-encoded value, but ideally not as a URL-parameter (as this might get cached).
Github provides a nice example of this (their OAuth tokens essentially are access tokens as they can be obtained via a non-OAuth flow as well):
https://developer.github.com/v3/auth/#basic-authentication
So are we concluding that it is safe enough to use Basic Auth as a one time mechanism to exchange username/password for an authentication token that would be utilized in making future request? If yes, what is the proper way to implement re authentication when the token expires?
I think the reasoning behind not using Basic Auth or any precautions should be added and explained in the docs.