Skip to content

Commit e0f61ab

Browse files
omonardenji
authored andcommitted
Added timestamps in ISO 8601 format. Support for proxy mode
1 parent 489108e commit e0f61ab

File tree

2 files changed

+277
-252
lines changed

2 files changed

+277
-252
lines changed

README

Lines changed: 78 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,99 @@ make install
2727
Usage:
2828
--
2929

30-
Message to be hashed is defined by secure_link_hmac_message, secret_key
31-
is given by secure_link_hmac_secret, and hashing algorithm H is defined
32-
by secure_link_hmac_algorithm. The expiration timestamp can be either
33-
appended to secret key, or message to be hashed, or both.
30+
Message to be hashed is defined by secure_link_hmac_message, secret_key
31+
is given by secure_link_hmac_secret, and hashing algorithm H is defined
32+
by secure_link_hmac_algorithm. For improved security the timestamp in
33+
ISO 8601 format should be appended to the message to be hashed.
3434

35-
Configuration example below.
35+
It is possible to create links with limited lifetime. This is defined by
36+
an optional parameter. If the expiration period is zero or it is not specified,
37+
a link has the unlimited lifetime.
38+
39+
Configuration example for server side.
3640

3741
location ^~ /files/ {
38-
secure_link $arg_st,$arg_e;
39-
secure_link_hmac_secret my_secret_key$arg_e;
40-
secure_link_hmac_message $uri;
42+
43+
# Variable to be passed are secure token, timestamp, expiration period (optional)
44+
secure_link $arg_st,$arg_ts,$arg_e;
45+
46+
# Secret key
47+
secure_link_hmac_secret my_secret_key;
48+
49+
# Message to be verified
50+
secure_link_hmac_message $uri$arg_ts$arg_e;
51+
52+
# Cryptographic hash function to be used
4153
secure_link_hmac_algorithm sha256;
4254

43-
if ($secure_link = "") {
44-
return 403;
45-
}
55+
# If the hash is incorrect then $secure_link is a null string.
56+
# If the hash is correct but the link has already expired then $secure_link is zero.
57+
# If the hash is correct and the link has not expired then $secure_link is one.
4658

47-
if ($secure_link = "0") {
48-
return 410;
59+
# In production environment, we should not reveal to potential attacker
60+
# why hmac authentication has failed
61+
if ($secure_link != "1") {
62+
return 404;
4963
}
5064

51-
rewrite ^/files/(.$)$ /files/$1 break;
65+
rewrite ^/files/(.*)$ /files/$1 break;
5266
}
5367

54-
Application side should use a standard hash_hmac function to generate
55-
hash, which then needs to be base64 encoded. Example in PHP
68+
Application side should use a standard hash_hmac function to generate hash, which
69+
then needs to be base64url encoded. Example in Perl below.
70+
71+
# Variable $data contains secure token, timestamp in ISO 8601 format, and expiration
72+
# period in seconds
73+
perl_set $secure_token '
74+
sub {
75+
use Digest::SHA qw(hmac_sha256_base64);
76+
use POSIX qw(strftime);
77+
78+
my $now = time();
79+
my $tz = strftime("%z", localtime($now));
80+
$tz =~ s/(\d{2})(\d{2})/$1:$2/;
81+
my $timestamp = strftime("%Y-%m-%dT%H:%M:%S", localtime($now)) . $tz;
82+
my $expire = 60;
83+
my $key = "my_very_secret_key";
84+
my $r = shift;
85+
my $data = $r->uri;
86+
my $digest = hmac_sha256_base64($data . $timestamp . $expire, $key);
87+
$digest =~ tr(+/)(-_);
88+
$data = "st=" . $digest . "&ts=" . $timestamp . "&e=" . $expire;
89+
return $data;
90+
}
91+
';
92+
93+
A similar function in PHP
5694

57-
$expire = time() + 3600;
58-
$secret = "my_secret_key" . $expire;
95+
$timestamp = date("c");
96+
$expire = 60;
97+
$secret = "my_very_secret_key";
5998
$algo = "sha256";
60-
$path = "/files/top_secret.pdf";
61-
$hashmac = base64_encode(hash_hmac($algo,$path,$secret,true));
99+
100+
$stringtosign = "/files/top_secret.pdf" . $timestamp . $expire;
101+
102+
$hashmac = base64_encode(hash_hmac($algo,$stringtosign,$secret,true));
62103
$hashmac = strtr($hashmac,"+/","-_"));
63104
$hashmac = str_replace("=","",$hashmac);
64105
$host = $_SERVER['HTTP_HOST'];
65-
$loc = "https://" . $host . "/files/top_secret.pdf" . "?st=" . $hashmac . "&e=" . $expire;
106+
$loc = "https://" . $host . "/files/top_secret.pdf" . "?st=" . $hashmac . "&ts=" . $timestamp . "&e=" . $expire;
107+
108+
It is also possible to use this module with a Nginx acting as proxy server.
109+
110+
The string to be signed is defined in secure_link_hmac_message, the secure_link_token
111+
variable contains then a secure token to be passed to backend server.
112+
113+
location ^~ /backend_location/ {
114+
set $expire 60;
115+
116+
secure_link_hmac_message $uri$time_iso8601$expire;
117+
secure_link_hmac_secret "my_very_secret_key";
118+
secure_link_hmac_algorithm sha256;
119+
120+
proxy_pass http://backend_server_ip_$uri?st=$secure_link_token&ts=$time_iso8601&e=$expire;
121+
}
122+
66123

67124
Contributing:
68125
--

0 commit comments

Comments
 (0)