Guzzle disabling certificate verification to false, how insecure is it? - laravel

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 :)

Related

Identifying which certificate is needed in order to perform https post using Oracle utl_http

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.

Securing communication on a portable intranet (changing IP addresses)

I have the following scenario:
A network will be set up on a Windows infrastructure
A website will be put on that network - It is not given a domain name and is not available on the internet. It will be addressed only via an internally recognised IP address.
A piece of software within that network will communicate with the website
(we want to avoid the 'Could not establish trust relationship issue' found with self-signed certificates without reducing security as, I believe, the accepted answer does).
The website will also be viewed on tablets and PCs.
After a few days, the service will be be put on a different network (with different IPs).
It will installed on many PCs/Networks.
I want to secure this via SSL, but it seems tricky following the 2015 update that disallowed IP addresses to have certificates.
This post suggests going via a public IP, but the solution may be completely offline in an area without internet access.
I've spent hours researching, but seem to be missing something.
How should this be done please?
I would setup a DNS server with an app.local domain that gets issued the certificate.
Even if you serve up the intermediate certificates in the TLS handshake (which you should ALWAYS do and not rely on AIA), verifying the chain becomes problematic without Internet access as browsers won't be able to reach the CRL URL (Certificate Revocation List). That is, of course, unless we're talking about your own CA (living in the same network) that issues the site certificate.
If everything you describe runs in a well guarded sandbox then you probably don't need the TLS layer at all, ask yourself WHO is the attacker and WHAT are you protecting.

Shipping SSL certificate in Mac OS X app

I'm writing a utility Mac OS X app that basically acts as a web server accepting incoming HTTP requests (think of it as a mock REST API server). I want to be able to support HTTPS, but ideally I'd like to remove the requirement for my users to have to purchase their own SSL certificates.
I've been thinking a little on how I might achieve this. Let's say I register a domain called myapp.com. I then purchase an SSL cert for myserver.myapp.com that is signed by a registered CA. I ship my app with those SSL cert details embedded within it. All my users have to do is update their /etc/hosts file to point myserver.myapp.com to whatever IP address my app is installed and running on.
In fact, by far, the most common scenario would be my app running on the same machine as the client, so I'm considering updating the main DNS entry for myserver.myapp.com to point to 127.0.0.1, and most users wouldn't have to change anything.
So, that's the basic theory. What have I missed that would make this an unworkable plan? A couple of things that have crossed my mind:
I could use a self-signed cert. However, many SSL clients barf (or throw up warnings) if the cert doesn't have a valid CA chain. I'm happy to pay the money for a real cert to alleviate this inconvenience for my users.
I would be embedding the private key for my SSL cert into my app. In theory, someone could extract that and use it to impersonate my app. I guess my reaction is "so what?" My app is a small productivity app, it isn't an e-commerce site. It doesn't collect sensitive info. It literally just simulates web server responses so devs can test their apps.
Any advice/feedback would be greatly appreciated. Thanks.
This won't work - but for nontechnical reasons.
Distributing an SSL certificate to your users along with its associated key will violate the issuance terms of your SSL certificate provider, and they will revoke the certificate when they discover what you have done. (This happened, for example, when Pivotal tried to offer SSL service for developers through sslip.io.) This will, of course, cause your application to stop working.
If your users have administrative access to their machines, they can create and trust their own self-signed CA using Keychain Access. Once they have done so, they could create a certificate (again, using Keychain Access) and insert that into your application to enable SSL.
As said in the other answer you can't ship the same certificate for everybody. What you could do is generate different for everybody:
The application ask them the domain name they want to use (a domain they must own, like myapp.example.com)
The application use the ACME protocol to get automatically a trusted certificate from let's encrypt
Note: you can provide them subdomains of a domain you control (like [clientid].yourappname.yourdomain.com) ONLY of you can register yourappname.yourdomain.com in the public suffix list (because let's encrypt have rate limits)

SSL without a certificate

I am developing a backend section for a company where they need as much security as possible because they will put sensible information in it.
They asked me to add SSL, which I added(the website is coded in codeigniter) but I don't know if a SSL certificate is really needed.
Having in mind that this website will only be accesible by a set of two different IPs, the two offices they have I don't think getting a certificate would be needed. Am I right?
Edit 24 Feb:
The data has the information of projects, list of clients so it is sensitive.
So I think I will go with a self signed ssl.
Thank you all
There are a few other issues you should keep in mind, in addition to those who have previously answered:
Will the users of this site be connecting and transferring this sensitive information over a wireless connection at any point in time? If this is the case, then yes, you need SSL.
HTTPS is not such a burden on server resources as it once was. Especially with a site only being used by a limited number of users at defined locations, you should certainly be able to provide for the maximum number of users.
If this is a private site, and cost is an issue, go with a self-signed certificate. The OpenSSL toolkit is your best bet for this. Numerous guides for setting up self-signed certificates with OpenSSL are available.
Are there legal issues involved with this sensitive data? If you are transmitting customer information in a client database with phone numbers, postal addresses, email addresses, login information - or even more seriously, credit card numbers - then you need SSL. Ask yourself if you would trust a company who transmitted this same information of yours without SSL.
If the client asked for it and is paying for it, this isn't an undue burden on you as a developer, and as a developer you really never want to be in the position where you're arguing for less security. If there's a problem later, it comes back to bite you. Cover your rear end.
Combine this with IP restricted access. If you can, do that at the Apache configuration level. If not, then do it with a .htaccess. Why at the Apache level? Again, that covers your rear end in case you forget to put the restrictions in a .htaccess, or in case someone else comes in and removes them by accident.
If there's even a question about it, use SSL.
SSL certificate is needed because somebody could read the request content on the way to your server. You can't add https to the web page without certificate (check if you have https protocol in the browser page address).
In developing stage you can generate SSL certificate by yourself (use openssl) there is no need to buy valid one. There will be warning in the browser that the certificate is not signed by any authority, but I don't think that is big problem.
If you need to protect clinet-server communication (http request/response headers and data) from being overheard, then you need to install SSL on your sever, and use https protocol. This is useful when you want to hide i.e. user credentials.
If it is just about allow/disable access for mentioned ip addresses, than it is enough to limit it in http server configuration (usually .htaccess).
Please keep in mind, that https requests requires more server/client resources (CPU), so it should not be used if not necessary.

Are valid digital certificates required on the clients (Java, C++ etc) to make successful https connections?

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.

Resources