How do http-websites prevent MITM attack for token based authentication? - web-services

I am new to web services and read about token based authentication which can be used with web services from What is token based authentication?. I searched on internet but its quite confusing how http based websites manage to do token based authentication without any security vulnerability.
What point I have?
I can sit in between server and client and store the token somehow by sniffing the traffic and make misuse of it before it expires. Am I wrong here?
EDIT
As mentioned on https://security.stackexchange.com/questions/46348/token-based-authentication-under-http.
"Facebook uses an OAuth token passed as a cookie or HTTP header and
protected by HTTPS."
How can I implement this as in that case the website will be http-based and only http-headers will be using https. Please correct me if I am wrong.

Your edit suggest a misunderstanding of what HTTPS does.
Normatively speaking, HTTP (meaning, the "language" that is spoken on the network, defined by https://www.ietf.org/rfc/rfc2616.txt) is a text based, "application level protocol", used over TCP sockets (TCP being the "transport level" layer).
In that sense, HTTP and HTTPS are the same "language", nothing differs in them. HTTP and HTTPS are both text based request/response protocols, each consisting of headers and an body, with requests specifying a verb such as GET, POST, PUT, ... No difference whatsoever.
What is different in HTTP vs. HTTPS, is that underneath this HTTP "language" (application level protocol), HTTPS uses TCP sockets that are encrypted using a SSL or TLS layer that provides encryption.
As the SSL/TLS layer happens under the HTTP layer, there can be no difference between what happens to the headers of a request and what happens to the body.
Back to your question :
How can I implement this as in that case the website will be http-based and only http-headers will be using https. Please correct me if I am wrong.
You can't have only the headers, and not the body using HTTPS in a single request/response cycle. It's all or nothing.
The conclusion is, as per the article you link to : token based authentication can only be secure if the token is always secured. Which, if you are always using HTTPS (in all request/response), is guaranteed (both the headers and the body are protected). If even one single request or response is not sent over HTTPS, then you have a flaw.

Related

Secure Cookies on http requests

What happens to secure cookies on http requests. will it be lost over the request? What will happen if the cookie is a secure auth cookie?
RFC 6265 formalizes the behavior of HTTP cookies (as they work in the real world, not as they should ideally work, unlike some previous failed RFC):
Introduction
This document defines the HTTP Cookie and Set-Cookie header fields.
The description of the behavior of the "secure" flag follows:
4.1.2.5. The Secure Attribute
The Secure attribute limits the scope of the cookie to "secure"
channels (where "secure" is defined by the user agent). When a
cookie has the Secure attribute, the user agent will include the
cookie in an HTTP request only if the request is transmitted over a
secure channel (typically HTTP over Transport Layer Security (TLS)
[RFC2818]).
In practice only connections over TLS (that is, HTTP/S) are considered secure. Browsers could conceivably define direct HTTP connections to host "localhost" or an IP address that is by definition "local" (address of that IP stack), like 127.0.0.1 or ::1, or other local addresses, as secure. That would be in the spirit of the specification. (I don't know browsers that actually do so.)

Boost ASIO with OpenSSL Can't Read HTTP Headers

I'm attempting to write a simple HTTP/HTTPS proxy using Boost ASIO. HTTP is working fine, but I'm having some issues with HTTPS. For the record this is a local proxy. Anyway so here is an example of how a transaction works with my setup.
Browser asks for Google.com
I lie to the browser and tell it to go to 127.0.0.1:443
Browser socket connects to my local server on 443I attempt to read the headers so I can do a real host lookup and open a second upstream socket so I can simply forward out the requests.
This is where things fail immediately. When I try to print out the headers of the incoming socket, it appears that they are already encrypted by the browser making the request. I thought at first that perhaps the jumbled console output was just that the headers were compressed, but after some thorough testing this is not the case.
So I'm wondering if anyone can point me in the right direction, perhaps to some reading material where I can better understand what is happening here. Why are the headers immediately encrypted before the connection to the "server" (my proxy) even completes and has a chance to communicate with the client? Is it a temp key? Do I need to ignore the initial headers and send some command back telling the client what temporary key to use or not to compress/encrypt at all? Thanks so much in advance for any help, I've been stuck on this for a while.
HTTPS passes all HTTP traffic, headers and all, over a secure SSL connection. This is by design to prevent exactly what you're trying to do which is essentially a man-in-the-middle attack. In order to succeed, you'll have to come up with a way to defeat SSL security.
One way to do this is to provide an SSL certificate that the browser will accept. There are a couple common reasons the browser complains about a certificate: (1) the certificate is not signed by an authority that the browser trusts and (2) the certificate common name (CN) does not match the URL host.
As long as you control the browser environment then (1) is easily fixed by creating your own certificate authority (CA) and installing its certificate as trusted in your operating system and/or browser. Then in your proxy you supply a certificate signed by your CA. You're basically telling the browser that it's okay to trust certificates that your proxy provides.
(2) will be more difficult because you have to supply the certificate with the correct CN before you can read the HTTP headers to determine the host the browser was trying to reach. Furthermore, unless you already know the hosts that might be requested you will have to generate (and sign) a matching certificate dynamically. Perhaps you could use a pool of IP addresses for your proxy and coordinate with your spoofing DNS service so that you know which certificate should be presented on which connection.
Generally HTTPS proxies are not a good idea. I would discourage it because you'll really be working against the grain of browser security.
I liked this book as a SSL/TLS reference. You can use a tool like OpenSSL to create and sign your own certificates.

how SSL & cookies work?

I understand, we use SSL to encrypt sensitive data like user name and password to transported to server without people in the network eavesdropping. So then server returns a secure token over HTTPS and its stored in cookie. We switch to HTTP after we have secure token, we attach cookie/secure token header to every HTTP request.
Now anybody can see my secure token and they can eavesdrop it and impersonate me. Is my understanding correct?
The cookies can be set per protocol, so that HTTPS cookies are not used for HTTP and vice versa. Also, the properly constructed secure token should include an IP address and have short expiration time.
But in general the best idea is of course to keep the authenticated session in secure channel - SSL is not that heavyweight these days (as computers became much faster than when SSL was first introduced) and also the heaviest part is handshake, which is performed only once if persistent HTTP connection is used (or when SSL session resuming is used).

Non-Transparent Proxy Caching of SSL

I asked the question before but didn't phrase it quite right. I'm using RESTful principles to build a secure web-app that uses both transport authentication/encryption and message level security.
The message level security is essentially client-independent (still encrypted though), and hence this allows the individual messages to be cached, or stored on an intermediary server without significant risk of exposing private data.
Transport level security is needed to authenticate both end-points using TLS client-authentication. The situation is analogous to having a central mainframe where messages originate, and caches at each branch where the clients are located. I want the client->cache and cache->mainframe connections to be secured using TLS and the individual X509 Certificates. Hence, the client will know it is talking to a proxy, and the mainframe will know it is talking to the proxy and not directly to the client.
Is there some way of doing this using HTTP standards, and not through some hack?
Essentially, I want the client to try and access the mainframe URI, to know it has to go through the proxy, and use TLS with the proxy (with the proxy having its own certificate), and then for the proxy to proceed to connect to the mainframe (with each having their own certificate) on behalf of the client. The proxy can cache the data the mainframe returns, and use that instead of having to connect to the mainframe each time.
Does anybody know proxy/caching software or a method that will allow this?
Would this get more responses on serverfault.com as it's essentially a server software/config question rather than a programming problem per se?
Basically, it sounds like you want a standard SSL reverse proxy with caching. You could do this without writing any code with Apache + mod_cache, configured as a reverse proxy.
The kicker is the message security. It'd only work if your requests are 100% cacheable based only on path/querystring, and if they were "unique by client" (eg, a client ID in the QS or something). Something tells me that one or both of these are not true. This would be pretty trivial to build in ASP.NET, or by extending mod_cache (basically just standard response caching, bucketed by the client cert thumbprint).

Are REST request headers encrypted by SSL?

I'm developing a client/server app that will communicate via rest. Some custom request data will be stored in the header of the request. Both the server sending the request and the receiving server have an SSL certificate - will the headers be encrypted, or just the content?
SSL encrypts the entire communications path from the client to the server and back, so yes - the headers will be encrypted.
By the way, if you develop networked applications and care about data security, the least you should do is read a book like Practical Cryptography, by Niels Ferguson and Bruce Schneier, and probably further reading that's more focused on web application security would be a good idea. If I may make an observation - and please, I don't mean that as a personal criticism - your question indicates a fundamental lack of understanding of very basic web security technologies, and that's never a good sign.
Also, it's never a bad idea to confirm that data which is assumed to be encrypted is indeed encrypted. You can use a network analyzer to monitor traffic on the wire and watch out for anything sensitive being sent in the clear. I've used Wireshark to do this before - the results can be surprising, sometimes.
As long as you're communicating in the SSL tunnel, everything sent between the server and the client will be encrypted. The encryption is done before any data is sent or received.
Both headers and content are encrypted.
You appear to think that REST is a distinct protocol.
REST is not a protocol. It is a design style for HTTP-based applications.
So, your a writing an HTTP application. Are the headers encrypted? Yes, if you are using the HTTPS (HTTP over SSL) protocol instead of plain HTTP.
Having certificates on both sides is not directly relevant to your question. SSL certificates are used for authentication. They help in detecting man-in-the-middle attacks such as are possible using DNS cache poisoning.
Having a certificate is not enough, you have to configure the web server to encrypt the connections (that is, to use the certificate) for that domain or virtual host. In addition, I think you would just need a single certificate, responses to requests will still be encrypted.
And yes, HTTP headers are encrypted as well as the data.
The other answers are correct that headers are indeed encrypted, along with the body, when using SSL. But keep in mind that the URL, which can include query parameters, is never encrypted. So be careful to never put any sensitive information in URL query parameters.
Update: as #blowdart pointed out below, this is wrong. See the comment below.
SSL..or rather HTTPS (HTTP over SSL) sends all HTTP content over SSL, and as HTTP content and headers are in fact the same thing, this means the headers are encrypted as well.
Seeing as GET and POST data is sent via HTTP headers, then it only makes sense then when sending data securely you wouldn't just want the response code or content to be encrypted.
Not everything is encrypted: the request query string is not encrypted. Believe me, I've seen requests like this:
https://mydomain.com/authenticate?user=username&password=MyStrongPasswordSentInTheClear
Please don't put sensitive data as parameters in the query string.