API Token Authentication - Security issue - rest

For token based authentication for any service, first we have to send username/password in the request. Doesn't this cause security issue? How can we overcome this security issue of passing username/password?

The initial request which contains the username and password is no more or less secure than subsequent requests which would instead be bearing some sort of token. The solution to this problem, really to sending any type of information across the network, is to use two way SSL/HTTPS. With HTTPS, information being sent gets encrypted on the client machine, and then (in theory) only the server would be able to read what is contained. So, sending the plain text username and password might seem insecure, but if using HTTPS, then in fact it is secure.

Related

How to secure self-hosted WCF WebHttp server?

I have a REST server over SSL.
Initially, the client logs in with the credentials.
To avoid sending the username/password for each request, I have created a custom token which is returned to the user in the login procedure.
This token contains some information about the client (IP and user-agent) as well as an expiration time; and of course the token is sent encrypted.
Further calls include the token in a custom header field; which are verified in IDispatchMessageInspector
The approach works fine, but I am pretty sure it's not a good approach.
Is there any benefit in using custom authentication than the message inspection?
Message inspection is the checking, changing, and replacing of messages after they are received and before they are sent.
Custom authentication requires the authentication of a username and password, which is more suitable for login or other situations where a username and password are required.
Both types of verification have their own applications.As you said to avoid sending the username and password every time you can choose message inspection. Personal words also tend to be message inspection.

Authentication Practices with Node Express

I built a simple authentication system for my backend API with Express using Cookie-Parser and/or sending the Token to the front end.
It works like this: the user makes a post request to the login route with the username and password, and if it matches, he gets back both a .json response with the token and a cookie set with the token.
I thought it would be nice for the frontend development and authorization purposes to have the current user available in every successive request after the login. So, I set a middleware that searches if there is a token, tries to find a user in database with the corresponding ID, and set the user info (without the password) as a parameter in the request object (req.user).
What I wanted to know is:
Is it a bad practice to put the user info in the request? Does it lead to security problems? Or maybe the database query in every request could overload the server if the app scales to much?
This is my first backend API, I'm trying out different ways of doing things, but I'm not aware of the best practices in the field. Any help is very much appreciated!
That is why there is encryption and in this context it is an ssl ticket. If you add login details to the request you NEED to make sure that the http response is encrypted. Once it is encrypted it is ok to do what you are doing. If it is not, an eaves dropper can snatch up that data from sniffing on your network.

Which is more better between basic auth and token auth as security perspective

I am currently developing a RESTful API server, and I am choosing between using ID and password or using a token to authenticate a user.
Let me, explain my situation first. I need to include static authentication information to my library to communicate between a client and my server or provide it to a partnership company to communicate between their server and my server. And when I was researching other services which are in a similar situation as us, they are using token now (for example, Bugfender is using a token to specify a user).
However, what I think is that using ID and PW and using the token are the same or using ID and PW is better because there are two factors to compare it is correct or incorrect.
Is there any reason why other services are using a token?
Which one is better as a security perspective or is there a better way to do this?
I think, if you are going go use on your client fixed username/password, or some fixed token, then the level of the security is the same.
Username and password is not considered as multi-factor authentication. Multi factor means that you are authenticating someone by more than one of the factors:
What you know. This can be the combination of username and password, or some special token.
What you have. Might be some hardware that generates an additional one time password - Google authenticator app on your telephone, or SMS with OTP received with some time expiration.
What you are. This is for example your fingerprint or retina of the eye.
Where you are. This can be the IP address of the origin if it is applicable for your setup.
How you behave. What is your normal way of using the service.
etc.
Maybe not needed to mention that both - the token and the username/password combination have to be carried in an encrypted requests (I believe you are using HTTPS). Otherwise the client's identity can be stolen.
How are you going to provide the credentials to your client library? I thnk this is the most tricky part. If those credentials are saved as a configuration (or worse hard coded) on their server, is that storage secure enough? Who is going to have access to it. Can you avoid it?
What would happen if your partner company realize that the username/password is compromised? Can they change it easily themselves? Or how fast you can revoke the permissions of stolen credentials?
My advice is also to keep audit logs on your server, recording the activity of the client requests. Remember also the GDPR if you work with Europe servers, check for similar regulations in your country based on what you are going to audit log.
In case the credentials (ID and password) and the token are being transferred the same way (say: by a header in a REST request) over a TLS secured channel, the only difference lies in the entropy of the password VS entropy of the token. Since it is something for you to decide in both cases, there is no real difference from the security perspective.
NOTE: I don't count the ID as a secret, as it usually is something far easier to guess than a secret should be.
I'd go for a solution that is easier to implement and manage.
IMHO this would be HTTP basic authentication, as you usually get full support from your framework/web server with little danger of making security mistakes in authentication logic. You know, friends don't let friends write their own auth. ;)

avoiding clear text password login for github3.py

From a post on another stackoverflow, the following was recommended.
Is there a way to avoid using cleartext, maybe supply an existing admin ssh key instead?
from github3 import login
g = login('abcd', password)
with open('~/.ssh/temp.k.pub', 'r') as fd:
key = g.create_key('abcd', fd)
print("Created {0}".format(key.title))`
So to be clear, when communicating with GitHub's API, your communications are secured over HTTPS. github3.py uses requests which performs certificate verification and properly secures the connection. That said when we authentication using basic authentication, you're sending your credentials in the headers after base 64 encoding (which is not encryption and is not secure if it is somehow intercepted).
So really, you need to consider who you're worried about "seeing" your credentials. If you're worried about your company running a proxy locally that is meant to man-in-the-middle your connection and steal your credentials that's a good use for a limited token. You can create the token via the API or via the web UI. Either way, you would then (instead of using the code you have) do the following:
g = login(token='myspecialtoken')
Then you would do everything else the same way. I haven't checked if you can create ssh keys for the user with a token, but if it won't work you'll get an error about needing to use basic authentication (your username and password).
I still want to stress, though, that using your login credentials should be fine. The difficulty of intercepting that and retrieving your credentials as an arbitrary attacker is high. If you're worried about a different situation, you should definitely look more closely into the threat level.
You can use environment variables
ie
gh_login = os.environ.get('GITHUB_LOGIN')
gh_pass = os.environ.get('GITHUB_PASS')
Then pass these into login

Security of REST authentication schemes

Background:
I'm designing the authentication scheme for a REST web service. This doesn't "really" need to be secure (it's more of a personal project) but I want to make it as secure as possible as an exercise/learning experience. I don't want to use SSL since I don't want the hassle and, mostly, the expense of setting it up.
These SO questions were especially useful to get me started:
RESTful Authentication
Best Practices for securing a REST API / web service
Examples of the best SOAP/REST/RPC web APIs? And why do you like them? And what’s wrong with them?
I'm thinking of using a simplified version of Amazon S3's authentication (I like OAuth but it seems too complicated for my needs). I'm adding a randomly generated nonce, supplied by the server, to the request, to prevent replay attacks.
To get to the question:
Both S3 and OAuth rely on signing the request URL along with a few selected headers. Neither of them sign the request body for POST or PUT requests. Isn't this vulnerable to a man-in-the-middle attack, which keeps the url and headers and replaces the request body with any data the attacker wants?
It seems like I can guard against this by including a hash of the request body in the string that gets signed. Is this secure?
A previous answer only mentioned SSL in the context of data transfer and didn't actually cover authentication.
You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs because you really want to authenticate the client.
If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth 1.0a or even HTTP Basic authentication (but over SSL only).
These schemes authenticate that the request was sent by someone expected. TLS (SSL) (without client authentication) ensures that the data sent over the wire remains untampered. They are separate - but complementary - concerns.
For those interested, I've expanded on an SO question about HTTP Authentication Schemes and how they work.
REST means working with the standards of the web, and the standard for "secure" transfer on the web is SSL. Anything else is going to be kind of funky and require extra deployment effort for clients, which will have to have encryption libraries available.
Once you commit to SSL, there's really nothing fancy required for authentication in principle. You can again go with web standards and use HTTP Basic auth (username and secret token sent along with each request) as it's much simpler than an elaborate signing protocol, and still effective in the context of a secure connection. You just need to be sure the password never goes over plain text; so if the password is ever received over a plain text connection, you might even disable the password and mail the developer. You should also ensure the credentials aren't logged anywhere upon receipt, just as you wouldn't log a regular password.
HTTP Digest is a safer approach as it prevents the secret token being passed along; instead, it's a hash the server can verify on the other end. Though it may be overkill for less sensitive applications if you've taken the precautions mentioned above. After all, the user's password is already transmitted in plain-text when they log in (unless you're doing some fancy JavaScript encryption in the browser), and likewise their cookies on each request.
Note that with APIs, it's better for the client to be passing tokens - randomly generated strings - instead of the password the developer logs into the website with. So the developer should be able to log into your site and generate new tokens that can be used for API verification.
The main reason to use a token is that it can be replaced if it's compromised, whereas if the password is compromised, the owner could log into the developer's account and do anything they want with it. A further advantage of tokens is you can issue multiple tokens to the same developers. Perhaps because they have multiple apps or because they want tokens with different access levels.
(Updated to cover implications of making the connection SSL-only.)
Or you could use the known solution to this problem and use SSL. Self-signed certs are free and its a personal project right?
If you require the hash of the body as one of the parameters in the URL and that URL is signed via a private key, then a man-in-the-middle attack would only be able to replace the body with content that would generate the same hash. Easy to do with MD5 hash values now at least and when SHA-1 is broken, well, you get the picture.
To secure the body from tampering, you would need to require a signature of the body, which a man-in-the-middle attack would be less likely to be able to break since they wouldn't know the private key that generates the signature.
In fact, the original S3 auth does allow for the content to be signed, albeit with a weak MD5 signature. You can simply enforce their optional practice of including a Content-MD5 header in the HMAC (string to be signed).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Their new v4 authentication scheme is more secure.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
Remember that your suggestions makes it difficult for clients to communicate with the server. They need to understand your innovative solution and encrypt the data accordingly, this model is not so good for public API (unless you are amazon\yahoo\google..).
Anyways, if you must encrypt the body content I would suggest you to check out existing standards and solutions like:
XML encryption (W3C standard)
XML Security