VYPR
Medium severity6.8OSV Advisory· Published Dec 12, 2024· Updated Apr 15, 2026

CVE-2024-55878

CVE-2024-55878

Description

SimpleXLSX is software for parsing and retrieving data from Excel XLSx files. Starting in version 1.0.12 and prior to version 1.1.12, when calling the extended toHTMLEx method, it is possible to execute arbitrary JavaScript code. Version 1.1.12 fixes the issue. As a workaround, don't use direct publication via toHTMLEx.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A stored XSS vulnerability in SimpleXLSX's toHTMLEx method allows arbitrary JavaScript execution, fixed in version 1.1.12.

SimpleXLSX is a PHP library for parsing Excel XLSx files. In versions 1.0.12 through 1.1.12, the toHTMLEx method does not properly sanitize output, allowing injection of arbitrary JavaScript code. This is a classic case of insufficient output encoding, leading to cross-site scripting (XSS) vulnerabilities [1].

An attacker can craft a malicious XLSx file containing JavaScript payloads in cell data. When the library processes this file and outputs HTML via the toHTMLEx method, the JavaScript executes in the browser of any user viewing the output. No authentication is required beyond the ability to supply the file to the processing script [1].

Successful exploitation allows the attacker to execute arbitrary scripts in the context of the user's session. This can lead to theft of cookies, session tokens, or other sensitive information; redirection to malicious sites; or performing actions on behalf of the user without their consent [1].

The issue is fixed in SimpleXLSX version 1.1.12. Users should upgrade immediately. As a workaround, avoid using the toHTMLEx method for direct publication until the upgrade can be performed [1].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
shuchkin/simplexlsxPackagist
>= 1.0.12, < 1.1.121.1.12

Affected products

3

Patches

2
cb4e716259e8

1.1.12

https://github.com/shuchkin/simplexlsxSergey ShuchkinDec 11, 2024via ghsa
1 file changed · +16 14
  • src/SimpleXLSXEx.php+16 14 modified
    @@ -129,9 +129,9 @@ public function readThemeColors()
                 foreach ($colors12 as $c) {
                     $v = $this->xlsx->theme->themeElements->clrScheme->{$c};
                     if (isset($v->sysClr)) {
    -                    $this->themeColors[] = (string) $v->sysClr['lastClr'];
    +                    $this->themeColors[] = substr((string) $v->sysClr['lastClr'], 0, 6);
                     } elseif (isset($v->srgbClr)) {
    -                    $this->themeColors[] = (string) $v->srgbClr['val'];
    +                    $this->themeColors[] = substr((string) $v->srgbClr['val'], 0, 6);
                     } else {
                         $this->themeColors[] = null;
                     }
    @@ -148,7 +148,7 @@ public function readFonts()
                 foreach ($this->xlsx->styles->fonts->font as $v) {
                     $u = '';
                     if (isset($v->u)) {
    -                    $u = isset($v->u['val']) ? (string) $v->u['val'] : 'single';
    +                    $u = isset($v->u['val']) ? htmlspecialchars((string) $v->u['val'], ENT_QUOTES) : 'single';
                     }
                     $f = [
                         'b' => isset($v->b) && ($v->b['val'] === null || $v->b['val']),
    @@ -157,10 +157,10 @@ public function readFonts()
                         'strike' => isset($v->strike) && ($v->strike['val'] === null || $v->strike['val']),
                         'sz' => isset($v->sz['val']) ? (int) $v->sz['val'] : 11,
                         'color' => $this->getColorValue($v->color),
    -                    'name' => isset($v->name['val']) ? (string) $v->name['val'] : 'Calibri',
    +                    'name' => isset($v->name['val']) ? htmlspecialchars((string) $v->name['val'], ENT_QUOTES) : 'Calibri',
                         'family' => isset($v->family['val']) ? (int) $v->family['val'] : 2,
                         'charset' => isset($v->charset['val']) ? (int) $v->charset['val'] : 1,
    -                    'scheme' => isset($v->scheme['val']) ? (string) $v->scheme['val'] : 'minor'
    +                    'scheme' => isset($v->scheme['val']) ? htmlspecialchars((string) $v->scheme['val'], ENT_QUOTES) : 'minor'
                     ];
                     $this->fonts[] = $f;
                 }
    @@ -174,7 +174,7 @@ public function readFills()
                 foreach ($this->xlsx->styles->fills->fill as $v) {
                     if (isset($v->patternFill)) {
                         $this->fills[] = [
    -                        'pattern' => isset($v->patternFill['patternType']) ? (string) $v->patternFill['patternType'] : 'none',
    +                        'pattern' => isset($v->patternFill['patternType']) ? htmlspecialchars((string) $v->patternFill['patternType'], ENT_QUOTES) : 'none',
                             'fgcolor' => $this->getColorValue($v->patternFill->fgColor),
                             'bgcolor' => $this->getColorValue($v->patternFill->bgColor)
                         ];
    @@ -185,35 +185,37 @@ public function readFills()
         public function readBorders()
         {
             $this->borders = [];
    +        $styles = ['none', 'thin', 'medium', 'dashed', 'dotted', 'thick', 'double', 'hair', 'mediumDashed', 'dashDot',
    +            'mediumDashDot', 'dashDotDot', 'mediumDashDotDot', 'slantDashDot'];
             if (isset($this->xlsx->styles->borders->border)) {
                 foreach ($this->xlsx->styles->borders->border as $v) {
                     $this->borders[] = [
                         'left' => [
    -                        'style' => (string) $v->left['style'],
    +                        'style' => in_array((string) $v->left['style'], $styles) ? (string) $v->left['style'] : 'none',
                             'color' => $this->getColorValue($v->left->color)
                         ],
                         'right' => [
    -                        'style' => (string) $v->right['style'],
    +                        'style' => in_array((string) $v->right['style'], $styles) ? (string) $v->right['style'] : 'none',
                             'color' => $this->getColorValue($v->right->color)
                         ],
                         'top' => [
    -                        'style' => (string) $v->top['style'],
    +                        'style' => in_array((string) $v->top['style'], $styles) ? (string) $v->top['style'] : 'none',
                             'color' => $this->getColorValue($v->top->color)
                         ],
                         'bottom' => [
    -                        'style' => (string) $v->bottom['style'],
    +                        'style' => in_array((string) $v->bottom['style'], $styles) ? (string) $v->bottom['style'] : 'none',
                             'color' => $this->getColorValue($v->bottom->color)
                         ],
                         'diagonal' => [
    -                        'style' => (string) $v->diagonal['style'],
    +                        'style' => in_array((string) $v->diagonal['style'], $styles) ? (string) $v->diagonal['style'] : 'none',
                             'color' => $this->getColorValue($v->diagonal->color)
                         ],
                         'horizontal' => [
    -                        'style' => (string) $v->horizontal['style'],
    +                        'style' => in_array((string) $v->horizontal['style'], $styles) ? (string) $v->horizontal['style'] : 'none',
                             'color' => $this->getColorValue($v->horizontal->color)
                         ],
                         'vertical' => [
    -                        'style' => (string) $v->vertical['style'],
    +                        'style' => in_array((string) $v->vertical['style'], $styles) ? (string) $v->vertical['style'] : 'none',
                             'color' => $this->getColorValue($v->vertical->color)
                         ],
                         'diagonalUp' => (bool) $v['diagonalUp'],
    @@ -616,7 +618,7 @@ public function getColorValue(SimpleXMLElement $a = null, $default = '')
             }
             $c = $default; // auto
             if ($a['rgb'] !== null) {
    -            $c = substr((string) $a['rgb'], 2); // FFCCBBAA -> CCBBAA
    +            $c = substr((string) $a['rgb'], 2, 6); // FFCCBBAA -> CCBBAA
             } elseif ($a['indexed'] !== null && isset(static::$IC[ (int) $a['indexed'] ])) {
                 $c = static::$IC[ (int) $a['indexed'] ];
             } elseif ($a['theme'] !== null && isset($this->themeColors[ (int) $a['theme'] ])) {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.