views:

562

answers:

13

Hi,

I have an HTML form where people can make payments on my sites. Instead of using SSL, I'm wondering whether I could use a JS lib that would encrypt the credit card information and send it to the server in clear text but encrypted, than the server would decrypt it. I found several libs that do that, they basically ask for a key pair from the server, encrypt it and send it to the server encrypted. Those are the ones I found:

http://www.jcryption.org/

http://www.hanewin.net/encrypt/

http://www.vincentcheung.ca/jsencryption/

Is that secure enough for credit card payments? I know the session is not encrypted but the only thing that really matters is the credit card information, right?

+17  A: 

You could do this, but don't. It requires javascript on the client side and while you get the encryption part you probably are going to lose the other portion of SSL which is authentication. Using your method a man in the middle attack is possible while with SSL certificates it is much less likely.

stimms
What do you mean by authentication?
Ggolo
The SSL certificate contains information about who issued it and to whom. This ensures that the certificate for foo.com is actually the certificate for foo.com and not for evilfoo.com. Oh those haXors at evilfoo.com, I despise them.
stimms
@Ggolo - The public certificate is tied to a domain and since only your server has the private key corresponding to this certificate clients can confirm it really is your server by encrypting something with the public key and getting your server to decrypt it. (Simplifying the process somewhat.)
Dave Webb
With jcryption, it works the same, the JS asks for the public key from my server and then encrypt it with this key. Then it submits it to my server which hold the private key to decode it. How could this be hacked?
Ggolo
@Ggolo The hacker points the user's DNS to a different server. Your JS thus gets *their* public key, and the user's data goes to *their* server. You never get the data, and the hacker gets the money.
ceejayoz
@Gigolo - You are right that if you used Public Key encryption in your JavaScript then if someone did pretend to be you all they would get is lots of encrypted data they couldn't decrypt. So it would be better than nothing, but the point is if someone was pretending to be you and serving a copy of your site they'd remove the JS encryption and get unencrypted credit card data. The authentication part of SSL prevents this.
Dave Webb
but in order to get the JS file that does the encryption, they need to query my server first, and there I can check the referer, if I see that it comes from other DNS I can deny the query.
Ggolo
@Dave Webb Someone could pretend to be me even if I had an SSL encryption.
Ggolo
@Ggolo No, they couldn't. That's one of the whole points of SSL - if someone tries to spoof your certificate, the certificate authority tells the user it's being spoofed.Hackers can **easily** host your JS themselves. Your server wouldn't ever know that someone was spoofing it.
ceejayoz
If an attacker was querying your server, it is absolutely trivial for them to pass any Referer line they like. HTTP Referer is **never** an adequate security mechanism for anything.
bobince
Ok so what you're saying is that someone would have access to the buyer computer, be able to modify his dns and then, instead of just installing a key logger, he would go to the trouble of replicating my site with the risk of getting caught and all? Doesn't make much sense. If I were the man in the middle, I would just let the buyer go the regular site and use the key logger to get the credit card information.
Ggolo
@Ggolo - that's why you have to pay for a _signed_ certificate. When Verisign (or whoever) sign your certificate they make some effort to confirm you are who you say you are. They user trusts Verisign so when they get a certificate for `ggolo.com` signed by Verisign they trust it. Someone pretending to be should find it difficult to get a certificate signed by a trusted authority. This is why your browser complains so much when it finds an unsigned certificate. Anyone can create an unsigned certificate for any site they like.
Dave Webb
No need for a physical keylogger. The trojans, viruses, worms, etc. that already send the vast majority of spam e-mails and are installed on millions of computers can easily edit the Windows/OSX/Linux HOSTS files to point domain names to any IP address. This is a well documented risk and pretending it doesn't happen makes you look moronic.
ceejayoz
@Ggolo - a common man in the middle attack is via DNS poisoning. Someone finds an ISPs DNS server with a security problem and reconfigures it to serve the wrong IP addresses for domains. So user browsing to say, www.amazon.com are sent the the cracker's server. This requires a mistake on the part of an ISP and requires no access at all to any systems at amazon.com.
Dave Webb
Many ADSL routers are also susceptible to attacks that let the attacker tell it what DNS servers to use.
caf
+15  A: 

You could use JS encryption and chose to ignore the fact that it wasn't secure.

The problem you'd have then is that people wouldn't want to enter their credit card details on a page without an SSL connection. It wouldn't just be techies; a lot non-technical users know to look for the padlock before entering their Credit Card number, even if they have no idea what TLS or SSL are.

Dave Webb
I could add a big icon that says it is encoded.
Ggolo
That wouldn't remove their skepticism. In fact, I'd assume it was a scam site if I saw that and no SSL icon - it's common for phishing sites to claim SSL when they're not.
ceejayoz
If they have a choice between not making a payment and making a payment over an unsecure line they will most likely choose the latter. That's a sad fact.
Joey
And I still wouldn't believe you. If I see a site asking for Credit Card details which hasn't gone to the effort of sorting out a certificate I _always_ assume it's some kind of scam.
Dave Webb
What's to stop a man in the middle from substituting his own public key?
erickson
@erickson - Nothing. Have removed the bit about "might be secure".
Dave Webb
Dave: I read a paper a while ago where they chose a padlock as a favicon and got away with it. You'd be surprised how little users actually look for signs of security.
Joey
@Johannes Rössel - sadly you're right. Whilst some know what to look for, I'm sure there are plenty of people out there who'd email their credit card details if asked nicely. People wouldn't bother phishing if there weren't some people who would fall for it.
Dave Webb
Why bother substituting his own public key? Just substitute his own javascript!
caf
+10  A: 

What if the user disables JavaScript in their browser? I would say, play it safe and stick with SSL.

nickyt
I could have a check that would disable payments for people with no javascript.
Ggolo
@Ggolo That seems like a shitty revenue model. Throwing away perfectly good customers?
ceejayoz
Good customers have js enabled, only ultra nerds don't have it, and those nerds usually don't spend a dime so I couldn't care less.
Ggolo
I'm a "nerd" and I spend plenty of dimes.
ceejayoz
Wow, you're a real charmer aren't you "Ggolo"? What about disabled users using a screen reader? I guess you don't want their money either, huh?
John Topley
Disabled users can use js perfectly, it just has do be done right, google it.
Ggolo
Disabled users can use JS if they have a JS-enabled screenreader. Many don't. Again, requiring JS for an e-commerce solution **will** lose you revenue. SSL certs are only $13 at GoDaddy.
ceejayoz
The JS is just used for encrypting the form before submission, nothing needs to be read here, what are you talking about?
Ggolo
@Golo - I actually said what if a user disables JavaScript. Not a disabled user using JavaScript.
nickyt
@Ggolo - Blind people usually use a browser called a screenreader. They generally won't be using Firefox.
ceejayoz
+11  A: 

Not at all. Remember that SSL also allows the client (the browser) to verify the authenticity of the remote party (your server). You have to make sure that the server you get the keys from is actually the one you want to get the keys from and not an entirely different machine. (cf. Man in the middle)

Joey
I don't need an SSL connection though to verify the authenticity of the remote party. I can check referer and more.
Ggolo
That doesn't help you one bit if the hackers have hijacked the user and pointed them at another server entirely.
ceejayoz
Ggolo: Sure, you could roll your own SSL replacement in JavaScript but heck, where's the point in that? There already is a protocol which allows for (a) authentication of remote parties and (b) encryption of traffic between them. Why re-do it if you can just rely on what others are providing already? Or, to paraphrase Bruce Schneier: "Anyone rolling his own crypto is either a genius or a fool. Given the genius/fool ratio of our species, the odds aren't very good."
Joey
HTTP Referer as a security measure: hilarious. HTTP Referer as a security measure protecting my credit card details: terrifying.
bobince
+15  A: 

No. Do not use javascript to secure credit card payments.

If you did, it would be trivial for someone to copy all your source code, and then poison the DNS cache or even setup phishing sites and send your users' payments into their bank account.

Here's a scenario.

  1. You complete your website, example.com, and put everything online. Site launches, yay. You've used javascript to secure your credit card payments system.

  2. Someone named Nefarious Hacker notices that you're not using a tried-and true method of securing vital personal information, so he downloads all of your HTML, JS, and CSS.

  3. N. Hacker strips out all the js based encryption, leaving only the form. He then hosts it at evil-example.com. It looks exactly like your site, and behaves exactly like your site. Except that it submits unencrypted credit card data to N Hacker's database.

  4. N. Hacker sends out some phishing emails that point users to evil-example.com. A few users, believing the evil site to be valid, submit payments. Their credit card is now stolen.

  5. N Hacker is able to successfully poison a DNS cache, so some users going to example.com instead are served up evil-example.com. They have no reason to believe the site is fake (the url is what they expect), so they submit payments. Their cards are now stolen.

If you had an SSL cert, the users would know IMMEDIATELY that the evil-example.com was not trusted, or that evil-example.com pretending to be example.com was fake.

(I'll make it big so it's obvious)

Bottom line - javascript is not secure enough to do CC payments.

davethegr8
+8  A: 

@stimms explains well why this is dangerous - SSL does both encryption and ensures that the encrypted data is going to the right place as well. On top of that, browsers treat SSL and non-SSL caching differently - if you're not serving these pages over SSL, the user's browser may store vital information in the clear on the user's computer.

Even if perfectly safe, this wouldn't be a good idea either. Many users have had the rule "look for the lock icon for e-commerce" drilled into their brains by IT staff, tech-savvy relatives, etc. Spring for the $25 for a SSL cert.

edit: Another potential issue - most credit card companies require transmission over SSL. Doing it with just JS may well violate your merchant agreement - fines and termination might ensue.

ceejayoz
Where can you get SSL certs for $25?
stimms
Actually, GoDaddy appears to be selling them for $13 - http://www.godaddy.com/Compare/gdcompare_ssl.aspx
ceejayoz
Huh, well look at that. My concept of SSL certificate prices is 5 years out of date.
stimms
+12  A: 

The potential legal trouble you could get in from this is way not worth avoiding the cost of SSL.

Peter Bailey
+1 Quite apart from all the technical reasons why this harebrained scheme is disastrously insecure, it's also against PCI-SIG rules and almost certainly against the rules for your merchant account.
bobince
+8  A: 

In addition to the points everyone else has made, SSL is an established standard and every Web browser has built-in support for that standard. The browser GUI changes in some way to let me know that I'm using a secure connection and I can inspect the certificate details if I want to.

Browsers don't have any support for whatever home-grown scheme you come up with.

John Topley
+29  A: 

This is not secure in any way, shape, or form.

A man-in-the-middle can replace the public key with his own. Any kludge you devise with "referer" or anything else besides SSL is not going to restore security to this atrocious scheme.

When you can get a marginal certificate for free, or a decent certificate for next to nothing, why would you screw around with people's credit card number? By failing to secure a credit card number in transit, you are violating PCI, and probably exposing yourself to a liability many times greater than the cost of obtaining and using a certificate. Or maybe you are just figuring that's the cardholders' problem?

You cannot bootstrap a secure channel entirely in-band. You need some secure medium for exchange of key material. That might be the distribution of a Certifying Authority's public key. Or perhaps meeting face-to-face to share a secret key.

Regardless of the scheme, you cannot build security out of insecurity.

erickson
I didn't know what PCI was so googled it: http://en.wikipedia.org/wiki/PCI_DSS
Dave Webb
The man in the middle doesn't even have to replace the public key with his own. He can just replace the javascript "encrypt" function with `function encrypt(str) { return str; }`.
caf
"you cannot build security out of insecurity"... I don't agree (SSL is built over TCP ordinary connections). But -with the rest- I TOTALLY AGREE.
helios
Helios, the point is precisely that you can't create a secure SSL connection without having first securely obtained some public key. That is, you have to have a secure channel for getting the CA certificate; if you got it over that ordinary TCP connection, it could be spoofed, and the authenticity of everything depends on it.
erickson
+6  A: 

Ggolo, seriously dude, don't do this. Any site passing credit card details is going to get attention from hackers, who WILL find some mistake or exploit in your hand-rolled approach if they try hard enough. Just stump up for the SSL cert.

JonoW
+8  A: 

While technically the data encrypted in JS would be similar to encrypting it with a real cert, I think you are missing a key element here; TRUST. When using a real SSL cert from a trusted provider, you are making a circle of trust:

  • Customer trusts Microsoft
  • Microsoft trusts GoDaddy/Verisign/whoever (by virtue of Windows or any other web browser shipping with the root certificates)
  • GoDaddy/Verisign/whoever trusts You (by virtue of you having bought a cert from them, and they verify your identity)
  • Green lights and locks appear in web browser, and user can inspect the certs themselves if they want, Which in turn means Customer trusts You.

When you just have an unsecured web site, with the words "your data is secure, just ignore what your web browser is telling you", then the customer does not trust you.

(and if they do, then forward me their info, I have a bridge to sell them...)

Also, for what it's worth, there are standards from the major CC companies on how to handle and store credit card info. Google "PCI DSS" for details, or: https://www.pcisecuritystandards.org/security_standards/pci_dss.shtml

rally25rs
+1  A: 

The PCI DSS standards are now a requirement so you even if you could do this with JS (which as has been extensively discussed on this page - you can't) then you still wouldn't get PCI approval so you wouldn't be allowed to use it.

If you absolutely want to avoid buying an SSL certificate then look into your payment providers service. Most of them provide a third party hosted solution such as Paypal, SagePay, etc where you are passed out from your site over to the providers website to take the credit card details and then passed back.

This removes the burden from you to a) be compliant and b) buy an ssl cert.

rtpHarry
The only problem is those payment providers charge a fee for every transaction. 3% on every credit card transaction is much greater than $13 for a SSL certificate.
Exception
credit card merchants also charge a fee per transaction, even if you have an ssl cert.
sfjedi
A: 

Hope you're kidding.

If not, please let us all know your future website address, so we can buy ourselves some free stuff with the credit card information we'll be able to read.

Cheers.

G.M.