TheGU / mod-auth-token

This module uses token based authentication to secure downloads and prevent deep-linking. Have your script or servlet generate a token to authenticate the download and let Apache handle the file transfer without having to pipe it through a script for security.
Apache License 2.0
0 stars 0 forks source link

Forbidden instead of granting access #11

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago

What is the expected output? What do you see instead?
should see a .jpg file, instead i get a forbidden message

What version of the product are you using? On what operating system?
tried 1.0.5 and 1.0.6 beta
debian (lenny) with apache2

Please provide any additional information below.

my httpd.conf
LoadModule auth_token_module  /usr/lib/apache2/modules/mod_auth_token.so
<Location /downloads/>
        AuthTokenSecret "secret"
        AuthTokenPrefix /downloads/
        AuthTokenTimeout 60
</Location>

php code:
<?php
// Settings to generate the URI
$secret = "secret";        // Same as AuthTokenSecret
$protectedPath = "/downloads/";         // Same as AuthTokenPrefix
$ipLimitation = false;                 // Same as AuthTokenLimitByIp
$hexTime = dechex(time());             // Time in Hexadecimal      
$fileName = "kannnichtkommen.jpg";    // The file to access

// Let's generate the token depending if we set AuthTokenLimitByIp
if ($ipLimitation) {
  $token = md5($secret . $fileName . $hexTime . $_SERVER['REMOTE_ADDR']);
}
else {
  $token = md5($secret . $fileName. $hexTime);
}

// We build the url
$url = $protectedPath . $token. "/" . $hexTime . "/" . $fileName;
echo 'http://ads.sui.at'.$url;

if the generated url is called within a browser:
Forbidden

You don't have permission to access 
/downloads/c3eee0620dd7022d4104152c69808194/4cb90464/kannnichtkommen.jpg on 
this server.

so it "does" work, but sadly does not grant me access when it should...

modules seems to be loaded successfully as i get it listed through "apache2 -M"

any ideas?

Original issue reported on code.google.com by 4501...@gmail.com on 16 Oct 2010 at 1:55

GoogleCodeExporter commented 9 years ago
ah forgot to add,

if i do remove the <Location ... </Location> part from my httpd.conf
i can access + view the file without any troubles...
so its most likely no owner issue nor spelling mistake.

Original comment by 4501...@gmail.com on 16 Oct 2010 at 2:02

GoogleCodeExporter commented 9 years ago
What does your apache error log say?

Original comment by andreas....@gmail.com on 26 Nov 2010 at 10:06

GoogleCodeExporter commented 9 years ago
well i got it working by fiddling/debugging the code and re-compile it,

at the end of the day i was so happy that it worked that i can't even say if 
this error could hit others aswell,

well what i can say is...
the md5 which is generated within this differs from mine, which is generated 
with php (due to apaches modified md5 algo), ive seen in the log files which 
md5 should come and which came actually - and they were different. 

Original comment by 4501...@gmail.com on 26 Nov 2010 at 10:14

GoogleCodeExporter commented 9 years ago
I got the same problem, look my apache error.log:

[Thu Feb 03 15:07:51 2011] [warn] [client ::1] mod_auth_token: failed token 
auth (got '38a4a6ef40cdd3c3be390ec7900abd01', expected 
'DBBEC1C6A5D594BC48594ABB676B35D2', uri 
'/download/38a4a6ef40cdd3c3be390ec7900abd01/4d4ae0e5/dvi.avi'), referer: 
http://localhost/authtoken.php

I triple checked a lot of things and I still didn't find a way to solve this 
issue. Does someone have an idea?

Original comment by lffiguei...@gmail.com on 3 Feb 2011 at 5:10

GoogleCodeExporter commented 9 years ago
hello,

well ive made a dirty hack in fact, didnt solve the problem itself...

i found out that its due to apr_md5_update hash code differs from php's md5 
hash value,
my dirty workaround (which does the job for the moment, at least for me) looks 
like...

uncommenting those 2 lines, then it should work out, havnt had the time to 
evaluate this in detail by now, but you should be able to at least use it (link 
does not expire anymore tho, but at least its hidden and more or less secure)

so i assume its either the amount of md5 update calls or the length of the path 
or maybe some timestamp issue (which i doubt)

/* create md5 token of secret + path + timestamp */
       apr_md5_init(&context);

       apr_md5_update(&context, (unsigned char *) conf->secret, strlen(conf->secret));
       // apr_md5_update(&context, (unsigned char *) path, strlen(path));
       // apr_md5_update(&context, (unsigned char *) timestamp, 8);
       if (conf->checkip)
               apr_md5_update(&context, (unsigned char *) remoteip, strlen(remoteip));
       apr_md5_final(digest, &context);

if you cant get it working, feel free to write in here, or paste the code and 
ill try it out if i can get it resolved,

bye

Original comment by 4501...@gmail.com on 3 Feb 2011 at 11:23

GoogleCodeExporter commented 9 years ago
Thanks for answer quickly, really started to work doing your changes.

By the way, I had made a test before, I changed md5 to sha1, even getting 
longer urls. But really looks like there are something happening in the 
timestamp, because after change md5 to sha1 I started get this error:

token expired at 52, now is 1296848391

I will try make it work with SHA1, if I get something, I'll post it too.

Thanks again.

Original comment by lffiguei...@gmail.com on 4 Feb 2011 at 7:45

GoogleCodeExporter commented 9 years ago
apache portable runtime (apr) => apr_md5 calculates md5 a different way than 
php's md5 does.

heres apr_md5.c source file:
http://www.opensource.apple.com/source/apr/apr-12/apr-util/apr-util/crypto/apr_m
d5.c

just had a brief view on this but it doesnt look like much fun to adapt a php 
function for this.

not sure if sh1 is not effected by a similar issue, can't remember if i have 
tried it or not, if you find out anything relevant i'd be more than happy if 
you would share this info with us!

sadly i am no expert at all but i assume there might be a "regular" (compatible 
with php) md5 function/class in c (other than this from apr), using that would 
most likely solve this issue aswell,

if you are able to find a "good" solution for this, it would be highly 
appreciated if you would share it with us!
thanks in advance,

Original comment by 4501...@gmail.com on 5 Feb 2011 at 3:44

GoogleCodeExporter commented 9 years ago
btw i assume you are also using apache2 rather than apache1?
some people do not encouter this issue as it looks, maybe it works on apache1.. 
well anyways its confusing, specially late night after a couple of beers :--)

gn8

Original comment by 4501...@gmail.com on 5 Feb 2011 at 3:48

GoogleCodeExporter commented 9 years ago
I've tried it with perl and php5. Using SHA1, MD5...

And what I get? That wasn't the problem. Looking other issues I saw some people 
generating the token in a different way, maybe this is what's happen with you.

The token should be formed like this (in PHP):

$secret = "config";
$protectedPath = "/download/";
$hexTime = dechex(time());     
$fileName = "div.avi";
$token = md5($secret ."/". $fileName. $hexTime);

This slash between "secret" and "filename" is what I was missing.

We always think about the worse thing, sometimes is just a slash.

Tell me if this work to you too.

Now is my turn to get out and have some beers. ;)

Original comment by lffiguei...@gmail.com on 6 Feb 2011 at 1:44

GoogleCodeExporter commented 9 years ago
i'll have a look at this, but i doubt that this slash is missing in my case, as 
it works with the "dirty hack" i wrote above, if the slash was missing the hash 
codes would still differ and i think it wouldnt work out at all.

you have been able to get it work with the original source code?

bye

Original comment by 4501...@gmail.com on 6 Feb 2011 at 12:18

GoogleCodeExporter commented 9 years ago
Exactly, with the original source code.

Just right now I'll make some changes.

This is a useful module for apache, but seems abandoned right now, and the 
documentation of how to implement and use it isn't good enough. Sometimes we 
need to read the original C source to view where to go and how to go.

Original comment by lffiguei...@gmail.com on 6 Feb 2011 at 3:56

GoogleCodeExporter commented 9 years ago
Sorry for the delay

Have you tried 
$fileName = "/div.avi"; ( note the slash)

Can you please try it and come back to me ? thanks

Original comment by teixeira...@gmail.com on 19 Apr 2011 at 4:47

GoogleCodeExporter commented 9 years ago

Original comment by teixeira...@gmail.com on 19 Apr 2011 at 4:50

GoogleCodeExporter commented 9 years ago
No response so i close the ticket, please reopen it if you need, thanks.

Original comment by teixeira...@gmail.com on 8 Jun 2011 at 11:04

GoogleCodeExporter commented 9 years ago
Hello everybody,
I found out why this happens. Apache md5 is different because garbage is added 
to conf->secret (3 bytes).

So changes i made: 
/* create md5 token of secret + path + timestamp */
apr_md5_init(&context);

//———changed/added
char trueSecret[strlen(conf->secret) - 2];
strncpy(trueSecret, conf->secret, strlen(conf->secret) - 3);
trueSecret[strlen(conf->secret) - 3] = '\0';
apr_md5_update(&context, (unsigned char *) trueSecret, strlen(trueSecret));
//——— changed/added

apr_md5_update(&context, (unsigned char *) path, strlen(path));
apr_md5_update(&context, (unsigned char *) timestamp, 8);

apr_md5_final(digest, &context);

So now it works fine.

Original comment by Kostenko...@gmail.com on 7 Sep 2014 at 8:41

GoogleCodeExporter commented 9 years ago
hello,

thanks for your effort on posting a solution on this, i havn't tried this fix 
yet but it makes sense.
i am sure it will be helpful for other users aswell, thank you!

Original comment by 4501...@gmail.com on 7 Sep 2014 at 8:52

GoogleCodeExporter commented 9 years ago
Hi Kostenko et al. Please can you explain a bit more about the fix discovered - 
i.e. what files does the fix have to be added to - and do any apache files need 
to be recompiled.

Am using the below as a test file hoping fix can be added to that directly do I 
can understand what I need to update. I'm getting properly formatted urls 
(structure wise), just they don't work.

thanks

<?php
// Settings to generate the URI
$secret = "happydays";             // Same as AuthTokenSecret
$protectedPath = "/d/";        // Same as AuthTokenPrefix
$ipLimitation = false;                 // Same as AuthTokenLimitByIp
$hexTime = dechex(time());             // Time in Hexadecimal
//$hexTime = dechex(time()+120);         // Link available after 2 minutes      
$fileName = "/test.avi";    // The file to access

// Let's generate the token depending if we set AuthTokenLimitByIp
if ($ipLimitation) {
  $token = md5($secret . $fileName . $hexTime . $_SERVER['REMOTE_ADDR']);
}
else {
  $token = md5($secret . $fileName. $hexTime);
}

// We build the url
$url = "http://www.domain.com" . $protectedPath . $token. "/" . $hexTime . 
$fileName;
echo $url;
?>

Original comment by soflo...@gmail.com on 30 Sep 2014 at 3:09

GoogleCodeExporter commented 9 years ago
only related file I can so far locate is apr_md5.h, but that doesn't have the 
contents referred to above.

Original comment by soflo...@gmail.com on 30 Sep 2014 at 4:02

GoogleCodeExporter commented 9 years ago
made the recommended updates to mod_auth_token.c and recompiled, but still not 
working. Not sure what to do next to resolve the issue. 
What is the actual process being used here (i.e. why are two hashes being 
described - one from apache and one from php) and how can I get a log that will 
help track the issue down.

Original comment by sofl...@gmail.com on 1 Oct 2014 at 9:59

GoogleCodeExporter commented 9 years ago
Was just looking over the original code and the updated code more carefully, 
and it's not actually that clear what should be updated - especially given 
comments. Please can you clarify. Here is the original:

/* create md5 token of secret + path + timestamp */
apr_md5_init(&context);

apr_md5_update(&context, (unsigned char *) conf->secret, strlen(conf->secret));
apr_md5_update(&context, (unsigned char *) path, strlen(path));
apr_md5_update(&context, (unsigned char *) timestamp, 8);
if (conf->checkip)
    apr_md5_update(&context, (unsigned char *) remoteip, strlen(remoteip));
apr_md5_final(digest, &context);

Obviously the inserted code (that marked //———changed/added ) goes after 
the first statement, however what about the lines after that - which are also 
changed - i.e. the if statement is not present (maybe that wasn't in the 
version you were working on). And also the following line has been removed (or 
wasn't present in version you working on):

apr_md5_update(&context, (unsigned char *) conf->secret, strlen(conf->secret));

Original comment by sofl...@gmail.com on 1 Oct 2014 at 10:30

GoogleCodeExporter commented 9 years ago
I found that the latest build of mod_auth_token worked for my purposes (as of 
1st October 2014) and that I didn't need to apply this patch. 

I was implementing this on centos 6.5 (running Plesk) and I had to use this 
command set for the additional vhost directives. Note it's a very slightly 
different setup to lighttpd:

Alias /downloads /var/www/vhosts/domain.name/httpdocs/downloads
<Location /downloads/>
    AuthTokenSecret       "yoursecrethere"
    AuthTokenPrefix       /downloads/
    AuthTokenTimeout      3600
</Location>

The matching php to generate the secret for the above would be:

<?php
// Settings to generate the URI
$secret = "yoursecrethere";             // Same as AuthTokenSecret
$protectedPath = "/downloads/";        // Same as AuthTokenPrefix
$ipLimitation = false;                 // Same as AuthTokenLimitByIp
$hexTime = dechex(time());             // Time in Hexadecimal
//$hexTime = dechex(time()+120);         // Link available after 2 minutes      
$fileName = "/path_to_file/filename.html";    // The file to access

// Let's generate the token depending if we set AuthTokenLimitByIp
if ($ipLimitation) {
  $token = md5($secret . $fileName . $hexTime . $_SERVER['REMOTE_ADDR']);
}
else {
  $token = md5($secret . $fileName. $hexTime);
}

// We build the url
$url = "http://www.domain.name" . $protectedPath . $token. "/" . $hexTime . 
$fileName;
echo $url;
?>

Original comment by sofl...@gmail.com on 29 Oct 2014 at 11:54