{"schema":"threatline.record/2","record":{"id":"CVE-2026-108258","aliases":["GHSA-47c3-hpmg-7j6p","PYSEC-2026-4300"],"summary":"Shiny for Python has path traversal in bookmark restore","details":"### Impact\n\nShiny for Python's bookmark-restore path accepted a client-supplied `_state_id_`\nquery-string value and joined it into the server-side bookmark directory\n(`<cwd>/shiny_bookmarks/<id>`) without validating it. A value containing `..`\npath segments, or an absolute path, could therefore cause the server to open and\nparse `input.json` and `values.json` from a directory outside the bookmark store.\n\nOn a default application the restore was attempted whenever the client supplied a\nURL query string — including when bookmarking was disabled\n(`bookmark_store=\"disable\"`) — so no opt-in configuration was required. For such\napplications the impact is an unauthenticated, server-side probe for the\nexistence and JSON-validity of attacker-chosen paths, constrained to those two\nfile names.\n\nApplications configured with `bookmark_store=\"server\"` **and** using\n`ui.input_file()` are affected more seriously. The file-input restore handler\ncopies files out of the restore directory, so the contents of an\nattacker-selected file name within an attacker-selected directory could be read\ninto the application.\n\n### Affected versions\n\n1.4.0 through 1.6.3. Bookmarking was introduced in 1.4.0; earlier releases do\nnot contain the affected code path and are not affected.\n\n### Patches\n\nFixed in **1.6.4**. Upgrade with:\n\n```\npip install --upgrade shiny\n```\n\nThe fix validates bookmark IDs against an allowlist — a single path segment\nmatching `[A-Za-z0-9_-]+`, which cannot express a path separator, a `..` parent\nreference, or an absolute path — before the ID is used to build a filesystem\npath. Bookmark IDs generated by Shiny are unaffected by this restriction.\nRestore is additionally gated on the application's `bookmark_store` setting at a\nsingle point, so it no longer runs when bookmarking is disabled, and the on-disk\nrestore path is honored only under `bookmark_store=\"server\"`.\n\n### Workarounds\n\nThere is no configuration change that mitigates this on an affected version:\nthe restore path ran even with `bookmark_store=\"disable\"`. Deployments that\ncannot upgrade immediately can strip the `_state_id_` parameter from incoming\nquery strings at a reverse proxy or load balancer, which prevents the affected\ncode path from being reached.\n\n### Credits\n\nReported by [@0xRenSec](https://github.com/0xRenSec).","categories":["Libraries & packages"],"product":"shiny","vendor":"posit-dev","ecosystem":"pip","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-47c3-hpmg-7j6p","source_modified_at":"2026-10-09T20:56:38Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"shiny"},"range":">= 1.4.0, <= 1.6.3"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-108258","source_modified_at":"2026-10-13T18:33:20.463Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"py-shiny","vendor":"posit-dev","versions":[{"version":">= 1.4.0, < 1.6.4","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-47c3-hpmg-7j6p","source_modified_at":"2026-10-15T14:56:16.567885576Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"shiny","ecosystem":"PyPI","purl":"pkg:pypi/shiny"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.4.0"},{"fixed":"1.6.4"}]}],"versions":["1.4.0","1.5.0","1.5.1","1.6.0","1.6.1","1.6.2","1.6.3"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-47c3-hpmg-7j6p","source_modified_at":"2026-10-09T20:56:38Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"shiny"},"version":"1.6.4"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-47c3-hpmg-7j6p","source_modified_at":"2026-10-15T14:56:16.567885576Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"shiny","ecosystem":"PyPI","purl":"pkg:pypi/shiny"},"version":"1.6.4"}],"cvss":6.9,"severity":"Medium","kev":{"listed":false},"epss":{"probability":0.00357,"percentile":0.28212,"score_date":"2026-10-23"},"published_at":"2026-10-09T20:34:39.539Z","modified_at":"2026-10-15T14:56:16.567885576Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-47c3-hpmg-7j6p","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-09T20:56:38Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-108258","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-13T18:33:20.463Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-47c3-hpmg-7j6p","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-15T14:56:16.567885576Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-108258","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/posit-dev/py-shiny/security/advisories/GHSA-47c3-hpmg-7j6p","tags":["x_refsource_CONFIRM"]},{"source":"CVE List","url":"https://github.com/posit-dev/py-shiny/commit/1d8ecb46cbc9621b7dc8812111d26692e086b376","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/posit-dev/py-shiny/releases/tag/v1.6.4","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-47c3-hpmg-7j6p","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"none","automatable":"yes","technical_impact":"partial","assessed_at":"2026-10-13T18:33:09.230741Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-15T14:56:16.567885576Z","content_hash":"900be03e03cd3bfa560b4111eb500df71cfce476379344f248e90e37b32365d4"}}
