Is accepting all client certificates considered insecure for a public OPC UA server? - opc-ua

I am aware of certificate chains when validating a client certificate. Still, this either puts a lot of burden on the server administrator or restricts clients, which can be unfavorable when implementing a public OPC UA server.
An implementation of the client certificate validator that accepts all certificates for message encryption/signing is certainly possible. But would such an implementation be considered insecure in that matter?
If yes, how?

Yes, it is considered insecure.
Aside from the (hopefully) obvious use case, where certificates ensure you know exactly what client applications are allowed to connect to the server, certificates are also the first line of defense against malicious clients and are part of a "defense in depth" strategy.
A malicious actor that can't establish a secure channel with the server doesn't have much to work with. A malicious actor that can establish a secure channel can, e.g., open many connections, create many sessions (without activating, potentially causing a DoS are you use resources), attempt to guess credentials, re-use default credentials that an application may ship with, etc...
Further... in the face of the recent CIS alert re: ICS/SCADA devices + OPC UA servers, you'd be a bit of a fool to willingly ship a less secure product for the sake of convenience.

Related

Can a application built with server certificate inserted in it?

I have a client a application which is distributed to multiple clients. Sometimes this application acts as server for some processes.I want the communication to be over ssl. I want to insert the server certificate inside the application and publish to multiple clients. Is this design a good idea?
Is there any real time product example which is using this design?
You could possibly add TLS communication this way, but as I understand your question, all application instances would receive the same certificate and they could thus impersonate each other. If someone extracts the private key for the certificate in one app they can decrypt all the communication for all processes and applications. Just the fact that the key is distributed to multiple environments outside your control could justify revocation of the certificate an any time.
The design is not a good idea if you want proper TLS communication with a publicly trusted root. The processes and applications will likely have to communicate using untrusted certificates, possibly self signed certificates.

Apache Thrift - How to provide secure communication

I want to secure the communication between Thrift server and client instances. To achieve that, firstly I enabled SSL communication using keystore on the server-side and truststore on the client-side as explained in this post: https://chamibuddhika.wordpress.com/2011/10/03/securing-a-thrift-service/
Afterwards, I wrapped my transport instances on both client and server with TEncryptedFramedTransport.java class provided in the following SO post: Symmetric encryption (AES) in Apache Thrift. This enabled symmetric encryption of messages transferred through socket connection.
My question is that does applying both of these make my communication more secure? Or is it unnecessary to apply both and should go with only one of these?
There is a concept called "defense in depth". The idea is that you still have one more defense in place even when one might got broken. The downside is, as always, that you have to pay for it with performance.
The real question here is this: Do I trust SSL/TLS alone or do I absolutely want to add another (application-)level of security that serves as another hurdle if some man-in-the-middle manages to get inside my SSL/TLS channel, even if that will cost me some performance?
Another aspect could be that might be forced to communicate across unsecure channels, i.e. when there is no TLS available. Remember, Thrift allows to switch transports as needed, and the SSL/TLS infrastructure is only available in certain cases.
If the answer is yes, do it. It would be the same answer with REST, SOAP, XMLRPC, Avro, gRPC or the well-known avian carriers.
So the final, decisive answer if you should do that depends on your priorities.
Be also aware that there could also be other attack vectors in your solution that might need to be adressed.

Best practice for secureing an existing socket connection, without SSL

In Best practice for secure socket connection, the OP wants to secure the connection between two sockets, without SSL.
Thomas Pornin suggests SSH is the answer.
Is this answer based on SSH port forwarding of existing sockets, or just switching to SSH in general?
If not, and the question was how to make existing sockets more secure without SSL, what is the best way to to do that?
If a client on port 10 connects to a server on port 20, how can the server restrict access so that only client on port 10 can connect? And that it really is the client on port 10 (not an imposter)? (Availability only for an authenticated client).
The answer there is any form of the SSH protocol, which is based on channels. You can use those channels to transmit fairly arbitrary information, including port-forwarded data or terminal sessions, or anything you can turn into a byte stream. That said, TLS is generally much easier to implement in code because the libraries are ubiquitous and designed to be used this way. SSH is easier to implement in scripts on Unix-like systems because it has a powerful command-line API.
In most cases, TLS is the better choice. Unless you have a very specialized problem, TLS is almost always the better choice. So the question here is, what problem do you have that TLS doesn't work for? If it's "I hate TLS" then sure, SSH. But TLS is better in most cases.
TLS authenticates using client certificates. SSH authenticates using your private key. In either case, the cert/key is stored in a file that the client reads and uses to authenticate to the server.
It's not clear from your question what you mean by "client" or "imposter" here. Anything that has access to the cert/key will be authorized (possibly requiring a user-provided password), so those must be protected. If when you say "client" you mean "my application," that is not a solvable problem. You can authenticate people. You can to some extent authenticate machines (particularly if you have an HSM or similar piece of security hardware available). You can weakly authenticate that client is claiming to be on port 10, but this is generally useless and extremely fragile, so I wouldn't pursue it. You cannot authenticate software over the network in any meaningful way.
Short answer, though, is to use TLS unless you have a very specialized problem and a good security expert to help you design another solution (and your security expert will almost certainly say "use TLS").

Secure RESTful API via HTTP(S): How to deal with the certificate host check without host name (only IP address)?

For implementing a RESTful API via HTTP I need a way to secure communication (encryption of communication, prevention of man-in-the-middle and replay attacks).
The API is supposed to be used for communication between software PC clients (Windows, Linux), smart phones, hardware clients on the one hand and an embedded device (the server) on the other hand.
If I use HTTPS with one (all embedded devices ever manufactured can use the same one I think) self-signed certificate (that clients have embedded/store somewhere) I get all the benefits I want.
Now I have got one issue:
As the embedded devices are always accessed by IP address, the client side host check for the certificate is going to fail. Whatever is written in the certificate is NOT going to be the host that answers.
E.g. with libcurl I have to disable the check via
curl_easy_setopt(curlEasyHandle, CURLOPT_SSL_VERIFYHOST, 0L);
This doesn't hurt too bad for self-written clients - but clients are also supposed to be written by 3rd party developers. What I find awkward now, is that 3rd parties have to know, that they have to disable the host check (and they have to do it...).
Also, I am not sure if disabling this check is always possible with whatever http/TLS lib that 3rd parties are using.
A certificate issued for an IP address (if even possible?!) is not an option, as the IP address can be changed by the user of the device.
Is there a way for a certificate to be "host neutral"? Or is a part of my approach incorrect and I should do something differently? Or is there nothing that can be done about it and everybody implements it like this?

how expensive is SSL for a RESTful API?

I am making a RESTful API and am wondering how computationally expensive it is for the server if each request is done using SSL? It's probably hard to quantify, but a comparison to non-SSL requests would be useful (e.g. 1 SSL is as expensive as 30 non-SSL request).
Am I right in thinking that for an SSL connection to be established, both parties need to generate public and private keys, share them with each other, and then start communicating. If when using a RESTful API, does this process happen on each request? Or is there some sort of caching that reuses a key for a given host for a given period of time (if so, how long before they expire?).
And one last question, the reason I am asking is because I am making an app that uses facebook connect, and there are some access tokens involved which grant access to someone's facebook account, having said that, why does facebook allow transmitting these access tokens over non-encrypted connections? Surely they should guard the access tokens as strongly as the username/passwd combos, and as such enforce an SSL connection... yet they don't.
EDIT: facebook does in fact enforce a HTTPS connection whenever the access_token is being transmitted.
http://www.imperialviolet.org/2010/06/25/overclocking-ssl.html
On our [Google's, ed.] production frontend machines, SSL/TLS accounts for less than 1% of the CPU load, less than 10KB of memory per connection and less than 2% of network overhead. Many people believe that SSL takes a lot of CPU time and we hope the above numbers (public for the first time) will help to dispel that.
If you stop reading now you only need to remember one thing: SSL/TLS is not computationally expensive any more.
SSL process is roughly as follows:
Server (and optionally client) present their (existing, not generated) public key using a certificate, together with a signed challenge. The opposite party verifies the signature (its mathematical validity, the certificate path up to the CA, the revocation status,...) to be sure the opposite party is who it claims to be.
Between the authenticated parties a secret session key is negotiated (for example using the Diffie Hellman algorithm).
The parties switch to encrypted communication
This is an expensive protocol up to here and happens every time a socket is established. You can not cache a check about "who's on the other side". This is why you should persistent sockets (event with REST).
mtraut described the way SSL works, yet he omited the fact that TLS supports session resuming. However, even as the session resuming is supported by the protocol itself and many conformant servers, it's not always supported by client-side implementations. So you should not rely on resuming and you better keep a persistent session where possible.
On the other hand, SSL handshake is quite fast (about a dozen of milliseconds) nowadays so it's not the biggest bottleneck in most cases.