When using HTTPS to consume REST API, is there a way to prevent client user to view data inside the call?
I thought that HTTPS does this but as I run Fiddler, I see an option to install fake certificate and peek request content.
How to secure this?
Bartek
That "install fake certificate and peek request content" is called MITM. Mitm is Man-In-The-Middle attack which hacker tries to inject it's own [fake] certificate to user, user encrypts data with hacker's certificate, hacker decrypts data, stores decrypted data, re-encrypts it with server certificate and sends it to server, etc.
The only way for you to protect again MITM is check certificate and make sure it's valid certificate and if client is your own application your application should store your real certificate's serial.
So only prevention against SSL MITM is storing or validating your certificate before sending request.
Related
QUESTION: The initial request/response HTTPS communication between client and server are not encrypted, except for the CA certificate in the response?
If so, what prevents a hacker from seeing the initial client request to the server, and intercept the response from the server,
containing its CA certificate, decrypting the certificate with the CA's public key, get the server's public key in the certificate,
and use it to encrypt its own symmetric key and send to the server, thereby bypassing the client, and establishing a bogus dialog between hacker and server?
This question has already been answered here.
TL;DR
What you are defining is a Man-In-The-Middle attack on SSL, and this can happen only if one of SSL preconditions is broken.
I understand the XSS vulnerability of using web storage and the CSRF vulnerability of using cookies. So I store the access token in memory and for persistence I have a refresh token in a cookie which I use to silently refresh my access token when we lose it. I feel somewhat better about XSS and CSRF threats... BUT how do we secure the token from a packet sniffer? A packet sniffer would find the token in the request. I see a lot of discussion on XSS and CSRF but how do we keep safe from packet sniffers, and are there even more threats we do not commonly think about?
You use HTTPS to defend against packet sniffers.
Fiddler as a proxy will not be able to decrypt HTTPS traffic in the cloud unless the fiddlers built in root certificate is added to the browser or client making the request.
Fiddler is able to decrypt HTTPS because you have added Fiddlers root certificate to your trusted store in YOUR computer. without this a proper HTTPS connections can't be made.
So , don't worry about Fidler in the cloud.
https provides an end to end encryption. Its implenented on the application level by browsers so no other users on the same network doesnt break https security.
The below is a short explanation of how ssl and https (http over ssl) works
Ssl:
The key idea is that mathematically you can generate a public key A and a private key B in a way that if you encrypt something with A you can only decrypt it with B.
So let's say the server google has a pair of public key A and private key B.
A client wants to send some data to google. The idea is if the client has key B he can encrypt the data he wants to send and he doesnt care anymore of network threats such as a man in the middle fishing the packet or data because only the owner of key B (google) can decrypt the data. So the man in the middle will only have encrypted data which has no use.
Note that from above it is clear that servers (google here) should keep their private key unshared, but should distribute their public key so that clients can use to communicate safely (with encryption) with the server.
How to distribute the public key ?
Using the public key infrastructure (PKI) which is a set of roles, entities, definitions, etc. used to manage and distribute public keys.
Again in short, a server request a certificate from a certificate authority (CA). That certificate contains information on the server (name, ip, etc.) And the public key and private key generated for that server (note here there are several procedures that a server might request to generate the keys, one of which is the server generates the private key and the CA only responsible for generating the public key).
Finally, there is a list of trusted CAs built into the browsers, so that these browsers such as chrome can go to and get google's public key A, and use it to encrypt the data it wants to send to google.
The above is how ssl communication protocol works (ssl certificates). Ssl is simply a protocol that provides secure communication. It provides no routing and networking capabilities.
Https:
Https is basically HTTP connection which is delivering the data secured using SSL.
That means SSL encrypted data will be routed using protocols like HTTP for communication.
I am familiar with SSL/TLS and its mechanism to protect data sent over HTTP between the browser and the web server. One of the issues identified by my security testing team is request tampering over SSL where they were able to modify the HTTP request payload of a POST request using man-in-the-middle attack. The browser obviously did show a certificate validity warning and it was ignored.
In my opinion, the application shouldn't handle or remediate such request tampering scenarios because SSL/TLS takes care of it. Server side validation of data that matches any client side validation should suffice to ensure that the HTTP payload is valid.
So my question is basically to confirm my understanding about this. Is request tampering using man-in-the-middle attack over SSL a valid security testing scenario? And should an application do any specific request encoding to protect from such attacks.
Yes, it is a valid testing scenario.
Depending on the threat model of your application, the application might implement Certificate Pinning, to mitigate that threat. With that, you can make sure that only a specific cert (or certs signed by a certain CA are trusted.
See this answer for reference.
When I type a URL for example, www.google.com for the first time in my browser.
I am sure that something is sent out containing the URL. Then the returned HTML page is displayed on the screen.
How does my browser make sure that the server who responds to my request is the real Google's Server not someone else's server (Man-in-the-middle)?
I can see that an HTTPS connection is also established. I believe that this has something to do with the above question.
Can anyone anwser this question in detail with my www.google.com example?
I know what is public key and private key. I know that public key can be used to encrypt a message then its private key is used to decrypt. Private key can be used do digital signature and public key can be used to verify this signature.
But I don't know how they are applied in the www.google.com case.
As for using the public key to verify the signature, how do we do it? We use the public key to decrypt the message to see if we can get something that is previously defined?
Edited
Once the browser knows that it is a real google server that sends back the page, how can browser make sure that the page content itself is not modified by someone else? Is the first page sent back already encrypted?
Is symmetric encryption used for the following requests and responses?
Is the URL itself is encrypted?
https uses signed certificates to ensure the identity of the responding server.
The request is sent to the IP address your name resolution claims the name resolves to. That is not really reliable, since you yourself can easily alter that resolution.
The response from the server however contains a certificate that has been issued for the hostname (www.google.com here). This also does not yet provide the security you are looking for, but it brings us closer.
To verify if the certificate tells the truth your local browser tries to verify the certificate (its content). That is done by using a "certificate chain". A certificate can be signed with another certificate. If you trust that other certificate, then you can also trust those certificates that have been signed with the one you trust. That way a chain is created that reaches up to so called "root certificates". Such are certificates that are locally installed inside your system, so known and available to your browser, so they cannot be spoofed by an attacker.
Reality is a bit more complex, as always, but the above should give you an idea of how things work.
Note: you can also create a certificate yourself, you can even sign it yourself. This actually is helpful if you are just interested to establish an encrypted connection to your own https server, for example. But such self signed certificate does not prove the servers identity. That can only be done by using a certificate that has been signed the way described above.
Once the browser knows that it is a real google server that sends back
the page, how can browser make sure that the page content itself is
not modified by someone else?
The browser verifies that the certificate sent back in the SSL handshake is signed by a Certificate Authority (CA) that the browser trusts, and checks that certain fields are set to the correct value (e.g. Subject or Alternative Name is set to the displayed domain name and the valid from and to dates are current).
There can be multiple certificates in the chain if intermediary certificates are used, which is likely. As long as the second to last certificate in the chain is signed by a trusted root then everything is good.
Is the first page sent back already encrypted?
Yes, as soon as the SSL handshake is made, everything is encrypted. This includes any data in the initial request sent from the browser (e.g. cookies or query string).
Is symmetric encryption used for the following requests and responses?
Yes, although the keys are a function of random numbers generated by both client and server and a "pre master secret" which is sent from client to server encrypted by the certificate public key (or encrypted by one time generated keys in the case of Diffie-Hellman).
Is the URL itself is encrypted?
The domain name is sent in cleartext for the Server Name Indication extension, and also the DNS lookup and destination IP can also be known by an evesdropper on the connection.
The URL path and query string are encrypted though.
They use certificates to verify identities and signatures.
When the server responds to you, this contains a certificated that is being issued for that specific host. In your example this would be www.google.com
This provides some sort of trust because the root certificate is contained within your browser installment.
Speaking of a root certificate you start to build a chain of trust and one certificate is signed by another certificate until it reaches the root of this trusttree. These are installed locally on your browser and are therefore very hard to spoof for an attacker.
I am curious how to properly send username and password from a website login form to a server.
If I just send the username and password without hashing them to an https server how exposed is the password I send in a POST request to somebody sniffing the package and finding out the password? The server is https enabled.
What would be the proper methodology to do this?
If the server is HTTPS enabled then any data going over the wire will be encrypted. It would be extraordinarily difficult for a network-only attacker to sniff even a plaintext password over HTTPS without one of the parties noticing.
HTTPS uses SSL/TLS on the transport layer, which is designed to provide both encryption and authentication. The SSL/TLS protocol, as part of its handshake, negotiates a symmetric encryption key that is different for each session and is used with a strong algorithm to protect data on the wire.
To mitigate 'man-in-the-middle' attacks, the asymmetric keys used by the client and server to establish a shared encryption key are also cryptographically signed by a certificate authority, both to provide assurance of trust and to prevent modification of the certificate. As long as the certificate authority can be trusted, it is easy to check the signature and and server name on the certificate itself. All modern browsers do this automatically and throw a warning to the user if there is any problem with the certificate.
As long as you and your users are aware of the issues surrounding the proper use of SSL (e.g. keep your private key safe, and make sure your users pay attention to browser warning), it's fine to send plaintext passwords over an SSL connection.
If the demands of your application are such that you cannot do even that, you might consider X.509 authentication (which uses certificates on the client side as well as the server side) or Kerberos authentication (which sends no passwords over the wire). For a basic web application, though, both of these solutions are overkill.