2

My users (researchers) will be storing where their website is on a mysql database on my server.

Ideally I want to hash the locations so that when the researchers' participants submit their data to my server, I can confirm whether the website they came from is registered on my MySQL database. If so, I want to save their data to a specific location that reflects which website they were participating at.

My problem is that when I use Php's password_hash, it returns different values during each hash. Thus, to verify the location I think I would need to loop through my whole mysql database to check if the website the participant is submitting from matches one of the rows of the list of websites.

So am I right in thinking there are 2 options:

  1. Keep using Php's password_hash, and loop as described above? I haven't found an elegant way to validate the participant's hashed version of the location to the original hash stored in the mysql database.
  2. Use an alternative Php hashing solution that produces a stable hash each time (is there a recommended way to do this? I've seen warnings about md5 and sha)

The reason I want to do the above is that I would like to reduce the chance that a malicious user could dump the database and then use it to systematically interfere with all the websites listed.

7
  • 1
    How would a hash of the website the content came from hinder a malicious user from interfering with all websites? Hashes won't help you if there's a very limited set of valid answers...
    – vidarlo
    Jan 3, 2021 at 17:47
  • Thanks for the quick reply - I guess that might be my problem, the structure of information will be as follows: researcher_group_name/repository_name/experiment_name is there enough variance in this to make hashing worthwhile? (I won't need to store the http, www, etc.)
    – user171545
    Jan 3, 2021 at 17:53
  • If it's a limited list of say 10 for each of those parts, it's trivial to run through all combinations; it's just 10*10*10 combinations. Can be done in <10 seconds with a few lines of code in any modern language. Even with a thousand variables for each part, it's within the reach of anyone who cares.
    – vidarlo
    Jan 3, 2021 at 17:55
  • 1
    Don't assume that an attacker is unaware. If they can access your database, they can probably access the information that will tell them that that's a valid path. Furthermore; an attacker that interferes with your data is not merely a passive attacker, but an very active attacker that will seek out more information. You assume a very competent attacker that gains privileged access and wants to interfere, yet not explore...? That attacker profile doesn't make much sense to me.
    – vidarlo
    Jan 3, 2021 at 18:02
  • 2
    I would focus on securing your system, and discovering manipulation. If an attacker has persistent access to your database, as you imagine here, most bets are off anyway, and you have a extremely tough task ahead.
    – vidarlo
    Jan 3, 2021 at 18:19

1 Answer 1

3

Hashes

Your issue is that password_hash is designed for passwords and so always assigns a random salt - this is why you get a different hash everytime. You want to use just a hash and skip the salt, which password_hash won't let you do. You should probably just use plain ol' SHA256 which PHP can provide for you via the hash function.

A Caveat

I don't quite understand the background of what you are doing, but there is a good chance that this entire idea is a non-starter. Here's the dangerous statement:

Ideally I want to hash the locations so ... I can confirm whether the website they came from is registered

You should know that there is simply no way to confirm where the data came from. Absolutely none at all. HTTP/browsers/the internet provide absolutely no way to tell for certain what website a particular request came from, especially since you can't even guarantee that a request is even coming from a browser in the first place.

You should probably make sure you understand the full implications of the above before you go much farther.

Brute Force

You asked about the risk of someone guessing a hash. You probably don't have to worry about that. The hash generated by the SHA256 algorithm is (not coincidentally) a 256 bit hash. This means that there are 1e77 possible hashes. This makes it statistically impossible for a user to guess a hash for any reasonable number of websites. From the description in your comments, it also seems unlikely that they would be able to bruteforce your plain text values, although that is harder to guess from here.

However, keep in mind that these values are not actually secrets. Anyone who is on one of these sites would be able to see the hash going back and forth, and so can easily find it once they are on the actual site. It sounds like the hash is kind of like an API key, but if it is sent/known by JavaScript running in the browser, then that means it is completely public. Once again, make sure you understand the full implications of that and are okay with it. In short:

If someone visits a website, takes the hash, and then starts doing [evil] with it, what is the worst that they can do?

Make sure you are okay with the answer to that question!

2
  • Thanks for this - I only need to know where the participant CLAIMS they are doing the experiment. So that part of the problem (I hope) is fine. But it sounds like SHA256 is fine for my purposes (assuming Vidarlo's comments above aren't terminal issues)?
    – user171545
    Jan 3, 2021 at 17:57
  • 1
    @BeepBop I've updated my answer and tried to address that as best as I could. The details are pretty fuzzy, so it's hard to say for sure. Jan 4, 2021 at 14:02

You must log in to answer this question.