To sum it up: I would like to have the security benefit of authentication on client cert, but don't want to pay the cost of encryption (and in Postgresql's case, compression) for the rest of the session.
In my pg_hba.conf on the server, for testing, I only have this:
hostssl all testuser 0.0.0.0/0 cert
On the client side, I have "sslmode={require,allow,...} options working already with psql. But I am looking at the "sslmode" option in the document and really wish there is one sslmode option called "require_only_for_authentication", but I can't find it.
Anyone knows a way to skip SSL encryption after authenticating with client cert in the same connection session?
Any suggestions will be appreciated!
Related
Recently I found myself working with Guzzle while making requests to another server to post and fetch some data, in some cases, tokens. But I was getting certificate invalid error and I even tried to get a new .pem certificate, but Guzzle was still not accepting and kept throwing that error. So finally, I did what the "Internet" said:
$guzzleClient = new Client([
'verify' => false
]);
Now although this solution works, I am not sure how insecure it can get. Do I need to worry? If yes, in what scenarios?
well this is a big problem if you are for example
having login system on the request you are sending using guzzle
having payment/checkout on the request
basically any sensitive data being passed to the other server
because when you pass data without SSL certificate then your requests might get caught by malicious programs like
BurbSuite / WireShark , cain and abel / EtterCap
as these programs are Sniffing programs and anyone can get a version from the internet as they are open sourced and every thing going without SSL can be intercepted by the hacker using the tools mentioned above and the hacker can look to the entire request in plaintext! so its highly recommended to use SSL connection when passing sensitive data
Worth Mentioning : now a days even SSL isn't very secure because hackers can remove it using SSLStrip tool but believe me SSL will make it much harder for them to get to your request because if they used it your website sometimes will make non-completed requests and it will notify the user that the network isn't secure this will make it very hard for the hacker to get the user's data,
TLS/SSL in common configurations is meant to give you three things:
confidentiality - no third party is able to read the messages sent and received,
integrity - no third party is able to modify the messages sent and received,
server authentication - you know who are you talking to.
What you do with setting verify to false is disabling the certificate verification. It immediately disables the server authentication feature and enables loosing confidentiality and integrity too when facing an active attacker that has access to your data stream.
How is that?
First of all TLS/SSL relieas on Public Key Infrastructure. Without going into too much details: you hold on your machine a set of certificates of so called Certification Authorities (CA) whom you trust. When you open a new communication to a service, you get the services certificates and in the process of verification you validate amongst other things if the certificate belongs to a CA you trust. If yes, then the communication may proceed. If no, then the communication channel is closed.
Attack patterns
Disabling certificate verification allows for Man-in-the-Middle (MitM) attacks than can easily be performed in your local network (e.g. via ARP poisoning attacks), in the local network of the service you are calling or in the network between. As we usually do not trust the network completely, we tend to verify.
Imagine me performing an attack on you. I have performed ARP poisoning, now I can see all your traffic. It's encrypted, isn't it? Well, not obviously. The TCP handshake and TLS handshake you believe you have performed with the target service - you have performed with me. I have presented you not the certificate of the target service, as I am unable to fake it, but my own. But you did not validate it to reject it. I have opened a connection between me and the target service on your behalf too so I can look into the decrypted traffic, modify if necessary and reply to you to make you believe everything is ok.
First of all - all your secrets are belong to me. Second of all - I am able to perform attacks on both you and the target service (which might have been secured by authentication mechanisms, but now is not).
How to fix this?
In XXI century there should be little reason to disable TLS verification anywhere. Configuring it to work properly might be a pain though, even more when you are doing it for the first time. From my experience the most common issues in the micro service world are:
the target certificate is self-signed,
you are missing a CA root certificate in your trust store,
the microservice does provide his certificate, but does not provide an intermediate CA certificate.
It's hard to guess what your issue is. We would need to dig deeper.
While the other answers points out some really good point about how important SSL/TLS is, your connection is still encrypted and the remote endpoint you're using has https:// in it as well. So you're not entirely disabling SSL when you set verify to false if I'm not mistken. It's just less secure since that you're not verifying the certificate of the remote server if they are signed by a Certificate Authority (CA) using the CA bundle.
Do you need to worry?
If this is something on your production, ideally you'd want things to be secure and configured correctly, so yes.
By not verifying the certificate, like Marek Puchalski mentioned, there's possibility of the server might not be the one you think it is and allows mitm (man in the middle) attack as well. More about mitm here, and peer verification here.
Why is it happening & how do you fix it?
Most common issue is misconfigured server, especially PHP configuration. You can fix your PHP configuration following this guide, where you'll be using adding the CA root certificates bundle to your configuration. Alternatively you can add this to Guzzle.
Another common issue is, the remote server is using a self-signed certificate. Even if you configured your CA bundle in your trustedstore, this certificate can't be trusted since it's not signed by a trusted CA. So the server needs to configure a SSL certificated signed by a CA. If that's not possible, you can manually trust this CA root, however this comes with some security concerns as well.
Hope this helped :)
Short story
I'm trying to send a POST request from a PL/SQL script using the utl_http utility in Oracle. I've been able to send the request using http, but not https. I've added what I thought was the necessary certificates to a Oracle Wallet, and I believe they are being imported and used (but in all honesty, this is a little hard to verify). My current assumption is that calls from our DB server are passing through a proxy server, and that that is somehow messing up some part of the https / certificate functionality.
Supporting evidence (possibly?): I tried to make calls (POST requests) to a dummy service at webhook.site. Again, I got this working with http, but not https - the latter results in a cert validation error.
I then tried to replicate the behavior using postman, and that basically produces the same result, unless I fiddle around with the settings:
Initial Postman result:
Could not get any response
There was an error connecting to https://webhook.site/950...
Disabling SSL verification
Under the Post man settings, I turned off SSL Certificate Verification, and tried again. This time, I got a 200 OK response, and confirmed that the webhook received the post request fine.
It seems clear that the error is due to a missing cert, but I can't figure out which, or how to configure it. My assumption is that if I can get this to work for a webhook-url from Postman (without disabling cert verification), then I should also be able to get it to work from PL/SQL later.
When I look at the webhook site in a browser and inspect the certs, the webhook cert is the lowest cert (leaf node?). Above it there is one intermediate cert related to the company I'm working for, and then a root cert also related to the company. The root node is named something like "Company Proxy Server CA" - So I'm assuming the proxy somehow manipulates my requests and inserts it's own cert here.
I've tried downloading all of these certs and importing them into my cert store, as well as importing them under the Postman settings (under Certificates) in various combinations, but nothing seems to make any difference; all attempts at posting with HTTPS produces the following error in my Postman Console:
POST https://webhook.site/9505...
Error: unable to verify the first certificate
Any ideas about how to resolve this, or at least obtain more information about what to do would be greatly appreciated.
Switching OFF "SSL Certificate Verification" in Postman only means that it (i.e. Postman) will not check the validity of SSL certificates while making a request. Meaning that it will just send the certificates as they are. Because your connection fails if the setting in ON, this means Postman cannot verify the validity of your certificates.
This is most likely the case with the actual service you're trying to POST to, they cannot verify the certificates. Is that service outside your company network? And is it a public one or one owned by your company? Where is that service hosted? What certificate do they need?
BTW, TLS client certificates are sent as part of establishing the SSL connection, not as part of the HTTP request. The TLS handshake (and exchange/validation of client and server certificates) happens before any HTTP message is sent.
I'm thinking this might be a blocked port issue.
You said... ""Company Proxy Server CA" - So I'm assuming the proxy somehow manipulates my requests and inserts it's own cert here."
That means your client software needs your Company Proxy Server CA in its trusted certificates list. If that client's list is that of the oracle wallet...
https://knowledge.digicert.com/solution/SO979.html
This talks about how to do that.
Also, if your system running postman has a non-oracle based wallet trusted certificate (probably the operating system?) you'll have to execute something like adding the trust to your account on the workstation
https://www.thewindowsclub.com/manage-trusted-root-certificates-windows
in order to have the proxy server certificate trusted.
Once the certificate you're making the connection with has a root of trust per the effective configuration of the client being used, then you'll be able to verify the certificate.
A couple of possible issues:
The server doesn't actually support HTTPS. Connect a browser to the URL that you POST to, and see if you receive a response. (It looks like you already did this, but I'm documenting it for completeness.)
The server uses the Server Name Indication (SNI) extension to determine what certificate chain to send back, but your POSTing client doesn't send that extension. You can identify this case by looking up the IP for the host you're POSTing to, then going to https://nnn.nnn.nnn.nnn/ (obviously use the IP here, instead of the literal string 'nnn.nnn.nnn.nnn') in your browser, and checking the certificate chain it returns. If it is not the same as you get from step 1, this is your problem, and you need to figure out how to either get SNI support in your Oracle PL/SQL client or get the POST endpoint exposed on that hostname. (alternatively, you might be able to use these certificates to prime your Oracle Wallet, but they might have an issue with the hostname in the certificate not matching the hostname you connect to.)
You have a proxy in the way. I don't think this is what's going on, since that would basically only cause problems if you were doing client-side certificate authentication. (If this is the problem or is a condition, you need to import those certificates into your trusted wallet; you also need to ensure that the server you're posting from is going through the same proxy. Otherwise, you need to ensure that the certificate authority for the proxy that the machine actually running the code sees is in the wallet. This may require the assistance of the system/network administrators who run that machine and its connection to the network.)
HTTPS is a finicky beast. Many, many things must work exactly correctly for TLS connections to work and the certificates to correctly verify (the TLS port must respond, the client and server must agree to speak the same version of TLS, the client and server must agree to use the same cipher combination, the certificate chain presented by the server must be issued by a CA the client recognizes, and the leaf certificate in that chain must certify the name client requested).
SNI is needed to support multiple names on a single host without messing with the certifications of other names on the same host. Unfortunately, SNI is one of those things that has been standardized for over a decade (RFC 3546), but many enterprise-grade softwares haven't implemented.
Is the Oracle Encryption good enough to encrypt Network trafic?
Or should I use the SSL option?
Update:
- Network = LAN
- With the Oracle Net manager, you can enable Encryption (AES256 for instance) or you can set up SSL.
Is the Encryption enough? When sniffing with Wireshark the data is indeed encrypted but the Protocol stays TNS. With SSL you get TLSv1.2.
I'm also looking for the option with the leaset performance drop.
As per the general configuration setup of TLS/SSL, you will have to get a certificate issued for the database. Once you have the certificate, you need to put it into a wallet, and then configure your listener to use the wallet. Also, for all the client who wants to connect to the database you will have to give them the trusted certificate and client setup will have to configured to use the certificate for validation.
For native network encryption, you need use a flag in sqlnet.ora to indicate whether you require/accept/reject encrypted connection. In case of server sqlnet.ora, the flag is SQLNET.ENCRYPTION_SERVER, and for client it's SQLNET.ENCRYPTION_CLIENT. Default value of the flag is accepted. This means you can get away without having to configure all client to use encryption for the connection. All you need is to configure the server to use network encryption.
The advantage of native network encryption over TLS/SSL is that you hardly need to do any configuration on the client. However the down side of this method is that you will not be knowing if you are connected to the intended database(server). To a certain extent, man-in-the-middle attack is possible with native network encryption. If an attacker can get into the network and redirect clients to use a malicious database, clients will not be knowing about this although all the communications will be encrypted. However, if the attacker joins the network after the client has finished connecting with the real database, he can't do any damage.
So, it all boils down to where you want to compromise. If you believe the risk of someone impersonating the database in your network is low, you should go ahead with native network encryption. However, if you want maximum security, use TLS/SSL. The downside of TLS/SSL is that it's harder to setup and maintain. You will have to reconfigure all the client connecting to the database, and everytime the server certificate changes you will have to again go to the client for reconfiguration.
Here's a great video explaining both, and the answer is mostly copied from this.
Russ Lowenthal, Director of Product Management for Oracle Security Products explains database security.
Regarding performance comparison between the two method, I don't have anything available at this moment.I will update this answer once I find something. You can see this for a comparison between unencrypted database vs native network encryped database performance.
Hope this will be helpful in some way. Thanks
Assume, I have two choices.
Use self-signed x.509 certificate on both the server and client and validate server using its certificate stored in client and authenticate client using client certificate stored in server.
Create only keys on both the server and client and validate server using server key stored in the client and authenticate client using client key stored in the server.
Assume we will use RSA with key length of 2048.
My query is what will be the performance difference. My worry is overhead involved in taking key out of certificate and doing channel encryption.
Our case is there will more number of requests and not much data to flow.
Let me know if you have any queries or concerns.
SSL and SSH they are all have the same functionality, which is Encryption. Both are Cryptographic Network protocols.
SSL:
port: 443
Application : Encryption between browser and server
SSH :
port : 22
Application : Between two Computers
This is the picture of Version Control system which has got SSH key to communicate between user and their repository!
Know how to generate SSH key Here!!
Know how to Generate SSL key Here!!
Credits :Medium
I am planning to implement a small standalone program that will make a https request to a server. Does that require a valid ssl certificate in the client? How does the SSL handshake work in that case? Are there any security issues in the client not have an SSL certificate?
Apart from encrypting the network traffic, HTTPS is normally used to authenticate the server. That is, to give clients reassuring information about who owns the server, etc. For that to work, the client needs to inspect the trust chain in the certificate published by the server. For that to happen automatically, the client machine should have a certificate installed that describes a Certification Authority that issued the server's certificate. Normally such certificates are found on your machine in a store called "Trusted Root Certification Authorities" and most OS come with a set of common CAs already installed.
In addition, many web servers offer a feature where the client can authenticate itself to the server by supplying a client certificate. The web server is able to inspect the certificate coming from the client and map it onto a set of permissions on the server. This "client authentication" is not necessary for a working HTTPS session however, it's just an option.
In short, you don't actually need any certificate on the client, but you will probably want to have a root CA certificate in order to validate the server's identity. If you don't have that certificate it will be impossible for you to trust the server (unless you have another good reason to do so), but you might choose to exchange data with it anyway.
If you wish to learn more about the HTTPS handshake and what is negotiated, i fully recommend you look at this excellent write up at moserware
http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html
A client certificate is required only if the server requires one. A client certificate allows the server to authenticate the client, but this is only useful if the server has a list of all authorized clients. That's generally not the case with a web server, so it's quite rare for them to require client certificates.
When present, the client-side certificate does not affect establishment of the secure channel. (Only the server's certificate is required for that and adding a client certificate into the mix doesn't change the process.) Once a secure channel is established, the server will use the client's certificate the authenticate the client (generally by comparing the client's public key or name with a list of authorized clients).
You dont need a certificate to make a HTTPS connection, but you do need to if you want to know with whom you are communicating.