Suppose you are writing a survey application and would like to somehow guarantee results to be secure from user stand point. Put simply, i know what IP you came from but i want to make sure you sleep well at night knowing i know nothing of your responses. I can't store IP in raw form.
I do need to guarantee 1 thing though, that is that you answer questions once. So once your PC comes in with some data, i need to recognize that your PC already has responsed to the survey.
Any suggestions on how to best handle it?
Thanks
-mac
Create a one-way hash of the IP address (and any other unique identifying attributes), and store the hash with the response. That way no one can lookup the IP address for a response, but you can compare the hash to previously submitted responses to keep ensure people only submit the form once.
There's not much you can do to convince someone your respecting their privacy. Just don't abuse the trust, and people will work it out.
(For an idea on how to create a hash in java see How can I generate an MD5 hash?)
You can't guarantee either of these. All you can do is raise the bar so it's harder to get around it. If someone really wants to get around your tracking they can if they know enough about your system. Good thing is most people either don't want to bother or don't know how.
You can generate a cryptographic hash and store that in a cookie on the persons browser if you want to prevent proxy problem. Lots of websites do this to keep session creation to track authentication. This is something like using an HMAC to generate something that identifies the browser with a unique key that can't be faked. If they clear their browser though you won't be able to track them.
One way hash of IP address is a way to keep your IP from being tracked, but the same IP always hashes to the same value so you can tell if someone is doing that. However if they go to an internet cafe viola they can resubmit. You'd use SHA1, MD5, etc for that.
You can do the same thing with email address and hash it. To get people to want to participate send the results to their email address instead of displaying in the browser. People just have to trust you won't do nasty things with their email.
Other ideas might be if you know who you want to send the survey too. Generate a random number that identifies the individual response. Then email those links to people. They will then submit under that number, and you don't track email -> random number then you can't correlate the answers with the email address. Once a random number is used once you don't let them submit it again. Track Responses once. Display results many times.
You can combine some of these together to try and work around the deficiencies of the other.
Related
I was hoping someone could help me sort something out. I've been working on a shopping cart plugin for WordPress for quite a while now. I started coding it at the end of 2008 (and it's been one of those "work on it when I have time" projects, so the going is very slow, obviously!) and got pretty far with it. Even had a few testers take me up on it and give me feedback. (Please note that this plugin is also meant to be a fee download - I have no intention of making it a premium plugin.)
Anyway, in 2010, when all the PCI/DSS stuff became standard, I shelved it, because the plugin was meant to retain certain information in the database, and I was not 100% sure what qualified as "sensitive data," and I didn't want to put anything out there that might compromise anyone, and possibly come back on me.
Over the last few weeks, some colleagues and I have been having a discussion about PCI/DSS compliance, and it's sparked a re-interest in finally finishing this plugin. I'm going to remove the storage of credit card numbers and any data of that nature, but I do like the idea of storing the names and shipping addresses of people who voluntarily might want to create an account with the site that might use this plugin so if they shop there again, that kind of info is retained. Keep in mind, the data stored would be public information - the kind of thing you'd find in a phone book, or a peek in the record room of a courthouse. So nothing like storing SS#'s, medical histories or credit card numbers. Just stuff that would maybe let someone see past purchases, and retain some info to make a future checkout process a bit easier.
One of my colleagues suggested I still do something to enhance security a bit, since the name and shipping address would likely be passed to whatever payment gateway the site owner would choose to use. They suggested I use "one-way encryption." Now, I'm not a huge security freak, but I'm pretty sure this involves (one aspect anyway) stuff like MD5 hashes with salts, or the like. So this confuses me, because I wouldn't have the slightest idea of where to look to see how to use that kind of thing with my code, and/or if it will work when passing that kind of data to PayPal or Google Checkout, or Mal's, or what have you.
So I suppose this isn't an "I need code examples" kind of question, but more of a "please enlighten me, because I'm sort of a dunce" kind of question. (which, I'm sure, makes people feel much better about the fact that I'm writing a shopping cart plugin LOL)
One way encryption is used to store information in the database that you don't need back out of the database again in its unencrypted stage (hence the one-way moniker). It could, in a more general sense, be used to demonstrate that two different people (or systems) are in possession of the same piece of data. Git, for instance, uses hashes to check if files (and indeed entire directory structures) are identical.
Generally in an ecomm contect hashes are used for passwords (and sometimes credit cards) because as the site owner, you don't need to retain the actual password, you just need a function to be able to determine if the password currently being sent by the user is the same as the one previously provided. So in order to authenticate a user you would pass the password provided through the encryption algorithm (MD5, SHA, etc) in order to get a 'hash'. If the hash matches the hash previously generated and stored in the database, you know the password is the same.
WordPress uses salted hashes to store it's passwords. If you open up your wp_users table in the database you'll see the hashes.
Upside to this system is that if someone steals your database, they don't get the original passwords, just the hash values which the thief can't then use to log in to your users' Facebook, banking, etc sites (if your user has used the same password). Actually, they can't even use the hashes to log in to the site they were stolen from as hashing a hash produces a different hash.
The salt provides a measure of protection against dictionary attacks on the hash. There are databases available of mappings between common passwords and hash values where the hash values have been generated by regularly used one way hash functions. If, when generating the hash, you tack a salt value on to the end of your password string (eg my password becomes abc123salt), you can still do the comparison against the hash value you've previously generated and stored if you use the same salt value each time.
You wouldn't one way hash something like an address or phone number (or something along those lines) if you need to use it in the future again in its raw form, say to for instance pre-populate a checkout field for a logged in user.
Best practices would also involve just not storing data that you don't need again in the future, if you don't need the phone number in the future, don't store it. If you store the response transaction number from the payment gateway, you can use this for fraud investigations and leave the storage of all of the other data up to the gateway.
I'll leave it to others to discuss the relative merits of MD5 vs. SHA vs ??? hashing systems. Note, there's functions built in to PHP to do the hashing.
I am writing a score submission system for games where I need to ensure that reports back to the server are not falsified (aka, hacked).
I know that I can store a password or private passkey in the program to authenticate or encrypt the request but if the program is decompiled, a crafty hacker can extract the password/passkey and use it to falsify reports.
Does a perfect solution exist?
Thanks in advance.
No. All you can do is make it difficult for cheaters.
You don't say what environment you're running on, but it sounds like you're trying to solve a code authentication problem*: knowing that the code that is executing is actually what you think it is. This is a problem that has plagued online games forever and does not have a good solution.
Common ways in which such systems are commonly broken:
Capture, modification and replay of submissions to the server
Modifying the binary to allow cheating
Using a debugger to modify the submission in-memory before the program applies signatures/encryption/whatever
Punkbuster is an example of a system which attempts to solve some of these problems: http://en.wikipedia.org/wiki/PunkBuster
Also consider http://en.wikipedia.org/wiki/Cheating_in_online_games
Chances are, this is probably too hard for your game. Hiding a public key in your binary and signing everything that leaves it will probably put you well ahead of the pack, security-wise.
* Apologies, I don't actually remember what the formal name for this is. I keep thinking "running code authentication", but Google comes up with nothing for the term.
There is one thing you can do - record all of the user inputs and send those to the server as part of the submission. The server can then replay the inputs through a local copy of the game engine to determine the score. Obviously this isn't appropriate for every type of game, though. Depending on the game, you may need to include replay protection.
Another method that may be appropriate for some types of games is to include a video recording of the high-scoring play within the submission. Provide links to the videos from the high score table, along with a link to report suspicious entries. This will let you "crowd-source" cheat detection - if a cheater's score hits the table at number 1, then the players behind scores 2 through 10 have a pretty big incentive to validate the video for you. If a score is reported enough times, you can check the video yourself and decide if it should be removed (and the user banned).
I am developing an HTTP server application (in PHP, it so happens). I am concerned about table IDs appearing in URLs. Is it possible to encrypt URL variables and values to protect my application?
oh ok, so for sensitive information best to use sessions then, are table Ids etc safe to throw in the GET var?
Yes, sensitive information must not leave your server in the first place. Use sessions.
As for "are table ids safe in the URL": I don't know, is there anything bad a user could do knowing a table id? If so, you need to fix that. Usually you need to pass some kind of id around though, whether that's the "native table id" or some other random id you dream up usually doesn't matter. There's nothing inherently insecure about showing the id of a record in the URL, that by itself means absolutely nothing. It's how your app uses this id that may or may not open up security holes.
Additionally think about whether a user can easily guess other ids he's not supposed to know and whether that means anything bad for your security.
Security isn't a one-off thing, you need to think about it in every single line of code you write.
Sounds like you want to pass sensitive information as a GET param.
Don't do that - use $_SESSION if you can.
However, if you want your params encoded (i.e. => +) use urlencode().
$a = 'how are you?';
echo urlencode($a); // how+are+you%3F
You can encrypt what you pass before you transmit, or you can run the entire communication over an encrypted channel (https or ssh for instance).
Your GET variables are called whatever you choose to call them, and assigned whatever values you choose to give them. So, yes: they can certainly be encrypted or, if you'd rather, simply obscured. If you're planning to encrypt variables, then PHP has quite a few options available.
For the above, I'd recommend using something like urlencode.
In general I'd suggest using POST instead of GET, assuming you're getting your variables from a form element. On the other hand it might be even wiser to use session variables.
Maybe this article can give you more ideas...
http://www.stumbleupon.com/su/1nZ6bS/:1PcFQMI0:6oJD.Hd1/www.ibm.com/developerworks/library/os-php-encrypt/index.html/
How to encrypt this url in asp.net (VB.NET), so that user cannot view this address bar text in their browser address bar ?
http://localhost:2486/volvobusesindia/passenger_info.aspx?from=Delhi&to=Manali&journey=21-Nov-2010
You can't. And before someone suggests using POST, that doesn't really hide anything. It's trivial to use Wireshark, Firebug, etc. either way.
Any communication between the user's machine and your server, in either direction, encrypted or unencrypted, can be monitored by the user.
EDIT: An alternative is to generate a unique GUID or session identifier, then keep track of the meaning on the server. This is not encryption, but it may serve the desired purpose.
You can do some really good obfuscating, but you probably want to roll-your-own, as if you are using this for security, you don't want everybody knowing how to decode your encoding.
We do it by using a single querystring parameter that contains ALL of the information we need from the request in our own format. Of course, this does mean giving up all of the handy .Request[] methods, but you've got to make the trade off somewhere.
The full path to a file with the fully encrypted URL also can get obscenely long with everything thrown in there. For example, this is a link that will display an image of a ring with the word "Landrum" on it (in both directions). The image is created the moment you request it, from the information contained in the encrypted query string.
http://www.flipscript.com/data/default/images/catalog/medium/AMBIRingTitanBlue_G1F88E4X57,409-945,591O0M0S2V6.jpgx?xq=45C35129$6zvtnw6m1280kwz8ucqjt6jjb2vtea43bio5ixmnge-5r4i-o1o32j43y58nv
I hope that helps a bit! There is no "out of the box" solution, but this one works pretty well.
Instead of hiding it, you could call this site internally from within some other site and do whatever you wish with the returned results (e.g. display them on your site). That would guarantee you that the user won't ever have the chance to see the actual site being called.
I'm using ASP.Net but my question is a little more general than that. I'm interested in reading about strategies to prevent users from fooling with their HTML form values and links in an attempt to update records that don't belong to them.
For instance, if my application dealt with used cars and had links to add/remove inventory, which included as part of the URL the userid, what can I do to intercept attempts to munge the link and put someone else's ID in there? In this limited instance I can always run a check at the server to ensure that userid XYZ actually has rights to car ABC, but I was curious what other strategies are out there to keep the clever at bay. (Doing a checksum of the page, perhaps? Not sure.)
Thanks for your input.
The following that you are describing is a vulnerability called "Insecure Direct Object References" And it is recognized by A4 in the The OWASP top 10 for 2010.
what can I do to intercept attempts to
munge the link and put someone else's
ID in there?
There are a few ways that this vulnerability can be addressed. The first is to store the User's primary key in a session variable so you don't have to worry about it being manipulated by an attacker. For all future requests, especially ones that update user information like password, make sure to check this session variable.
Here is an example of the security system i am describing:
"update users set password='new_pass_hash' where user_id='"&Session("user_id")&"'";
Edit:
Another approach is a Hashed Message Authentication Code. This approach is much less secure than using Session as it introduces a new attack pattern of brute force instead of avoiding the problem all togather. An hmac allows you to see if a message has been modified by someone who doesn't have the secret key. The hmac value could be calculated as follows on the server side and then stored as a hidden variable.
hmac_value=hash('secret'&user_name&user_id&todays_date)
The idea is that if the user trys to change his username or userid then the hmac_value will not be valid unless the attacker can obtain the 'secret', which can be brute forced. Again you should avoid this security system at all costs. Although sometimes you don't have a choice (You do have a choice in your example vulnerability).
You want to find out how to use a session.
Sessions on tiztag.
If you keep track of the user session you don't need to keep looking at the URL to find out who is making a request/post.