SSL Certificate Authentication - ssl

We have a HTTP endpoint where a form request is posted containing transaction data from a 3rd party https website.
We are investigating ways that our HTTP endpoint can contain code to check that the host that posted the request is the 3rd party website and no-one else (i.e. a hacker).
Is there any way our HTTP endpoint can authenticate with the website where the posted form request originated? Maybe by SSL Certificate Authentication?
Many thanks in advance.

To guarantee that the server on the other side is who they say they are the safest way is to have them use an SSL Certificate. If the they also need to trust who you are then each side should have their own SSL Certificate.
The IP Range solution provided in the comment could be a possible hack but it's quite brittle and it couldn't be applied in a very serious environment.
The Shared Key solution will work and it's reliable but you have to change keys from time to time depending on the volume of traffic between the two servers.
Hope this helps.

It might be better to use message-level security instead of transport-level security (SSL/TLS).
The third party website would sign the message using its certificate (or to be precise, using the private key matching its certificate), and your website would verify this signature.
This could allow for that message to be relayed by the user's browser, without needing a direct connection between the two servers.
This sort of mechanism already exists in the Identity Management world, for example with SAML and Shibboleth. (You can still have direct connections between the servers to get additional information too.)

Related

Detect when users deliberately bypass https server certificate errors

Is there a https header on the server, or JavaScript method in the browser, that will let us detect when the user has intentionally bypassed the security certificate, or any other way to detect and report this kind of situation? (We are using Linux / Apache / jQuery.)
The Web is filled with ways to routinely skip the warning, but I haven't been able to find a single thing about detecting when users skip it - just the horrifying statistic that 70% of users bypass the warning as quick as they can. (How do they measure that?)
We operate a web application that lets teachers make and administer tests. Teachers are connecting to unauthorized WiFi networks, getting invalid certificate warnings, and clicking on the browser's "accept anyway" feature so they can get to our application despite having certificate that is not authenticated. We want to understand how often this happens, and who is doing it, and progress to stopping it.
I should note that there are schools that proxy requests through their own server, with their own certificate, and we are OK with this - it's the "ignore and connect anyway" connections that we want to measure and mitigate, because those are the ones that students are setting up, without access to their own CA but ample access to lazy users.
One way to make sure that the client has seen the server certificate you sent is to use client-certificate authentication. One of the last steps of the SSL/TLS handshake when using client-certificate authentication consists of a hash of all the handshake messages signed with the client's private key.
A side effect of this is that, if the client didn't see the exact same server certificate, the server wouldn't be able to validate this signed hash coming from the client.
This certainly doesn't necessarily mean that the client checked the certificate as it should have (i.e. whether the certificate was trusted and belonged to the server the client intended to contact), but at least the server has a way there was no fake cert in the middle.
HSTS (which you mention) also has a way to make the client enforce these checks (see Section 8.4 of RFC 6797). However, it only works if the client already knows HSTS needs to be used (either as a pre-loaded host, or after a first visit), and of course relies on the client supporting HSTS (browser support is still limited).
Not sure what you mean by bypassing HTTPS. If you mean they can visit your URI without HTTPS, that means you need to block HTTP access in Apache's .htaccess, httpd.conf, or default-ssl config files. Broken padlock could mean a number of different things so it's not clear which problem you're having. You can test your site for SSL security problems here:
https://www.ssllabs.com/ssltest/
Edit:
You can compare the fingerprint of the SSL certificate on the server and on the client to make sure they match (if the client is able to get the fingerprint). That should prevent man-in-the-middle attacks with bogus certificates.
Article
and here's an answer for doing this on the server side of things. It sounds like the best way to avoid interception is to authenticate the client with their own certificate.
There is no way to detect this - the user is the only one who can see if the padlock is green and locked or red and broken.
Firefox will do this by extension and through xhtml, but it is, as of now, the only browser to support this.
I was looking for HSTS. Here is how it works and how to implement it.
TL;DR: Header add Strict-Transport-Security "max-age=15768000 includeSubDomains"

WCF Service with Message Level Encryption over HTTPS

I have seen one or two questions about this but no definite answers. I have a customer requirement to implement a WCF-based client/server solution using Message Encryption AND HTTPS. I understand that WCF doesn't support this as standard, and the options are HTTP with Message Encryption, HTTPS without Message Encryption, or HTTPS with Message Credentials.
None of these will satisfy the customer requirement. I have control over both the service and the desktop-based clients. The service is hosted at my location and the clients access it over the internet.
I have dug around for days (and nights :( ) trying out custom bindings and so on, but whenever I try to combine message encryption with Https, I come up against this error:
"The binding contains both a SymmetricSecurityBindingElement and a secure transport binding element. Policy export for such a binding is not supported."
I would prefer to user username/password for authentication but I am prepared to use client certificates if this makes it possible. So far I haven't found any combination which is acceptable to WCF.
Is there any way to achieve this or am I just wasting my time? I would value a quick answer because my customer's deadline is drawing very near!
Thanks!
According to this, the special both mode for security (meaning both message and transport) is only supported in the NetMsmqBinding binding, which I'm guessing, is not an option for you. Does your client happen to be the NSA? (Just wondering why anyone would need their communication encrypted twice).
OK I've found a solution ...
Using IMessageInspector I intercepted the incoming and outgoing messages so that they can be encrypted and decrypted. Encryption uses a symmetric technique - best because asymmetric only allows encryption of short strings and is very slow.
The downside is that both ends need to have the private key of the certificate - so the cert needs to be installed on both client and server machines (or the key could be placed in config). This works for me though because the number of users is limited and all are under the control of the IT dept.
If I had more time I would have looked at setting up a second SSL connection with a different cert, purely to handle the certificate negotiation and avoid placing the cert on the client machine. Using SslStream was a possibility but I wasn't sure whether I could access key information to use for my own encryption, or whether this is held privately within SslStream class.
For now I'm just pleased to have it working before my deadline (only just though :) ) ...

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.

Verifying caller/server in WCF

My scenario:
Many WCF clients which are in environments outside of my control
Server will either be mine OR in an environment outside of my control
So worst case the client and the server is outside of my control. More specifically, I might assume that someone hosting this code could try to maliciously impersonate either the server or the client (the server being more likely). However, the client needs to verify that the server is my code and the server needs to verify that the client is my code. I've seen all the recommendations to use certificates; however, is that an option given my scenario?
One approach I've considered is to write an IClientMessageInspector and an IDispatchMessageInspector to set and verify a custom SOAP header on both sides. I would create an HMAC signature based on a secret key contained within the source code (assume I have a way to keep this hidden) and then verify the digest based on the message body.
I feel like this would work; however, I feel like there might be something more out-of-the-box that I'm missing here. Am I close, way off track? Thanks for any guidance!
Certificates are definitely the way to go in your situation.
Your server will easily be authenticated by clients because it will provide a certificate known to each client, SSL is a good option here.
The server will also be able to authenticate clients by requesting that every client should provide a certificate (server can check for a specific issuer of the certificate - your own issuer in that case).
Now you just need to correctly manage/secure your certificate server to make sure that it won't be compromised.
I don't think there is anything out of the box to do this, simply because it is an unusual requirement for the server to verify that the code on the client calling the service is authorized code.
Generally, it is sufficient to establish trust as follows:
Server has a certificate and service uses SSL - this way clients are confident that they are connecting to the correct server machine.
Clients provide authentication details (eg username/password, certificate etc) to the server so the server knows the connecting client can be trusted.
You are attempting to go the extra step to verify that not only are the users/machines verified, but also that the code running is verified - this is simply overkill. If the code running is not verified, either:
One of the machines has been compromised, in which case you have bigger issues to worry about.
One of your users has written code against your service and is using it 'illegally'. This should not be a problem if your service only allows authorized users to perform 'dangerous' operations.

OpenID Over SSL with self signed certificate

I setup my own open id provider on my personal server, and added a redirect to https in my apache config file. When not using a secure connection (when I disable the redirect) I can log in fine, but with the redirect I can't log in with this error message:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
I'm guessing that this is because I am using a self signed certificate.
Can anyone confirm if the self signed certificate is the issue? If not does anyone have any ideas what the problem is?
The primary benefit of using SSL for your OpenID URL is that it gives the relying party a mechanism to discover if DNS has been tampered with. It's impossible for the relying party to tell if an OpenID URL with a self-signed certificate has been compromised.
There are other benefits you get from using SSL on your provider's endpoint URL (easier to establish associations, no eavesdropping on the extension data) which would still hold if you used a self-signed cert, but I would consider those to be secondary.
OpenID is designed in a redirect-transparent way. As long as the necessary key/value pairs are preserved at each redirect, either by GET or POST, everything will operate correctly.
The easiest solution to achieve compatibility with consumers that do not work with self-signed certificates is to use a non-encrypted end-point which redirects checkid_immediate and checkid_setup messages to an encrypted one.
Doing this in your server code is easier than with web server redirects as the former can more easily deal with POST requests, while also keeping code together. Furthermore, you can use the same end-point to handle all OpenID operations, regardless whether or not it should be served over SSL, as long as proper checks are done.
For example, in PHP, the redirect can be as simple as:
// Redirect OpenID authentication requests to https:// of same URL
// Assuming valid OpenID operation over GET
if (!isset($_SERVER['HTTPS']) &&
($_GET['openid_mode'] == 'checkid_immediate' ||
$_GET['openid_mode'] == 'checkid_setup'))
http_redirect("https://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
As the openid.return_to value was generated against a plain HTTP end-point, as far as the consumer is concerned, it is only dealing with a non-encrypted server. Assuming proper OpenID 2.0 operation with sessions and nonces, whatever information passed between the consumer and your sever should not reveal exploitable information. Operations between your browser and the OpenID server, which are exploitable (password snooping or session cookie hijacking) are done over an encrypted channel.
Aside from keeping out eavesdroppers, having authentication operations be carried out over SSL allows you to use the secure HTTP cookie flag. This adds yet another layer of protection for checkid_immediate operations, should you wish to allow it.
(Disclaimer: I'm new to OpenID, so I might be wrong here.) The communication between the Open ID Consumer (e.g., StackOverflow) and the Open ID Provider (your server) does not require HTTPS -- it will work just as fine and just as securely over plain HTTP. What you need to do is to configure your server to switch to HTTPS only when it shows you your login page. In that case, only your browser needs to concern itself with the self-signed certificate. You could import the certificate onto your PC and everything will be as secure as with, say, Verisign-issued certificate.
It sounds like it. The client of your OpenID server doesn't trust the root certification authority.