{"id":"CVE-2026-114140","kind":"vulnerability","aliases":["CVE-2026-114140","GHSA-pjvx-prjx-h659"],"related":[],"title":"nbconvert: Arbitrary file write through path traversal in cell output filenames when exporting to md, latex, rst and asciidoc","description":"### Summary\n\nnbconvert <= v7.17.1 has an arbitrary file write vulnerability due to a path traversal in ipynb cell output metadata, more specifically on the filename attribute.\n\nVulnerable converters : `--to markdown`, `--to latex`, `--to rst`, `--to asciidoc`.\n\nIn `ExtractOutputPreprocessor`, `extractoutput.py:116-119` joins attacker-controlled  `path` to `output_files_dir` with no canonicalization check, enabling arbitrary file write.\n\nThis is a sibling vulnerability of https://github.com/advisories/GHSA-4c99-qj7h-p3vg.\n\n### Impact\n\nIf a victim runs nbconvert on a malicious ipynb file, it can create some files with arbitrary data in arbitrary locations, i.e. override authorized_keys.\n\nNote that running the cell with jupyter overrides the output, so it would \"clean up\" malicious cells.\n\n### PoC\n\nIn a ipynb file:\n\n```json\n\n\"cells\": [{\n        \"cell_type\": \"code\", \"id\": \"abc123\", \"execution_count\": 1,\n        \"metadata\": {}, \"source\": \"# PoC\",\n        \"outputs\": [{\n            \"output_type\": \"display_data\",\n            \"metadata\": {\n                \"filename\": \"../../../tmp/PWNED.png\"  # ← traverses outside output_dir\n            },\n            \"data\": {\n                # minimal valid PNG (1×1 pixel)\n                \"image/png\": \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\"\n            }\n        }]\n    }]\n\n```\n\n\n### Patches\n\nFixed in \n- https://github.com/jupyter/nbconvert/commit/ce4bd99aec31d81d759fa8eeb8643179392ec66f\n- [7.17.2](https://github.com/jupyter/nbconvert/releases/tag/v7.17.2)","summary":"nbconvert up to 7.17.1 lets a malicious notebook set an output filename with path traversal, so converting it to markdown, LaTeX, rst or asciidoc writes files outside the output directory. An attacker who gets a victim to run nbconvert on a crafted .ipynb can overwrite arbitrary files the victim can write, such as authorized_keys.","severity":"high","cvss":8.8,"epss":0.0031300000846385956,"exploited":false,"exploited_at":null,"products":[{"name":"nbconvert","fixed":["7.17.2"],"affected":">= 5.4.0, <= 7.17.1","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["ci","cwe-22","jupyter","nbconvert","package","python","self-hosted"],"not_affected_if":["default-config"],"how_to_check":"pip show nbconvert or python -c \"import nbconvert; print(nbconvert.__version__)\"\nIf the version is 5.4.0 through 7.17.1, you are exposed when converting untrusted notebooks with --to markdown, latex, rst or asciidoc.","fix":"Upgrade to nbconvert 7.17.2 or later.\nUntil then, only convert notebooks you trust.","status":"open","published_at":"2026-10-21T21:17:56+00:00","first_seen_at":"2026-10-23T19:11:31+00:00","triaged_at":"2026-10-23T20:09:55+00:00","updated_at":"2026-10-23T21:57:29+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-10-23T20:09:55Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade to nbconvert 7.17.2 or later.\nUntil then, only convert notebooks you trust.","summary":"nbconvert up to 7.17.1 lets a malicious notebook set an output filename with path traversal, so converting it to markdown, LaTeX, rst or asciidoc writes files outside the output directory. An attacker who gets a victim to run nbconvert on a crafted .ipynb can overwrite arbitrary files the victim can write, such as authorized_keys.","category":"package","who_cares":["python","jupyter","nbconvert","self-hosted","ci"],"confidence":0.85,"analyst_note":"","how_to_check":"pip show nbconvert or python -c \"import nbconvert; print(nbconvert.__version__)\"\nIf the version is 5.4.0 through 7.17.1, you are exposed when converting untrusted notebooks with --to markdown, latex, rst or asciidoc.\nunknown","needs_analyst":false,"not_affected_if":["default-config"],"severity_if_unknown":"high"},"cost_usd":0.00045,"input_tokens":2666,"output_tokens":366,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-114140':22A,30A '-119':135C '-2026':21A,29A '-22':34B '/../../tmp/pwned.png':230C '/advisories/ghsa-4c99-qj7h-p3vg.':161C '/jupyter/nbconvert/commit/ce4bd99aec31d81d759fa8eeb8643179392ec66f':250C '/jupyter/nbconvert/releases/tag/v7.17.2)':254C '1':219C,239C,240C '7.17.1':45B '7.17.2':251C 'abc123':216C 'arbitrari':2A,87B,102C,150C,179C,182C 'asciidoc':19A,65B,131C 'attack':73B,138C 'attacker-control':137C 'attribut':121C 'author':95B,186C 'canonic':147C 'cell':9A,113C,192C,204C,211C,212C 'check':148C 'ci':32B 'clean':201C 'code':214C 'control':139C 'convert':58B,123C 'count':218C 'craft':83B 'creat':175C 'cve':20A,28A 'cwe':33B 'data':180C,227C,235C 'dir':144C,234C 'directori':71B 'display':226C 'due':106C 'enabl':149C 'execut':217C 'export':13A 'extractoutput.py:116':134C 'extractoutputpreprocessor':133C 'file':3A,67B,88B,103C,143C,151C,172C,177C,209C 'filenam':11A,53B,120C,229C 'fix':246C 'get':75B 'ghsa':24A 'ghsa-pjvx-prjx-h659':23A 'github.com':160C,249C,253C 'github.com/advisories/ghsa-4c99-qj7h-p3vg.':159C 'github.com/jupyter/nbconvert/commit/ce4bd99aec31d81d759fa8eeb8643179392ec66f':248C 'github.com/jupyter/nbconvert/releases/tag/v7.17.2)':252C 'h659':27A 'host':41B 'i.e':184C 'id':215C 'image/png':242C 'impact':162C 'ipynb':84B,112C,171C,208C 'ivborw0kggoaaaansuheugaaaaeaaaabcayaaaaffcsjaaaaduleqvr42mnk':243C 'join':136C 'json':210C 'jupyt':35B,194C 'key':96B,187C 'latex':16A,62B,127C 'let':46B 'locat':183C 'm9qdwadhggawjr9awaaaabjru5erkjggg':244C 'malici':48B,170C,203C 'markdown':61B,125C 'md':15A 'metadata':115C,220C,228C 'minim':236C 'nbconvert':1A,31A,36B,42B,80B,98C,167C 'note':188C 'notebook':49B 'output':10A,52B,70B,114C,142C,197C,223C,224C,233C 'outsid':68B,232C 'overrid':185C,195C 'overwrit':86B 'packag':37B 'patch':245C 'path':6A,55B,109C,140C 'pixel':241C 'pjvx':25A 'png':238C 'poc':205C,222C 'prjx':26A 'python':38B 'rst':17A,63B,129C 'run':79B,166C,190C 'self':40B 'self-host':39B 'set':50B 'sibl':156C 'sourc':221C 'specif':117C 'summari':97C 'travers':7A,56B,110C,231C 'type':213C,225C 'v7.17.1':99C 'valid':237C 'victim':77B,90B,165C 'vulner':105C,122C,157C 'would':200C 'write':4A,66B,92B,104C,152C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-21T21:17:56+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-pjvx-prjx-h659","url":"https://github.com/advisories/GHSA-pjvx-prjx-h659","severity":"high","published_at":"2026-10-22T16:23:28+00:00","modified_at":"2026-10-22T16:23:29+00:00","first_seen_at":"2026-10-23T19:11:31+00:00","fetched_at":"2026-10-23T19:11:31+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-114140","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-114140","severity":null,"published_at":"2026-10-21T21:17:56+00:00","modified_at":"2026-10-22T17:29:28+00:00","first_seen_at":"2026-10-23T21:57:29+00:00","fetched_at":"2026-10-23T22:29:02+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}