Stripe secret key security? - stripe-payments

I am having a developer build me a website that he has been working on for about a month now. He's doing great, and it looks fantastic. Maybe I'm being paranoid, or maybe I'm not, but this is my first venture into an online business. He needed my stripe api key and secret key. Was it safe to give him the secret key for the coding end? He asked for both. Just wondering if I could be scammed somewhere down the line and not know it from the freelancer. Or be scammed and it is too late.....Sorry I'm coding illiterate for the most part. If I have to take any steps to ensure safety of any funds or my website after he creates it; please let me know.

For Stripe, and many other API systems like it, there are two sets of keys. One is for testing/development, and does not do any actual live work. The other is the live set, and that will hit the live API and allow the person with the keys to act as your business.
In an ideal, secure organization you'd have the live and test sides completely separated. The developers would not have access to the live site, and thus the live keys at all. Not in the UI, not in the database, nothing. This limits the vulnerability to only those people who are assigned to keep the live site running.
Since you're working with a freelancer it's a bit murkier. I'm assuming you don't have an internal team to handle the maintenance on the site. If that's the case then even if you were to insert the live keys yourself during the launch, the freelancer would likely be the person you're contacting to address issues, at which time they'll have access to the keys anyways.
However, if the freelancer will not be the person maintaining or supporting the site, then the best course of action is for them to provide you with a spot on the back-end of the site where you can enter the live keys yourself before making the site active to the public. Again, this is only something that provides security if the freelancer will not have access to the website after it is launched.

If he is your developer then he would need both keys. Here is some more information about the keys and what they can do
https://stripe.com/docs/keys

Related

what is the simplest protocol to securely tether a hardware device to a network?

After the Sony PSN debacle, I am trying to find examples of secure hardware tethering to a network. There are two use cases in particular:
1- computer downloads a piece of software that then uniquely and securely labels it to a cloud service
2- a hardware manufacturer uniquely labels a hardware device that then negotiates membership on the network.
Given the fact that the hardware device might have to change (revoke or service enhancements) it feels like #2 becomes #1.
The broad outline is this:
- connect to the service via HTTPS to protect against man in the middle
- device generates a GUID and presents it via HTTPS to service
- service records GUID against account
- on success, service 'enables' device
But how do you protect the GUID so that it cannot be stolen?
I just wanted to comment here:
Sony's PSN issues started with horrible practices with regards to their QA environment.
First, they defaulted to trusting anything that was sent to those servers using their developers toolkit. The reason they did this was that the dev kit used to cost upwards of $10k US and therefore they thought anyone who paid that amount would be on the up and up. However, when they radically lowered the price things changed externally and they didn't account for it.
The second issue with PSN was that the security between QA and live was, well, weak at best and easily circumvented. My understanding is that you could send commands to live using QA credentials. Because QA credentials were used, all chargeable actions were approved without money changing hands and the actions were applied to live accounts. When several people told Sony about this they did nothing.
A third issue was a reliance on hardware based encryption keys. Even hardware encryption keys installed on the devices can be figured out.
Point is, Sony dug their own grave on it so I wouldn't use anything they did as a template for how to do things. Heck, a lot of their websites were open to SQL injection which in today's day and age should get you fired.
Another example here is the iPhone. Each iPhone has a unique identifier that installed apps can grab and send back across the network; similar to a serial number. Some apps use this ID to try and tie a particular device to a person. However, it's trivial to create ID's and broadcast them, so this hasn't worked out so well for the partners. Also Apple does not expose a way to ensure a given ID (UUID) is valid to app producers.
A third example is mobile phone carriers. They use a particular ID baked into your SIM card to identify your account in order to know who to bill when a call is made. This ID is verified whenever the phone checks in with the network. However, we're dealing with radio signals and any device that can broadcast a correct ID can gain access. Point is, honest people think that only AT&T approved devices can get on an AT&T network. Reality is, anything can but they are going to bill the owner of the particular ID...
That said, any software you have running on a remote device that is not under your direct control is likely to be hacked. The popularity of the device will increase the likelihood of it happening sooner rather than later.
Where do we go from here?
On a basic level you associate an ID with an account in your service. PSN, Apple and others have done this. When an ID is broadcast, you need to verify that it exists AND that it's tied to an active account. If both pass then you have two options: either perform the action requested OR request additional verification.
For any actions that require money to be spent, do the additional verification (usually some form of username/password), capture the funds, then perform the action. Go one step further and every time a bad login is entered, send an email to the user on file. Further, automatically send a receipt. These are typically done so that your honest users can tell when something is going on.
Anything else just let through.
Bearing in mind, of course, that QA credentials should NOT work in your Live environment. Those systems should not be tied to each other under any condition and, quite frankly, should even live on separate hardware. In other words, QA and Live should NOT share a login database.
The thing here is that you shouldn't care about the device itself; just the account. You can't control the device as it's out of your hands; heck you can't even be sure it hasn't been physically tampered with. (XBox has been fighting this one with people adding resistors or burning out certain components to get past physical security features).
So, IMHO, do a bit to keep honest people honest but overall don't worry about it. Now, you should transfer everything via SSL or someother encrypted connection between the device and your cloud so that you don't leak ID's to anyone that wants to grab them. This will help protect those honest people.
Further, you shouldn't have a direct way to query whether an ID is valid or not from the outside. This will make it a bit more difficult for a hacker to find existing valid IDs and take over accounts. If you want to get fancy you could honey pot those and track the hackers down in order to sue them into oblivion, but that takes time and resources companies don't normally have. Also you could log all of the requests that contained bad IDs and use that to track hackers down.
Note that even after the device has been "enabled" I still suggest you have two levels of authentication. The first is for simple actions like downloading free content; the second kicks in anytime there is a fee associated. Again, we're trying to protect your honest subscribers.
For the dishonest ones you will have to apply some statistical analysis on the transactions coming across. Things like the transaction rate can help identify bots that are running and allow you to kill their IDs. There are others but they'll be unique to your application.
This was long winded. But my point is:
You can't secure the ID or anything else you pass out.
You can't ensure the requests are coming from your devices or your own approved devices.
You better take actions to keep QA and production separate for those building software for these devices using your services.
You better take actions to protect your normal honest users.
Trust NOTHING.
Due to the above you should evaluate your business model so that you don't care what device was used and instead focus on the individual accounts themselves; which you do have control over.
I am not sure I entirely understand the question, but I think you want some sort of device to hold on to a GUID assigned to it by a web service, and you don't want someone finding out what that GUID is, correct?
If so, there isn't a lot you can do. You have already mentioned one option... using HTTPS during the assigning of the ID. That is a good start, but remember that anyone who has physical access to the device can do a lot of things to look up this ID.
In short, it is impossible to completely hide. Someone can always reverse engineer it. There are folks out there reading data right out of memory with hardware.

Collecting Credit Card Information - not to collect payment

I am working in PHP on a Linux server with MySQL.
I have a requirement (that I have attempted to talk them out of) to collect credit card information from users so that our company can use the card numbers to hold hotel rooms for a conference. We will not be charging the cards ourselves at all, but instead just sending them to the hotel. I then need to be able to download a CSV file and each time someone signs up an email to go to the admin with all the information.
I tried to explain that this wasn't secure, but several other developers have done this for them in the past before I was working here.
My question is; is there anyway to make this secure? If not are there any third party options to make this happen?
EDIT:
I appreciate everyone who has posted so far, it has simply made me want to attempt to do this less and less. If you could add to your answers simple explanations, oriented at non-tech people, it would be greatly appreciated, in fact site source and links would help me a great deal. I haven't found any sites that would explain this in a non-tech way.
First of, I am not a lawyer. I have implemented CC-handling code several times previously, but I am only familiar with Danish laws and regulations, so your mileage may vary.
As far as I know, there are restrictions in place (law and regulations from the CC providers) that you need to be aware of. I don't know where you are in the world, but in many countries you need to be PCI certified to handle credit card data and that is an extremely onerous, expensive and on-going process.
Other countries, or states, may have notification rules in play that requires you to pay the cost of notifying the card holder if security is broken - and unless you are very careful, it is not unlikely.
In general, I would recommend against that procedure. You may risk being liable for any costs if it goes wrong.
It's really a bad idea to be storing card details. You're opening yourself up for a world of pain in the form of PCI-DSS audits. It is not as simple as 'use encryption', you need to have processes in place to securely manage the encryption keys, schedule key rotation, securely log access and so on and on... Storing card details is absolutely something you want to avoid.
If you have to have something in place, then the best option may be for you (as a company) to take payments from the credit cards to your own merchant account, then pay the hotels separately (from your bank account/whatever). You act as a proxy for the client making the payment to the hotel.
Most payment gateways allow you to store the card details securely, and charge at a later date (using a token id returned by the gateway), which will likely be useful here. But you wont be able to retrieve the card details to pass them through to the hotel in any way, which is why you would need to take payment, then organise a separate payment to the hotel.
Its still quite an undertaking though because a lot of areas of PCI-DSS will come into play even with this simplified solution.
You asked, so here is more information:
PCI-DSS is the Payment Card Industry Data Security Standard. It's a set of guidelines which basically apply to any company that 'touches' cardholder data, in particular the card number. Touching it literally means any handling of the data, even just having it pass through your network without it ever being persisted to disk is enough to mandate that you must comply, (though it is significantly easier if you don't persist the details to disk)
You didn't yet state which part of the world you're in, or how these card details are captured (internet/telephone/in person). These details are significant to how you can achieve compliance.
Start by taking a look at the PCI-DSS SAQ (Self Assessment Questionnaires). These SAQ's are the minimum requirements for companies that do not store cardholder details to disk, and should give a good impression of the security that needs to be in place across the network and policies that should be applied across the company.
As I said, if you're thinking of storing card details then things get more complicated, because as a general rule the SAQ is no longer good enough. You need to enrol the assistance of a QSA (Qualified Security Assessor) who will visit and advise on best practice for data storage and the various other points that come into play. For this level of compliance you're looking at yearly audits (carried out by the QSA), and quarterly network scans. Take a look at the audit procedures to get a detailed look at what is involved. In particular take a look at section 3 and do not underestimate the difficulty of implementing proper key management.
In summary, full PCI compliance will be very costly. Even for a company which already has pretty strong security policies the cost of bringing in a QSA and running quarterly scans and yearly audits alone will likely cost $thousands.
This is very insecure and I think you're correct for opposing it. That said...
Some ideas:
Can the hotel give you a rate/group code that you can disseminate to your users directly? Perhaps you could even give them a link that goes right to the hotel's reservation page, with the code already filled in.
Don't even think about implementing this unless you can do it on an SSL-enabled site.
Don't save the CC number anywhere,
just generate the email and toss the
number out. This alleviates you from having to worry about a ton of very difficult application / server security issues.
Encrypt the email with GPG or
equivalent so that it's protected in
transit and can only be read by the intended recipient.
I suggest you follow the Card Industry PCI compliance closely at least. Here is a PDF document.
As someone who has worked on a system like this, it is 100% illegal to store any credit card information in plain text. You must encrypt all of the data and you are not allowed to know any piece of the keys. It is quite the catch 22, the only way to validate data is to guess as sad as that sounds. This is the exact reason why accidental charges occur.
As others have said here, it's a fact that storing credit card information requires you to be certified. You can ask for information to process the transaction but keeping it on storage of any kind is a big no-no.
Fortunately sites like authorize.net, braintree.com, paypal.com, etc will let you interact with their APIs in such a way that you get a "Customer Vault ID" for each entity you'd like to make transactions for.
These 3rd parties store all the sensitive information in a 100% legit way. And whenever you would like to make a transaction using their saved information, you interact with the service using their "Vault ID".
I've used authorize.net, BrainTree and PayPal. Most recently it was BrainTree and had some good success with them. I would not recommend PayPal unless you need the brand recognition or you just want to do a direct transfer whereby you bypass asking them for account information of any kind (because they already entered it in PayPal).
Make sure your server is as secure as possible and prove that it isn't already compromised. None of this will really work well if you have a compromised server.
Use SSL to protect this information during transit.
Encrypt these details immediately upon receipt. This will help protect it at rest. If possible, encrypt it with a public key for a key pair where the private key (used for decryption) is not on your server. This could easily be that you place this information into the body of the email that you're required to send, then encrypt the body with public-key encryption where your client has the private key. (You could use PGP here). In this way, the data is help on your server as briefly as possible, then once off your server, is accessible only by your client. If you use a symmetric encryption algorithm, then your key will necessarily also be on your server somewhere (on disk, in memory, etc.), which could be obtained and used by an attacker to regain access to the details.
This isn't an endorsement, per se, but I have used this before in similar situations with good results: http://www.pgp.com/products/commandline/
Remember that there are always security holes, but you'll be raising a large barrier against attacks with these steps. I might also add that you look into a system integrity solution like Trip Wire from the immediate build of your server. And of course, ensure that all of your passwords are strong.
If you send the file via email, be sure to use secured connexions (HTTPS / IMAP or POP3 over SSL, SMTP over SSL) on both sending and receiving computers and have the file encrypted prior sending. You can encrypt your mail and attachment via OpenPGP, too. Also, ensure the security between the two mail servers (sending and receiving), or simply use the same domain for sending and receiving email addresses. Do not use the password-feature of a ZIP file or related comrpessing container, since they are usually cryptographically weak.
If you send it on a filesystem (ie. USB pendrive), be sure to use a crypted one (ie. TrueCrypt).
Be sure to have a secured computer where the download and upload takes part (encrypted partition where the download/upload takes place, no spywares on the system, passworded system, firewalled).

Security Beyond a Username/Password?

I have a webapp that requires security beyond that of a normal web application. When any user visits the domain name, they are presented with two text fields, a username field, and a password field. If they enter a valid user/pass, they get access to the web application. Standard stuff.
However, I'm looking for additional security beyond this standard setup. Ideally it would be a software solution, but I'm also open for hardware solution as well (hardware=key fobs), or even procedural changes (one time use passwords on a password pad for example).
The webapp is unique in that we know all our users ahead of time, and we create their username and password and give it to them. In this sense, we can be assured that the username and password are "strong".
However, our clients have requested additional security beyond this. Anyone have any ideas on how to add another layer of complexity to the security?
Our company used PhoneFactor and we absolutely love it.
We've also used Safeword Tokens in the past.
However, it's notthe only game in the book. I'd start by googling "Two factor authentication"
The OWASP guide to authentication is another good place to start. Actually, OWASP is the first place I'd look for ANY web security question.
Another option for additional security is to use a piece of physical 'evidence' such as a Smart Card: Protect Your Data Via Managed Code And The Windows Vista Smart Card APIs
There are lots of different areas that web apps can have their security improved on. Before getting started you need to determine what, exactly, your problem areas might be and what you want to focus on.
You might start this process by having a third party do Penetration Testing (PEN Testing) on your application. This should give a quick hit list of things you can take care of and, when you have a passing grade, is something to use in your sales literature.
Next you'll want to talk to your customers to understand what they mean by "more secure". Is it simply two factor authentication like David and Mitch mentioned or are they more concerned about things such as data in motion (ARP Poisoning, SSL, and the like), data at rest (everything from hard drive encryption to database encryption), authorization, impersonation (cross site and replay), personnel (ongoing background checks on who has access to the machines), etc..
The concept of security covers a lot of ground.

How can you ensure that a user knows they are on your website?

The talk of internet town today is the SNAFU that led to dozens of Facebook users being led by Google search to an article on ReadWriteWeb about the Facebook-AOL deal. What ensued in the comments tread is quickly becoming the stuff of internet legend.
However, behind the hilarity is a scary fact that this might be how users browse to all sites, including their banking and other more important sites. A quick search for "my bank website login" and quickly click the first result. Once they are there, the user is willing to submit their credentials even though the site looks nothing like the site they tried to reach. (This is evidenced by the fact that user's comments are connected to their facebook accounts via facebook-connect)
Preventing this scenario is pretty much out of our control and educating our users on the basics of internet browsing may be just as impossible. So how then can we ensure that users know they are on the correct web site before trying to log in? Is something like Bank of America's SiteKey sufficient, or is that another cop-out that shifts responsibility back on the user?
The Internet and web browsers used to have a couple of cool features that might actually have some applicability there.
One was something called "domain names." Instead entering the website name over on the right site of your toolbar, there was another, larger text field on the left where you could enter it. Rather than searching a proprietary Google database running on vast farms of Magic 8-Balls, this arcane "address" field consulted an authoritative registry of "domain names", and would lead you to the right site every time. Sadly, it sometimes required you to enter up to 8 extra characters! This burden was too much for most users to shoulder, and this cumbersome feature has been abandoned.
Another thing you used to see in browsers was something called a "bookmark." Etymologists are still trying to determine where the term "bookmark" originated. They suspect it has something to do with paper with funny squiggles on it. Anyway, these bookmarks allowed users to create a button that would take them directly to the web site of interest. Of course, creating a bookmark was a tedious, intimidating process, sometimes requiring as many as two menu clicks—or worse yet, use of the Ctrl-key!
Ah, the wonders of the ancients.
The site could "personalize" itself by showing some personal information,
easy recognizable by the user, on every page.
There are plenty of ways to implement it. The obvious one:
under first visit, the site requires user to upload some avatar,
and adds user's id to the cookies. After that, every time the user browses
the site, the avatar is shown.
When I set up my online bank account, it asked me to choose from a selection of images. The image I chose is now shown to me every time I login. This assures me that I am on the right website.
EDIT: i just read the link about the BoA SiteKey, this is apparently the same thing (it sounded from the name like a challenge-response dongle)
I suppose the best answer would be a hardware device which required a code from the bank and the user and authenticated both. But any of these things assume that people are actually thinking about the problem, which of course they don't. This was going on before internet banking was common - I had a friend who had her wallet stolen back in the 90s, and theif phoned her pretending to be her bank and persuaded her to reveal her PIN...
When the user first visits the site and logs in, he can share some personal information (even something very trivial) that imposter sites couldn't possible know - high school mascot, first street lived on, etc.
If there's ever any question of site authenticity, the site could share this information back to the user.
Like on TV shows/movies with the evil twin. The good twin always wins trust by sharing a secret that only the person who's trying to figure out who the good twin is would know.
You cannot prevent phishing per-se but you can take several steps each of which do a little bit to mitigate the problem.
1) If you have something like site-key or a sign-in seal, please ensure that these cannot be iframed on a malicious website. Just javascript framebusting may not be enough as IE has security="restricted".
2) Be very consistent about how you ask for user credentials - serve the login form over SSL (not just post-back over SSL). Do not ask for login on several places or sites. Encourage third parties who want to work with user data stored on your site to use OAuth (instead of taking your user's password).
3) You should never ask for information via email (with or without link).
4) Have a security page where you talk about these issues.
5) Send notification on changes to registered phone, email, etc.
Apart from above, monitor user account activity - such as changes to contact information, security Q&A, access, etc (noting time, ip, and there are several subtle techniques).

What kind of damage could one do with a payment gateway API login and transaction key?

Currently, I'm in the process of hiring a web developer who will be working on a site that processes credit cards. While he won't have the credentials to log into the payment gateway's UI he will have access to the API login and transaction key since it's embedded in the application's code.
I'd like to be aware of all the "what if" scenarios pertaining to the type of damage one could do with that information. Obviously, he can process credit cards but the money goes into the site owner's bank account so I'm not sure how much damage that could cause. Can anyone think of any other possible scenarios?
UPDATE: The payment gateway being used is Authorize.net.
Do they really need access to your production sites?
Don't store the key in your code, store it in your production database, or on a file on the production server.
Some good answers here, I'll just add that you'd probably have some trouble with PCI.
PCI-DSS specifically dictates separation of duties, isolation of production environments from dev/test, protection of encryption keys from anyone who does not require it, and more.
As #Matthew Watson said, rethink this, and dont grant production access to developers.
As an aside, if he can access the API directly, how do you ensure that "the money goes into the site owner's bank account"? Not to mention access to all that credit card data...
If the developer gets access to the raw credit card numbers that can become a bigger problem as your site can be associated with fraudulent activity, assuming the developer is a bad apple. (They could redirect account numbers, CCV, expiration date to another site, though this should be spottable through network tools and a comprehensive code review.)
Does the API perform the "$1.00" charge (or "$X.XX") to verify that a credit card can be charged a certain amount (and thus returning the result to the caller, such as "yes" or "no")? If so, it could be used to automate the validation of credit card account numbers traded on the Internet and abuse of such a system could lead back to you.
With any gateway I have worked with, the payment processor ties the API key to the specific IP or IP range of the site of the merchant. With that said, unless the malicious(?) code in question is executed on the same server as the merchant - there shouldn't be any security concerns in that regard.
If this is not the case for your merchant site - contact them and ask if this is feasible.
Does the payment gateway allow for reversal of charges? If so there is the possibility of a number of scams being run.
Does the site process refunds? Will it ever in the future?
If we're talking about nefarious uses, then the site owner might be investigated if lots of unauthorized purchases are made. How would that affect you if the owner is investigated?
From your description it seems that this developer will have access to the customer cards detail in which case the customers privacy may be compromised. You might consider wording the contract appropriately to make sure that this angle is covered.
However the main point is that if you're working on a sensitive project/information it's better for you to find people you could trust. Hiring a software house to do the job may save you some sleep later on.
First and foremost, it is best that you never store this type of information in plain text. Usually people take this as second-hand knowledge for credit card numbers (Sadly, only because of legal reasons), but any sort of private data that you don't want others with database/source-code access viewing should be encrypted. You should store the account information somewhere in a well encrypted format, and you should provide a test account for your developers to use on their development workstations. This way, only people with server access are able to see even the encrypted information.
This way, you can have a database on the developer's workstation with the test account's API information stored (hopefully encrypted) in it's local database, but when the code is mirrored onto the production server it will still use the live, real gateway information stored on the production server's database without extra code/configuration.
With this said, I don't think that a programmer with API authentication details can do too much. Either way, it's not worth the risk - in my opinion.
Hope this help.
PS: If something bad does end up happening, you can always generate a new key in the web interface on authorize.net after you've taken the precautions to make sure it wont happen again.
In the specific case of Authorize.Net they would not be able to do credits towards their own credit cards since Authorize.Net only allows this to be done on transactions performed through them within the last six months. The only exception being allowed if you are granted an exception for unlinked refunds. If you have signed the proper paperwork for this and someone has your API login and transaction key then can then process credits towards their own credit cards. The only way for you to catch this would be to monitor your statements carefully.
To help mitigate this you should change your transaction key immediately upon completion of the work they perform for you. That would render the key they have useless after 24 hours.

Resources