{"id":"CVE-2026-107219","kind":"vulnerability","aliases":["CVE-2026-107219","GHSA-jrfj-fhj2-jjvm","GO-2026-6681"],"related":[],"title":"Excelize: Unbounded spinCount in agile decryption burns CPU during OpenFile","description":"Opening a file whose first eight bytes are the OLE magic number sends excelize down the decryption path whether or not the caller set a password, or supports encrypted workbooks at all. `openReaderAt` (excelize.go:198-215) branches on the header alone, and `agileDecrypt` calls `convertPasswdToKey` before the verifier hash is checked, so the key-derivation loop runs `spinCount` times regardless.\n\n`spinCount` (crypt.go:98) is a plain `int` filled by a bare `xml.Unmarshal` of the file's own EncryptionInfo stream. Nothing bounds it.\n\nA 3072-byte file with spinCount 100000000 makes `OpenFile` take 58.65s on v2.11.0 with default options, then return `zip: not a valid zip file`. It is linear at about 0.6 microseconds per iteration and the attacker picks the number, so 1e9 is roughly ten minutes. Nothing on the path takes a `context.Context`, so the caller cannot cancel it; in an HTTP handler the write timeout returns a response while the goroutine keeps spinning. Memory stays flat at 24 MB, so nothing reclaims it either.\n\n```\nv2.5.0   spinCount=10000000   5.307s\nv2.9.1   spinCount=10000000   5.444s\nv2.11.0  spinCount=10000000   7.529s\nv2.11.0  spinCount=100000000  58.654s\n```\n\nThe loop arrived with `crypt.go` in v2.3.1 and is unchanged through v2.11.0.\n\nExcel and LibreOffice write spinCount 100000, which costs 61ms here, so a ceiling well above the legitimate value would cost real files nothing. \n\nThis is availability only, and it is not a vulnerability for a program that only opens files its own operator produced.","summary":"Excelize, a Go library for reading and writing Excel files, does not cap the spinCount value when decrypting password-protected agile-encrypted workbooks. A crafted encrypted file can make OpenFile consume large amounts of CPU.","severity":"high","cvss":7.5,"epss":0.00363,"exploited":false,"exploited_at":null,"products":[{"name":"github.com/360EntSecGroup-Skylar/excelize/v2","fixed":[],"affected":">= 2.3.1","ecosystem":"go"},{"name":"github.com/xuri/excelize/v2","fixed":["2.11.1-0.20260906004932-2badfcd5841d"],"affected":"< 2.11.1-0.20260906004932-2badfcd5841d","ecosystem":"go"},{"name":"excelize","fixed":[],"affected":">= 2.3.1, <= 2.11.0","ecosystem":"vendor"},{"name":"github.com/xuri/excelize/v2","fixed":["2.11.1-0.20260906004932-2badfcd5841d"],"affected":">= 2.3.1, < 2.11.1-0.20260906004932-2badfcd5841d","ecosystem":"go"}],"ecosystems":["go","vendor"],"tags":["cwe-400","excel","file-upload","go","package"],"not_affected_if":["no-encrypted-workbooks","no-untrusted-files"],"how_to_check":"- Check the Go module version in `go.mod` for `github.com/xuri/excelize/v2`\n- Check whether the application calls OpenFile on user-supplied or uploaded .xlsx files\n- Check whether the old module path `github.com/360EntSecGroup-Skylar/excelize/v2` appears in `go.mod`","fix":"- `github.com/xuri/excelize/v2`: move to `2.11.1-0.20260906004932-2badfcd5841d` or later\n- `github.com/360EntSecGroup-Skylar/excelize/v2`: no fixed version is listed in the sources","status":"open","published_at":"2026-10-07T19:17:34+00:00","first_seen_at":"2026-11-06T00:09:03+00:00","triaged_at":"2026-11-06T00:10:46+00:00","updated_at":"2026-11-06T00:19:08+00:00","category":"package","confidence":0.6,"triage":{"at":"2026-11-06T00:10:46Z","model":"claude-haiku-5-5","output":{"fix":"- `github.com/xuri/excelize/v2`: move to `2.11.1-0.20260906004932-2badfcd5841d` or later\n- `github.com/360EntSecGroup-Skylar/excelize/v2`: no fixed version is listed in the sources","reach":"internet","title":"Excelize Go library: unbounded decryption work lets a file burn CPU","impact":"low","summary":"Excelize, a Go library for reading and writing Excel files, does not cap the spinCount value when decrypting password-protected agile-encrypted workbooks. A crafted encrypted file can make OpenFile consume large amounts of CPU.","audience":"developers","category":"package","nicknames":[],"who_cares":["go","excel","file-upload"],"confidence":0.6,"fix_status":"available","needs_auth":"no","worst_case":"Crafted file makes the server spend excessive CPU time","analyst_note":"","how_to_check":"- Check the Go module version in `go.mod` for `github.com/xuri/excelize/v2`\n- Check whether the application calls OpenFile on user-supplied or uploaded .xlsx files\n- Check whether the old module path `github.com/360EntSecGroup-Skylar/excelize/v2` appears in `go.mod`","plain_action":"","needs_analyst":false,"not_affected_if":["no-untrusted-files","no-encrypted-workbooks"],"who_is_affected":"Applications that open Excel files with Excelize's OpenFile, especially files supplied by users or external parties, are exposed. Projects that only generate workbooks or never open untrusted encrypted files can skip it.","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.000729,"input_tokens":4302,"output_tokens":598,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-107219':13A,24A '-2026':12A,20A,23A '-215':114C '-400':36B '-6681':21A '/360entsecgroup-skylar/excelize/v2':27A '/xuri/excelize/v2':30A,34A '0.6':191C '100000':283C '10000000':248C,253C,258C '100000000':167C,263C '1e9':202C '24':239C '3072':162C '5.307':249C '5.444':254C '58.65':171C '58.654':264C '61ms':286C '7.529':259C 'agil':5A,65B 'agile-encrypt':64B 'agiledecrypt':121C 'alon':119C 'amount':77B 'arriv':268C 'attack':197C 'avail':303C 'bare':149C 'bound':159C 'branch':115C 'burn':7A 'byte':86C,163C 'call':122C 'caller':102C,216C 'cancel':218C 'cannot':217C 'cap':55B 'ceil':290C 'check':129C 'consum':75B 'context.context':213C 'convertpasswdtokey':123C 'cost':285C,297C 'cpu':8A,79B 'craft':69B 'crypt.go':270C 'crypt.go:98':141C 'cve':11A,22A 'cwe':35B 'decrypt':6A,60B,96C 'default':176C 'deriv':134C 'eight':85C 'either':245C 'encrypt':66B,70B,108C 'encryptioninfo':156C 'excel':1A,37B,43B,51B,93C,278C 'excelize':31A 'excelize.go:198':113C 'fhj2':17A 'file':39B,52B,71B,82C,153C,164C,185C,299C,317C 'file-upload':38B 'fill':146C 'first':84C 'flat':237C 'ghsa':15A 'ghsa-jrfj-fhj2-jjvm':14A 'github.com':26A,29A,33A 'github.com/360entsecgroup-skylar/excelize/v2':25A 'github.com/xuri/excelize/v2':28A,32A 'go':19A,41B,45B 'goroutin':232C 'handler':223C 'hash':127C 'header':118C 'http':222C 'int':145C 'iter':194C 'jjvm':18A 'jrfj':16A 'keep':233C 'key':133C 'key-deriv':132C 'larg':76B 'legitim':294C 'librari':46B 'libreoffic':280C 'linear':188C 'loop':135C,267C 'magic':90C 'make':73B,168C 'mb':240C 'memori':235C 'microsecond':192C 'minut':206C 'noth':158C,207C,242C,300C 'number':91C,200C 'ole':89C 'open':80C,316C 'openfil':10A,74B,169C 'openreaderat':112C 'oper':320C 'option':177C 'packag':42B 'password':62B,105C 'password-protect':61B 'path':97C,210C 'per':193C 'pick':198C 'plain':144C 'produc':321C 'program':313C 'protect':63B 'read':48B 'real':298C 'reclaim':243C 'regardless':139C 'respons':229C 'return':179C,227C 'rough':204C 'run':136C 'send':92C 'set':103C 'spin':234C 'spincount':3A,57B,137C,140C,166C,247C,252C,257C,262C,282C 'stay':236C 'stream':157C 'support':107C 'take':170C,211C 'ten':205C 'time':138C 'timeout':226C 'unbound':2A 'unchang':275C 'upload':40B 'v2.11.0':174C,256C,261C,277C 'v2.3.1':272C 'v2.5.0':246C 'v2.9.1':251C 'valid':183C 'valu':58B,295C 'verifi':126C 'vulner':310C 'well':291C 'whether':98C 'whose':83C 'workbook':67B,109C 'would':296C 'write':50B,225C,281C 'xml.unmarshal':150C 'zip':180C,184C","nicknames":[],"mitigations":[],"who_affected":"Applications that open Excel files with Excelize's OpenFile, especially files supplied by users or external parties, are exposed. Projects that only generate workbooks or never open untrusted encrypted files can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["excelize","githubcom360entsecgroupskylarexcelizev2","githubcomxuriexcelizev2"],"ptokens":["360entsecgroup","com","excelize","github","skylar","v2","xuri"],"labels":["cwe400","excel","fileupload","go","high","package","vendor"],"campaign_type":null,"first_public_at":"2026-09-06T00:47:54+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"govuln","external_id":"GO-2026-6681","url":"https://pkg.go.dev/vuln/GO-2026-6681","severity":null,"published_at":"2026-11-05T22:53:46+00:00","modified_at":"2026-11-05T22:53:46+00:00","first_seen_at":"2026-11-06T00:09:03+00:00","fetched_at":"2026-11-06T00:09:03+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-107219","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107219","severity":null,"published_at":"2026-10-07T19:17:34+00:00","modified_at":"2026-10-13T14:23:15+00:00","first_seen_at":"2026-11-06T00:19:01+00:00","fetched_at":"2026-11-06T00:19:01+00:00","note":null},{"source":"ghsa","external_id":"GHSA-jrfj-fhj2-jjvm","url":"https://github.com/advisories/GHSA-jrfj-fhj2-jjvm","severity":"high","published_at":"2026-10-07T20:23:22+00:00","modified_at":"2026-10-07T20:23:23+00:00","first_seen_at":"2026-11-06T00:19:08+00:00","fetched_at":"2026-11-06T00:19:08+00:00","note":null}],"documents":[{"id":81821,"url":"https://github.com/qax-os/excelize/commit/2badfcd5841d0d88b0ffea119f5a2f3c53b4910b","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":81822,"url":"https://github.com/qax-os/excelize/pull/2389","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":81823,"url":"https://github.com/qax-os/excelize/security/advisories/GHSA-jrfj-fhj2-jjvm","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-09-06T00:47:54+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"},{"id":81926,"url":"https://api.github.com/repos/qax-os/excelize/security-advisories/GHSA-jrfj-fhj2-jjvm","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"}],"exploit_sources":[{"type":"epss","score":0.00363,"url":"https://api.first.org/data/v1/epss?cve=CVE-2026-107219"}],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}