CVE-2026-45553
Local file inclusion vulnerability in NiceGUI's ui.restructured_text.
- CVSS 7.5
- CWE-200
- Input Validation and Sanitization
- Remote
NiceGUI is a Python-based UI framework. Prior to version 3.12.0, ui.restructured_text() renders reStructuredText server-side with Docutils without disabling file insertion directives. When a NiceGUI application passes attacker-controlled content to ui.restructured_text(), an attacker can use standard Docutils directives (include, csv-table with :file:, raw with :file:) to read local files readable by the NiceGUI server process. Applications that only pass trusted static strings to ui.restructured_text() are not affected. This issue has been patched in version 3.12.0.
- CWE
- CWE-200
- CVSS base score
- 7.5
- Published
- 2026-06-02
- OWASP
- A05 Security Misconfiguration
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Local File Inclusion (LFI)
- Accessibility scope
- Remote
- Impact
- Information Disclosure
- Affected component
- NiceGUI
- Fixed by upgrading
- Yes
Solution
Upgrade NiceGUI to version 3.12.0 or later.
Vulnerable code sample
from nicegui import ui
# This application is vulnerable if run with a NiceGUI version prior to 1.12.0.
# It directly passes user-provided text to the ui.restructured_text function.
# An attacker can input a directive like ".. include:: /etc/passwd"
# to read and display local files from the server.
output_container = ui.column()
def render_user_content(e):
"""Renders the content from the textarea using ui.restructured_text."""
output_container.clear()
with output_container:
try:
# The vulnerable call: user input is passed directly to the function.
ui.restructured_text(e.value)
except Exception as err:
ui.label(f'Error rendering content: {err}')
ui.label('Enter reStructuredText content below to see it rendered:')
ui.label('To test the vulnerability, try: .. include:: /etc/passwd')
ui.textarea(
label='reStructuredText Input',
placeholder='Enter your text here...',
on_change=render_user_content
).style('width: 100%')
ui.run()Patched code sample
import docutils.core
from pathlib import Path
# This code demonstrates the fix for the reStructuredText file inclusion vulnerability.
# The core of the fix is to explicitly disable file I/O directives within Docutils settings.
# 1. Create a dummy local file that an attacker might try to access.
secret_file = Path("secret-data.txt")
secret_file.write_text("SENSITIVE_INFORMATION")
# 2. Define malicious reStructuredText input attempting to include the local file.
# This is the payload that would be sent by an attacker.
malicious_input = f".. include:: {secret_file.name}"
# 3. Define the secure settings for the Docutils publisher.
# This is the actual fix: 'file_insertion_enabled' and 'raw_enabled' are set to False.
# Prior to the fix, these settings were not specified, leaving them at their
# default (and insecure) value of True.
secure_settings_overrides = {
'report_level': 5, # Suppress non-error system messages for clean output
'file_insertion_enabled': False,
'raw_enabled': False,
}
# 4. Attempt to render the malicious input using the SECURE settings.
# In a vulnerable application, `secure_settings_overrides` would be an empty dict.
try:
parts = docutils.core.publish_parts(
source=malicious_input,
writer_name='html5',
settings_overrides=secure_settings_overrides
)
html_output = parts['html_body']
# 5. Print the output and verify the fix.
print("--- Rendered HTML with Fix ---")
print(html_output)
print("----------------------------")
if "SENSITIVE_INFORMATION" in html_output:
print("\n[VULNERABILITY] Secret file was read and included.")
else:
print("\n[FIX VERIFIED] The 'include' directive was safely disabled.")
print("The output contains an error/warning instead of the file content.")
finally:
# 6. Clean up the dummy file.
if secret_file.exists():
secret_file.unlink()Payload
.. include:: /etc/passwd
Cite this entry
@misc{vaitp:cve202645553,
title = {{Local file inclusion vulnerability in NiceGUI's ui.restructured_text.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-45553},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-45553/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
