Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aiohttp sends Sec-WebSocket-Key with in wrong with b'' envelope #853

Closed
wohltat opened this issue May 7, 2024 · 2 comments
Closed

aiohttp sends Sec-WebSocket-Key with in wrong with b'' envelope #853

wohltat opened this issue May 7, 2024 · 2 comments

Comments

@wohltat
Copy link

wohltat commented May 7, 2024

@Carglglz
During the handshake the Sec-WebSocket-Key is send undecoded which results in it being sent with an additional b'' (like b'tb4IfqY2SEcIEy0pv0opLQ==').

If the line:

headers["Sec-WebSocket-Key"] = key

is changed to the following it doesn't cause an error anymore:

headers["Sec-WebSocket-Key"] = key.decode()

I used a python-websocket Server for testing which seems to make more sense than the other options as a servers, since it claim to be more strickly following the RFC6455 specification and offers informative error logging.

Here is the server error log of the handshake:

= connection is CONNECTING
< GET / HTTP/1.1
< Origin: https://192.168.178.123:4443
< Connection: Upgrade
< Sec-WebSocket-Key: b'tb4IfqY2SEcIEy0pv0opLQ=='
< Host: 192.168.178.123:4443
< Upgrade: websocket
< Sec-WebSocket-Version: 13
s_w_key="b'tb4IfqY2SEcIEy0pv0opLQ=='"
! invalid handshake
Traceback (most recent call last):
  File "/home/username/tls-test/venv/lib/python3.11/site-packages/websockets/legacy/handshake.py", line 86, in check_request
    raw_key = base64.b64decode(s_w_key.encode(), validate=True)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/base64.py", line 88, in b64decode
    return binascii.a2b_base64(s, strict_mode=validate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
binascii.Error: Only base64 data is allowed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/username/tls-test/venv/lib/python3.11/site-packages/websockets/legacy/server.py", line 167, in handler
    await self.handshake(
  File "/home/username/tls-test/venv/lib/python3.11/site-packages/websockets/legacy/server.py", line 609, in handshake
    key = check_request(request_headers)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/username/tls-test/venv/lib/python3.11/site-packages/websockets/legacy/handshake.py", line 88, in check_request
    raise InvalidHeaderValue("Sec-WebSocket-Key", s_w_key) from exc
websockets.exceptions.InvalidHeaderValue: invalid Sec-WebSocket-Key header: b'tb4IfqY2SEcIEy0pv0opLQ=='
> HTTP/1.1 400 Bad Request
> Date: Tue, 07 May 2024 00:14:16 GMT
> Server: Python/3.11 websockets/12.0
> Content-Length: 102
> Content-Type: text/plain
> Connection: close
> [body] (102 bytes)
connection rejected (400 Bad Request)
x closing TCP connection
! timed out waiting for TCP close
x aborting TCP connection
= connection is CLOSED
connection closed

After the change the connection works as expected. Strangely two other servers i've tested connected despite of this bug. After the code change they also still connect as to be expected.

Here is the server code:

#!/usr/bin/env python

import asyncio
import pathlib
import ssl
import websockets
import logging

logging.basicConfig(
    format="%(message)s",
    level=logging.DEBUG,
)

async def hello(websocket):
    while True:
        msg = await websocket.recv()
        print(f"{msg}")
        # await websocket.send(msg)

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_cert = "cert.pem"
ssl_key = "key.pem"
ssl_context.load_cert_chain(ssl_cert, ssl_key)

async def main():
    async with websockets.serve(hello, "0.0.0.0", 4443, ssl=ssl_context):
        await asyncio.Future()  # run forever

if __name__ == "__main__":
    asyncio.run(main())
@Carglglz
Copy link
Contributor

Carglglz commented May 7, 2024

@wohltat yes this is known see #846

@dpgeorge
Copy link
Member

Fixed by 2b0d761

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants