Secure web form for accepting bank routing and account numbers - php

We have a website where we need to obtain our customers routing and bank acct #'s who want to sign up for monthly ACH withdrawals. I was wondering the best way to achieve that. I thought about first making the form an SSL/https link and forcing it with .htaccess modrewrite. Currently we are emailed the results of any information submitted to the site web forms. My next concern is the email sent from the server encrypted if you use smtp TLS etc? In other words what is the best may to transmit the data from the server back to our email securely. Or is using email to transmit the data a bad idea altogether. Any help/reccomendations is greatly appreciated.
NOTE: I would like to add that we are not actually performing the ach. We are just getting the information and passing it on to the vendor to perform the ach. Currently it is a written and signed form they fax. We can continue this process. I was just looking to automate this portion only. However, it sounds best to just outsource even this piece?

The best way to achieve this is to outsource it to a financial institution which is already compliant with PCI DSS rules, local financial regulations, and the like.
I'll repeat that: do not do it yourself. Have someone else who knows what's up do it for you.
There are services that provide this: Amazon Payments, Dwolla... Why would you need to handle the actual account numbers? What you care about is that the cash gets to you, not its exact origin.
And NO, EMAIL IS NOT SECURE. Unless you're encrypting it, and if you had to ask the question, you're not. NEVER send confidential information in a plain email. (Caveat for experts: a TLS-secured SMTP session with no intermediate relays connecting to a DNSSEC-provided IP address is reasonably secure. It's doubtful that your average Joe would implement this properly, however).

Related

Improve password security in server verification

I am currently building a setup to take credit card information. The following structure was used:
Server 1:
MySQL user set to read only
Holds the login credentials.
I use PBKDF2 hashing, done with a class i built based on this code.
Server 2:
MySQL user set to read and write
holds all of the customers credit card information
My question:
If server 1 stores the paswword in this format: algorithm:iterations:salt:hash
For example: sha256:1000:Pe27BkIKkBHklogp9Io80iRKtF+6koly:nrYUwOlixwJECRcjBRKwQ+MVNMTbnYnm
If server one was compromised, it seems to me that having the password in this format would make it easy for them to crack the passwords for the site and access the users credit card information.
Is this a case where I need to use Mysql (AES_ENCRYPT() and AES_DECRYPT())?
Am I over thinking this?
Is there a better way to protect the information in server 1?
Update Based on Comments
I built my heating and air company system. Any one that pays online can store their cc information with quickbooks if they choose. I have a few larger clients that we bill monthly in office, and process cc's through a desktop terminal. These clients have customer profiles on our servers, which they can access. These are the clients that I want to allow to store there cc information. This way I don't have to have the cc information stored on paper in our office for anyone to find.
To be honest, if I manage to compromise server 1, I'm not going to try to crack those passwords. They should be secure. What I would more likely do is try to get my own code installed on the server to send me the passwords and/or credit card information when the user logs in. For example, let's say you process the authentication in a file named login.php. If I can compromise login.php, then when it is validating the login, I can have it execute a curl command or something to send the login information to my own server where I can collect it.
But I digress... The answer is that your hashing of the user login details should be secure as you've described it. If server 1's database is compromised, it should be about as secure as it can be. You could add a layer of obfuscation within your PHP code to do something like munge in the a hash of the salt or something so that someone with access to the database but not the code would have a much harder time knowing what process you used to hash the passwords, which would avoid hackers from trying to brute force passwords such as password, iloveu, etc. I would also highly suggest that the credit card information on server 2 is stored in an encrypted format using either AES_ENCRYPT() or PHP's mcrypt_encrypt() function.
Make sure you sanitize all input via POST forms, and you should be good to go.

Is email verification with a link a bad idea

In my registration process, the user registers, they get emailed a verification link, and if they click it, only then would their account be verified. But isn't this verification method too easy for the bots?
I think an email could be created by a bot, but for sure if the verification is just clicking a link, it could also be automated by a bot. I'm not sure since I haven't done this and don't care to test it just to know, but my question is isn't this verification method flawed?
I'm thinking about sending the verification code to the user as a text which they would have to copy/paste manually into a form AND the form is captcha protected. Is this a better idea? any flaws with it?
Most of the suggestions are about verifying emails and using CAPTCHAs which of course you should do, but keep in mind that none of these methods is completely bulletproof.
Email verification
A bot can easily "click" on links in any email. Copying and pasting something would be slightly more annoying for the bot author but not much. Generally email verification is just that - email verification.
You verify if the email is likely to be controlled by whoever tries to register, but of course since email is usually sent in cleartext over untrusted TCP and relies on insecure DNS, then until we're all using DNSSEC and encrypt all traffic it will be easy to sniff emails and spoof servers and clients. The important thing to realize is that using email verification you get only a certain degree of confidence that whoever or whatever you are talking to is really a user of that email address.
Turing test
Answering a question that only human should know the answer to would be still more annoying but considering that you probably wouldn't have an infinite number of questions, the bot author might redirect unknown question to a real human and use cached answers if any question repeats more than once. Answering a question like "what is 12+8" like I've seen in some websites lately as a Turing test is completely counterproductive since this question is actually easier for bots than for humans. Probably the most popular Turing test for that are CAPTCHAs but here you also have to realize that they can be fooled.
First of all people are showing methods of circumventing CAPTCHAs, for example see the Decoding reCAPTCHA talk from DEFCON 18. Many CAPTCHAs are much easier for robots to decipher since they are generated by algorithms that are trivial to reverse. The reCAPTCHA distortions are also pretty simple but the words that they use are real scanned words that was hard for OCRs so in principle it should be much harder for bots, but it is not always the case.
And there is also a possibility to display captchas that you want to guess on other websites and have people answer it for you. Also there is a black market of people actually solving captchas so if your bot author doesn't mind paying something like two cents for a dozen then no matter how hard it is for humans, actual humans will solve it anyway.
Bottom line
The bottom line is that using any of the bot-stopping techniques will always be a compromise of how much would a bot owner (a spammer or anyone else who wants to register a lot of users in your system) be willing to spend time, effort and money to do it, and how much inconvenience for your users are you going to tolerate, because ultimately you will never be able to do any automated test to tell humans and bots apart without actually annoying humans and alienating people with disabilities (has anyone ever tried to guess the audio version of reCAPTCHA?), and still your bots may actually be human-powered, so not really bots but cyborgs, so to speak.
It's an arms race for which your honest users are paying a price. Please keep all of that in mind.
The questions is what are you trying to verify? When you send a link to an email address, what you can know is that whoever registered that account has access to the email address. It doesn't tell you anything about them other than that.
So yeah, bots can create an account, and use it for registration. If you want to stop bots, then yeah, a captcha is what you need to add. Note that there's little point in adding the code to copy/paste - that's both easy for a bot to do, and also doesn't gain you anything over the captcha.
As always, security and convenience are generally competing with each other.
A link in an email simply validates that it is an active email address. Yes, it's easy for the bots to handle this. But is your service so valuable that bots will be attacking it?
A CAPTCHA is always the way to go to ensure your users are human. The additional coding and frustrations involved with it are a trade-off.
In the end, keep things as simple as possible, but not simpler.
As pointed out already, you simply have some CAPTCHA validation.
My suggestion is though do human validation before your app creates the user account and sends the verification email. Added value of your site can't easily be forced to just spam verification emails and create bogus waiting to be verified accounts.
Nothing wrong with a link if you do that.
Yes, bots can enter emails and check the responses. I've also heard of endeavors toward bots getting better at image recognition and answering captchas, although I can't say for sure how good they are. If you are really really concerned, I would go with:
Email verification
Captcha
Simple random questions (How many ears/fingers do most humans have?)
Cell phone number that sends a code via SMS
The last one might prove to be the best in eliminating bots, but it will also limit who signs up for your website. Also, the more validations you have, the more you'll annoy users and the more you'll increase the barriers to getting them to sign up, which could also be a pretty big drawback. Personally, I think captchas are a good balance of bot protection vs. user inconvenience.
Are you verifying an email only or doing a full registration?
I always verify the email account first. then once verified complete the registration process.
so add a captcha at the verify email step.
In other words, ask the user to enter their email address, enter the captcha and submit the form.
That way only real people get the verification email sent.
It doesn't prevent human bots of course.
DC
It also means you don't need to store failed/bad registration data.
One problem is a user validating with one email address and then changing it during the registration process, I handle that this way..
When a user submits their email address the data is not stored at all. Instead I use $validation_code = md5(trim($email)+$secret) to generate the verification code. That way they can't change the email address on the actual registration form. The email and verification code is carried as a hidden field to the end to validate the email address. if the email address is altered from the verified one, registration will fail as the md5 no longer matches.
DC
I ran into similar problems with verification emails and testing. If you want to end-to-end test email verification try EmailE2E.com — it's free.
You can send and receive emails from randomly generated inboxes via an API.
It's perfect for testing Firebase, Amazon Cognito, or other OAuth providers that use email verification codes during sign up. Plus it has clients in Java and JS.

How to prevent referral registrations/downloads/visit by IP address?

Is there a way to prevent the same person from referring itself? IP address is obviously not enough to prevent these kind of scammers that know how to game a system like these. So in the current technology, how do you prevent it from happening? I can use sending messages but these process is to extensive for user registration. I can also do credit card validation but it is also very extensive for my system.
I need to track unique visits.. How?
Lets look at this the analytical way.
You need to either know whether the user is already in the system at least one time.
So you need a way of recognizing a user.
There are a lot of different methods. They all vary in convinience and security.
Some of the also are secure but can by their nature not be a unique. For example a person can hold two credit cards or mail accounts.
So I will give you a list of the common ones with their specialities:
E-Mail validation
very common, very insecure. You can make it better by blocking "junk-mail"-services, but its still very bad. For example you can use youraccount+anything#gmail.com to recieve mail. You can block that too, but there will always be leaks. Anyone can register new mail adresses)
IP validation
Very insecure. Most poeple have danymic ip adresses and you can use proxies at any time.
Only useful when wanting to confirm the same user in a short period of time. And not even that is secure.
Cookie Validation.
Very insecure for your purpose, but very effective to confirm the same user if its in the users desire. (encrypted token are a secure teqnique)
-- lets get to the really useful stuff --
Credit card validation
Kinda useful. There are algorithms for common credit cards publicly available to check the validity of a card. But they can be broken. So some1 can generate "valid" credit card numbers. Brute force attacks are also possible.
The only way of knowing the validity is making a transaction which costs about 30 cents.
SMS Validation. Sender numbers can be faked, so it must go the other way round. The user gives their mail adress and you send an sms with a code to enter. There are gatways available, one sms is about 2-4 cents.
This teqnique is commonly used and quite useful, however it cannot guarantee that a user doesnt have more than one cell phone or numbers.
Paper-Mail Validation
Perhapst the most secure way, but rather inconvinient. Send a letter with a code to the person. As long as the mailbox doesnt get hijacked or us mail doesnt miss-deliver its very good. You can even enhance by personal or secured mailing. Google uses that for adsense accounts. The user can fool you by having multiple adresses or have it delivered to a friends place or something or give the name of a co-worker at work keep that in mind.
System-Serial validation
Download a tool that generates a checksum of the computer parts you have built in. Or just take the HDD serial number. This ensures uniqueness of one pc. But it can be cracked or have the miss comfort that the same user suddenly isnt recognised anymore because the hardware has changed.
Confirmed mails
There are providers that offer mail adresses that are verified. Meaning the user has with a legally legit way confirmed their identity which is bound to to that adress.
There are also providers which ensure uniqueness of users in their system.
This is very useful, however not wide spread.
To sum up: SMS is probably the fastest and easiest way.
I think there is no way of making sure they are unique visitors without some extensive system like creditcard validation. Identifying unique visitors on the internet is next to impossible without some kind of non-internet verification. (credit card, digID (dutch), personal call)

How to send and receive encrypted email using PHP

I work at a hospital and have developed a way to estimate the total patient financial responsibility for services, after insurance has paid it's obligation, and before any services are rendered. A lot of patients are calling for quotes, and I wanted to find a secure way to email those results to the patient at their request.
I'm considering removing all patient information from the generated quote, so there would not be any security concerns, but would like to find a way to encrypt the email, send it, and allow the patient's email client to decrypt the email.
I'm not sure how to use security certificates, though they might be the best option for me, even though I'd have to jump through corporate hoops to be granted access to internet facing hosting for certificates, all applications other than email are hospital side only.
I'm also considering creating a PDF from the generated letter and encrypting the PDF, assigning their last four of their social, or some other private info they've shared with us during the quote generation process, as their password.
You would be better off sending a link to an SSL encrypted site that has all the information. It would not require any additional software on the client side, and would allow you to have a bit more control and accounting of who is accessing it.
You must of course secure it with username/password of some kind, you could even just use their social security + a generated hash sent in the email. The hash prevents a user from guessing random ssn's.
If you're employed by a hospital in the USA, you had better not try to email protected health information. (Similar things are true in other countries.) Even if you scrub the patient's name out of the message, you'll definitely have the patient's email address in the message (duh!). You'll most likely have diagnoses, dates of birth, dates of proposed care, medical record numbers, or account numbers. That's all protected data. Bad. Bad. See here for the regulations, which are rigid.
http://www.hhs.gov/ocr/privacy/hipaa/understanding/summary/index.html
If you want to do this, you must use TLS (https) security, and you must go to some length both to ensure that the person logging in to your secure web site is who they claim to be, and you must log accesses.
Please, if you value your job and your savings account, check with your hospital's privacy officer before sending emails with PHI in them. The ARRA 2009 law makes individuals personally liable for breaches even if they work for corporations. Plus, your hospital does NOT want its name in lights here.
http://www.hhs.gov/ocr/privacy/hipaa/administrative/breachnotificationrule/postedbreaches.html
You could use encrypted email, as long as the unencrypted part (e.g. the subject line) only said "here's the information you requested" or something like that. But, you know, many persons seeking medical care won't be able to cope with a complex addin to their mail client software.
The PGP company offers an encrypted email gateway system that some people with PHI use.
http://www.pgp.com/products/universal_gateway_email/index.html
But you should still check with your privacy officer.
I accomplished this about 10 years ago using PGP. GPG is a similar library.
These options may be way too involved for an older user though, as I believe they both involve the recipient installing a certificate of sorts on their end.
Might be a good place to start looking...
From what I know, this is essentially impossible unless the recipient is also using the same e-mail client. The problem is that even if you encrypt on your end, the recipient will received a garbage message simply because they don't have the functionality to decrypt.
While I was typing this, TomWilsonFL posted information on a possible encryption method, but you will still need to provide the recipient an application to decrypt the data.

HTTPS and encrypted database is really secured in shared hosting?

I read all posts on HTTP over SSL. So far, I know how to get the data securely in a Web form. But I miss the part of recover and keep the data in the same way.
I need in my Website a form to collect sensible data from customers (may be also credit cards numbers for booking, but no credit card authorization process is required) and later keep and read that data in a secure way.
Then, for a basic secure Web application I need:
a) Web site with SSL Domain Validated (DV) Certificate (I don't have fixed IP address. I use basic shared or "virtual" hosting service).
b) Develop a simple PHP & MySQL application that collect sensible data of customers, putting all the app PHP files on the SSL secure folder.
c) All the collected data is gonna be stored in the server MySQL database.
This is the questions part of my message:
1) If I enter later using phpmyadmin to take look at the database over regular hoster services (HTTP), isn't this insecure??
2) What about the hosting administrators? They could also read all sensible data if I use plain text in the database. But encryption methods for data on the server (not only in transmission over SSL) could be enough? Isn't true that the encryption encoding/decoding method could be intercepted by the hosting administrators?? (consider this: the method is inside the application in the same server).
I can't pay the convenience and security of an own server.
3) Considering those things, and assuming that they are true... really matter if I go for a database encryption?
May be I missed something or I misinterpreting some issue.
Thanks a lot for your help and patience.
These shared hosting plans are not really up to the job of collecting credit card numbers - you are betting using a payment gateway and not storing them yourself.
See some regulations on this: PCI
Yes. HTTP is insecure.
Yes, plain text in the database is insecure. Encrypted is slightly more "secure" - it'll deter someone who casually looks through - but anyone with access to the server also has access to the script doing the encrypting / decrypting.
I'd say yes. Encryption in your case won't do a thing against a dedicated attacker, but it'll prevent some sysadmin idly browsing through from immediately having the data without having to make the deliberate step to break in.
I hope you're not storing credit card or other sensitive data, particularly if covered by privacy laws in your jurisdiction. Storing that sort of stuff on a shared server will probably get you sued. If nothing else, storage of credit card data in this manner will be a violation of your merchant account - if they get wind of it, Visa and MasterCard will become unavailable to you.
1) Seeing the data with phpmyadmin over HTTP is insecure, of course.
Regarding 2), if you don't have physical security, then you can't have any security (perhaps with the exception of storing encrypted data which you encrypt and decrypt outside the hosting site).
As your hosting company has access to the computer, they can read all your data.
Having said that, in my experience hosting providers will not do that and try to keep your data safe (because that is their business), pretty much in the same way banks' business is to try to keep your money for you and safeguard it and not taking it.
3) Go for database encryption only if you keep backups. For running the live version it provides little more security (if at all) and makes things more cumbersome.
It is.
They can.
Not really but it could still be a good idea. Someone could get hold of your database and not the PHP source code. Then encryption in the database would be a good thing.
You are correct. The only way to be sure is to run your own server. Also you should know about the Payment Card Industry Data Security Standard.
I think that bobince is totally correct. Public key crypto can help you but keep in mind that you loose comfort of using PHPMyAdmin to view the data - you will see garbage that will need to be decrypted somewhere on the side. See http://www.php.net/openssl to learn more about PHP and public key crypto.
Having an encryption/decryption process entirely on the server is, as you suspect, mere obfuscation and not secure in itself. It can help in cases of a partial compromise, where an attacker gains read access to the database (typically through an SQL injection hole) but no ability to read the site scripts or run arbitrary code.
If you only need to write out sensitive data (canonically credit card numbers) that the server doesn't need to be able to read back in, you can do that with public key cryptography. Encrypt the data with your public key, then read it only on a known-secure machine that has the corresponding private key. This protects past data in the case of a greater compromise where the scripts are readable, and in the case where an attacker gains write-access to the scripts, they at least only get new incoming data leaked, and not the old stuff. Hopefully that would give you time to detect the intrusion and rebuild.
Isn't true that the encryption encoding/decoding method could be intercepted by the hosting administrators?
Yes. But then the hosts have physical access to the machine, so could bang a rootkit on it that intercepted everything the webapp was doing on the fly from day one, if they really wanted. There's no way around trusting your host, so pick a reputable one and don't run sensitive systems on shared servers.

Categories