CVE-2026-35585: Github.com/filebrowser/filebrowser/v2 File Browser Has A Command Vulnerability

HIGH
Advisory Identifier: GHSA-jvpw-637p-h3pw
CVSS 7.2
CWE-78 CWE-88
Published
Advisory Summary

CVE-2026-35585 is a HIGH (CVSS 7.2) file browser has a command vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting Github.com/filebrowser/filebrowser/v2 libraries in the Go ecosystem. The issue involves file browser has a command injection via hook runner. Remediation is available by upgrading affected packages to version 2.33.8.

CVE-2026-35585 at a Glance

CVE Identifier CVE-2026-35585
GHSA Identifier GHSA-jvpw-637p-h3pw
Severity HIGH
CVSS v3.1 Base Score 7.2
CWE Classification CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Affected Product Github.com/filebrowser/filebrowser/v2
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 7.2

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required High (PR:H)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-35585

To remediate this vulnerability, upgrade all affected Github.com/filebrowser/filebrowser/v2 dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/filebrowser/filebrowser/v2 fixed: 2.33.8
Upgrade github.com/filebrowser/filebrowser/v2 to 2.33.8
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/filebrowser/filebrowser/v2

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-35585, inspect your project dependencies for Github.com/filebrowser/filebrowser/v2:

inspect dependencies for github.com/filebrowser/filebrowser/v2

Analyze the terminal output to locate any version of Github.com/filebrowser/filebrowser/v2 in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.33.8), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where the product constructs all or part of an os command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended os command when it is sent to a downstream component. In Github.com/filebrowser/filebrowser/v2, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

> [!NOTE] > **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. > > For more information about tracking vulnerability issues related to the Command Execution features, check https://github.com/filebrowser/filebrowser/issues/5199. ## Overview The 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)**. ## Affected Location - **File:** `runner/runner.go` - **Function:** `Runner.exec` ## Technical Details `Runner.exec` expands template variables inside hook command strings using `os.Expand`: ```go // runner/runner.go envMapping := func(key string) string { switch key { case "FILE": return path // attacker-controlled filename case "USERNAME": return username // attacker-controlled username // ... } } for i, arg := range command { if i == 0 { continue } command[i] = os.Expand(arg, envMapping) // expands $FILE, $USERNAME, etc. } ``` The 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: ``` sh -c "echo created $FILE" ``` ...and an attacker creates a file named `; id #`, the variable expansion produces: ``` sh -c "echo created /path/to/; id #" ``` The `;` terminates the `echo` command and the shell executes `id` with server privileges. The `#` character comments out the remainder, preventing syntax errors. This pattern is exploitable across all hook events: `before_upload`, `after_upload`, `before_rename`, `after_rename`, `before_delete`, `after_delete`, etc. ## Attack Scenario / Reproduction Steps 1. Admin configures an `after_upload` hook: `sh -c "echo created $FILE"`. 2. The attacker (authenticated user with upload permission) uploads a file named `; id #`. 3. The upload succeeds and the hook fires automatically. 4. The server executes: ```sh sh -c "echo created /uploads/; id #" ``` 5. The `id` command runs, confirming RCE. ## Impact Any 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. ## Proof of Concept ```go package runner import ( "os" "testing" "github.com/filebrowser/filebrowser/v2/settings" ) func TestPoC_FileHookInjection(t *testing.T) { // Simulate an admin-configured shell-based hook r := &Runner{ Enabled: true, Settings: &settings.Settings{ Shell: []string{"sh", "-c"}, Commands: map[string][]string{ "after_upload": {"echo Uploaded $FILE"}, }, }, } // Malicious filename crafted by the attacker maliciousFilename := "/tmp/safe; id #" // Simulate the exec logic in runner/runner.go raw := r.Commands["after_upload"][0] command, _, _ := ParseCommand(r.Settings, raw) envMapping := func(key string) string { if key == "FILE" { return maliciousFilename } return os.Getenv(key) } for i, arg := range command { if i == 0 { continue } // os.Expand substitutes $FILE with the attacker-controlled filename — // no escaping is applied, so shell metacharacters pass through unchanged. command[i] = os.Expand(arg, envMapping) } // The resulting command argument is the injected shell script: // sh -c "echo Uploaded /tmp/safe; id #" expectedArg := "echo Uploaded /tmp/safe; id #" if command[2] != expectedArg { t.Errorf("Expected command argument %q, got %q", expectedArg, command[2]) } t.Logf("Confirmed: filename injection succeeded. Shell will execute: %v", command) } ```

CVE-2026-35585 Affected Github.com/filebrowser/filebrowser/v2 Versions

1 component(s)
Fixed Versions:
2.33.8
Product / Package Ecosystem Affected Versions Fixed Version
github.com/filebrowser/filebrowser/v2
Go
< 2.33.8
2.33.8

References

Frequently Asked Questions

What is CVE-2026-35585?
CVE-2026-35585 is a security vulnerability in Github.com/filebrowser/filebrowser/v2 involving File Browser has a Command Injection via Hook Runner under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
Which Github.com/filebrowser/filebrowser/v2 versions are affected?
Affected versions include releases prior to 2.33.8 across affected packages: github.com/filebrowser/filebrowser/v2.
What version fixes CVE-2026-35585?
Upgrading to 2.33.8 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/filebrowser/filebrowser/v2 affected?
Yes, github.com/filebrowser/filebrowser/v2 is affected in releases prior to 2.33.8. Upgrade your dependency to 2.33.8 or later.
What is the CVSS score of CVE-2026-35585?
CVE-2026-35585 has a CVSS v3.1 base score of 7.2 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-35585?
CVE-2026-35585 is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.).
How can I check Go dependencies for CVE-2026-35585?
Run the dependency tree command: 'inspect dependencies for github.com/filebrowser/filebrowser/v2'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-jvpw-637p-h3pw",
  "modified" : "2026-06-09T18:39:58Z",
  "published" : "2026-04-08T00:04:27Z",
  "aliases" : [ "CVE-2026-35585" ],
  "summary" : "File Browser has a Command Injection via Hook Runner",
  "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```",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H"
  }, {
    "type" : "CVSS_V4",
    "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"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/filebrowser/filebrowser/v2"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "2.33.8"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-jvpw-637p-h3pw"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-35585"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/filebrowser/filebrowser/issues/5199"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/filebrowser/filebrowser"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-78", "CWE-88" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-08T00:04:27Z",
    "nvd_published_at" : "2026-04-07T17:16:33Z"
  }
}