{"id":"CVE-2026-108360","kind":"vulnerability","aliases":["CVE-2026-108360"],"related":[],"title":"PhpSpreadsheet: image redirects let a server send blind internal requests","description":"PhpSpreadsheet is a pure PHP library for reading and writing spreadsheet files. Prior to 1.30.7, 2.1.19, 2.4.8, 3.10.8, and 5.10.0, Worksheet\\Drawing::setPath validates only the initial external-image URL with setIsWhitelisted when setAllowExternalImages is enabled. The HTTP stream context permits PHP to follow a redirect without applying the callback to the redirected URL, so a permitted image host can redirect the server to an internal address and cause a blind GET request. The response body is not returned to the attacker because the reader validates the downloaded content as an image and removes the temporary file, but internal GET-driven endpoints, network reachability, and cloud metadata endpoints may be reached. This issue is fixed in versions 1.30.7, 2.1.19, 2.4.8, 3.10.8, and 5.10.0.","summary":"PhpSpreadsheet only checks the first URL of an external image when external images are allowed, and PHP follows redirects without rechecking them. An attacker who controls an allowed image host can make the server send a blind GET request to internal addresses, including cloud metadata endpoints, though the response body is not returned.","severity":"medium","cvss":6.4,"epss":0.00221,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["cloud","package","php","phpspreadsheet","self-hosted"],"not_affected_if":["default-config","external-images-disabled"],"how_to_check":"- Run `composer show phpoffice/phpspreadsheet` and compare the version to the fixed releases.\n- Check whether `setAllowExternalImages(true)` is called anywhere in the application code.\n- Check whether `setIsWhitelisted` is set on the drawing or reader.","fix":"- Upgrade phpoffice/phpspreadsheet to `1.30.7`, `2.1.19`, `2.4.8`, `3.10.8`, or `5.10.0` depending on the major line in use.\n- Disable external images with `setAllowExternalImages(false)` if upgrading is not possible.","status":"open","published_at":"2026-10-22T18:17:26+00:00","first_seen_at":"2026-10-23T21:57:31+00:00","triaged_at":"2026-10-25T03:59:17+00:00","updated_at":"2026-10-25T03:59:17+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-10-25T03:59:17Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade phpoffice/phpspreadsheet to `1.30.7`, `2.1.19`, `2.4.8`, `3.10.8`, or `5.10.0` depending on the major line in use.\n- Disable external images with `setAllowExternalImages(false)` if upgrading is not possible.","reach":"internet","title":"PhpSpreadsheet: image redirects let a server send blind internal requests","impact":"medium","summary":"PhpSpreadsheet only checks the first URL of an external image when external images are allowed, and PHP follows redirects without rechecking them. An attacker who controls an allowed image host can make the server send a blind GET request to internal addresses, including cloud metadata endpoints, though the response body is not returned.","category":"package","nicknames":[],"who_cares":["php","phpspreadsheet","self-hosted","cloud"],"confidence":0.7,"needs_auth":"unknown","worst_case":"Server makes blind requests to internal addresses and cloud metadata endpoints","analyst_note":"","how_to_check":"- Run `composer show phpoffice/phpspreadsheet` and compare the version to the fixed releases.\n- Check whether `setAllowExternalImages(true)` is called anywhere in the application code.\n- Check whether `setIsWhitelisted` is set on the drawing or reader.","needs_analyst":false,"not_affected_if":["default-config","external-images-disabled"],"who_is_affected":"Applications that read or write spreadsheets with PhpSpreadsheet and have external image loading enabled via setAllowExternalImages are exposed, especially when they process user-uploaded spreadsheets. Applications that keep external images disabled, which is the default, can skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000668,"input_tokens":3551,"output_tokens":626,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-108360':13A,16A '-2026':12A,15A '1.30.7':91C,196C '2.1.19':92C,197C '2.4.8':93C,198C '3.10.8':94C,199C '5.10.0':96C,201C 'address':65B,144C 'allow':38B,51B 'appli':125C 'attack':47B,159C 'blind':8A,60B,148C 'bodi':73B,153C 'callback':127C 'caus':146C 'check':26B 'cloud':17B,67B,184C 'content':166C 'context':117C 'control':49B 'cve':11A,14A 'download':165C 'draw':98C 'driven':179C 'enabl':113C 'endpoint':69B,180C,186C 'extern':32B,35B,105C 'external-imag':104C 'file':88C,174C 'first':28B 'fix':193C 'follow':41B,121C 'get':61B,149C,178C 'get-driven':177C 'host':23B,53B,136C 'http':115C 'imag':2A,33B,36B,52B,106C,135C,169C 'includ':66B 'initi':103C 'intern':9A,64B,143C,176C 'issu':191C 'let':4A 'librari':82C 'make':55B 'may':187C 'metadata':68B,185C 'network':181C 'packag':18B 'permit':118C,134C 'php':19B,40B,81C,119C 'phpspreadsheet':1A,20B,24B,77C 'prior':89C 'pure':80C 'reach':189C 'reachabl':182C 'read':84C 'reader':162C 'recheck':44B 'redirect':3A,42B,123C,130C,138C 'remov':171C 'request':10A,62B,150C 'respons':72B,152C 'return':76B,156C 'self':22B 'self-host':21B 'send':7A,58B 'server':6A,57B,140C 'setallowexternalimag':111C 'setiswhitelist':109C 'setpath':99C 'spreadsheet':87C 'stream':116C 'temporari':173C 'though':70B 'url':29B,107C,131C 'valid':100C,163C 'version':195C 'without':43B,124C 'worksheet':97C 'write':86C","nicknames":[],"mitigations":[],"who_affected":"Applications that read or write spreadsheets with PhpSpreadsheet and have external image loading enabled via setAllowExternalImages are exposed, especially when they process user-uploaded spreadsheets. Applications that keep external images disabled, which is the default, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-22T18:17:26+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-108360","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-108360","severity":null,"published_at":"2026-10-22T18:17:26+00:00","modified_at":"2026-10-23T19:42:24+00:00","first_seen_at":"2026-10-23T21:57:31+00:00","fetched_at":"2026-10-23T22:29:02+00:00","note":null},{"source":"epss","external_id":"CVE-2026-108360","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-108360","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-24T07:15:51+00:00","fetched_at":"2026-10-24T07:15:51+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"}