{"items":[{"id":"NVI-00003882","kind":"vulnerability","title":"PhpSpreadsheet ODS Reader: Unbounded number-rows-repeated → CPU & Memory Exhaustion (DoS)","revision":5,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected.","NVD lastModified does not establish freshness of every associated CPE record."],"lifecycle":"active","identifiers":["GHSA-j2w7-387v-m2rq","CVE-2026-108359"],"plain_summary":"GitHub lists this reviewed advisory for phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet. Published version ranges and source prerequisites are shown below; this is not an inspection of a visitor’s application.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-12a4cdb193d0c96d458ec849a96c74e7"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 5.10.0 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 3.10.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.4.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.19 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.30.7 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[{"kind":"CVSS","as_of":"2026-10-29T12:17:09.343Z","value":"8.7 HIGH (4.0)","meaning":"security-advisories@github.com severity; no combined Null risk score.","source_id":"sr-45f01c5a2151a61c52d18394e69fab4b"},{"kind":"EPSS","as_of":"2026-11-02T12:00:30.000Z","value":"0.660%","meaning":"FIRST EPSS model v2026.06.15; exploitation probability over 30 days, percentile 0.51548. Missing scores are unknown.","source_id":"sr-12a4cdb193d0c96d458ec849a96c74e7"}],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-7eee0f04696291da1c6998e313672471","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub Advisory Database; CC-BY-4.0. Each advisory links its original attribution. Null normalizes fields.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database","observed_at":"2026-10-31T21:56:51.534Z"},{"id":"sr-4e811780d846ad0e2a8749f169190e8e","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:42:20.435Z"},{"id":"sr-45f01c5a2151a61c52d18394e69fab4b","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-108359","basis":"official_catalog","notes":"This product uses data from the NVD API but is not endorsed or certified by the NVD.","title":"CVE-2026-108359","publisher":"NIST National Vulnerability Database","observed_at":"2026-11-01T01:40:38.141Z"},{"id":"sr-12a4cdb193d0c96d458ec849a96c74e7","url":"https://www.first.org/epss/data.html","basis":"official_catalog","notes":"FIRST EPSS; probability of exploitation in the next 30 days, not local compromise. Dataset date/model retained; FIRST services terms apply.","title":"CVE-2026-108359","publisher":"FIRST EPSS","observed_at":"2026-11-02T20:15:58.840Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 4.0.0, <= 5.9.0"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 3.3.0, <= 3.10.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.2.0, <= 2.4.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.0.0, <= 2.1.18"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["<= 1.30.6"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 4.0.0; fixed 5.10.0"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 3.3.0; fixed 3.10.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.4.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.1.19"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.30.7"]}],"null_published_at":"2026-11-04T10:04:47.613Z","source_updated_at":"2026-10-27T15:38:35.000Z","source_disclosed_at":"2026-10-27T15:38:33.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Dated EPSS estimate updated; this is not a new disclosure or proof of exploitation.","null_first_observed_at":"2026-10-31T21:42:20.435Z"},{"id":"NVI-00003882","kind":"vulnerability","title":"PhpSpreadsheet ODS Reader: Unbounded number-rows-repeated → CPU & Memory Exhaustion (DoS)","revision":4,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected.","NVD lastModified does not establish freshness of every associated CPE record."],"lifecycle":"active","identifiers":["GHSA-j2w7-387v-m2rq","CVE-2026-108359"],"plain_summary":"GitHub lists this reviewed advisory for phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet. Published version ranges and source prerequisites are shown below; this is not an inspection of a visitor’s application.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-1c92c838a6394dad77e72727a0fc1743"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 5.10.0 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 3.10.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.4.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.19 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.30.7 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[{"kind":"CVSS","as_of":"2026-10-29T12:17:09.343Z","value":"8.7 HIGH (4.0)","meaning":"security-advisories@github.com severity; no combined Null risk score.","source_id":"sr-45f01c5a2151a61c52d18394e69fab4b"},{"kind":"EPSS","as_of":"2026-10-31T12:00:27.000Z","value":"0.660%","meaning":"FIRST EPSS model v2026.06.15; exploitation probability over 30 days, percentile 0.51561. Missing scores are unknown.","source_id":"sr-1c92c838a6394dad77e72727a0fc1743"}],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-7eee0f04696291da1c6998e313672471","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub Advisory Database; CC-BY-4.0. Each advisory links its original attribution. Null normalizes fields.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database","observed_at":"2026-10-31T21:56:51.534Z"},{"id":"sr-4e811780d846ad0e2a8749f169190e8e","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:42:20.435Z"},{"id":"sr-45f01c5a2151a61c52d18394e69fab4b","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-108359","basis":"official_catalog","notes":"This product uses data from the NVD API but is not endorsed or certified by the NVD.","title":"CVE-2026-108359","publisher":"NIST National Vulnerability Database","observed_at":"2026-11-01T01:40:38.141Z"},{"id":"sr-1c92c838a6394dad77e72727a0fc1743","url":"https://www.first.org/epss/data.html","basis":"official_catalog","notes":"FIRST EPSS; probability of exploitation in the next 30 days, not local compromise. Dataset date/model retained; FIRST services terms apply.","title":"CVE-2026-108359","publisher":"FIRST EPSS","observed_at":"2026-10-31T22:06:15.373Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 4.0.0, <= 5.9.0"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 3.3.0, <= 3.10.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.2.0, <= 2.4.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.0.0, <= 2.1.18"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["<= 1.30.6"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 4.0.0; fixed 5.10.0"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 3.3.0; fixed 3.10.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.4.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.1.19"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.30.7"]}],"null_published_at":"2026-11-01T14:34:07.639Z","source_updated_at":"2026-10-27T15:38:35.000Z","source_disclosed_at":"2026-10-27T15:38:33.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Source facts changed; compare the preserved prior revision.","null_first_observed_at":"2026-10-31T21:42:20.435Z"},{"id":"NVI-00003882","kind":"vulnerability","title":"PhpSpreadsheet ODS Reader: Unbounded number-rows-repeated → CPU & Memory Exhaustion (DoS)","revision":3,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected."],"lifecycle":"active","identifiers":["GHSA-j2w7-387v-m2rq","CVE-2026-108359"],"plain_summary":"GitHub lists this reviewed advisory for phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet. Published version ranges and source prerequisites are shown below; this is not an inspection of a visitor’s application.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-1c92c838a6394dad77e72727a0fc1743"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 5.10.0 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 3.10.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.4.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.19 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.30.7 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[{"kind":"EPSS","as_of":"2026-10-31T12:00:27.000Z","value":"0.660%","meaning":"FIRST EPSS model v2026.06.15; exploitation probability over 30 days, percentile 0.51561. Missing scores are unknown.","source_id":"sr-1c92c838a6394dad77e72727a0fc1743"}],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-7eee0f04696291da1c6998e313672471","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub Advisory Database; CC-BY-4.0. Each advisory links its original attribution. Null normalizes fields.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database","observed_at":"2026-10-31T21:56:51.534Z"},{"id":"sr-4e811780d846ad0e2a8749f169190e8e","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:42:20.435Z"},{"id":"sr-1c92c838a6394dad77e72727a0fc1743","url":"https://www.first.org/epss/data.html","basis":"official_catalog","notes":"FIRST EPSS; probability of exploitation in the next 30 days, not local compromise. Dataset date/model retained; FIRST services terms apply.","title":"CVE-2026-108359","publisher":"FIRST EPSS","observed_at":"2026-10-31T22:06:15.373Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 4.0.0, <= 5.9.0"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 3.3.0, <= 3.10.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.2.0, <= 2.4.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.0.0, <= 2.1.18"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["<= 1.30.6"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 4.0.0; fixed 5.10.0"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 3.3.0; fixed 3.10.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.4.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.1.19"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.30.7"]}],"null_published_at":"2026-10-31T22:27:09.604Z","source_updated_at":"2026-10-27T15:38:35.000Z","source_disclosed_at":"2026-10-27T15:38:33.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Dated EPSS estimate updated; this is not a new disclosure or proof of exploitation.","null_first_observed_at":"2026-10-31T21:42:20.435Z"},{"id":"NVI-00003882","kind":"vulnerability","title":"PhpSpreadsheet ODS Reader: Unbounded number-rows-repeated → CPU & Memory Exhaustion (DoS)","revision":2,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected."],"lifecycle":"active","identifiers":["GHSA-j2w7-387v-m2rq","CVE-2026-108359"],"plain_summary":"GitHub lists this reviewed advisory for phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet, phpoffice/phpspreadsheet. Published version ranges and source prerequisites are shown below; this is not an inspection of a visitor’s application.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 5.10.0 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 3.10.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.4.8 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.19 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.30.7 for phpoffice/phpspreadsheet. Confirm the publisher’s latest guidance.","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-7eee0f04696291da1c6998e313672471","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub Advisory Database; CC-BY-4.0. Each advisory links its original attribution. Null normalizes fields.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database","observed_at":"2026-10-31T21:56:51.534Z"},{"id":"sr-4e811780d846ad0e2a8749f169190e8e","url":"https://github.com/advisories/GHSA-j2w7-387v-m2rq","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-j2w7-387v-m2rq","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:42:20.435Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 4.0.0, <= 5.9.0"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 3.3.0, <= 3.10.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.2.0, <= 2.4.7"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":[">= 2.0.0, <= 2.1.18"]},{"certainty":"source_listed","source_ids":["sr-7eee0f04696291da1c6998e313672471"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["<= 1.30.6"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 4.0.0; fixed 5.10.0"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 3.3.0; fixed 3.10.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.4.8"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.1.19"]},{"certainty":"source_listed","source_ids":["sr-4e811780d846ad0e2a8749f169190e8e"],"technology":"phpoffice/phpspreadsheet","known_exclusions":[],"conditions_summary":"## Summary\n\nWhen PhpSpreadsheet loads an OpenDocument Spreadsheet (`.ods`), `Ods::processTableRow()`\nreads the `table:number-rows-repeated` attribute of a `` with an unchecked \n`(int)` cast, then materialises one cell per repeated row. This value is **completely unbounded**, \nso a **single ~1.4 KB file** can instruct the reader to create up to **millions of cells**, \nexhausting memory (fatal OOM). No authentication, no special configuration, and the default read \nfilter are required - any application that loads a user-supplied `.ods` is affected.\n\n---\n\n## Affected versions\n\nThe `number-rows-repeated` expansion has existed in the ODS reader since its inception\n(pre-dating the current release branches), so all maintained lines are affected.\n\n| Branch | Affected |\n|--------|----------|\n| 1.x    | ≤ 1.30.6 |\n| 2.0–2.1 | ≤ 2.1.18 |\n| 2.2–2.4 | ≤ 2.4.7 |\n| 3.x    | ≤ 3.10.7 |\n| 4.x–5.x | ≤ 5.9.0 (latest) |\n\n---\n\n## Root cause (source → sink)\n\n`src/PhpSpreadsheet/Reader/Ods.php`:\n\n```php\n// line 816 — row repeat, unchecked (int) cast\n$rowRepeats = (int) $childNode->getAttributeNS($tableNs, 'number-rows-repeated');\n...\n// line 1151 — row materialisation loop: NO upper boun","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.30.7"]}],"null_published_at":"2026-10-31T22:13:31.267Z","source_updated_at":"2026-10-27T15:38:35.000Z","source_disclosed_at":"2026-10-27T15:38:33.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Source facts changed; compare the preserved prior revision.","null_first_observed_at":"2026-10-31T21:42:20.435Z"}],"next_cursor":null,"snapshot_revision":"42594"}