FAQ

Page Discussion History

Difference between revisions of "HttpSecureLinkModule"

(secure_link_secret)
 
(secure_link_secret)
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
= Synopsis =
 
= Synopsis =
  
This module computes and checks request URLs for a required security token.  
+
This module checks request URLs for a required security token.  
 
This module is not compiled by default and must be specified using the
 
This module is not compiled by default and must be specified using the
  
Line 11: Line 11:
  
 
== Example usage: ==
 
== Example usage: ==
Consider the example where a link that should be accessible throughout a year starting December 22 2010, is located in a given URI. The request URI includes a query string with an argument, ''st'', that specifies the MD5 hash:  
+
Imagine having a pdf file you want to ensure isn't linked from else where, to do this we need to add a unique token and an expiration date, we use the following PHP code to generate a token and an expire time
<pre>
+
To construct the above hash, in PHP you can issue the following:
http://example.com/p/files/top_secret.pdf?st=PIrEk4JX5gJPTGmvqJG41g&e=1324527723
+
<geshi lang="php">
</pre>
+
$secret = 'segredo'; // To make the hash more difficult to reproduce.
 +
$path  = '/p/files/top_secret.pdf'; // This is the file to send to the user.
 +
$expire = 1096891200; // At which point in time the file should expire. time() + x; would be the usual usage.
  
To construct the above hash, in PHP you can issue the following command (using PHP CLI):
+
$md5 = base64_encode(md5($secret . $path . $expire, true)); // Using binary hashing.
<geshi lang="php">
+
$md5 = strtr($md5, '+/', '-_'); // + and / are considered special characters in URLs, see the wikipedia page linked in references.
php -r 'print  str_replace("=", "", strtr(base64_encode(md5("segredo/p/files/top_secret.pdf1324527723", TRUE)), "+/", "-_")) . "\n";'
+
$md5 = str_replace('=', '', $md5); // When used in query parameters the base64 padding character is considered special.
 
</geshi>
 
</geshi>
to print the MD5 hash in a separate line. Of course if you're running a web app your app must do this automatically. Note that the MD5 hash is in '''binary''' form.
 
  
 
The expire time can obtained by using the [http://pt2.php.net/manual/en/function.time.php time()] function in PHP &mdash; or similar in other programming language &mdash; in order to obtain the [https://secure.wikimedia.org/wikipedia/en/wiki/Unix_epoch Unix epoch].
 
The expire time can obtained by using the [http://pt2.php.net/manual/en/function.time.php time()] function in PHP &mdash; or similar in other programming language &mdash; in order to obtain the [https://secure.wikimedia.org/wikipedia/en/wiki/Unix_epoch Unix epoch].
 +
 +
Now that we have a hash that cannot easily be reproduced and an expire time we link the file in the following way:
 +
 +
<pre>
 +
http://example.com/p/files/top_secret.pdf?st=PIrEk4JX5gJPTGmvqJG41g&e=1324527723
 +
</pre>
 +
 +
To have Nginx protect this URL we need to tell it how to reproduce the MD5 hash. We do this in the following way:
  
 
<geshi lang="nginx">
 
<geshi lang="nginx">
Line 29: Line 38:
 
     secure_link $arg_st,$arg_e;
 
     secure_link $arg_st,$arg_e;
  
     ## This is how the MD5 hash is built from a secret token, an URI and an
+
     ## The MD5 hash is built from our secret token, the URI($path in PHP) and our expiration time.
    ## expiration time.
+
 
     secure_link_md5 segredo$uri$arg_e;
 
     secure_link_md5 segredo$uri$arg_e;
  
Line 48: Line 56:
  
 
= 
Directives =
 
= 
Directives =
== secure_link_secret ==
 
 
{{Directive|name=secure_link_secret|args=secret_word|default=none|context=location|vars=no|deprecated=0.8.50, use [[#secure_link_md5|secure_link_md5]]}}
 
 
This directive has been deprecated as of nginx 0.8.50 in favor of [[#secure_link_md5|secure_link_md5]].
 
 
 
== secure_link ==
 
== secure_link ==
  
 
{{Directive|name=secure_link|args=md5_hash[,expiration_time]|default=none|context=location|vars=yes}}
 
{{Directive|name=secure_link|args=md5_hash[,expiration_time]|default=none|context=location|vars=yes}}
  
This directive specifies the MD5 hash value and the expiration time of this link URI. The md5_hash '''should''' be encoded using [http://en.wikipedia.org/wiki/Base64#URL_applications Base64 for URLs]. expiration_time is the [https://secure.wikimedia.org/wikipedia/en/wiki/Unix_epoch Unix epoch].  
+
This directive specifies the MD5 hash value and the expiration time of this link URI. The md5_hash '''must''' be encoded using [http://en.wikipedia.org/wiki/Base64#URL_applications Base64 for URLs]. expiration_time is the [https://secure.wikimedia.org/wikipedia/en/wiki/Unix_epoch Unix epoch].  
  
 
If no expiration_time is specified then the link '''never''' expires.
 
If no expiration_time is specified then the link '''never''' expires.
Line 66: Line 68:
 
{{Directive|name=secure_link_md5|args=secret_token_concatenated_with_protected_uri|default=none|context=location|vars=yes}}
 
{{Directive|name=secure_link_md5|args=secret_token_concatenated_with_protected_uri|default=none|context=location|vars=yes}}
  
This directive specifies the string you want to be hashed by MD5. The string can be obtained using variables like in the example above. This hash value is compared with the md5_hash given in the '''secure_link''' directive. If they agree $secure_link equals '''1''', otherwise it's the null string.
+
This directive specifies the string you want to be hashed by MD5. The string can be obtained using variables like in the example above. This hash value is compared with the md5_hash given in the '''secure_link''' directive. If they match then $secure_link is set to '''1''', otherwise it's the null string.
 +
 
 +
== secure_link_secret ==
 +
<include wikitext nopre src="http://wiki.nginx.org/nginx.org/http/ngx_http_secure_link_module/secure_link_secret.txt" />
 +
 
 +
This directive has been deprecated as of nginx 0.8.50 in favor of [[#secure_link_md5|secure_link_md5]].
  
 
= variables =
 
= variables =
Line 73: Line 80:
  
 
This variable behaves differently depending on whether [[HttpSecureLinkModule#secure_link_secret|secure_link_secret]] is used or not:  
 
This variable behaves differently depending on whether [[HttpSecureLinkModule#secure_link_secret|secure_link_secret]] is used or not:  
* If using '''secure_link_secret''', when the requested URI is correct, i.e., matches the computed MD5 hash, $secure_link equals the protected URI. Otherwise it's the null string.
+
* If using '''secure_link_secret''', when the requested URI matches the computed MD5 hash, $secure_link is set to the protected URI. Otherwise it's a null string.
  
* If using '''secure_link''' and '''secure_link_md5''', when the requested URI is correct, i.e., matches the computed MD5 hash, then $secure_link equals '''1'''. If the current local time exceeds the $expiration_time then $secure_link equals '''0'''. Otherwise it's the null string.
+
* If using '''secure_link''' and '''secure_link_md5''', when the requested URI matches the computed MD5 hash, then $secure_link is set to '''1'''. If the current local time exceeds the $expiration_time then $secure_link is set to '''0'''. Otherwise it's set to a null string.
  
 
== $secure_link_expires ==
 
== $secure_link_expires ==
  
Equals the $expiration_time when specified.
+
Is set to the $expiration_time when specified.
 +
 
 +
= References =
 +
* [http://nginx.org/en/docs/http/ngx_http_secure_link_module.html Original Documentation]
 +
* [http://en.wikipedia.org/wiki/Base64#URL_applications Base64 for URLs]

Revision as of 19:46, 2 May 2012

Contents

Synopsis

This module checks request URLs for a required security token. This module is not compiled by default and must be specified using the

--with-http_secure_link_module

argument to configure when compiling nginx. Note that this module is only supported in nginx version 0.7.18 and higher.

Example usage:

Imagine having a pdf file you want to ensure isn't linked from else where, to do this we need to add a unique token and an expiration date, we use the following PHP code to generate a token and an expire time To construct the above hash, in PHP you can issue the following:

$secret = 'segredo'; // To make the hash more difficult to reproduce.
$path   = '/p/files/top_secret.pdf'; // This is the file to send to the user.
$expire = 1096891200; // At which point in time the file should expire. time() + x; would be the usual usage.
 
$md5 = base64_encode(md5($secret . $path . $expire, true)); // Using binary hashing.
$md5 = strtr($md5, '+/', '-_'); // + and / are considered special characters in URLs, see the wikipedia page linked in references.
$md5 = str_replace('=', '', $md5); // When used in query parameters the base64 padding character is considered special.

The expire time can obtained by using the time() function in PHP — or similar in other programming language — in order to obtain the Unix epoch.

Now that we have a hash that cannot easily be reproduced and an expire time we link the file in the following way:

http://example.com/p/files/top_secret.pdf?st=PIrEk4JX5gJPTGmvqJG41g&e=1324527723

To have Nginx protect this URL we need to tell it how to reproduce the MD5 hash. We do this in the following way:

location /p/ {
    ## This must match the URI part related to the MD5 hash and expiration time.
    secure_link $arg_st,$arg_e;
 
    ## The MD5 hash is built from our secret token, the URI($path in PHP) and our expiration time.
    secure_link_md5 segredo$uri$arg_e;
 
    ## If the hash is incorrect then $secure_link is a null string.
    if ($secure_link = "") {
        return 403;
    }
 
    ## The current local time is greater than the specified expiration time.
    if ($secure_link = "0") {
        return 403;
    }
 
    ## If everything is ok $secure_link is 1.
}


Directives

secure_link

syntax: secure_link md5_hash[,expiration_time]

default: none

context: location

variables: yes


This directive specifies the MD5 hash value and the expiration time of this link URI. The md5_hash must be encoded using Base64 for URLs. expiration_time is the Unix epoch.

If no expiration_time is specified then the link never expires.

secure_link_md5

syntax: secure_link_md5 secret_token_concatenated_with_protected_uri

default: none

context: location

variables: yes


This directive specifies the string you want to be hashed by MD5. The string can be obtained using variables like in the example above. This hash value is compared with the md5_hash given in the secure_link directive. If they match then $secure_link is set to 1, otherwise it's the null string.

secure_link_secret

Syntax: secure_link_secret word
Default:
Context: location
Reference:secure_link_secret


This directive has been deprecated as of nginx 0.8.50 in favor of secure_link_md5.

variables

$secure_link

This variable behaves differently depending on whether secure_link_secret is used or not:

  • If using secure_link_secret, when the requested URI matches the computed MD5 hash, $secure_link is set to the protected URI. Otherwise it's a null string.
  • If using secure_link and secure_link_md5, when the requested URI matches the computed MD5 hash, then $secure_link is set to 1. If the current local time exceeds the $expiration_time then $secure_link is set to 0. Otherwise it's set to a null string.

$secure_link_expires

Is set to the $expiration_time when specified.

References