I'm about to add a feature on my website that will post stuff to the users' twitter accounts. I read that storing an "OAuth" token is better than storing their usernames and passwords (which makes sense).
What should I store in my MySQL database? The token, secret and username? Or just the token?
What data type(s) would you use? How big are they?
Thanks!
They're not very big (maybe 15 or 20 chars, can't remember exactly), and are strings. Note: this could change. Nothing in the OAuth spec describes how to generate tokens and secrets, nor what they look like. I expect they'll always be strings, but I might want to make the column a little bigger than currently necessary for contingency.
If you store them in the database, you need some other way of authenticating the users so that you know whose tokens to pull out and use so they can't be used maliciously. If you already have that and it's working then that makes sense, otherwise you might want to rethink it.
Another way to do it is to store their tokens in a cookie, the drawbacks of that are that (if you don't encrypt them or use SSL) they are traveling over the net in the clear, and if they change computers, browsers, or delete their cookies you have to make them go through the whole OAuth process again.
For a website with no other auth, I would encrypt them and store them in a cookie. If you already make them log in, then associate both the token and secret with the login and store them in the database.
There are other ways, too. You could use a randomly generated ID like a GUID/UUID in a cookie to point to a record in a database with the tokens if you didn't want to use encryption. All in all, it depends on how you want your application to behave from the users' point of view.
Make sure you handle the case where the user de-authorizes your app too.
The application secret and token, is specific to your application and that can be stored in database or some config file.
User token you should store in to databse with varchar (100) (at max) along with his twitter ID. you can get the twitter ID while getting the other details from twitter OAuth.
For further guidance, following this link
http://www.9lessons.info/2010/02/connect-twitter-api-with-oauth-using.html
Related
I have a laravel site and i have a mysql table with, among other columns, a column with a Md5 unique code.
Then I create a Get request with parameter id = Md5 that reload in a form web the others datas specific for that Md5 number.
It could be considered a site secure about these informations, even if this site has no login and password?
Or there is another method to implement a secure page for datas without login and pass
Thx a lot
#Marco, for the overall "Is my site secure?" question, theres not any method/tech that ensure you 100% security, so probably the question should be "Is this site secure enough, based on its usage scenario? Which risks are we able to take in?"
Md5 hashes can be easily cracked by bruteforce, so a possible attack to your site could involve using a md5 dictionary attack to exfiltrate all possible data.
I'd think about other non-static(without user-password pairs) authentication methods as :
Challenge response
One-time passwords based on previous passwords
One-time passwords based on time
Of course, all of the above are subject to resources avaliable to your organization, and again, your current site usage context.
I have a database along with REST API for clients to access the data. For performance and other reasons, I need to move the application along with the data to the client's physical server. Is there a way for me to encrypt the data in the database, so the only way the client can get access to it is through API that I expose, and not by cracking MySql and getting at raw data. I do not want the client to see the data stored on my DB, as I feel they will steal it or share it. What can I do to accomplish that?
One idea:
Is it possible to implement some form of one-way encryption, where its based on the lookup value provided in api.
e.g. api lookup by email, that is then gets one-way encrypted compared in the DB for match, and returns a record. This way if they happen to look at my database, the can not see list of emails, all they see is data that is something similar /etc/passwd file.
No.
From the 10 Immutable Laws of Security
Law #3: If a bad guy has unrestricted physical access to your computer, it's not your computer anymore
What you want is fundamentally impossible, without caveats. Always and everywhere.
I have already read through Saving credit card information in MySQL database? and Storing Credit Card Information.
I'm aware that storing credit card information requires PCI compliance, which is not an easy task.
That is not what this question is about. My question is the following:
What is a secure way to encrypt user credit cards? The simplest and easiest that comes to mind is using a private key and encrypting CC's with that. This doesn't seem very secure because the key has to be stored on the server, and if an attacker can get my database, they can probably get the key too.
What I'd like to be able to do is encrypt every CC using that users password as part of the encryption process. If anyone gets the database, they can't decrypt anything because the passwords are stored as salted hashes. This would work great for transactional purchases - the user clicks "Buy," types in their password as a confirmation, I decrypt their CC and make the charge. Their password is only in memory for the duration of the request, and is never written to disk.
Unfortunately this won't work for what I'm trying to build - a service which charges a recurring fee (say, once a month), regardless of whether or not the user is logged in when I need to make the charge.
Given this scenario, is there a secure way of storing user CC's?
As you need to be able to decrypt, there's always the possibility that the encryption keys leak and you'll lose everything. So you'll never get to absolute security, but you can make it harder for attackers to get to the data.
Nobody but you can really judge what level of security (or obscurity) you should have. This is most likely a function of size of database, visibility etc.
For leaks, unfortunately you'll have to assume that everything leaks and sooner or later (e.g. with brute force attacks on weak passwords) you haven't gained too much when they get out.
Given the last credit card leak scandals - the worst ones had the 3-digit (CVV) number saved with the regular credit card number, which credit card companies explicitly forbid (that's why you'll always have to give it again even if someone has your credit card information on file)
If you don't want to assume the responsibility for holding and processing this kind of data, a good way to go is with an external payment service - let them do the processing and just assert to you that the payment has been processed. You'd have to pay them for their services, but you'd also have to pay for implementing your own solution and for taking the risk.
If you use the password as the salt for the CC encryption, it would be a very effective way of securing the information, however, they would never be able to change their password... If it is changed, then the encrypted data is lost. The bottom line for securing the encryption key is to make it as difficult as possible to find... essentially the more steps you use to hide the key, the harder it is for them to find it... which means it is harder for you to use and program for it. There is no magic bullet at this time to protect everything. (Invent a secure way to keep the key and you will be rich)
As for the CVV number, it cannot be stored as previously mentioned. With each transaction the cc processing company will give the merchant a Reference Number which is then used in each reoccurring payment. This means if the original transaction required the CVV number, then logic will dictate that the recurring payment will also be authorized by the same user who put it in on the first transaction. Therefore, the reoccurring payments will not need the CVV to maintain the same level of security.
You could essentially use multiple servers. Encrypt the cc with a key, but keep that key on a separate encryption server, the is only accessible by a master username and password for windows or whatever OS you're using. This way you're securing your key, setting up a services on the encyrption service to run the card through the encryption and then submit it to the database.
Use php's private/public openssl functions when a user makes a purchase you use the data in memory to make the purchase then you store the information using a public key to encrypt it.
To process billing monthly you decrypt the data using the private key that could be manually punched in or stored in code. If you want to store the ssl key in code and not have to remember it or get it everytime. I would encrypt the key using a salt stored in the configuration variables + buy a yubi key and generate a 32 character password + my own password on top of it. Store the yubikey in a safe place (A safe lol). When you need to process credit cards do it with a script that runs in the background and runs all billing at once. To change the password would require you decrypt all cards and re-encrypt them using the new private/public key, or you may just decrypt and re-encrypt the private key ssl.
Magic :)
You require the card information to be reversibly encrypted. The decryption information has to come from somewhere. You've said the data cannot come from the user, and you don't want it stored at the server, so it must be on separate equipment that is presumably more secure. And if you have the ability to recall that information, so does an attacker who has compromised your system. So presumably the decryption information is not retrieved at the vulnerable host during decryption.
Perhaps consider a third-party service that you can encrypt and send information to, perhaps one that specializes in PCI compliance. It might be able to decrypt the credit card information when you send it a second time and apply a charge, or it might actually store the card information for later use. It might even perform recurring transactions for you.
http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/
I just Googled that, I don't recommend them. But it's an example.
Encrypt the CC information twice. First, encrypt the credit card data based off the user's password (+ salt). Then encrypt the output of that with the server's key.
To access the information, you thus require the user's password (i.e. decrypt using server's key, then decrypt based off password). If the database and server key are compromised, the information still isn't exposed without attacking the user's password first.
It's important that the user's password is for the internal encryption - this allows you to re-encrypt when you change server encryption keys.
When the user changes their password, you also re-encrypt the data. If the user resets their password, then the CC information should be erased (and is lost anyway, as it can't be unencrypted).
My university has a portal which students use to register for classes. If you want to get into a full class, you have to keep checking the portal, and sign up when the class has an opening.
I wrote a tool that can check for openings and register automatically, but it needs the students university username and password. These passwords are tied to email accounts, network shares, server logins, and most every other university service.
Is there any way to do this securely?
In security, the most important thing is the "threat model". What kind of attack do you fear?
somebody may steal the computer where this program runs on: put the computer in a locked room.
somebody may hack into the computer and read it from memory: use firewalls and other protection against remote attacks
other users may read the hard disk where the password is stored: only store the password in memory (which would require re-entering it every time you start the program)
the super user may read the password even if it is in memory: only run the program on a computer where you trust the superuser.
etc.
Unfortunately, this is not really possible -- at least not the way you want to do it -- unless the university provides a key-based authentication API. You could always ask them nicely, but they'll probably be too busy to help. If you give your users full disclosure and keep your server secure, it should be enough.
Actually, there is one way to do it through the web without storing passwords -- you could use a Java or Flash app. Unfortunately your users would need to leave the browser open while the app does its work, but this way you wouldn't need to store the information.
You could encrypt the password strings when you store them and then decrypt them when you need to try logging in. Simply generate a symmetric key and use that to encrypt and decrypt the passwords for storage and retrieval (respectively).
You can't store them entirely secure because you'd need to be able to encrypt and decrypt so one-way hash algorithms like MD5, SHA-1, SHA-2 wouldn't suffice. You could look into something like DES or Triple-DES encryption.
I do not think there is. As Martin pointed out one way encryption won't do it for you. Also this will create a maintenance nightmare for you - every time a user changes password you will have to update your data.
I think to make it really work you have to change the design: find a way to do the registration without the user password, i.e. talk to the owners of the app if they would give you an account through which you can do registration on behalf of somebody else
I have a simple REST JSON API for other websites/apps to access some of my website's database (through a PHP gateway). Basically the service works like this: call example.com/fruit/orange, server returns JSON information about the orange. Here is the problem: I only want websites I permit to access this service. With a simple API key system, any website could quickly attain a key by copying the key from an authorized website's (potentially) client side code. I have looked at OAuth, but it seems a little complicated for what I am doing. Solutions?
You should use OAuth.
There are actually two OAuth specifications, the 3-legged version and the 2-legged version. The 3-legged version is the one that gets most of the attention, and it's not the one you want to use.
The good news is that the 2-legged version does exactly what you want, it allows an application to grant access to another via either a shared secret key (very similar to Amazon's Web Service model, you will use the HMAC-SHA1 signing method) or via a public/private key system (use signing method: RSA-SHA1). The bad news, is that it's not nearly as well supported yet as the 3-legged version yet, so you may have to do a bit more work than you otherwise might have to right now.
Basically, 2-legged OAuth just specifies a way to "sign" (compute a hash over) several fields which include the current date, a random number called "nonce," and the parameters of your request. This makes it very hard to impersonate requests to your web service.
OAuth is slowly but surely becoming an accepted standard for this kind of thing -- you'll be best off in the long run if you embrace it because people can then leverage the various libraries available for doing that.
It's more elaborate than you would initially want to get into - but the good news is that a lot of people have spent a lot of time on it so you know you haven't forgotten anything. A great example is that very recently Twitter found a gap in the OAuth security which the community is currently working on closing. If you'd invented your own system, you're having to figure out all this stuff on your own.
Good luck!
Chris
OAuth is not the solution here.
OAuth is when you have endusers and want 3rd party apps not to handle end user passwords. When to use OAuth:
http://blog.apigee.com/detail/when_to_use_oauth/
Go for simple api-key.
And take additional measures if there is a need for a more secure solution.
Here is some more info, http://blog.apigee.com/detail/do_you_need_api_keys_api_identity_vs._authorization/
If someone's client side code is compromised, they should get a new key. There's not much you can do if their code is exposed.
You can however, be more strict by requiring IP addresses of authorized servers to be registered in your system for the given key. This adds an extra step and may be overkill.
I'm not sure what you mean by using a "simple API key" but you should be using some kind of authentication that has private keys(known only to client and server), and then perform some kind of checksum algorithm on the data to ensure that the client is indeed who you think it is, and that the data has not been modified in transit. Amazon AWS is a great example of how to do this.
I think it may be a little strict to guarantee that code has not been compromised on your clients' side. I think it is reasonable to place responsibility on your clients for the security of their own data. Of course this assumes that an attacker can only mess up that client's account.
Perhaps you could keep a log of what ip requests are coming from for a particular account, and if a new ip comes along, flag the account, send an email to the client, and ask them to authorize that ip. I don't know maybe something like that could work.
Basically you have two options, either restrict access by IP or then have an API key, both options have their positive and negative sides.
Restriction by IP
This can be a handy way to restrict the access to you service. You can define exactly which 3rd party services will be allowed to access your service without enforcing them to implement any special authentication features. The problem with this method is however, that if the 3rd party service is written for example entirely in JavaScript, then the IP of the incoming request won't be the 3rd party service's server IP, but the user's IP, as the request is made by the user's browser and not the server. Using IP restriction will hence make it impossible to write client-driven applications and forces all the requests go through the server with proper access rights. Remember that IP addresses can also be spoofed.
API key
The advantage with API keys is that you do not have to maintain a list of known IPs, you do have to maintain a list of API keys, but it's easier to automatize their maintenance. Basically how this works is that you have two keys, for example a user id and a secret password. Each method request to your service should provide an authentication hash consisting of the request parameters, the user id and a hash of these values (where the secrect password is used as the hash salt). This way you can both authenticate and restrict access. The problem with this is, that once again, if the 3rd party service is written as client-driven (for example JavaScript or ActionScript), then anyone can parse out the user id and secret salt values from the code.
Basically, if you want to be sure that only the few services you've specifically defined will be allowed to access your service, then you only option is to use IP restriction and hence force them to route all requests via their servers. If you use an API key, you have no way to enforce this.
All of production of IP's security seems produces a giant bug to users before getting connected. Symbian 60s has the fullest capability to left an untraced, reliable and secure signal in the midst of multiple users(applying Opera Handler UI 6.5, Opera Mini v8 and 10) along with the coded UI's, +completely filled network set-up. Why restrict for other features when discoverable method of making faster link method is finally obtained. Keeping a more identified accounts, proper monitoring of that 'true account'-if they are on the track-compliance of paying bills and knowing if the users has an unexpired maintaining balance will create a more faster link of internet signal to popular/signatured mobile industry. Why making hard security features before getting them to the site, a visit to their accounts monthly may erase all of connectivity issues? All of the user of mobile should have no capability to 'get connected' if they have unpaid bills. Why not provide an 'ALL in One' -Registration/Application account, a programmed fixed with OS, (perhaps an e-mail account) instead with a 'monitoring capability' if they are paying or not (password issues concern-should be given to other department). And if 'not' turn-off their account exactly and their other link features. Each of them has their own interests to where to get hooked daily, if you'd locked/turn them off due to unpaid bills that may initiate them to re-subscribe and discipline them more to become a more responsible users and that may even expire an account if not maintained. Monthly monitoring or accessing of an identified 'true account' with collaboration to the network provider produces higher privacy instead of always asking for users 'name' and 'password', 'location', 'permissions' to view their data services. IP's marked already their first identity or 'finding the location of the users' so, it's seems unnessary to place it on browsers pre-searches, why not use 'Obtaining data' or 'Processing data.'