Security is very important for NiceGUI and its community. π
Learn more about it below. π
The latest version of NiceGUI is supported.
You are encouraged to write tests for your application and update your NiceGUI version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and security fixes.
Automated scanners and AI-assisted reviews frequently flag the patterns below. They are by design or already bounded, so please trace the data flow and check them against this list before filing β it keeps the advisory queue focused on real issues. The Security Best Practices documentation is the canonical reference for the security model itself β what the framework guarantees and what the application must do β while this list only records why each pattern is repeatedly misread.
| safein the page template (nicegui/templates/index.html). Jinja auto-escaping is bypassed there intentionally; the values are escaped at the source instead (for example, element data is escaped with a table sized for theString.rawscript context it lands in). A bare| safeis not itself a finding β trace where the value comes from and how it is escaped.- Raw
innerHTMLinui.html/ui.markdown(nicegui/elements/html.js,markdown.js). The raw assignment is theelsebranch ofsanitize: the opt-insanitize=Falsepath. The default (sanitize=True) sanitizes via DOMPurify. Passing untrusted input withsanitize=Falseis the caller's documented responsibility. ui.add_head_html,ui.add_body_html,ui.run_javascript,ui.add_css. These inject raw HTML/JS/CSS by design and are documented as never-for-untrusted-input. Using them with unsanitized user data is an application bug, not a framework vulnerability.ast.literal_evalin the docs.literal_evalonly parses literals; it is the safe alternative toevalthat the documentation demonstrates.- Forging Socket.IO events with a known
client_id(nicegui/nicegui.py, theevent/javascript_response/ack/loghandlers). Theclient_idis a per-session secret capability (an unguessableuuid4), and every attack of this shape presupposes the attacker already knows it. Binding the socketsidto the client does not change this: the handshake is reached with the sameclient_id, so anyone holding it can bind their own socket. Cross-origin connections are a separate concern already addressed independently. - Guessing a
uuid4identifier (client_id, theapp.storage.userID, event-listener / Leaflet-layer / scene-object IDs). Not every ID is a secret, and the ones that are carry 122 bits of platform-CSPRNG randomness β the security documentation describes which is which. The margins do shrink as more IDs are issued, but realistic deployments stay far below either bound: at a billion IDs the collision probability is around 10^-19, and a blind guess against a million live sessions succeeds with probability around 10^-31. Assuming such an ID can simply be guessed is not a finding β a leak path, predictable generation, or a route that treats a public ID as authority is. - Code in
examples/andwebsite/. Neither the examples nor the website with its documentation demos are part of theniceguipackage. They demonstrate one mechanism in the smallest runnable form and may intentionally omit hardening, as the security documentation explains under "Examples Are Starting Points". A pattern that only becomes unsafe when an example or demo is copied and fed untrusted data is not a framework vulnerability; feel free to suggest an improvement via a regular issue or pull request instead.
If instead you have found a way around one of these protections β
an escaping bypass, or a default sanitize=True path that still executes script β
that is a real issue and we would very much like to hear about it.
Please include a reproduction.
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by creating a private security advisory (GitHub β Security β Report a vulnerability) so we can discuss and patch the issue in a secure workspace. If you cannot use GitHub, you can also send an email to: nicegui@zauberzeug.com.
Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
When filling out the advisory form:
- Use the dedicated fields for severity (CVSS vector), weaknesses (CWEs) and affected versions instead of repeating them in the description.
- Don't hard-wrap the description: GitHub renders every line break, so keep each paragraph on a single line.
- If AI tools helped to find or write up the issue, please say so in the form. That's perfectly fine, we'd just like to know.
We (the team at Zauberzeug) will review it thoroughly and get back to you.
Please restrain from publicly discussing a potential security vulnerability. π
It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
Thanks for your help!
The NiceGUI community and the Zauberzeug team thank you for that. π