1

I'm using crypt() which in the particular case uses an md5 hash with 12 character salt.

Here is an example of the string crypt() returns modified from php.net, crypt documentation.

$1$rasmusle$rISCgZzpwk3UhDidwX/in0

Here is the salt which also includes the encoding type.

$1$rasmusle$ 

Here it the encoding type. ( MD5 in this case )

$1$ 

and finally the hash value.

rISCgZzpwk3UhDidwX/in0

You can not have forward slashes in file names as this will be interpreted as a folder.

Should I simply remove all the forward slashes and are there other issue with the characters set that crypt() uses.

4 Answers4

5

It looks like you want to prevent / allow access to the image for specific users. If that is the case I would do the following:

  1. Store the images outside of the document root. This makes sure the images cannot simply be directly requested.
  2. Store the images original name in the database and also store the sha1_file() hash in the same record. This adds the benefit if not having duplicate images on your server. Although images are small it prevents cluttering of the system.
  3. When somebody requests a "private" image they will request it through a PHP file which will check whether the user has the privileges to access the file and if so serves the file (from the database).

With the above method you will have the most control over who can request the images and your users will thank you for that.

Note: that you cannot simply store all images in the same folder, because all filesystems have limits as to how many files can be stored in a single directory

A simple example of a PHP script that serves an image would look something like the following:

<?php

// always set the header and change it according to the type of the image
header("Content-type: image/jpeg");
echo file_get_contents('/path/to/the/image.jpg');
Community
  • 1
  • 1
PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • The limits are quite high nowadays – Marcin Orlowski Nov 26 '12 at 21:59
  • @WebnetMobile.com Yup they are. – PeeHaa Nov 26 '12 at 22:01
  • Because as I read it you want to the file to be not public. What you are talking about is security through obscurity. – PeeHaa Nov 26 '12 at 22:50
  • Nope not the same reason you hash passwords. The hashes of passwords may get in an attackers hand. The only thing they know in that case is the hash and not the password itself. If an attacker gets his hands on the image hash he/she will have the image itself instead of only the hash. – PeeHaa Nov 27 '12 at 09:59
1

/$1$/ - Is an algorithm that used to create a hash

You can just use md5 md5_file/ sha1 sha1_file functions that would create hash without that additional information. Unless you want to use different algorithms at the same time.

E_p
  • 3,136
  • 16
  • 28
  • Sounds like you use wrong tool to solve problem. If content is public who cares if somebody can guess it. If it is not, you need a layer of acl above it anyway. I would use sha1 to avoid collisions, it is more than enough. i would also split it in to folders, like very 5-10 symbols. – E_p Nov 26 '12 at 21:55
  • Never solve problem that does not exist. It one of the ways never to release a product. – E_p Nov 26 '12 at 22:05
  • It's the other way around, now you need to figure out (know) algorithm every time you access that file. If you just flip a coin and pick one, that would make your life way easier as algorithm always the same. – E_p Nov 26 '12 at 22:11
1

Run a URLEncode method over your hash, and it should replace all of the '/' with %2F... I know this isn't a perfect fix, because i think things like apache server still block any web requests with '%2F' in the url. Just my 2 cents on the matter

Brent Echols
  • 590
  • 2
  • 9
1

ALWAYS normalize user provided data, including file names, unless you want to be hacked by uploading file with name containig NULL to fool PHP. Specify allowed characters (i.e A-Za-z0-9 and convert all other to i.e. underscore. Or use sha1/md5 to create hash from filename and store file under that name.

EDIT

This will replace all characters except for A-Z, a-z, 0-9 with underscore _:

$normalizedName = preg_replace('/[^A-Za-z0-9]/', '_', $userProvidedName);
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • I doubt you *"do not use filenames"*. You use them to let your users download the file for example. That's sufficient to pay attention and not let your users be hacked by planted i.e. `.scr` looking like `.jpg`. – Marcin Orlowski Nov 26 '12 at 21:58
  • Ok. Then you seem to be on safer ground at least with that :) – Marcin Orlowski Nov 26 '12 at 22:00
  • Then what is really your problem there? hash does not contain forward slases. It's just alphanumeric – Marcin Orlowski Nov 26 '12 at 22:04
  • No, that's nonsense. MD5 is 128 bit hash and is typicaly shown as hex string. – Marcin Orlowski Dec 01 '12 at 00:01
  • Exactly. I mean that hash function result is one thing (in this case it returns 128 bits of hash), representation of hash is another (most implementations returns it as 32 hexadecimal based string). – Marcin Orlowski Dec 06 '12 at 23:08
  • So there are 128 bits stored in memory, how you represent that in text is irrelevant, wether it is binary, octal, hex, or the character set that crypt() uses. –  Dec 10 '12 at 20:26