I'm working on an open source PHP application. The application may need to connect to my server, to transfer sensitive data. I have SSL installed on my server and I think I have set it up properly, but I'm hoping someone here can confirm.
The application will be used on other users servers, so it will be server to server communication.
I will treat users servers as clients when connecting to my server. My server will never connect to their server, so they don't need SSL on their end (right?).
I use cURL to make the calls (to my server) and POST data during the connection. So I cURL to a https address.
Now I thought that is it. Once I cURL a https address, everything is secure. I can send whatever I like (Credit card numbers, passwords, etc etc) securely, without worrying about the middle man. End of story.
But after reading around, I've noticed that some people are doing other stuff in their cURL session - Like including a certificate (.crt file):
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
Is that safe for open source? Should I do it too? Or am I safe with what I've got?
Depending on the system you're installing cURL on, it may or may not have enough information to verify an SSL certificate (this can be improved by linking intermediate and root certificates into your website certificate). You can also read it here: http://curl.haxx.se/docs/sslcerts.html
It sometimes makes sense to ship a bundle explicitly, especially since cURL tends to get shipped with old certificate bundles. You can download a more recent one here (which is taken from the Firefox source code): http://curl.haxx.se/docs/caextract.html
If your software will exclusively talk to your own server, you could also ship a bundle containing only your own public certificate. This would allow you to use self signed certificates which is free :)
You attach your client certificate along CURL calls if the server at the other end has specifically provided you with them and are not accepting any connection from other clients than the ones who have those client certificates.
If you are talking about a website here, you dont even need to worry about that here.
But if you are talking about some service providers which you access for any secured resources, and if they require you to produce client certificates, they will issue them for you and tell you explicitely to use them.
For an example, we have a system which only private members can access. We have an RPC endpoint where other members send request to. And since we only allow access to our members (private NOT public like websites) we issue them client certificates and explicitely direct them to attach those along with their service calls.
Related
I deal a lot with self-signed SSL certificates as I deploy the systems in offline environments. The problem is that for example Chrome users has to deal with "dangerous site errors" etc, also if I want to even use GuzzleHttp library for connecting to any other service I have to setting secure to none. What's the best way to deal with it?
If you have a Selfsigned certificate this can be made trusted to the specific system that you use. If others from your office uses it then they may need to add this Selfsigned certificate as trusted by adding it to their system certificate store to make this trusted.
When it comes to office environment it is better to contact the Administrator and add the certificate to all the systems (certlm.msc in run for local machine / certmgr.msc for current user) so your colleagues won't get this dangerous site errors.
Is it possible to authenticate a web browser using an ssl certificate.
Say i store a private key in my application, is there any way to read a key from a browser and try to authenticate based on that?
You can authenticate a browser/user using SSL/TLS client-certificate authentication.
The client certificate must be requested by the server, so you'd need access to the server configuration (not just installing some PHP code on a shared server). This is done at the SSL/TLS layer (in fact, the mechanism is not specific to HTTPS): the server requests the client-certificate during the SSL/TLS handshake (sometimes via a renegotiated handshake). In Apache Httpd, this is typically done via SSLVerifyClient (although you'll need to specify other options too).
The server will then verify the certificate against the CAs you've configured it with (possibly your own, and possibly independent of the CAs used for the server certificate itself). (Alternatively, you could disable certificate verification at the server level in some cases, and have the PHP application do it, but this is a bit more advanced and you'd need to know what you're doing.)
You can access the client certificate from your application and obtains its Subject DN (or alternative names), to identify the client.
It's not clear whether you're after identifying a browser or a user. In the end, everything goes through the browser anyway, but client certificates tend to be allocated to users. Users would have to install that certificate into their browser.
EDIT: For further details, it would help if you could clarify your question and what you intend to do with this.
Is it possible to authenticate a web browser using an ssl certificate.
Say i store a private key in my application, is there any way to read
a key from a browser and try to authenticate based on that?
Firstly, strictly speaking, there's no such thing as an "SSL certificate", since multiple types of certificates can be used for SSL/TLS, and some of these same certificates can also be used for other purposes than SSL/TLS. Typically, "SSL certificate" means "X.509 certificate in the context of SSL/TLS".
Therefore, authenticating a web browser using an SSL certificate implies doing it at the SSL/TLS layer. (There have been attempts to implement message-level security using X.509 certificates at the HTTP layer, but they're not widely supported by browsers.)
Secondly, the private key is held by the remote party that you authenticate. The local party that authenticates the remote party doesn't see any private key. If you (as a server) want to authenticate a web browser, it's the browser that needs to have the private key, not your (presumably PHP) application. In this context, it's not quite clear why your (PHP?) application would have/need a private key if it's the browser that you want to authenticate.
What your verifying application may need (if it's not done by the server itself) is a CA certificate to be able to verify the client certificate it is presented with (or at least some form of trust anchors with which to verify the client certificate). There's no private key required here, just public keys and certificates, unless you want your application to be a CA too.
Indeed, you could have your application be a mini CA. It could make the browser generate a key-pair and send a certificate request to the server (there are mechanisms to have a web page make the browser do all that). Then the server would generate the certificate and make the browser import it back against its private key. Subsequently, the browser could use this certificate for authentication with that server (or other servers that would recognise these certificates).
No, you cannot do that.
There is some development going on, and a few day ago W3C has made a proposal for a encryption standard.
You can however put a key in a cookie and use that to identify. This is the default PHP session id behavior.
Here's the situation:
I'm working on an open source web application (in PHP) that will be distributed to domain owners (abbit like WordPress).
Now I (my server) needs to communicate with my users (users server). I'm going to be using cURL to transfer data between servers (using POST).
The only problem is, I have a SSL certificate, but the users won't have one. So the users server will be able to talk to my server without some evil b***** eavesdropping, but my server will not be able to talk to my users server, securely.
And I certainly do not want to require users to purchase SSL certificates in order to use the application.
I was wondering if there is a way to get away with only using one SSL certificate and still manage to POST data to and from securely?
I'm also open to any alternative suggestions.
Thanks!
You can post a request to call your server back (and pass some unique ID of the data to be requested from your server), so that servers connect to your server as clients, pass the ID and get their information.
The question, though, is what you need the certificate for. If you want to authenticate those servers (or ensure that your data only reaches legitimate servers), then you need those servers to have valid certificates (BTW They are not called SSL certificates, the naming is wrong). Otherwise spoofing the server is easy.
Currently setting up a backup solution that sends a database dump and some other files from a Wordpress network to a NAS on my LAN, via WebDAV. I have installed PHP WebDAV on my web server and the basic code to get that that to work is:
webdav_connect('http://webdav.example.com/dav', 'davuser', 'davpassword');
webdav_put('/your/nice/thing.txt', $data);
webdav_close();
The issue is, my NAS requires this connection to be done via HTTPS, so in a web browser you'd see a warning which you can ignore, but PHP gives the following warning and the code fails:
Warning: webdav_put() [function.webdav-put]: Server certificate verification failed: certificate issued for a different hostname, issuer is not trusted in /var/www/vhosts/blah/blah/blah.php on line 5
Is there a way in which I can ask PHP to ignore this, or will I need to obtain an SSL certificate? The domain name used for accessing the WebDAV service on my NAS is one provided by Dynamic DNS if that makes a difference.
Is there a way in which I can ask PHP to ignore this, or will I need to obtain an SSL certificate?
I don't know which HTTP Layer PHP WebDAV uses (which extension are you using?), but often it's possible to configure the underlying layer to ignore certificate errors.
If you need certificate verification for security reasons, you should obtain a valid certificate.
Just for completeness as I don't like leaving things un-answered. I've decided to access my WebDAV service via SMEStorage. They provide an API which developers can use for this sort of thing:
http://smestorage.com/?p=static&page=for_developers
I have a program written in PHP, and I'd like to make sure that login pages etc. are all served over SSL. Is there any good start to finish tutorial for doing so?
Also, does this affect my code in any way, or is it just a matter of getting a SSL cert, and setting up a server correctly?
If your html code contains absolute urls ("http://my-domain.com/...") to:
stylesheets
images
javascripts
Browsers will complain "This page contains both secure and non-secure items".
Use relative urls if you can, or link to "https://my-domain.com/..." urls.
Use free certificates
You don't have to spend money to get valid SSL certificate:
Let’s Encrypt
Let’s Encrypt is a free, automated, and open Certificate Authority.
It depends on the hosting how easy this is to setup, it could be just a checkbox.
The process is well documented on https://letsencrypt.org/
StartSSL
For more traditional certificates, you can get a "StartSSL™ Free" from StartCom.
The site also contains information on installing the certificate.
Firstly a word of warning. if you are considering using SSL its because you have something to protect. Therefore take the time to understand what you are doing every step of the way. Security (not just SSL) is a minefield even for the experienced.
I don't know of any tutorials, but there are plenty of gotcha's you have to be aware of.
Rolling your own ssl cert for testing purposes is free, but you will need to install it on your server.
Most of the time your code does not need to be any different for an ssl page or non ssl as the code itself is ssl agnostic, but as Bob says you must be careful of things like images.
Also redirects can cause popups to warn the user of redirections.
To test if the code is being called from a browser using SSL check for the SSL flag $_SERVER['HTTPS'] this should be a non empty value if SSL is being used.
$ssl_is_on = $_SERVER['HTTPS'] ? true:false;
Personally I prefer to keep my SSL code in a separate folder altogether and use apache to direct all SSL connections to that folder. that way I can be confident a script that should be protected by SSL is not called from a non SSL connection.
If you are logging them in under SSL and then redirecting them to non SSL pages you may need to account for domains and cookies
for example I always use a different domain for ssl normally https;//secure.blah.com and then redirect them to the non secure domain http;//www.blah.com so your cookie domain will need to be blah.com the default is the full domain name which means cookies for secure.blah.com won't be sent to www.blah.com and therefore your users will never be logged in.
Don't use this technique if you use a shared domain name otherwise you could have a problem with cookie information being leaked.
DC
It should not affect your code. Add modrewrite rules to your Apache config. Yes, just obtain an SSL cert (you'll need to pay to have it signed by Verisign or another certificate authority).