How to secure access token beyond XSS and CSRF - security

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.

Related

What are some approaches to exchange data without using SSL/TLS

When creating any kind of application web,api etc; This days the best practices recommend to secure endpoints by using TLS, but what we can learn from the cloudbleed issue, is that it may not be enough.
Therefore I would like to know what could be done to keep a certain level of security even when TLS is compromised.
For web applications what I currently use is jsencrypt, basically encrypts all data on client browser side before it is sent, but in order to to this I need first to exchange a shared secret (token/cookie) between the server and client, but when dealing with API's that don't support javascript what could be used?
Regarding the exchange of tokens, by instinct it may be obvious to say use OAUTH, OpenID Connect, json tokens , but all of them require or delegate trust to TLS, and again when this is compromised it became useless.
If I am right OpenID could be used without SSL to share a "common secret" by doing Diffie–Hellman key exchange, is there something similar that could be implemented keeping in mind that if TLS gets compromised, easy measure could be taking like revoking tokens or changing "salts" ?
For now I think by following the gpg or rsa (private/public) keys is the way to go, in a way that probably everyone could have access to the public keys but will not be available to see the content of some data signed to a specific user.
But question remains in how to exchange that very first "known secret" between client and server avoiding a possible man in the middle attack considering TLS can't be trusted.
The problem of exchanging the first "known secret" is the same for all protocols, SSL or not. SSL is a public key infrastructure where the basic information that needs to be distributed is the public key of the root certificate of the certificate issuer. The public keys for all ssl certificate issuers are distributed with the browser installation.
Any protocol will depend on some information that is communicated between the server and client in a different channel from the channel where the communication is established. If you don't trust the SSL infrastructure, you will have to send this information by email, postal mail, sms, or by some other means.
However, your problem does not start with the keys neccesary for the encryption libraries you are using in you web application. Your very web application (the javascript files) are also sent from the server to the web browser over SSL. If your SSL communication is compromised by a man-in-the-middle, this man-in-the-middle is also probably able to change the web pages and javascript code that you send to the browser. He could just rewrite your application and remove all encryption code, add new fields and messages for the user, send the user to a different site and so on.
The SSL infrastructure is really a cornerstone in web security, and a neccessity for web applications. Without it, you would have to build a custom protocol for sending encrypted web pages and write a custom browser that would understand this protocol.
With all that said, it is of course possible to add a tiny layer of extra security on top of SSL. You may i.e. create a private/public keypair for each user, send a public key to the user and encrypt all messages from your server to the user with the private key. This could protect against a scenario where a main-in-the-middle is able to listen to the communication but not able to change your messages.

Login Authentication Mechanism - Proper way for client to send username/password

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.

Best approach to pass the public key from client to server

I have a tcp server and using cms/pkcs#7 to secure the message passed between the client and server. Would it be normal practice to pass the clients public key to the server, as part of initial session? As its the public key, when the session starts up, the initial clp command, would pass the key, along with other salient details that the server needs to know about the client. It's the public, so it doesn't need to be encrypted, it public.
The client/server communication is secured with ssl/tls.
Thanks.
Bob.
Don't you trust SSL/TLS or why do you encrypt again within the secure channel? That only makes sense if the server will pass the message on to other nodes and it will be decrypted somewhere else, thereby creating end-to-end security.
In any case, you should not have the client pass just the public key to the server. Instead it should pass a certificate to the server, which should authenticate the client based on a signature made with the private key matching the public key contained in the certificate. Also, the server will need to check the certificate itself (is it from a trusted CA, do the signatures in the chain verify, etc.).
If you can, you should do all this on the SSL/TLS layer by using SSL/TLS mutual authentication (client cert authentication). If you cannot, then make sure you design a secure application layer protocol for authenticating the client and it's public key. Otherwise it may be possible to impersonate other clients.

Are OAuth2 and SSL enough to secure an API

I'm trying to figure out the best way to secure an API. I only allow SSL and I'm using OAuth2 for authentication, but that doesn't seem like enough.
The major concern I have is that anyone could inspect the requests being made by a legitimate client to the API and steal the OAuth client_id. At that point they would be able to construct any request they want to impersonate the legitimate client.
Is there any way to prevent this? I've seen people use a HMAC hash of the parameters using a secret key known only to the client and server but I see 2 problems with that.
It's very difficult (impossible?) to prevent a malicious user from decompiling your client and figuring out the secret key.
Some parameters seem odd to make an HMAC hash of. For example if a parameter was bytes of a file, do you include the whole thing in your HMAC hash?
You can deploy mutually-authenticated SSL between your legitimate clients and your API. Generate a self-signed SSL client certificate and store that within your client. Configure your server to require client-side authentication and only accept the certificate(s) you've deployed to your clients. If someone/something attempting to connect does not have that client certificate, it will be unable to establish an SSL session and the connection will not be made. Assuming you control the legitimate clients and the servers, you don't need a CA-issued certificate here; just use self-signed certificates since you control both the client-side and server-side certificate trust.
Now, you do call out that it's really hard to prevent someone from reverse engineering your client and recovering your credential (the private key belonging to the client certificate, in this case). And you're right. You'll normally store that key (and the certificate) in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.
Are you running the OAuth authentication step over SSL itself? That prevents all kinds of snooping though it does mean you'll have to be careful to keep your OAuth server's certificate up to date. (Note, the OAuth server can have a public SSL identity; it's still impossible to forge with even vaguely-reasonable amounts of effort. It's only the private key that needs to be kept secret.)
That said, you need to be more careful about what you are protecting against. Why do people have to use your client code at all? Why does it have to be “secret”? Easier to give that away and put the smarts (including verification of login identity) on your server. If someone wants to write their own client, let them. If someone wants to wave their account in public in a silly way, charge them the costs they incur from their foolishness…

Transport-level vs message-level security

I'm reading a book on WCF and author debates about pros of using message-level security over using transport-level security. Anyways, I can't find any logic in author's arguments
One limitation of transport
security is that it relies on every
“step” and participant in the network
path having consistently configured
security. In other words, if a message
must travel through an intermediary
before reaching its destination, there
is no way to ensure that transport
security has been enabled for the step
after the intermediary (unless that
interme- diary is fully controlled by
the original service provider). If
that security is not faithfully
reproduced, the data may be
compromised downstream.
Message security focuses on ensuring the integrity and privacy of
individ- ual messages, without regard
for the network. Through mechanisms
such as encryption and signing via
public and private keys, the message
will be protected even if sent over an
unprotected transport (such as plain
HTTP).
a)
If that security is not faithfully
reproduced, the data may be
compromised downstream.
True, but assuming two systems communicating use SSL and thus certificates, then the data they exchange can't be decrypted by intermediary, but instead it can only be altered, which the receiver will notice and thus reject the packet?!
b) Anyways, as far as I understand the above quote, it is implying that if two systems establish a SSL connection, and if intermediary system S has SSL enabled and if S is also owned by a hacker, then S ( aka hacker ) won't be able to intercept SSL traffic travelling through it? But if S doesn't have SSL enabled, then hacker will be able to intercept SSL traffic? That doesn't make sense!
c)
Message security focuses on ensuring the integrity and privacy of individ-
ual messages, without regard for the network. Through mechanisms such
as encryption and signing via public and private keys, the message will be
protected even if sent over an unprotected transport (such as plain HTTP).
This doesn't make sense, since transport-level security also can use encryption and certificates, so why would using private/public keys at message-level be more secure than using them at transport-level? Namelly, if intermediary is able to intercept SSL traffic, why wouldn't it also be able to intercept messages secured via message-level private/public keys?
thank you
Consider the case of SSL interception.
Generally, if you have an SSL encrypted connection to a server, you can trust that you "really are* connected to that server, and that the server's owners have identified themselves unambiguously to a mutually trusted third party, like Verisign, Entrust, or Thawte (by presenting credentials identifying their name, address, contact information, ability to do business, etc., and receiving a certificate countersigned by the third party's signature). Using SSL, this certificate is an assurance to the end user that traffic between the user's browser (client) and the server's SSL endpoint (which may not be the server itself, but some switch, router, or load-balancer where the SSL certificate is installed) is secure. Anyone intercepting that traffic gets gobbledygook and if they tamper with it in any way, then the traffic is rejected by the server.
But SSL interception is becoming common in many companies. With SSL interception, you "ask" for an HTTPS connection to (for example) www.google.com, the company's switch/router/proxy hands you a valid certificate naming www.google.com as the endpoint (so your browser doesn't complain about a name mismatch), but instead of being countersigned by a mutually trusted third party, it is countersigned by their own certificate authority (operating somewhere in the company), which also happens to be trusted by your browser (since it's in your trusted root CA list which the company has control over).
The company's proxy then establishes a separate SSL-encrypted connection to your target site (in this example, www.google.com), but the proxy/switch/router in the middle is now capable of logging all of your traffic.
You still see a lock icon in your browser, since the traffic is encrypted up to your company's inner SSL endpoint using their own certificate, and the traffic is re-encrypted from that endpoint to your final destination using the destination's SSL certificate, but the man in the middle (the proxy/router/switch) can now log, redirect, or even tamper with all of your traffic.
Message-level encryption would guarantee that the message remains encrypted, even during these intermediate "hops" where the traffic itself is decrypted.
Load-balancing is another good example, because the SSL certificate is generally installed on the load balancer, which represents the SSL endpoint. The load balancer is then responsible for deciding which physical machine to send the now-decrypted traffic to for processing. Your messages may go through several "hops" like this before it finally reaches the service endpoint that can understand and process the message.
I think I see what he's getting at. Say like this:
Web client ---> Presentation web server ---> web service call to database
In this case you're depending on the middle server encrypting the data again before it gets to the database. If the message was encrypted instead, only the back end would know how to read it, so the middle doesn't matter.

Resources