Skip to content

Commit d20bbe1

Browse files
1 parent 8062e67 commit d20bbe1

6 files changed

Lines changed: 52 additions & 13 deletions

File tree

advisories/github-reviewed/2025/06/GHSA-3q2w-42mv-cph4/GHSA-3q2w-42mv-cph4.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-3q2w-42mv-cph4",
4-
"modified": "2026-06-09T11:48:30Z",
4+
"modified": "2026-06-09T18:40:07Z",
55
"published": "2025-06-27T15:19:16Z",
66
"aliases": [
77
"CVE-2025-52903"
@@ -52,6 +52,10 @@
5252
"type": "WEB",
5353
"url": "https://github.com/filebrowser/filebrowser/commit/4d830f707fc4314741fd431e70c2ce50cd5a3108"
5454
},
55+
{
56+
"type": "WEB",
57+
"url": "https://github.com/GoogleContainerTools/distroless"
58+
},
5559
{
5660
"type": "PACKAGE",
5761
"url": "https://github.com/filebrowser/filebrowser"
@@ -60,6 +64,10 @@
6064
"type": "WEB",
6165
"url": "https://github.com/sbaresearch/advisories/tree/public/2025/SBA-ADV-20250326-02_Filebrowser_Shell_Commands_Can_Spawn_Other_Commands"
6266
},
67+
{
68+
"type": "WEB",
69+
"url": "https://manpages.debian.org/bookworm/util-linux/prlimit.1.en.html"
70+
},
6371
{
6472
"type": "WEB",
6573
"url": "https://pkg.go.dev/vuln/GO-2025-3786"

advisories/github-reviewed/2026/03/GHSA-hv2w-8mjj-jw22/GHSA-hv2w-8mjj-jw22.json

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-hv2w-8mjj-jw22",
4-
"modified": "2026-03-31T18:56:02Z",
4+
"modified": "2026-06-09T18:39:02Z",
55
"published": "2026-03-30T17:26:44Z",
66
"aliases": [
77
"CVE-2026-34237"
88
],
99
"summary": "MCP Java SDK has a Hardcoded Wildcard CORS (Access-Control-Allow-Origin: *)",
10-
"details": "### Summary\n\n**Hardcoded Wildcard CORS (Access-Control-Allow-Origin: * )**\n\n- https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java#L289\n- https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java#L525\n\n### Attack Scenario\nAn attacker-controlled web page instructs the victim's browser to open GET https://internal-mcp-server/sse. Because Access-Control-Allow-Origin: * allows cross-origin SSE reads, the attacker's page receives the endpoint event — which contains the session ID. The attacker can then POST to that endpoint from their page using the victim's browser as a relay.\n\n### Comparison with python-sdk\nNo Access-Control-Allow-Origin header is emitted by either Python transport. The browser's default same-origin policy remains in full effect.\nhttps://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/sse.py\nhttps://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/streamable_http.py\n\n### Recommendation\nIn the SDK, the transport layer should not own CORS policy. Server implementors who need cross-origin access can add a CORS filter at the servlet filter or Spring Security layer.\n\n### Resources\n\n- https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#access-control-allow-origin",
10+
"details": "### Summary\n\n**Hardcoded Wildcard CORS (Access-Control-Allow-Origin: * )**\n\n- https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java#L289\n- https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java#L525\n\n### Attack Scenario\nAn attacker-controlled web page instructs the victim's browser to open GET https://internal-mcp-server/sse. Because Access-Control-Allow-Origin: * allows cross-origin SSE reads, the attacker's page receives the endpoint event — which contains the session ID. The attacker can then POST to that endpoint from their page using the victim's browser as a relay.\n\n### Comparison with python-sdk\nNo Access-Control-Allow-Origin header is emitted by either Python transport. The browser's default same-origin policy remains in full effect.\nhttps://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/sse.py\nhttps://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/streamable_http.py\n\n### Recommendation\nIn the SDK, the transport layer should not own CORS policy. Server implementors who need cross-origin access can add a CORS filter at the servlet filter or Spring Security layer.\n\n### Reference\n\n- https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#access-control-allow-origin",
1111
"severity": [
1212
{
1313
"type": "CVSS_V3",
@@ -25,17 +25,17 @@
2525
"type": "ECOSYSTEM",
2626
"events": [
2727
{
28-
"introduced": "0"
28+
"introduced": "1.0.0"
2929
},
3030
{
3131
"fixed": "1.0.1"
3232
}
3333
]
3434
}
3535
],
36-
"database_specific": {
37-
"last_known_affected_version_range": "< 1.0.0"
38-
}
36+
"versions": [
37+
"1.0.0"
38+
]
3939
},
4040
{
4141
"package": {
@@ -58,6 +58,25 @@
5858
"versions": [
5959
"1.1.0"
6060
]
61+
},
62+
{
63+
"package": {
64+
"ecosystem": "Maven",
65+
"name": "io.modelcontextprotocol.sdk:mcp-core"
66+
},
67+
"ranges": [
68+
{
69+
"type": "ECOSYSTEM",
70+
"events": [
71+
{
72+
"introduced": "0"
73+
},
74+
{
75+
"fixed": "0.18.3"
76+
}
77+
]
78+
}
79+
]
6180
}
6281
],
6382
"references": [

advisories/github-reviewed/2026/04/GHSA-jvpw-637p-h3pw/GHSA-jvpw-637p-h3pw.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-jvpw-637p-h3pw",
4-
"modified": "2026-06-09T11:49:59Z",
4+
"modified": "2026-06-09T18:39:58Z",
55
"published": "2026-04-08T00:04:27Z",
66
"aliases": [
77
"CVE-2026-35585"
88
],
99
"summary": "File Browser has a Command Injection via Hook Runner",
1010
"details": "> [!NOTE]\n> **This feature has been disabled by default for all installations from v2.33.8 onwards, including for existent installations**. To exploit this vulnerability, the instance administrator must turn on a feature and ignore all the warnings about known vulnerabilities. We're publishing this new advisory to make it clear that all vulnerabilities concerning this feature are disclosed.\n>\n> For more information about tracking vulnerability issues related to the Command Execution features, check https://github.com/filebrowser/filebrowser/issues/5199.\n\n## Overview\n\nThe hook system in File Browser — which executes administrator-defined shell commands on file events such as upload, rename, and delete — is vulnerable to OS command injection. Variable substitution for values like `$FILE` and `$USERNAME` is performed via `os.Expand` without sanitization. An attacker with file write permission can craft a malicious filename containing shell metacharacters, causing the server to execute arbitrary OS commands when the hook fires. This results in **Remote Code Execution (RCE)**.\n\n## Affected Location\n\n- **File:** `runner/runner.go`\n- **Function:** `Runner.exec`\n\n## Technical Details\n\n`Runner.exec` expands template variables inside hook command strings using `os.Expand`:\n\n```go\n// runner/runner.go\nenvMapping := func(key string) string {\n switch key {\n case \"FILE\":\n return path // attacker-controlled filename\n case \"USERNAME\":\n return username // attacker-controlled username\n // ...\n }\n}\n\nfor i, arg := range command {\n if i == 0 { continue }\n command[i] = os.Expand(arg, envMapping) // expands $FILE, $USERNAME, etc.\n}\n```\n\nThe expanded value is then passed as a shell argument string. `os.Expand` performs plain string substitution with no escaping. If an admin has configured a hook such as:\n\n```\nsh -c \"echo created $FILE\"\n```\n\n...and an attacker creates a file named `; id #`, the variable expansion produces:\n\n```\nsh -c \"echo created /path/to/; id #\"\n```\n\nThe `;` terminates the `echo` command and the shell executes `id` with server privileges. The `#` character comments out the remainder, preventing syntax errors.\n\nThis pattern is exploitable across all hook events: `before_upload`, `after_upload`, `before_rename`, `after_rename`, `before_delete`, `after_delete`, etc.\n\n## Attack Scenario / Reproduction Steps\n\n1. Admin configures an `after_upload` hook: `sh -c \"echo created $FILE\"`.\n2. The attacker (authenticated user with upload permission) uploads a file named `; id #`.\n3. The upload succeeds and the hook fires automatically.\n4. The server executes:\n ```sh\n sh -c \"echo created /uploads/; id #\"\n ```\n5. The `id` command runs, confirming RCE.\n\n## Impact\n\nAny authenticated user with file create, upload, or rename permissions can achieve arbitrary RCE on the server when shell-based hooks are configured. The attacker does not need to know the exact hook command — any hook that embeds `$FILE` in a shell string is exploitable by crafting the filename accordingly.\n\n## Proof of Concept\n\n```go\npackage runner\n\nimport (\n \"os\"\n \"testing\"\n\n \"github.com/filebrowser/filebrowser/v2/settings\"\n)\n\nfunc TestPoC_FileHookInjection(t *testing.T) {\n // Simulate an admin-configured shell-based hook\n r := &Runner{\n Enabled: true,\n Settings: &settings.Settings{\n Shell: []string{\"sh\", \"-c\"},\n Commands: map[string][]string{\n \"after_upload\": {\"echo Uploaded $FILE\"},\n },\n },\n }\n\n // Malicious filename crafted by the attacker\n maliciousFilename := \"/tmp/safe; id #\"\n\n // Simulate the exec logic in runner/runner.go\n raw := r.Commands[\"after_upload\"][0]\n command, _, _ := ParseCommand(r.Settings, raw)\n\n envMapping := func(key string) string {\n if key == \"FILE\" {\n return maliciousFilename\n }\n return os.Getenv(key)\n }\n\n for i, arg := range command {\n if i == 0 {\n continue\n }\n // os.Expand substitutes $FILE with the attacker-controlled filename —\n // no escaping is applied, so shell metacharacters pass through unchanged.\n command[i] = os.Expand(arg, envMapping)\n }\n\n // The resulting command argument is the injected shell script:\n // sh -c \"echo Uploaded /tmp/safe; id #\"\n expectedArg := \"echo Uploaded /tmp/safe; id #\"\n if command[2] != expectedArg {\n t.Errorf(\"Expected command argument %q, got %q\", expectedArg, command[2])\n }\n\n t.Logf(\"Confirmed: filename injection succeeded. Shell will execute: %v\", command)\n}\n```",
1111
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H"
15+
},
1216
{
1317
"type": "CVSS_V4",
1418
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"

advisories/github-reviewed/2026/05/GHSA-wxrr-jp8m-qq7f/GHSA-wxrr-jp8m-qq7f.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-wxrr-jp8m-qq7f",
4-
"modified": "2026-06-09T13:10:58Z",
4+
"modified": "2026-06-09T18:40:29Z",
55
"published": "2026-05-14T16:19:52Z",
66
"aliases": [
77
"CVE-2026-46480"
88
],
99
"summary": "FlowiseAI: Evaluator create+update mass-assignment allows cross-workspace evaluator takeover",
1010
"details": "## Summary\n\n**Type:** Mass assignment via `Object.assign(entity, body)` -> client-controlled `workspaceId` (and on create, `id`) overwritten on the Evaluator entity -> cross-workspace data takeover and IDOR.\n**File:** `packages/server/src/Interface.Evaluation.ts`\n**Root cause:** The Evaluator controller/service constructs a `new Evaluator()` and copies the request body into it via `Object.assign(...)` without an explicit field allowlist. The request body therefore can include `workspaceId`, `id`, `createdDate`, `updatedDate`. The server only rebinds *some* of these after the assign (e.g. on create, it overwrites `workspaceId` but not `id`; on update, it overwrites `id` but not `workspaceId`). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the evaluator entity's sibling controllers and as `DocumentStore` before it was patched in commit 840d2ae.\n\n## Affected Code\n\n**File:** `packages/server/src/Interface.Evaluation.ts`\n\n```ts\n// at line 85\nObject.assign(newEvaluator, body) // <-- BUG: body.id, body.workspaceId, body.createdDate, body.updatedDate accepted\n```\n\n**Why it's wrong:** `Object.assign(target, source)` copies every own enumerable property of `source` onto `target`. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so `workspaceId` set in the request body lands as the new `workspaceId` of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity.\n\n## Exploit Chain\n\n1. Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A.\n2. Attacker creates a evaluator in workspace A via the documented API (or reuses an existing one they own). They note its entity `id`.\n3. Attacker issues a `PUT /api/v1/evaluators/<id>` (or equivalent endpoint) with a JSON body that includes `\"workspaceId\": \"<workspace-B-id>\"` (an arbitrary other workspace's UUID). State at this point: the request reaches the controller as a workspace-A authenticated request.\n4. The controller calls `Object.assign(updateEntity, body)`. The body's `workspaceId` overwrites the entity's `workspaceId` field. The persistence layer commits the row.\n5. Final state: the evaluator row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator's workspace audit shows nothing because the operation looked like a normal update.\n\n## Security Impact\n\n**Severity:** High. Cross-workspace boundary violation by any authenticated workspace member.\n**Attacker capability:** Any authenticated user with permission to update a evaluator can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). Evaluators score model outputs and can be moved into another workspace via `workspaceId` overwrite, making the evaluator (and its scoring rubric) appear there.\n**Preconditions:** Authenticated session with edit permission for the source evaluator. No second factor required. Workspace UUIDs are exposed via the `/api/v1/workspaces` listing or via any cross-referenced object's `workspaceId` field, so target enumeration is trivial.\n**Differential:** PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the `workspaceId` field; vulnerable build accepts it and persists it.\n\n## Suggested Fix\n\nAlready fixed in PR https://github.com/FlowiseAI/Flowise/pull/6050 (allowlist pattern applied).\n\n```ts\n// Allowlist pattern (matches commit 840d2ae for DocumentStore):\nconst updatedEvaluator = new Evaluator()\nif (body.<allowed_field_1> !== undefined) updatedEvaluator.<allowed_field_1> = body.<allowed_field_1>\nif (body.<allowed_field_2> !== undefined) updatedEvaluator.<allowed_field_2> = body.<allowed_field_2>\n// ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client.\n```\n\nRegression tests should assert that a request body containing `workspaceId`, `id`, `createdDate`, or `updatedDate` is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.",
1111
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
15+
},
1216
{
1317
"type": "CVSS_V4",
1418
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"

0 commit comments

Comments
 (0)