0

We installed websockets for Python on macOS using this terminal command:

(.venv) a@as-MacBook-Pro dic % python3 -m pip install websockets

server.py:

#!/usr/bin/env python3

"""Secure WebSocket echo server with TLS."""

import asyncio
import ssl
from websockets.asyncio.server import serve


async def echo(websocket):
    async for message in websocket:
        await websocket.send(message)


async def main():
    # Create and configure SSL context
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    ssl_context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

    print("Starting secure WebSocket server on wss://localhost:8765")
    async with serve(echo, "localhost", 8765, ssl=ssl_context):
        await asyncio.Future()  # Run forever


if __name__ == "__main__":
    asyncio.run(main())

localhost_cert.cnf:

[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
CN = localhost

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost

We generated key.pem using this terminal command:

(.venv) a@as-MacBook-Pro dic % openssl genrsa -out key.pem 2048

We created/overridden cert.pem using this terminal command:

(.venv) a@as-MacBook-Pro dic % openssl req -x509 -new -nodes \                 
  -key key.pem \
  -sha256 \
  -days 365 \
  -out cert.pem \
  -config localhost_cert.cnf \
  -extensions req_ext

We have already gone to Keychain Access > File > Import Items... > /Users/a/Documents/dic/cert.pem > Open > entered our password and clicked Modify Keychain > double-clicked on localhost > clicked on Trust > changed When using this certificate: value from Use System Defaults to Always Trust > closed the window > entered our password > clicked Update Settings

We tested the following code with multiple domains:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);

http://127.0.0.1:5500/index.html browser console:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
msg => ws.send(msg)
VM1009:2 Connected securely!

However, we are not able to do the same on HTTPS websites.

https://github.com/ browser console:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
VM185:1 Connecting to 'wss://localhost:8765/' violates the following Content Security Policy directive: "connect-src 'self' uploads.github.com ...". The action has been blocked.
(anonymous) @ VM185:1
msg => ws.send(msg)

https://github.com/:

Declarative net rule:

{
        "id": 23,
        "priority": 1,
        "action": {
            "type": "modifyHeaders",
            "responseHeaders": [
                {
                    "header": "Content-Security-Policy",
                    "operation": "remove"
                },
                {
                    "header": "X-Frame-Options",
                    "operation": "remove"
                }
            ]
        },
        "condition": {
            "resourceTypes": [
                "main_frame",
                "sub_frame",
                "stylesheet",
                "script",
                "image",
                "font",
                "object",
                "xmlhttprequest",
                "ping",
                "csp_report",
                "media",
                "websocket",
                "webtransport",
                "webbundle",
                "other"
            ]
        }
    }

browser console after using the declarative net rule on Brave browser:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
msg => ws.send(msg)
VM856:1 WebSocket connection to 'wss://localhost:8765/' failed: 
(anonymous) @ VM856:1
VM856:4 Closed: CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}

https://mastodon.social/home browser console:

Warning: Don’t paste code into the DevTools Console that you don’t understand or haven’t reviewed yourself. This could allow attackers to steal your identity or take control of your computer. Please type ‘allow pasting’ below and press Enter to allow pasting.
allow pasting
const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
VM177:1 Connecting to 'wss://localhost:8765/' violates the following Content Security Policy directive: "connect-src 'self' data: blob: https://mastodon.social https://files.mastodon.social wss://streaming.mastodon.social". The action has been blocked.
(anonymous) @ VM177:1
msg => ws.send(msg)

https://mastodon.social/explore browser console after using declarative net rules to remove the Content-Security-Policy headers.

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
msg => ws.send(msg)
VM140:1 WebSocket connection to 'wss://localhost:8765/' failed: 
(anonymous) @ VM140:1
VM140:4 Closed: CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}

https://x.com/home browser console:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
VM529:1 Connecting to 'wss://localhost:8765/' violates the following Content Security Policy directive: "connect-src 'self' blob: https://fonts.googleapis.com/css ...". The action has been blocked.
(anonymous) @ VM529:1
msg => ws.send(msg)

https://x.com/home browser console after using declarative net rules to remove content security headers:

const ws = new WebSocket('wss://localhost:8765');
ws.onopen = () => console.log('%cConnected securely!', 'color: lime');
ws.onmessage = e => console.log('Server →', e.data);
ws.onclose = e => console.log('Closed:', e);
window.send = msg => ws.send(msg);
msg => ws.send(msg)
VM436:1 WebSocket connection to 'wss://localhost:8765/' failed: 
(anonymous) @ VM436:1
VM436:4 Closed: CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}
New contributor
user31965232 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.