Pull to refresh
158
0
Andrew Krasichkov @dharrya

Application security engineer

Send message

Да, ты прав, мой косяк. Думал везде поправил

Ещё хочу добавить — проблема с переопределением вышестоящих настроек встречается не только у add_header, но и у error_page.

А так же у proxy_set_header. Думаю, что список таких директив можно продолжить.

А давайте продолжим список! Главное, что бы это могло привести к проблемам безопасности.
К примеру, с proxy_set_header я могу придумать кейс в котором это может стать проблемой (хоть пока и не встречал). А вот не сознательное переопределение error_page не выглядит чем-то серьезным.

Хотелось бы только узнать на сколько она применима в случае если у меня на серверах стоит какая-нибудь панель управления хостингом типа ИСП\Адженти\Весты\Плеска?

Честно говоря, ничего не могу сказать по этому поводу. Я не большой сторонник панелей управления, поэтому опыта работы с ними крайне мало. Быть может, кто-то с большим опытом подскажет как правильно сделать интеграцию, какие существуют подводные камни и вот это все. А может и сделает это самостоятельно ;-)
Точного roadmap пока нет, примерные планы выглядят так:
— улучшить работу с переменными, добавить новых директив которые могут их предоставлять. Например, сейчас нет поддержки server_name :(
— продолжить улучшать работу с регулярками, что мы можно было делать более хитрые проверки. Кстати, я его обернул в самостоятельное приложение (бывает полезно, когда нужно быстренько проверить регулярочку): Regex Ninja
— разобраться с разными стьюпидами и написать хорошую документацию

Ну и, конечно же, написать новых проверок:)
Например, для Open Redirect'ов в реврайтах:
    location /a {
        rewrite (.*)$ https://example.com$1 permanent;
    }

    location /b {
        rewrite ^/(.*)$ https://example.com$1 permanent;
    }

Экплуатация:
$ http -h http://localhost/a%0a.evil.com
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 185
Content-Type: text/html
Date: Sat, 29 Apr 2017 10:07:21 GMT
Location: https://example.com.evil.com
Server: nginx/1.13.0

$ http -h http://localhost/b.evil.com
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 185
Content-Type: text/html
Date: Sat, 29 Apr 2017 10:07:40 GMT
Location: https://example.comb.evil.com
Server: nginx/1.13.0

У меня нет ответа на вопрос, почему if используется чаще, чем map. Map, конечно же, тоже используется для валидации, но заметно реже:( Я это вижу как в Яндексе так и за его пределами.
Именно поэтому я и начал с валидации регулярок в if. В будущем планирую добавить проверки для map (там будут примерно те же проблемы) и возможно добавить какую-то рекомендательную проверку по переписыванию if на map. Тут есть над чем подумать:)
А в итоге Splunk какие-то задачи для ИБ выполняет? Или теперь это целиком на OpenSOC?
Должен попросить у вас прощения. Скучное решение будет работать не во всех кейсах (в частности если в base64-кодированной строке будет "/").

Лучшим решением проблемы с OCSP Stapling'ом и WoSign — обновить nginx 1.7.11 (можно и ниже, просто не имеет смысла, ибо если уж обновлять до mainline то до текущего), там судя по коду все должно завестить без патчей и костылей (если не вылазить за 255 байт в закодированном OCSP-запросе) :-)
Мне кажется, что вы просто этого не замечаете за счет некого везения:-) И поэтому у вас в тестах иногда все хорошо (в ваших), а иногда (как писали выше в комментах) плохо:-)

Вот сейчас для вашего домена у меня получается запрос к WoSign без доп. символов "/+=" (подлежащий кодированию при NGX_ESCAPE_URI_COMPONENT) алфавита base64, поэтому все и работает:
$ openssl ocsp -issuer chain.pem -cert kai.pem -text -url http://ocsp6.wosign.com/ca6/server1/free -header "HOST" "ocsp6.wosign.com" -reqout ocsp_req -respout ocsp_rep > /dev/null

$ cat ocsp_req | base64 -w 0
MHYwdDBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQUTgvvGqRAW6UXaYcwyjRoQ9BBrvICEEwwZIaWm8vBrlVaHYwRe4eiIzAhMB8GCSsGAQUFBzABAgQSBBCvSssLj9nA8Qe1nuXN8yry

$ http http://ocsp6.wosign.com/ca6/server1/free/MHYwdDBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQUTgvvGqRAW6UXaYcwyjRoQ9BBrvICEEwwZIaWm8vBrlVaHYwRe4eiIzAhMB8GCSsGAQUFBzABAgQSBBCnEPCW98JQIKmStIdgyEP4
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 1514
Content-Transfer-Encoding: Binary
Content-Type: application/ocsp-response
Date: Sat, 28 Mar 2015 10:35:35 GMT
Expires: Mar 30 10:35:35 2015 GMT
Server: nginx/1.0.15



+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+


Поэтому за счет периодического везения у вас сложилось впечатление что все работает, т.к. nginx кеширует валидный ocsp-ответ на 1 час, а не валидный на 5 минут.
Тоже решил завести OCSP Stapling для на своем тестовом сервере для WoSign, но ничего не помогало.
nginx в error.log'е ругался на не правильный тип ответа:
2015/03/27 21:07:18 [error] 21722#0: OCSP responder sent invalid "Content-Type" header: "text/html" while requesting certificate status, responder: ocsp6.wosign.com

Не долго думая, решил посмотреть на трафик к OCSP Responder'у:
$ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:00:00.000000 IP (tos 0x0, ttl 64, id 51790, offset 0, flags [DF], proto TCP (6), length 60)
    10.0.0.234.34479 > 104.192.110.199.80: Flags [S], cksum 0xe29f (incorrect -> 0x42a6), seq 3856552277, win 29200, options [mss 1460,sackOK,TS val 1468635931 ecr 0,nop,wscale 7], length 0
00:00:00.164134 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    104.192.110.199.80 > 10.0.0.234.34479: Flags [S.], cksum 0x756a (correct), seq 3408811202, ack 3856552278, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 7], length 0
00:00:00.000018 IP (tos 0x0, ttl 64, id 51791, offset 0, flags [DF], proto TCP (6), length 40)
    10.0.0.234.34479 > 104.192.110.199.80: Flags [.], cksum 0xe28b (incorrect -> 0xee57), seq 1, ack 1, win 229, length 0
00:00:00.000213 IP (tos 0x0, ttl 64, id 51792, offset 0, flags [DF], proto TCP (6), length 213)
    10.0.0.234.34479 > 104.192.110.199.80: Flags [P.], cksum 0xe338 (incorrect -> 0x1006), seq 1:174, ack 1, win 229, length 173: HTTP, length: 173
   GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d HTTP/1.0
   Host: ocsp6.wosign.com
   
00:00:00.163712 IP (tos 0x0, ttl 50, id 16259, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.80 > 10.0.0.234.34479: Flags [.], cksum 0xee14 (correct), seq 1, ack 174, win 123, length 0
00:00:00.000377 IP (tos 0x0, ttl 50, id 16260, offset 0, flags [DF], proto TCP (6), length 365)
    104.192.110.199.80 > 10.0.0.234.34479: Flags [P.], cksum 0xc7d3 (correct), seq 1:326, ack 174, win 123, length 325: HTTP, length: 325
   HTTP/1.1 502 Bad Gateway
   Server: nginx/1.0.15
   Date: Fri, 27 Mar 2015 18:25:22 GMT
   Content-Type: text/html
   Content-Length: 173
   Connection: close
   
   <html>
   <head><title>502 Bad Gateway</title></head>
   <body bgcolor="white">
   <center><h1>502 Bad Gateway</h1></center>
   <hr><center>nginx/1.0.15</center>
   </body>
   </html>
00:00:00.000012 IP (tos 0x0, ttl 64, id 51793, offset 0, flags [DF], proto TCP (6), length 40)
    10.0.0.234.34479 > 104.192.110.199.80: Flags [.], cksum 0xe28b (incorrect -> 0xec5d), seq 174, ack 326, win 237, length 0
00:00:00.000006 IP (tos 0x0, ttl 50, id 16261, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.80 > 10.0.0.234.34479: Flags [F.], cksum 0xecce (correct), seq 326, ack 174, win 123, length 0
00:00:00.000604 IP (tos 0x0, ttl 64, id 51794, offset 0, flags [DF], proto TCP (6), length 40)
    10.0.0.234.34479 > 104.192.110.199.80: Flags [F.], cksum 0xe28b (incorrect -> 0xec5b), seq 174, ack 327, win 237, length 0
00:00:00.163723 IP (tos 0x0, ttl 50, id 16262, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.80 > 10.0.0.234.34479: Flags [.], cksum 0xeccd (correct), seq 327, ack 175, win 123, length 0

Отлично:-( Смотрим в RFC 6960:
HTTP-based OCSP requests can use either the GET or the POST method to
submit their requests. To enable HTTP caching, small requests (that
after encoding are less than 255 bytes) MAY be submitted using GET.
If HTTP caching is not important or if the request is greater than
255 bytes, the request SHOULD be submitted using POST. Where privacy
is a requirement, OCSP transactions exchanged using HTTP MAY be
protected using either Transport Layer Security/Secure Socket Layer
(TLS/SSL) or some other lower-layer protocol.

An OCSP request using the GET method is constructed as follows:

GET {url}/{url-encoding of base-64 encoding of the DER encoding of
the OCSPRequest}

where {url} may be derived from the value of the authority
information access extension in the certificate being checked for
revocation, or other local configuration of the OCSP client.

An OCSP request using the POST method is constructed as follows: The
Content-Type header has the value «application/ocsp-request», while
the body of the message is the binary value of the DER encoding of
the OCSPRequest.

С виду запрос от nginx полностью соответствует RFC. Немного поиграем:
# Пробуем запрос полученный от nginx
$ http -v http://ocsp6.wosign.com/ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d
GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY%3d HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: ocsp6.wosign.com
User-Agent: HTTPie/0.9.2



HTTP/1.1 502 Bad Gateway
Connection: keep-alive
Content-Length: 173
Content-Type: text/html
Date: Sat, 28 Mar 2015 09:14:25 GMT
Server: nginx/1.0.15

<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.0.15</center>
</body>
</html>


# Пробуем запрос без урлкодирвоания
$ http -v http://ocsp6.wosign.com/ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY\=
GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY= HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: ocsp6.wosign.com
User-Agent: HTTPie/0.9.2



HTTP/1.0 200 OK
Connection: close
Content-Length: 1514
Content-Transfer-Encoding: Binary
Content-Type: application/ocsp-response
Date: Mar 28 09:14:29 2015 GMT
Expires: Mar 30 09:14:29 2015 GMT



+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+


# Пробуем отправить POST запрос вместо GET
$ http -v post http://ocsp6.wosign.com/ca6/server1/free/ < ocsp
POST /ca6/server1/free/ HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 83
Content-Type: application/json
Host: ocsp6.wosign.com
User-Agent: HTTPie/0.9.2



+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 1514
Content-Transfer-Encoding: Binary
Content-Type: application/ocsp-response
Date: Sat, 28 Mar 2015 09:14:37 GMT
Expires: Mar 30 09:14:37 2015 GMT
Server: nginx/1.0.15



+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+


Хм, любопытно. Похоже на расхождение логики nginx и OCSP Responder'а WoSign — первый считает OCSPRequest компонентом URI, поэтому закодировал не только основные разделители но и дополнительные (= в нашем случае), вторые же на это видимо не расчитывают.
Я нашел два варианта решения этой проблемы:
1. Скучный — исправить урл. Просто заменить ssl_stapling_responder на свой и с него уже запроксировать на ocsp6.wosign.com.
Добавляем сервер:
server {
        listen 9000;
        server_name ocsp.localhost;

        location / {
            return 503;
        }

        location ~ ^/request/(.*)$ {
            allow 127.0.0.1;
            deny  all;
            proxy_pass http://ocsp6.wosign.com/ca6/server1/free/$1;
        }
 }

В настройках заменяем адрес OCSP Responder'а:
ssl_stapling_responder 'http://127.0.0.1:9000/request/';

Делаем тестовый запрос и смотрим на трафик:
$ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:51:34.631598 IP (tos 0x0, ttl 64, id 27478, offset 0, flags [DF], proto TCP (6), length 60)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [S], cksum 0xe29f (incorrect -> 0x44ab), seq 2011672765, win 29200, options [mss 1460,sackOK,TS val 4709355 ecr 0,nop,wscale 7], length 0
09:51:34.801707 IP (tos 0x0, ttl 51, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [S.], cksum 0x40b8 (correct), seq 187184398, ack 2011672766, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 7], length 0
09:51:34.801728 IP (tos 0x0, ttl 64, id 27479, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb9a5), seq 1, ack 1, win 229, length 0
09:51:34.802596 IP (tos 0x0, ttl 64, id 27480, offset 0, flags [DF], proto TCP (6), length 230)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [P.], cksum 0xe349 (incorrect -> 0xe51a), seq 1:191, ack 1, win 229, length 190: HTTP, length: 190
  GET /ca6/server1/free/MFEwTzBNMEswSTAJBgUrDgMCGgUABBSgZmHxbLzCPpi8cZFIMLhaqo0KawQU0qcWIHyv2ZWe60MKGfLguXQOqMcCEEbxnVuQIuYg4cpCNpVclHY= HTTP/1.0
  Host: ocsp6.wosign.com
  Connection: close
  
09:51:34.972743 IP (tos 0x0, ttl 51, id 22415, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xb951 (correct), seq 1, ack 191, win 123, length 0
09:51:34.974872 IP (tos 0x0, ttl 51, id 22416, offset 0, flags [DF], proto TCP (6), length 1500)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xbf3d (correct), seq 1:1461, ack 191, win 123, length 1460: HTTP, length: 1460
  HTTP/1.1 200 OK
  Server: nginx/1.0.15
  Date: Sat, 28 Mar 2015 09:51:34 GMT
  Content-Type: application/ocsp-response
  Connection: close
  Content-Transfer-Encoding: Binary
  Content-Length: 1514
  Expires: Mar 30 09:51:34 2015 GMT
  
09:51:34.974887 IP (tos 0x0, ttl 64, id 27481, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb31d), seq 191, ack 1461, win 251, length 0
09:51:34.975080 IP (tos 0x0, ttl 51, id 22417, offset 0, flags [DF], proto TCP (6), length 324)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [P.], cksum 0xb6de (correct), seq 1461:1745, ack 191, win 123, length 284: HTTP
09:51:34.975089 IP (tos 0x0, ttl 64, id 27482, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [.], cksum 0xe28b (incorrect -> 0xb1ea), seq 191, ack 1745, win 274, length 0
09:51:34.975096 IP (tos 0x0, ttl 51, id 22418, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [F.], cksum 0xb280 (correct), seq 1745, ack 191, win 123, length 0
09:51:34.977809 IP (tos 0x0, ttl 64, id 27483, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.43435 > 104.192.110.199.http: Flags [F.], cksum 0xe28b (incorrect -> 0xb1e8), seq 191, ack 1746, win 274, length 0
09:51:35.147834 IP (tos 0x0, ttl 51, id 22419, offset 0, flags [DF], proto TCP (6), length 40)
    104.192.110.199.http > ip-10-0-0-234.eu-west-1.compute.internal.43435: Flags [.], cksum 0xb27f (correct), seq 1746, ack 192, win 123, length 0

Выглядит работоспособным. Тест так же говорит что OCSP Stapling работает

2. Интересный:) Будучи программистом — мне больше нравится исправлять код, нежели раставлять костыли в конфигах. Поэтому я сделал простой патч gist.github.com/buglloc/6f14a16ab702478d23e3 который добавляет булевую опцию ssl_stapling_force_post по которой nginx начинает делать POST запрос вместо GET.
# Скачиваем nginx. Я пользую последнюю стабильную версию
$ wget http://nginx.org/download/nginx-1.6.2.tar.gz

# Распаковываем
$ tar -xzf nginx-1.6.2.tar.gz

# Скачиваем патч
$ wget https://gist.githubusercontent.com/buglloc/6f14a16ab702478d23e3/raw/4779a940a0040857ecbc7eea410f7f34fc1f5627/post-ocsp-nginx.patch

# Применяем патчик
$ patch -p 1 -d nginx-1.6.2 < post-ocsp-nginx.patch
patching file src/event/ngx_event_openssl.h
patching file src/event/ngx_event_openssl_stapling.c
patching file src/http/modules/ngx_http_ssl_module.c
patching file src/http/modules/ngx_http_ssl_module.h


# Смотрим как собран текущий nginx
$ nginx -V
nginx version: nginx/1.6.2
built by gcc 4.9.2 20150304 (prerelease) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-imap --with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module

# Собираем и ставим
$ cd nginx-1.6.2

$ ./configure --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-imap --with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module

$ make

$ sudo make install

После этого идем в настройки и добавляем:
ssl_stapling_force_post on;

Перезапускаем nginx и опять смотрим на трафик:
$ tcpdump -vv host 111.206.66.61 or host 104.192.110.199
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:04:04.626853 IP (tos 0x0, ttl 64, id 23709, offset 0, flags [DF], proto TCP (6), length 60)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [S], cksum 0xbd23 (incorrect -> 0x32b9), seq 3842006142, win 29200, options [mss 1460,sackOK,TS val 4784355 ecr 0,nop,wscale 7], length 0
10:04:05.016292 IP (tos 0x0, ttl 46, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [S.], cksum 0xea1a (correct), seq 1986999145, ack 3842006143, win 14600, options [mss 1452,nop,nop,sackOK,nop,wscale 9], length 0
10:04:05.016324 IP (tos 0x0, ttl 64, id 23710, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x630a), seq 1, ack 1, win 229, length 0
10:04:05.017243 IP (tos 0x0, ttl 64, id 23711, offset 0, flags [DF], proto TCP (6), length 243)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [P.], cksum 0xbdda (incorrect -> 0x121b), seq 1:204, ack 1, win 229, length 203: HTTP, length: 203
  POST /ca6/server1/free/ HTTP/1.0
  Host: ocsp6.wosign.com
  Content-Type: application/ocsp-request
  Content-Length: 83
  
10:04:05.409413 IP (tos 0x0, ttl 46, id 13576, offset 0, flags [DF], proto TCP (6), length 40)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x6305 (correct), seq 1, ack 204, win 31, length 0
10:04:05.411395 IP (tos 0x0, ttl 46, id 13577, offset 0, flags [DF], proto TCP (6), length 133)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [P.], cksum 0xc2f9 (correct), seq 1:94, ack 204, win 31, length 93: HTTP, length: 93
  HTTP/1.0 200 OK
  Content-Type: application/ocsp-response
  Content-Transfer-Encoding: Binary
10:04:05.411412 IP (tos 0x0, ttl 64, id 23712, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x61e2), seq 204, ack 94, win 229, length 0
10:04:05.411551 IP (tos 0x0, ttl 46, id 13578, offset 0, flags [DF], proto TCP (6), length 1500)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x2eea (correct), seq 94:1554, ack 204, win 31, length 1460: HTTP
10:04:05.411561 IP (tos 0x0, ttl 64, id 23713, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [.], cksum 0xbd0f (incorrect -> 0x5c18), seq 204, ack 1554, win 251, length 0
10:04:05.411587 IP (tos 0x0, ttl 46, id 13579, offset 0, flags [DF], proto TCP (6), length 204)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [FP.], cksum 0x9869 (correct), seq 1554:1718, ack 204, win 31, length 164: HTTP
10:04:05.414802 IP (tos 0x0, ttl 64, id 23714, offset 0, flags [DF], proto TCP (6), length 40)
    ip-10-0-0-234.eu-west-1.compute.internal.41798 > 111.206.66.61.http: Flags [F.], cksum 0xbd0f (incorrect -> 0x5b5b), seq 204, ack 1719, win 274, length 0
10:04:05.802684 IP (tos 0x0, ttl 46, id 13580, offset 0, flags [DF], proto TCP (6), length 40)
    111.206.66.61.http > ip-10-0-0-234.eu-west-1.compute.internal.41798: Flags [.], cksum 0x5c4e (correct), seq 1719, ack 205, win 31, length 0

Выглядит корректным, проверяем:
$ echo QUIT | openssl s_client -connect www.buglloc.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:'
OCSP response: 
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = CN, O = WoSign CA Limited, CN = WoSign Free SSL OCSP Responder(G2)
    Produced At: Mar 28 10:04:05 2015 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: A06661F16CBCC23E98BC71914830B85AAA8D0A6B
      Issuer Key Hash: D2A716207CAFD9959EEB430A19F2E0B9740EA8C7
      Serial Number: 46F19D5B9022E620E1CA4236955C9476
    Cert Status: good
    This Update: Mar 28 10:04:05 2015 GMT
    Next Update: Mar 30 10:04:05 2015 GMT


Надеюсь кому-то поможет. Я старался обойтись минимальными правками и вроде достаточно внимательно поправил код. Конечно, скорее более правильно было бы сделать как современные браузеры (которые славятся своей «приспосабливаемостью»;) — они зачастую сначала шлют GET и в случае провала пытаются сделать POST запрос. Но патч получился бы менее легким и читабельным, поэтому я не стал этого делать.
Да, пожалуй вы правы :-(
Подправил, спасибо.
Так же одна из хороших статей была у Тараса Иващенко: https://www.oxdef.info/posts/2013/02/03/webapp-scan-ru/
Я говорю про дефолтные конфиги непосредственно PHP, что при стандартном stack size в 8-10M и дефолтном pcre.recursion_limit в 100000 в сегфолт от подобных регулярок в КОДЕ php уходит одинаково хорошо как php-fpm так и php в виде модуля к apache. Неправильно приготовить php-fpm можно скорее не конфигами самого php-fpm (как вы правильно подметили о количестве параметров) а настройками php, к примеру не отключить user_ini.filename или cgi.fix_pathinfo или еще не одним параметр специфичный и важный непосредственно в контексте php-fpm.
В точку! Не однократно вижу целые группы разработчиков, которые не в состоянии ответить нужен ли им какой либо php-модуль и приходтся открывать список функций и шерстить сорцы, а между тем их зоопарк это потенциальные баги, уязвимости и т.д. и т.п.
Для php-fpm проблем не меньше, он так же легко уходит в сегфолт, например, при дефолтных конфигах и рекурсивных регулярках (#([a-z])+# к примеру). Я бы сказал 50/50, уходя от монстроидального apache с его порой причудливыми конфигами (в более чем распространенных дистрах) к php-fpm ведет к проблеме его правильного приготовления, т.к. увы число системных администраторов способных на это пока остается в меньшенстве.
Хм, перепроверил — а вы правы, черт побери! Видимо я последние тесты проводил или со странной сборкой IE или еще что, в любой случае склоняю шляпу, век живи — век учисью.

В общем же случае, если вы допускаете загрузку скриптов на ваш сервер — у вас уже проблемы, и рано или поздно кто-нибудь найдет способ это поэксплуатировать.

А с этим никто и не спорит, вопрос в другом — как максимально обезопасить свой аплоад разработчикам которые не знают на какой конкретной конфигурации будет работать их код (разработчики CMS/CMF, модулей и т.д.). Вот и приходится искать все возможные «странности» и подстраиваться под них, как в моем примере с nginx + файл только с расширением. Люди ведь извращенцы, некоторые работают и на связке IIS+PHP. С позиции разработки проекта все прозрачно — используем CDN, другой домен для статики и т.д.
Да, вы правы фактически имя у файла ".jpg" просто как иначе «обозвать» подобные файлы я увы не придумал, посему счел уместным употребить именно такое обозначение. Возможно, говорить «файлы без названия» было бы более корректным.

application/octet-stream безобидное? С чего бы вдруг? А как же mime-сниффинг в IE, включенный у абсолютного большинства его пользователей? Как раз по этой причине у меня обычно «default_type» и выставлен в force-download.
Достаточно часто встречаются ситуации когда люди пользуются какой либо функцией в фреймворке для описанных вами и совсем уж очевидных проверок, а сохраняют файл собственными силами и тогда оказывается, что при проверке делается trim (к примеру) а при сохранении вы его не делаете, что позволяет загрузить изображение с именем «file.jpg » и провернуть XSS для пользователей IE.
И совсем забыли об одной еще достаточно хитрой особенности nginx — нельзя допускать загрузки картинок без имени, только с расширением (например ".jpg"), т.к.:

anri@AKrasichkov:~$ curl -I http://localhost/test.gif | grep Content-Type
Content-Type: image/gif


anri@AKrasichkov:~$ curl -I http://localhost/.gif | grep Content-Type
Content-Type: application/octet-stream


Имхо, считаю статью из серии К.О.
Куда более интересней вопрос — правильная загрузка/отдача любых произвольных файлов, т.к. помимо изображений все чаще есть необходимость в загрузке тех же аудио/видео/офисный и иных файлов.
В отдельно взятых случаях я бы еще подстраховал разработчиков и выставил дефолтный content-type как force-download:
[root@localhost conf.d]# cat /etc/lighttpd/conf.d/mime.conf | grep '""'
#  ""              =>      "application/octet-stream",
  ""              =>      "application/force-download",


Увы не могу ничего сказать на тему стабильности работы подобной схемы на Lighttpd, проверял работоспособность только на nginx. Наши реалии таковы, что зачастую разработчики не умеют и не хотят правильно работать с файлами, обычно от незнания специфики веб-серверов на которых работают/могут работать их разработки, отсюда и получаем что допускаются к загрузке расширения с пробелами в конце (очень частый случай, когда при проверке в какой нить функции IsImage делается trim/rtrim а при сохранении нет) или же загрузка файлов только с расширением (например .jpg — смертельный файл для проекта в связке nginx + клиент на IE), а отдача всей статики кроме разрешенной с force-download их от этого убережет.
Чёрт, писать комменты с утра — зло:)
Естественно должно быть так:
<FilesMatch "\.php$">
AddHandler php5-script .php
AddType text/html .php
</FilesMatch>


и не забыть вычистить php из типов (зависит от ОСи):
root@AKrasichkov:/etc# cat mime.types | grep php
application/x-httpd-php				phtml pht php
application/x-httpd-php-source			phps
application/x-httpd-php3			php3
application/x-httpd-php3-preprocessed		php3p
application/x-httpd-php4			php4
application/x-httpd-php5			php5

Это во-первых не даст выполнять pht файлы как php, о которых разработчики обычно не догадываются. Во-вторых это не позволит дергать php на файлах вида file.php.any

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity