Pull to refresh

Недокументированные возможности secure_link

Reading time 2 min
Views 13K
  Начиная с версии 0.8.50 в модуле Nginx secure_link появилось значительное улучшение по защите ссылок от подделывания. Как ни странно, новые возможности до сих пор не отражены в официальной документации [1]. Описание на английском можно найти на сайте Nginx Community [2], а также пояснения Сысоева по данным изменениям [3]. Код на PHP для генерации защищённых ссылок можно найти в форуме по nginx [4].
 В общем, новшество выглядит так :

nginx.conf:
location ~ ^/p/(?<secure>[\w-]+,\d+)/(?<secured_stuff>.+)$ {
     secure_link     $secure; 
     # в данном примере '$secure' = "HASH,TIMESTAMP"
     secure_link_md5      PASSWORD$secure_link_expires$secured_stuff;
     # '$secure_link_expires' это переменная nginx содержащая значение после запятой из 'secure_link' = TIMESTAMP

     if ($secure_link = "") { return 403; } # invalid link
     if ($secure_link == 0) { return 410; } # expired link
     
     # link is ok, do something here
}


URL может выглядеть так: /p/HASH,TIMESTAMP/ANYTHING где
 PASSWORD секретный пароль
 TIMESTAMP это время до которого действительна ссылка в unix epoch
 ANYTHING произволный текст
 HASH кодированный в base64-URL [5] md5 хэш из шаблона secure_link_md5 ($secured_stuff = ANYTHING в данном примере). Символы '=' после base64 можно опускать

  Nginx имеет пару неявных нюансов в подсчете md5 суммы:
1. строка для подсчета из URL ($secured_stuff) декодируется из URL encoding в оригинальный вид
2. md5 хэш должен передаваться в бинарном виде для кодирования в base64

  код для PHP может быть такой:
$time  = time() + EXPIRE_TTL; # = TIMESTAMP
$hash = md5(PASSWORD.$time.$secured_stuff, true);
$hash = strtr( base64_encode($hash), array( '+' => '-', '/' => '_', '=' => '' ));
$url    = 'http://example.tld/p/$hash.','.$time.'/'.$secured_stuff;


Для передачи хэша и времени можно также использовать аргументы и куки:
для URL вида
http://example.com/p/files/top_secret.pdf?st=PIrEk4JX5gJPTGmvqJG41g&e=1324527723

где агрумент st это хэш от PASSWORD, URI и аргумента e
location вида
 
location /p/ {
     secure_link $arg_st,$arg_e; # this must match the URI part related 
     secure_link_md5 PASSWORD$uri$arg_e; # PASSWORD is the secret token
     ....
}

Как не сложно догадаться, при формировании хэша можно использовать IP адрес клиента.

Ссылки:
[1] sysoev.ru/nginx/docs/http/ngx_http_secure_link_module.html
[2] wiki.nginx.org/HttpSecureLinkModule
[3] nginx.org/pipermail/nginx/2010-September/022324.html
[4] forum.nginx.org/read.php?21,126363,128324#msg-128324
[5] en.wikipedia.org/wiki/Base64#URL_applications
Tags:
Hubs:
+34
Comments 30
Comments Comments 30

Articles