Do we need to make the response secure? - api

Most of the time we are using JWT access token validation to make sure that the request to e.g. an API is secure. However do we need to make sure that the response that comes back from that system (or API) is secure enough? Do we need to be worry? and how should we mitigate it?
appreciate all kind of advice.

As usually with those things, the answer is it depends ;)
Who is the owner of the API that you're calling? If you're calling your own API then you can be pretty sure about the validity and safeness of the response. If you're calling a third-party API then you might add some checks. Maybe scan files for malicious code if you're downloading any files from that API? Or check whether the response is not trying to inject any code, etc. It might not be the easiest thing to do, though.
Are you using a secure connection to the API? If you use SSL then you're sure that no one has tampered with the response. Additionally you can verify certificate chains to verify that you're connecting to the right API endpoint and not to a malicious one. If you're not using SSL then you might want to verify the response from the API, whether it's been tampered or not. How to do that verification again might not be trivial, but maybe the response can be signed?
Where is the client which is talking to the API? If you have a backend client talking to an API then you should not worry that response might be altered at client side. If you have an SPA running in a browser, then the response might be altered by a man-in-the-browser attack. Such response can be altered even if you use SSL to connect to the API, as SSL is terminated in the browser and a compromised user-agent will grant the attacker access to the decrypted API response. You can also have an XSS attack which alters responses in your app. Again, to protect from that threat you would need responses to be signed, or have another way of verifying integrity.
One way of verifying integrity of a response is to use signed JWTs with asymmetric signing. The API can sign the response with its private key, and then you can verify whether it's not been tampered with. E.g. the JARM spec uses that for OAuth flow responses.

Related

Difference between SSL and JWT

I've been reading and trying to comprehend the differences in browser side security. From what I gather, SSL is used to keep people from sniffing the traffic you send to the server. This allows you to send a password to a server in clear text...right? As long as you are in an SSL encrypted session you don't have to worry about hashing the password first or anything weird, just send it straight to the server along with the username. After the user authenticates you send them back a JWT and then all future requests to the server should include this JWT assuming they are trying to access a secured area. This allows the server to not even have to check the password, all the server does is verify the signature and that's all the server cares about. As long as the signature is verified you give the client whatever info they are requesting. Have I missed something?
You are correct. "This allows the server not to even have to check the password." Why would you have to check a password on each request?
A JWT is a means of verifying authentication. It is generated upon a successful authentication request and hence forth passed with each request to let the server know this user is authenticated.
It can be used to store arbitrary values such as user_id or api_key but they are not very secure so don't store any valuable information here.
Be wary though, if a plain JWT is intercepted by a third party, it can assume this user's session and possible data.
SSL is a lower level form of security, encrypting every request from and to the server to prevent interception and retains integrity.
SSL is achieved by (purchasing) an SSL certificate and installing it on your server. Basically an SSL certificate is a small data file that binds a cryptographic key to an 'organisation'. Once installed succesfully, HTTPS requests (on port 443 by default) are possible.

Is SSL enough for protecting a request and its headers?

I ask this because I work on an application where the X-AUTH-TOKEN can be copied from one request to another and impersonate another person. This makes me nervous, but I'm told since we're going to use HTTPS we don't have to worry about anything.
So, my question is: Is it good enough trust SSL to protect against stealing headers used for auth/sessions?
Thanks,
Using HTTPS encryption will indeed prevent someone from stealing your authentication token if they can intercept the traffic. It won't necessarily prevent a man-in-the-middle attack though unless the client enables peer certificate checking.
This question from the security stackexchange describes how to implement MITM attacks against SSL. If I can convince a client running HTTPS to connect to my server, and they accept my certificate then I can steal your authentication token and re-use it. Peer certificate validation is sometimes a bit of a pain to setup but it can give you a higher chance of whomever you are connecting to are who they say that are.
"Good enough" is a relative definition and depends on your level of paranoia. Personally I would be happy that my connection is secure enough with HTTPS and peer certificate validation turned on.
Presumably also your authentication token times out so the attack window would be time limited. For example the OpenStack authentication token is by default valid for 24 hours before it expires and then you are required to obtain a new one.
The HTTPS standard implements HTTP entirely on top of SSL/TLS. Because of this, practically everything except for the DNS query is encrypted. Since headers are part of the request and response, and only sent after the secure-channel has been created, they are precisely as secure as the implementation of HTTPS on the given server.
HTTPS is an end-to-end encryption of the entire HTTP session, including the headers, so on the face of it, you should be safe from eavesdropping.
However, that is only part of the story: depending on how the clients are actually connecting (is this a website or an API service?), it may still be possible to trick them into sending the data to the wrong place, for instance:
Presenting a "man in the middle" site with an invalid SSL certificate (since it won't be from a trusted authority, or won't be for the right domain) but convincing users to by-pass this check. Modern browsers make a big fuss about this kind of thing, but libraries for connecting to APIs might not.
Presenting a different site / service end-point at a slightly different URL, with a valid SSL certificate, harvesting authentication tokens, and using them to connect to the real service.
Harvesting the token inside the client application, before it is sent over HTTPS.
No one approach to security is ever sufficient to prevent all attacks. The main consideration should be the trade-off between how complex additional measures would be to implement vs the damage that could be done if an attacker exploited you not doing them.

Client certificate based access to specific resources using twisted webserver

I was wondering if the twisted webserver offers the possibility to restrict access to some resources using client certificate based authentication and to allow access to other resources without certs.
I searched trough the questions and found this posting: Client side SSL certificate for a specific web page
Now my question is if someone knows if twisted has implemented the ssl renegotiation and how an example would look like.
Or has there been a different approach since then?
Just to make things clear and to give additional information:
What I actually want to achieve is something like this:
A new user visits a site and has not yet granted access to the resource because he has no token yet that allows him to view the site.
Therefore, he gets redirected to a login resource that is asking for a client certificate. If everything is correct, additional data retrieved from the certificate is stored in the session, which makes up the token.
He then gets redirected back to the entry site, the token is validated, and according to his authorization level specific content is displayed
If I understood you correct Jean-Paul, this seems to be possible to implement with your strategy, right?
Correct me if I'm missing something or doing it wrong.
It doesn't seem to me that SSL renegotiation is particularly applicable here. What you actually want to do is authorize a request based on the client certificate presented. The only reason SSL renegotiation might be required is if you want the client to be able to request multiple resources over a single persistent HTTPS connection, presenting a different client certificate for each. This strikes me as unlikely to be necessary (or at least, the reasons for wanting this - rather than just letting the client establish a new HTTPS connection, or just authorizing all your resources based on a single client certificate - are obscure).
Authorization in Twisted Web is straightforward. Many prefer a capability-like approach, where the server selects a resource object based on the credentials presented by the client. This resource object has complete control over its content and its children, so by selecting one appropriate for the credentials presented, you completely control what content is available to what clients.
You can read about twisted.web.guard in the http auth entry in the web in 60 seconds series.
This will familiarize you with the specifics of authentication and authorization in Twisted Web. It will not tell you how to authenticate or authorize based on an SSL client certificate, though.
To do that, you'll need to write something similar to HTTPAuthSessionWrapper - but which inspects the client SSL certificate instead of implementing HTTP authentication as HTTPAuthSessionWrapper does. This will involve implementing:
IResource to inspect the transport over which the request is received to extract the client certificate
implementing a credentials type which represents an X509 certificate
implementing a credentials checker which can authenticate your users based on their X509 certificate
and possibly implementing a realm which can authorize users (though you may have written this already, since it is orthogonal to the authentication step, and therefore is reusable even if you don't want to authenticate with SSL certificates)
This functionality would be quite welcome in Twisted itself, so I'm sure you can find more help from the Twisted development IRC channel (#twisted-dev on freenode), and I hope you'll contribute whatever you write back to Twisted!

Setting up a web application to automatically run authenticated calls over HTTP to a remote website without repeated human authentication

I want to be able to set up a web application to automatically (i.e. on a cron run) send a POST request to a remote website. The remote website requires a username/password combination to be sent as part of the POST data. I want the web application to be able to make the POST requests of the remote website without requiring the user to provide the password to be sent with the POST data, each time the request is made.
It seems to me that the only way to do this is to store passwords directly in the database, so that the cron run can execute a POST request that includes the password as part of its POST data. Without storing the password in some form in the database, it seems it would be impossible to provide it in the POST data, unless the user provides it each time the request is made.
Question 1: Am I mistaken and somehow overlooking something logical?
Question 2: Assuming I have to store the passwords in the database, what is the safest procedure for doing so? (MD5 and similar one-way encryption clearly will not work because I have to send an unencrypted password in the POST request.)
Thank you for your help!
a. if you don't know the password... you can't authenticate, that's the idea of a password !
b. if you need to know the password - you need to save it in a decryptable way - hence - less secured.
c. if you own the site, you can use a cookie with a very long timeout value, but - you still need to authenticate at least once.
d. unless you're guarding money / rocket science, you need to encrypt the password and store it in the DB and decrypt it every time before use, at least you are guarded from DB theft.
e. make sure you're authenticating over secure channel (as https) so the password will no be sent as clear text.
One good solution is probably to use SSL (i.e. HTTPS). You can create a certificate authority on the server side, then have this certificate authority sign a client certificate that you generate. Make sure the HTTP server is configured to trust the newly created certificate authority.
Once this is done, you should install the certificate on the client side. The client must present the certificate when talking to the HTTP server. You have to configure the HTTP server to require a trusted certificate when POSTing to your secure URLs.
Awesome example of how to do this with Apache HTTPD is posted right here!
The document I linked doesn't describe how to set up the certificate authority and create self-signed certificates, but there are tons of examples out there, for example here.
This is a good solution because:
no passwords are stored in the clear
if the private key of the client's certificate is stolen or compromised, you can revoke it on the server side
The key here is that the client is providing its credentials to the server, which is the opposite of what is usually done in a browser context. You can also have the client trust your newly created certificate authority so that it knows it's talking to the right server and not a man in the middle.
Given that you have to send the password in clear-text and do it repeatedly without user-interaction you'll need to store and retrieve the same from a data-store (file/database/memory).
What you really need to consider is the last-line-of-security of the password store.
Whether you encrypt it or not doesn't matter. The person/program with access to the data or the cipher key will be able to read that password.
Sort this issue out, document it - (this becomes your security policy for the app) and then implement it.
Security is only a level of difficulty you implement to lessen a risk.
Fortunately, Tumblr now implements OAuth, which solves this problem.

Is it safe to share md5(cookie, some_string) with a third party service?

I need my users to authenticate against a third party service with the same cookie the use with my website.
Is it safe to share the md5(cookie, service_name) with the service, where service_name
is a constant string that all the users will use.
To authenticate against the service a js function will do the md5 of the cookie on the client side and use it.
Is there a better and safer hashing to use or is md5 secure enough?
Do I need to base64 decode the cookie before doing the md5?
Thanks
There is little chance of reversing the hash to obtain the original cookie data so it is safe in that regard.
You could use SHA-1 hash instead however both are vulnerable to collision attacks, perhaps allowing an unauthorized attacker (who doesn't have the cookie) to gain access to the 3rd party service. I don't know how likely that would be.
As far as base64 decoding it, check and see if it is base64 encoded first.