Werkzeug: Werkzeug Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ многострочныС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ

Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ Π½Π° 10 ΠΌΠ°Ρ€. 2017  Β·  8ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ  Β·  Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: pallets/werkzeug

Богласно RFC 2616 :

ЗначСния поля Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° HTTP / 1.1 ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π° нСсколько строк, Ссли строка продолТСния начинаСтся с ΠΏΡ€ΠΎΠ±Π΅Π»Π° ΠΈΠ»ΠΈ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ табуляции. ВсС Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ сворачиваниС, ΠΈΠΌΠ΅ΡŽΡ‚ Ρ‚Ρƒ ΠΆΠ΅ сСмантику, Ρ‡Ρ‚ΠΎ ΠΈ SP. ΠŸΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»ΡŒ ΠœΠžΠ–Π•Π’ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ любой Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ±Π΅Π» ΠΎΠ΄Π½ΠΈΠΌ SP ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ значСния поля ΠΈΠ»ΠΈ пСрСсылкой сообщСния Π² нисходящСм Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ.

Однако werkzeug Π½Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ значСния Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² с символами Π½ΠΎΠ²ΠΎΠΉ строки, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ ΡΠΎΠ±Π»ΡŽΠ΄Π°ΡŽΡ‚ это соглашСниС.

>>> import werkzeug
>>> werkzeug.Headers().add('foo', 'bar\n baz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../venv/local/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1136, in add
    self._validate_value(_value)
  File ".../venv/local/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1143, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

Π’Π°ΠΊΠΆΠ΅ это ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ примСняСтся Π½Π΅ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ.

>>> werkzeug.Headers([('foo', 'bar\n baz')])
Headers([('foo', 'bar\n baz')])

Π― столкнулся с этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ тСстовыС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹, ΠΊΠ°ΡΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ пСрСсылки клиСнтских сСртификатов nginx Ρ‡Π΅Ρ€Π΅Π· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования для ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ этого.

Π‘Π°ΠΌΡ‹ΠΉ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

@davidism Как я ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π» Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, Π½Π° самом Π΄Π΅Π»Π΅ здСсь Π΅ΡΡ‚ΡŒ Π΄Π²Π΅ ошибки, Π½ΠΈ ΠΎΠ΄Π½Π° ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π±Ρ‹Π»Π° исправлСна ​​в Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ основной Π²Π΅Ρ‚ΠΊΠ΅.


ΠŸΠ΅Ρ€Π²Π°Ρ ошибка связана с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ сСрвСр Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ werkzeug ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ строковыС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ. Π•Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ воспроизвСсти с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ сСрвСрного ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° X-Example :

from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response

def app(environ, start_response):
    request = Request(environ)
    print(repr(request.headers.get('X-Example')))
    response = Response(status=204)
    return response(environ, start_response)

run_simple('localhost', 8080, app)

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΌΡƒ запрос с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ, ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ нСсколько строк:

GET / HTTP/1.1
Host: localhost:8080
Connection: close
X-Example: foo
 bar

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ сСрвСра:
Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° объСдинСно Π² ΠΎΠ΄Π½Ρƒ строку

'foo bar'

ЀактичСский Π²Ρ‹Π²ΠΎΠ΄ сСрвСра (Python 2):

----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 57361)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 320, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 355, in handle_one_request
    return self.run_wsgi()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 238, in run_wsgi
    self.environ = environ = self.make_environ()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 217, in make_environ
    for key, value in self.get_header_items():
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 441, in get_header_items
    key, value = header[0:-2].split(":", 1)
ValueError: need more than 1 value to unpack
----------------------------------------

ЀактичСский Π²Ρ‹Π²ΠΎΠ΄ сСрвСра (Python 3):
Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° содСрТит символы Π½ΠΎΠ²ΠΎΠΉ строки, Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Π½Ρ‹Π΅ спСцификациСй WSGI.

'foo\r\n bar'

Вторая ошибка связана с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Headers ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ значСния Π½ΠΎΠ²ΠΎΠΉ строки.

>>> from werkzeug import Headers
>>> h1 = Headers([('X-Example', 'foo\r\n bar')])
>>> h2 = Headers()
>>> h2.add('X-Example', 'foo\r\n bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1166, in add
    self._validate_value(_value)
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1173, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:
ОбС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π±ΡƒΠ΄ΡŒ Ρ‚ΠΎ ValueError ΠΈΠ»ΠΈ успСх.

ЀактичСский Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:
ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ Headers Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ строки, Π° Headers.add() ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ValueError .

ВсС 8 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ HTTP Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки. Π’ Ρ€Π°Π·Π΄Π΅Π»Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹ Ρ†ΠΈΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅, говорится ΠΎ сворачивании, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ строки ΠΈΠ· Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΠΎΠ³ΠΎ значСния. Π­Ρ‚ΠΎΡ‚:

"""foo
     bar"""

Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

"foo bar"

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Werkzeug Π½Π΅ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ HTTP Π½Π° этом ΡƒΡ€ΠΎΠ²Π½Π΅, это Ρ€Π°Π±ΠΎΡ‚Π° сСрвСра WSGI. ЕдинствСнная ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠ½ отклоняСт символы Π½ΠΎΠ²ΠΎΠΉ строки ΠΏΡ€ΠΈ синтаксичСском Π°Π½Π°Π»ΠΈΠ·Π΅, - это выявлСниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ.

Π­Ρ‚ΠΎΡ‚ Π±ΠΈΠ»Π΅Ρ‚ Π±Ρ‹Π» ΠΌΠΎΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ Flask Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π° клиСнтскими сСртификатами прокси-сСрвСра nginx. ΠŸΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΉ настройкС я Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ» Π½ΠΎΠ²Ρ‹Π΅ строки Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ. Но ΠΊΠΎΠ³Π΄Π° я попытался воспроизвСсти это Π² ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠΌ тСстС, я ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π²Ρ‹ΡˆΠ΅ ValueError ΠΏΡ€ΠΈ создании Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² запроса.

Π― ΠΏΡ€ΠΎΠ²Π΅Π» Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ большС исслСдований ΠΏΠΎ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ΅ ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ» ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

  • Π’ спСцификации HTTP ( RFC 2616 ) ΡƒΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ символы Π½ΠΎΠ²ΠΎΠΉ строки Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… ΠœΠžΠ“Π£Π’ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ ΠΎΠ΄Π½ΠΈΠΌ ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠΌ, Π° Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ (см. Π¦ΠΈΡ‚Π°Ρ‚Ρƒ Π²Ρ‹ΡˆΠ΅).

  • БпСцификация CGI ( RFC 3875 ), ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ WSGI, Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π·Π°ΠΌΠ΅Π½Ρ‹ Π½ΠΎΠ²Ρ‹Ρ… строк Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… запросов:

    Π’ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΏΠΎΠ»Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ нСсколько строк, Π”ΠžΠ›Π–ΠΠž Π±Ρ‹Ρ‚ΡŒ объСдинСно Π² ΠΎΠ΄Π½Ρƒ строку.

  • БпСцификация WSGI ( PEP 333 ) Ρ‚Π°ΠΊΠΆΠ΅ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ символы Π½ΠΎΠ²ΠΎΠΉ строки Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²:

    ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ header_value Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… символов, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ символы Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ΠΊΠ°Ρ€Π΅Ρ‚ΠΊΠΈ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки, ΠΊΠ°ΠΊ встроСнныС, Ρ‚Π°ΠΊ ΠΈ Π² ΠΊΠΎΠ½Ρ†Π΅.

Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ здСсь Π΅ΡΡ‚ΡŒ Π΄Π²Π΅ ошибки:

  • Π‘Π΅Ρ€Π²Π΅Ρ€ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ werkzeug Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ свСрнутыС строки Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… запросов.

  • ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Headers нСсовмСстим с ΠΏΡ€ΠΈΠ΅ΠΌΠΎΠΌ Π½ΠΎΠ²ΠΎΠΉ строки Π² значСниях Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ². НовыС строки ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ Π² конструкторС, Π½ΠΎ Π½Π΅ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ add() . ВСроятно, Π»ΡƒΡ‡ΡˆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Headers оставался Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‰ΠΈΠΌ ΠΈ выполнял ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ ΠΏΡ€ΠΈ фактичСском построСнии ΠΎΡ‚Π²Π΅Ρ‚Π° WSGI Π² BaseResponse . Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠΉ строки Π² конструкторС Π½Π΅ Π½Π°Ρ€ΡƒΡˆΠΈΡ‚ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ с Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ сСрвСрами WSGI (Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ собствСнный сСрвСр Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ werkzeug).

Π‘ΠΏΡ€Π°Π²Π΅Π΄Π»ΠΈΠ²ΠΎ. Π’Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€ 1070, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ³Ρ€Π°Π΅Ρ‚ Π² это.

Π‘ΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΡƒΠ²Π΅Ρ€Π΅Π½, Ρ‡Ρ‚ΠΎ это Π±Ρ‹Π»ΠΎ исправлСно с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ исправлСния для # 1070. Если Π½Π΅Ρ‚, сообщитС ΠΌΠ½Π΅ воспроизводимый ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

@davidism Как я ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π» Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, Π½Π° самом Π΄Π΅Π»Π΅ здСсь Π΅ΡΡ‚ΡŒ Π΄Π²Π΅ ошибки, Π½ΠΈ ΠΎΠ΄Π½Π° ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π±Ρ‹Π»Π° исправлСна ​​в Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ основной Π²Π΅Ρ‚ΠΊΠ΅.


ΠŸΠ΅Ρ€Π²Π°Ρ ошибка связана с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ сСрвСр Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ werkzeug ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ строковыС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ. Π•Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ воспроизвСсти с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ сСрвСрного ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° X-Example :

from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response

def app(environ, start_response):
    request = Request(environ)
    print(repr(request.headers.get('X-Example')))
    response = Response(status=204)
    return response(environ, start_response)

run_simple('localhost', 8080, app)

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΌΡƒ запрос с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ, ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ нСсколько строк:

GET / HTTP/1.1
Host: localhost:8080
Connection: close
X-Example: foo
 bar

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ сСрвСра:
Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° объСдинСно Π² ΠΎΠ΄Π½Ρƒ строку

'foo bar'

ЀактичСский Π²Ρ‹Π²ΠΎΠ΄ сСрвСра (Python 2):

----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 57361)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 320, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 355, in handle_one_request
    return self.run_wsgi()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 238, in run_wsgi
    self.environ = environ = self.make_environ()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 217, in make_environ
    for key, value in self.get_header_items():
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 441, in get_header_items
    key, value = header[0:-2].split(":", 1)
ValueError: need more than 1 value to unpack
----------------------------------------

ЀактичСский Π²Ρ‹Π²ΠΎΠ΄ сСрвСра (Python 3):
Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° содСрТит символы Π½ΠΎΠ²ΠΎΠΉ строки, Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Π½Ρ‹Π΅ спСцификациСй WSGI.

'foo\r\n bar'

Вторая ошибка связана с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Headers ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ значСния Π½ΠΎΠ²ΠΎΠΉ строки.

>>> from werkzeug import Headers
>>> h1 = Headers([('X-Example', 'foo\r\n bar')])
>>> h2 = Headers()
>>> h2.add('X-Example', 'foo\r\n bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1166, in add
    self._validate_value(_value)
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1173, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:
ОбС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π±ΡƒΠ΄ΡŒ Ρ‚ΠΎ ValueError ΠΈΠ»ΠΈ успСх.

ЀактичСский Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:
ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ Headers Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ строки, Π° Headers.add() ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ValueError .

НСдавно я Π²ΠΈΠ΄Π΅Π» ValueError Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Π½Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² (Python 2.7 с Flask), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ находится Π·Π° прокси-сСрвСром nginx. Π’ ΠΈΡ‚ΠΎΠ³Π΅ я вСрнулся ΠΊ 0.14.1 (ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ² Π²Π΅Ρ€ΡΠΈΡŽ, ΡΠ²ΡΠ·Π°Π½Π½ΡƒΡŽ с Flask ), ΠΈ моя ошибка исчСзла. Π”ΡƒΠΌΠ°Π», Ρ‡Ρ‚ΠΎ добавлю, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ каТСтся, Ρ‡Ρ‚ΠΎ Π²Π΅Ρ‚Π²ΡŒ 0.15.x прСдставила эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ (ΠΈΠ»ΠΈ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ создала Π½ΠΎΠ²ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π»Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ запросов).

------ΠžΠ‘ΠΠžΠ’Π˜Π’Π¬-------:

Π― отслСдил, ΠΊΠ°ΠΊΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ, ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… Π±Ρ‹Π» многострочным сСртификатом Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ pem, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ:

SSL_CLIENT_CERT: -----BEGIN CERTIFICATE-----
    MIIFHzCCAwegAwIBAgICEDgwDQYJKoZIhvcNAQELBQAwajELMAkGA1UEBhMCdXMx
    GDAWBgNVBAoMD3Uucy4gZ292ZXJubWVudDEPMA0GA1UECwwGcGVvcGxlMQwwCgYD
    VQQLDANkYWUxEDAOBgNVBAsMB2NoaW1lcmExEDAOBgNVBAMMB0ludGVyQ0EwHhcN
    MTcwODMxMTUwMzEwWhcNMjcwODI5MTUwMzEwWjBwMQswCQYDVQQGEwJVUzEYMBYG
    A1UECgwPVS5TLiBHb3Zlcm5tZW50MRAwDgYDVQQLDAdjaGltZXJhMQwwCgYDVQQL
    ....  
    -----END CERTIFICATE-----

Наш сСрвСр nginx Π±Ρ‹Π» настроСн Ρ‚Π°ΠΊ:

proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;

ВСроятно, Π½Π°ΠΌ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ $ssl_client_escaped_cert вмСсто $ssl_client_cert (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это Π² любом случаС устарСло). НС ΡƒΠ²Π΅Ρ€Π΅Π½, Ρ‡Ρ‚ΠΎ это ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π΅ΡˆΠΈΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ с синтаксичСским Π°Π½Π°Π»ΠΈΠ·ΠΎΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°.

НадСюсь, это ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ всСм, ΠΊΡ‚ΠΎ сталкиваСтся с этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ. ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ 0.15.1 Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ многострочный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠ°ΠΊ сСртификат PEM, Π² настоящСС врСмя с Python 2.7.

Π­Ρ‚ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° вСрсии 2.7, снова вызванная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° сСрвСра Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. Π― добавляю Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сворачивания Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² Π² ΠΊΠΎΠ΄ совмСстимости 2.7 для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² запросов.

ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΎ, Ρ‡Ρ‚ΠΎ ошибка сСрвСра Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ исправлСна ​​как Π² Python 2, Ρ‚Π°ΠΊ ΠΈ Π² 3. Вторая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Headers всС Π΅Ρ‰Π΅ присутствуСт. ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ β„–1608.

Π‘Ρ‹Π»Π° Π»ΠΈ эта страница ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ?
0 / 5 - 0 Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ΠΈ

Π‘ΠΌΠ΅ΠΆΠ½Ρ‹Π΅ вопросы

caiz picture caiz  Β·  3ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

lepture picture lepture  Β·  6ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

d42 picture d42  Β·  6ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

miki725 picture miki725  Β·  10ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

mrx23dot picture mrx23dot  Β·  6ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ