Summary
Several NiceGUI APIs that execute methods on client-side elements (Element.run_method(), AgGrid.run_grid_method(), EChart.run_chart_method(), and others) use an eval() fallback in the JavaScript-side runMethod() function. When user-controlled input is passed as the method name, an attacker can inject arbitrary JavaScript that executes in the victim's browser.
Additionally, Element.run_method() and Element.get_computed_prop() used string interpolation instead of json.dumps() for the method/property name, allowing quote injection to break out of the intended string context.
Attack Vector
An attacker crafts a malicious URL with a payload as a query parameter. If the application passes this parameter as a method name to any of the affected APIs, the payload is sent to the client via WebSocket and executed via eval().
Example: /?method=alert(document.cookie) combined with application code like:
element.run_method(user_provided_method_name)
Impact
- Cookie/token theft
- DOM manipulation (phishing, fake login forms)
- Actions performed as the victim user
Affected Methods
Element.run_method()
Element.get_computed_prop()
AgGrid.run_grid_method()
AgGrid.run_row_method()
EChart.run_chart_method()
JsonEditor.run_editor_method()
Xterm.run_terminal_method()
Leaflet.run_map_method()
Leaflet.run_layer_method()
LeafletLayer.run_method()
Fix
- Use
json.dumps() for proper escaping of method/property names in run_method() and get_computed_prop()
- Remove the
eval() fallback from runMethod() in nicegui.js — method names that are not found on the element now raise an error instead of being evaluated as arbitrary JavaScript
Migration
Code that previously passed JavaScript functions as method names needs to use ui.run_javascript() instead:
# Before:
row = await grid.run_grid_method('g => g.getDisplayedRowAtIndex(0).data')
# After:
row = await ui.run_javascript(f'return getElement({grid.id}).api.getDisplayedRowAtIndex(0).data')
References
Summary
Several NiceGUI APIs that execute methods on client-side elements (
Element.run_method(),AgGrid.run_grid_method(),EChart.run_chart_method(), and others) use aneval()fallback in the JavaScript-siderunMethod()function. When user-controlled input is passed as the method name, an attacker can inject arbitrary JavaScript that executes in the victim's browser.Additionally,
Element.run_method()andElement.get_computed_prop()used string interpolation instead ofjson.dumps()for the method/property name, allowing quote injection to break out of the intended string context.Attack Vector
An attacker crafts a malicious URL with a payload as a query parameter. If the application passes this parameter as a method name to any of the affected APIs, the payload is sent to the client via WebSocket and executed via
eval().Example:
/?method=alert(document.cookie)combined with application code like:Impact
Affected Methods
Element.run_method()Element.get_computed_prop()AgGrid.run_grid_method()AgGrid.run_row_method()EChart.run_chart_method()JsonEditor.run_editor_method()Xterm.run_terminal_method()Leaflet.run_map_method()Leaflet.run_layer_method()LeafletLayer.run_method()Fix
json.dumps()for proper escaping of method/property names inrun_method()andget_computed_prop()eval()fallback fromrunMethod()innicegui.js— method names that are not found on the element now raise an error instead of being evaluated as arbitrary JavaScriptMigration
Code that previously passed JavaScript functions as method names needs to use
ui.run_javascript()instead:References