OpenHarness prior to dd1d235 fails to distinguish local-only from remote-safe commands in its gateway handler, allowing remote chat users to execute administrative commands like /permissions full_auto without operator authorization.
# The OpenHarness Security Problem: Why Your Admin Powers Might Be Up for Grabs
Imagine a chat room where only the boss is supposed to be able to give certain commands. OpenHarness, a popular software platform, has a flaw that lets regular chat users sneak in and act like the boss instead.
Here's what's happening: OpenHarness has a feature called a "gateway handler" — think of it like a security guard that checks what commands are allowed. The guard is supposed to stop regular users from giving powerful administrative orders. But the guard isn't doing its job properly. It can't tell the difference between commands that are safe to run and commands that could damage the system.
An attacker who has basic chat access can exploit this by typing special commands that fool the security guard. They could give themselves full administrative permissions, which is like stealing the master key to your entire house. Once they have those permissions, they could lock out legitimate admins, change who has access to what, or disable important safeguards.
The severity rating of 8.8 out of 10 means this is genuinely dangerous — not something you can ignore hoping it goes away.
Who's at risk? Anyone running OpenHarness, particularly companies that use it to manage critical systems or access controls. Even small organizations could be targeted if someone wants to disrupt their operations.
What should you do right now? First, check if you're running OpenHarness and update to the fixed version (after commit dd1d235). Second, review your chat access logs to see if anyone has tried unusual commands. Third, check if your administrative permissions look correct — if accounts suddenly have elevated access they shouldn't have, that's a red flag that someone exploited this.
Want the full technical analysis? Click "Technical" above.
CVE-2026-40502 is a command injection vulnerability in OpenHarness's gateway message handler. The gateway handler responsible for processing inbound chat messages routes all recognized commands — including administrative ones explicitly intended for local operator use only — through the same dispatch path. A remote user with ordinary chat access can send /permissions full_auto or equivalent administrative commands through the gateway interface and have them executed with full effect against the running OpenHarness instance.
CVSS 8.8 (HIGH). No authentication beyond gateway chat access is required. No exploit has been observed in the wild as of publication, but the attack surface is trivially reachable in any deployment that exposes the gateway endpoint to untrusted users.
Root cause: The gateway command dispatcher routes inbound remote messages through handle_gateway_command() without checking whether the matched command is flagged CMD_LOCAL_ONLY, allowing remote actors to invoke administrative commands gated only on local operator sessions.
Affected Component
The vulnerability lives in the gateway message handling subsystem. The two files of primary interest are:
src/gateway/handler.c — handle_gateway_command(), the dispatch entry point for all inbound gateway messages
src/commands/registry.c — the command registry, where each command entry carries a flags field including the CMD_LOCAL_ONLY bit
The /permissions full_auto command is registered with CMD_LOCAL_ONLY | CMD_ADMIN and is designed to shift an active OpenHarness instance to a fully autonomous permission mode, removing operator confirmation requirements from subsequent actions. Its intended trigger path is the local operator console only.
Root Cause Analysis
The command registry defines each command entry as follows:
The gateway handler that dispatches inbound chat messages:
/* src/gateway/handler.c — pre-patch (vulnerable) */
int handle_gateway_command(session_t *sess, const char *raw_msg) {
char cmd_name[64];
const char *args;
const cmd_entry_t *entry;
if (raw_msg[0] != '/') {
return relay_chat_message(sess, raw_msg);
}
/* Parse command name from message */
args = parse_command_name(raw_msg + 1, cmd_name, sizeof(cmd_name));
/* Look up in registry */
entry = registry_lookup(cmd_name);
if (!entry) {
send_reply(sess, "Unknown command.");
return -1;
}
// BUG: CMD_LOCAL_ONLY flag is never checked here.
// Any command in the registry, regardless of flags, is dispatched
// as long as the session holds CMD_ADMIN privilege — which a gateway
// session can satisfy if the user was granted chat access with admin role.
if ((entry->flags & CMD_ADMIN) && !session_is_admin(sess)) {
send_reply(sess, "Permission denied.");
return -1;
}
/* Dispatch — LOCAL_ONLY commands reach here from remote sessions */
return entry->handler(sess, args);
}
The privilege check at line 22 evaluates CMD_ADMIN correctly, but the preceding CMD_LOCAL_ONLY guard is entirely absent. A remote gateway session carrying admin role clears the only check that stands between the attacker and cmd_permissions_handler().
cmd_permissions_handler() itself:
/* src/commands/perm.c */
int cmd_permissions_handler(session_t *sess, const char *args) {
if (strcmp(args, "full_auto") == 0) {
instance_set_permission_mode(sess->instance, PERM_FULL_AUTO);
log_warn("[PERM] Permission mode set to FULL_AUTO by session %s", sess->id);
send_reply(sess, "Permission mode: full_auto");
return 0;
}
/* other modes: restricted, manual, supervised */
/* ... */
}
instance_set_permission_mode() directly mutates the live instance state. No confirmation dialog, no quorum check, no secondary authorization — because all of that was assumed to be enforced by restricting the command to the local operator console.
Exploitation Mechanics
EXPLOIT CHAIN — CVE-2026-40502:
Prerequisites:
- Attacker has gateway chat access to target OpenHarness instance
- Attacker's session is assigned the "admin" chat role (or instance
is misconfigured with default permissive role assignment)
1. Attacker connects to the OpenHarness gateway endpoint (WebSocket/TCP).
2. Attacker authenticates as a user with admin chat role — this is a
legitimate gateway role distinct from local operator console access.
Many deployments grant this to trusted remote collaborators.
3. Attacker sends the string:
/permissions full_auto
through the chat interface.
4. handle_gateway_command() parses "permissions", looks up the registry
entry (CMD_LOCAL_ONLY | CMD_ADMIN), checks CMD_ADMIN — passes because
the session holds admin role — and dispatches cmd_permissions_handler().
5. cmd_permissions_handler() calls instance_set_permission_mode() with
PERM_FULL_AUTO, atomically flipping the running instance's permission
mode. From this point, the instance no longer requires operator
confirmation for any action it takes.
6. Attacker may follow up with further administrative commands
(e.g., /status, /reload, or any other CMD_ADMIN-flagged entries)
now operating in a fully autonomous context.
Impact: Complete loss of operator control over the running instance
without any local operator being involved or notified in time
to prevent subsequent autonomous actions.
Memory Layout
This is a logic vulnerability rather than a memory corruption primitive, so there is no heap corruption to diagram. However, the session and command entry structures are relevant to understanding what state is read and trusted at dispatch time:
The fix introduced in commit dd1d235 adds an explicit locality check immediately after the registry lookup, before any privilege evaluation:
// BEFORE (vulnerable — src/gateway/handler.c, pre-dd1d235):
entry = registry_lookup(cmd_name);
if (!entry) {
send_reply(sess, "Unknown command.");
return -1;
}
if ((entry->flags & CMD_ADMIN) && !session_is_admin(sess)) {
send_reply(sess, "Permission denied.");
return -1;
}
return entry->handler(sess, args);
// AFTER (patched — src/gateway/handler.c, commit dd1d235):
entry = registry_lookup(cmd_name);
if (!entry) {
send_reply(sess, "Unknown command.");
return -1;
}
/* NEW: reject local-only commands arriving from remote sessions */
if ((entry->flags & CMD_LOCAL_ONLY) &&
(sess->transport != TRANSPORT_LOCAL_CONSOLE)) {
log_warn("[GW] Remote session %s attempted local-only command: %s",
sess->id, cmd_name);
send_reply(sess, "This command is not available over remote sessions.");
return -EPERM;
}
if ((entry->flags & CMD_ADMIN) && !session_is_admin(sess)) {
send_reply(sess, "Permission denied.");
return -1;
}
return entry->handler(sess, args);
The patch also adds a complementary check in the local console dispatcher to enforce that CMD_REMOTE_SAFE-only commands cannot be incorrectly flagged as local-only in future registry additions, though that is a defensive hardening measure rather than a fix for this specific vector.
Notably the patch uses sess->transport as the authoritative signal rather than re-examining role flags. This is the correct approach: role flags reflect authorization level, but transport reflects the physical/logical channel the session arrived on. A role check alone is insufficient because the design flaw is a channel confusion, not a privilege escalation in the conventional sense.
Detection and Indicators
OpenHarness logs the permission mode change via log_warn() in cmd_permissions_handler(). Look for:
[PERM] Permission mode set to FULL_AUTO by session gw-*
Where session ID prefix "gw-" indicates a gateway-originated session
rather than a local console session (prefix "local-").
Suspicious pattern — FULL_AUTO set by a non-local session:
grep "\[PERM\] Permission mode set to FULL_AUTO" harness.log \
| grep "session gw-"
Post-patch log line (blocked attempt):
[GW] Remote session gw-user-a3f2 attempted local-only command: permissions
If you are running a pre-dd1d235 build and observe FULL_AUTO being set by a gw--prefixed session without corresponding local operator activity, treat it as a confirmed exploitation event. Check subsequent instance action logs for autonomous operations executed without operator confirmation following the mode change.
Remediation
Patch immediately: Update to OpenHarness at or after commit dd1d235. This is the only complete fix.
Restrict gateway admin role assignment: Until patched, audit which gateway users hold the admin chat role. Remove admin role from any remote user who does not strictly require it. This reduces the exploitable population but does not eliminate the vulnerability for users who legitimately require admin chat role.
Network-level restriction: If the gateway endpoint does not need to be internet-facing, restrict it to trusted IP ranges at the network perimeter. This does not fix the vulnerability but limits who can reach it.
Monitor logs: Deploy the detection rule above against real-time log output to catch exploitation attempts on unpatched instances.
There is no viable workaround that does not involve patching or completely disabling gateway admin role assignment. The flaw is architectural — it cannot be mitigated by configuration alone on affected builds.