Quick question. Does SSL totally prevent session hijacking/fixation? Thanks.
No. Hijacking may be done for example in these scenarios:
Hacked CA root signs invalid certificates. The certificate may be used to stage man-in-the-middle attacks.
Hacked domain owner e-mail inbox makes it possible for the hacker to buy a domain-validated certificate.
Bad key policies may make it possible for an attacker to gain the private key for the certificate.
A local attack on the client computer may make it possible to see what's going on in the system, including reading session cookies, intercepting SSL traffic, injecting false CA root certificates in the systems keychain and so on.
An intrusion by an attacker on the server may be used in any number of ways to intercept traffic, reroute packets or read important system files.
The client library must validate the SSL certificate and deny sessions with invalid or expired certificates, otherwise it's as trivial to intercept the HTTP traffic as if it where in plain text.
It may be possible with an XSS attack which gives the cookie away. Web browsers should try to protect against this but you never know if all components works as expected.
Related
I have a form for name, address, bank account, iban on my website.
When the user clicks the submit button, the data gets sent to my server via PHP and is stored in my MySQL database.
How can I prevent someone from grabbing the data while it is sent from the browser to my server?
Is an SSL certificate the right way? And if so, is an SSL certificate enough?
I found this website: www.selfsignedcertificate.com. You can create a certificate for free. What's the difference between a paid and a free SSL certificate?
How can I prevent somebody grabs the data while they get send from the
browser to my server?
SSL prevents MITM (Man in the middle) attacks nicely.
Is a SSL certificate the right way? And if, is an SSL certificate enough?
SSL certificate is the right way to provide a layer of security. BUT it is not enough. SQL Injection attacks are still possible. (Many other attacks also)
I found this website: www.selfsignedcertificate.com. You can create a certificate for free. What's the difference between a paid and a free SSL certificate?
SSL certificates are generated by a signing authority. So these signing authorities charge you to verify that you really own the domain you're claiming. When you yourself become the signing authority, the certificate becomes free, (because you dont charge yourself to verify that you are you :P). And, the 'free' SSL cert will show a red bar on all browsers, because the browser does not trust the signing authority, that is you. More on this here : https://www.globalsign.com/en/ssl-information-center/what-is-an-ssl-certificate/
I've just answered a very similar question a few minutes ago.
SSL is the standard. It provides:
Confidentiality: the data is encrypted between the client and the server and cannot be read by an attacker. Typically uses the RSA
algorithm.
Integrity: an attacker cannot tamper with the messages sent between the client and the server. Typically implemented using
HMAC
Authentication: the browser is able to check that the server it is talking to is actually yours, and not an attacker. Basically, the
server shows to the browser a certificate signed by the Certificate
Authority having issued the SSL certificate (e.g. VeriSign), that
proves its identity.
All that is assuming SSL is configured properly on the server's side:
up-to-date ciphers, no support for outdated ones, proper key length
(2048 bits or higher), etc.
You can use SSL Labs to check if your SSL configuration looks
secure. Also, be sure to enforce your users to use SSL, for instance
by automatically redirecting http:// URLs to https:// ones.
SSL Certificate is the best option to prevent someone from grabbing data traveling between browser and server. But Self-signed certificate is not a solution as it won't be trusted by most of web browsers because it is not issued Trusted Certificate Authority. To overcome from this issue, I suggest you to get SSL issued by trusted CA. You will have to pay few dollars but it is worth investment. Big downside of self-signed certificate is, browsers will not consider it valid and will blow warning message to the users. It will not create great impression in users' mind.
As per the CAB Forum guidelines, certificate issued by CA should have minimum 256-bit encryption but you will not have such high encryption in the case of self-signed certificate. Paid SSL will be a good option instead of opting self-signed certificate. You can read this SSL FAQs to solve more doubts on SSL Certificates.
<form name='form1' method="post" action="nextpage.php">
<input type="text" name="t1" value="firstname">
<input type="text" name="t2" value="secondname">
<input type="submit" name="submit1">
</form>
nextpage.php
<?php
echo $_POST['t1'];
echo $_POST['t2'];
?>
I'm using multiple services to accept mobile payments for stuff like virtual currency.
Many companies will include an MD5 signature in the POST or GET callback which I can calculate to verify that the request is authentic and then reward the user with the purchased credits.
This method is very secure as it's nearly impossible to guess the signature.
Other companies will not provide a signature and just tell me to check if the call is from their server IP like the following code:
<?php
if(!in_array($_SERVER['REMOTE_ADDR'],array('xxx.xx.x.xx'))) {
header('HTTP/1.0 403 Forbidden');
die('Error: Unknown IP');
}
?>
Is this IP check secure enough?? Isn't it now very easy to spoof an IP address and make a GET or a POST request using that IP?
The other answers are incorrect. So I'll write my own.
With the exception of exceedingly rare situations, REMOTE_ADDR is 100% trust worthy. It comes from the TCP connection to the server, so it's practically impossible to forge without actually compromising something on the network (like the router the IP belongs to) or without having your server misconfigured (severely, Apache doesn't even let you misconfigure it like that).
So, there are two questions that I can see:
Is it safe to trust REMOTE_ADDR
Yes.
If the REMOTE_ADDR variable in PHP indicates the request came from their server, then it came from their server.
If you're using a remote proxy, then X-HTTP-FORWARDED-FOR is not to be trusted. That's where you can get into problems if you're not careful.
Is MD5() of the request safer than REMOTE_ADDR verification
NO!!!
It's a lot easier to forge an MD5 signature than it is to forge an IP address (which requires you to breach specific network hardware). And if the attacker breaches the network hardware, the game is over anyway.
What's The Best Solution?
The best solution is three fold:
Use HTTPS with Certificate Pinning
On your app, store the public key of their server. Then force the peer verification to use that certificate. That means that an attacker would need to steal the certificate of the remote server to be able to connect.
Verify IP Addresses
Using REMOTE_ADDR
Sign requests using HMAC+SHA2
Use HMAC with SHA-256 or SHA-512.
But yes, the IP check alone is quite secure.
To go deeper, we'd need to go into what types of attacks you're defending from.
Relying on server remote address is not a secure way since IP spoofing can breach the security.
But yes there are some ways by which you can prevent it like key exchange between the machines but still there is no assurance.
Better you should not rely on IP based security.
I've been looking around for a way to check if a user has connected to my website using the right (my server's) SSL certificate in PHP. I guess my question is similar to this one,
except that I'm not implying the MITM.
I've looked around but didn't find a way to get the info from the cert used in the current connection and compare it to the servers cert. This to prevent users connecting with other certs.
How would one go about doing this?
Short Answer
You don't.
Longer Answer
This is only possible with client certificates.
Your webserver identifies you to the client, not PHP. PHP never sees this and no environment variables are sent/passed to PHP aside from HTTPS=on. You don't verify yourself to yourself as it would always evaluate true. The question you linked to already has the answer, and man in the middle doesn't mean much. You are effectively asking for a solution to any and all SSL Man in the Middle attacks with a definitive PHP script.
There is no such thing as being able to connect to your host with another SSL certificate, unless something Diginotar-esque happens to your Certificate Authority.
If you want assurance that they really meant to connect to your site, simply just check the host the client connected to. If they hit your IP, and requested a certificate from it, and then verified it with your CA, they will continue with the connection, and connect to $_SERVER["SERVER_NAME"] and $_SERVER["HTTPS"] == "on"
But, honestly, why are you worried about an incorrect SSL certificate? It will be flagged by the user's PC. I'd be more worried about session decrypting.
I have no idea what you mean by "to prevent users connecting with other certs" which sounds impossible to begin with, but:
SSL happens at a layer in the protocol stack to which PHP has no access or control.
The security of your clients' connections [in the context of running a website] is beyond your control.
I have a web site written in PHP and I want to be sure that my visitors use my SSL certificate, I mean I want to be sure that there is no man in the middle. How I'll do it?
Edit: Any trick to send certificate name from POST or GET?
Edit: Or I'll send a hash to a user computer, the user computer will hash the cert name with a javascript, and compare both of them whether they mach or not. Not best solution but better than nothing.
You cannot do that: MitM attack is based on the fact that the person between server and valid client already has all the valid certificates. So for your server he behaves like any other valid client.
Assuming that there is a man in the middle, all information that "your visitor" provides (which you might somehow use to identify what certificate they are using) would actually be information that the man in the middle provides. That means you cannot trust it (which is a good rule of thumb really even when there is no MITM).
In other words, this is not possible.
Another way you could reach this conclusion is this: if this were somehow possible, "man in the middle" would not be a term we all know today.
As #Jon and #zerkms have already said, it's the client's responsibility to check the server certificate.
One way you could make sure, as a server, that the client is using a connection that has presented your server certificate is to request client-certificate authentication. Indeed, during the handshake with a client certificate, the CertificateVerify TLS message contains the signature of a digest of all the handhsake messages that have been exchanged so far, including the server certificate. If the TLS handhsake succeeds, the client will have sent the correct signature, verifiable against its certificate.
Of course, from the server point of view, this only works if you trust the client certificate.
This wouldn't completely solve the problem, in particular because it's not advisable for a client to accept to authenticate using its certificate against a server it cannot verify (even if the private key wouldn't be leaked, the identity of the certificate would be sent to the rogue party).
Again, at the end of the day, it's still the user's responsibility to decide whether it trusts the identity of the server.
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).