Using a time-based, rotating hash or string for se

2019-02-17 12:57发布

In a CMS app I occasionally need to open an iframe of another domain. At the moment I am setting the URL for that iframe to something very obscure. Like http://domain.com/iframe/jhghjg34787386/. This works but theoretically that iframe source url will get saved in the user's history and could be accessed from the outside world.

So, I am wondering about using a time-based approach to an ever-changing hash or string that is processed on the request side and is checked on the iframe source side. However I would like it to be time based.

I could do this to get my hash:

<?php 

   $seed = '123456789'; // a password that both the parent and source have
   $string = md5(time().$seed); 
?>

But then the two servers have to be exactly synced. Any way to make the time constraint more fuzzy?

I am also open to other approaches. Is there any way to validate that the parent window for an iframe is of a certain domain?

4条回答
聊天终结者
2楼-- · 2019-02-17 13:21

If it is time based, then the amount of possible keys that a person would have to guess would be tiny. Since I would know approximately when a URl might be generated, and I know how you are hashing it, then I can just create hundreds of thousands of links and test them out.

You should use UUID or something equivalent. The probability of a collission would be essentially impossible.

查看更多
干净又极端
3楼-- · 2019-02-17 13:23

Be careful of using MD5 for hashing - it is cryptographically broken. There are any number of online sites to help create collisions. Rather use something like SHA256 and always include a long salting string.

If the user does not have to interact with the site in the iframe you could consider scraping the site code and inserting it directly into your code. There are a number of libraries available for this.

What about using something like

$hash = hash ( "sha256" , date("h") . 'myverylongsaltstring' );

So long as the servers have their timezones correct and are synchronized to within an hour this approach will work like your time() hash.

Additionally you could use something like TinyUrl to obfuscate the link a little further. Something along the lines of http://www.technabled.com/2008/12/create-your-own-tinyurl-with-php-and.html

查看更多
ら.Afraid
4楼-- · 2019-02-17 13:27

You could add a key to your hash and send the timestamp with the query, e.g.:

$key = "YOUR_SECRET_KEY";
$time = time();
$hash = hash_hmac('sha256', $time, $key);
$url = "https://example.com/iframe?hash=$hash&time=$time";

On the other side you should first check if the timestamp is in the limits (e.g. not older than five minutes) and than rehash with the key and the submitted timestamp. If you get the same hash the request is valid.

Notes:

查看更多
冷血范
5楼-- · 2019-02-17 13:39

You shouldn't use plain MD5 that; MD5 is not designed for ensuring message authenticity. Instead you can just give the timestamp publicly, alongside with other information (message), base64 encoded, so that it does not contain the ':' character. Then you can calculate the HMAC code of the message for example with

$hmac = hash_hmac("md5", $message, $secret)
$signed_message = $message . ":" . $hmac

On the other end you can then check this signature, by first splitting with ":", getting $message and $hmac, then you can check authenticity with

$hmac == hash_hmac("md5", $message, $secret)

If codes match, then check if the timestamp in the $message is still within the limits.

查看更多
登录 后发表回答