Open security reports in luci, packages and routing

Jo-Philipp Wich jo at mein.io
Sun Jun 28 04:54:50 PDT 2026


Hi,

many of the LuCI reported issues are systemic and not easily fixable, if at all.

They roughly fall into four categories:

1) simple shell injection; many packages ship ad-hoc rpcd ubus plugins which
    provide methods that end up calling various commands to scrape info from,
    passing user input as shell arguments without proper escaping - commonly
    in the form 'fs.popen(`/usr/bin/somecomannd ${some_ubus_arg}`)' which is
    a textbook injection; I'll fix these case by case and work on an improved
    popen() implementation in ucode which takes an array command vector to
    make it easier to write safe code, e.g.
    `fs.popen(['/usr/bin/somecommand', some_ubus_arg])`

2) stored XSS; external sources or saved uci values providing some kind of
    freetext description field (e.g. DHCP hostnames, UPnP lease descriptions)
    which are then output as-is without additional HTML escaping, leading to
    XSS. I'll fix these case by case.

3) stored command privilege escalation; many packages support specifying
    arbitrary command hooks in their uci configuration. Even if a restricted
    user context is set up which is only allowed to read and write the uci
    configuration of a particular package (e.g. ddns-scripts), the restricted
    user can set an arbitrary command (e.g. ddns-scripts `ip_script` option)
    which ends up being executed as root by the packages init script or some
    event handler. These class of bugs cannot be reasonably fixed in LuCI and
    require a general rearchitecturing of the backend package, e.g. by dropping
    support for command hooks, using restricted user contexts, some sort of
    jailing, pre-approved whitelists etc.

4) newline injections; many init script implementations translate uci to
    native configuration without actually validating the values, allowing users
    to plant uci values which end up being written as additional options, e.g.
    `option 'foo' 'value\nbar value2'` would be written as
       foo = value
       bar = value2
    into the ephemeral native configuration, allowing a uci write privileged
    user to inject arbitrary native settings, even those deliberately left out
    from uci for e.g. security reasons. If a process happens to support options
    taking shell commands to excecute or files to read from/write to, chances
    are high that those end up getting executed as root on the next service
    restart.


While class 1 and 2 issues are simple web develpoment things we have to take 
care of, class 3 and 4 ones are systemic problems which require a concerted 
effort in the entire OpenWrt and packages ecosystem to solve. Fixing those 
entails migrating packages to non-root users, jailing, restructuring 
configuration, auditing uci translations, introducing safe by default behavior 
(e.g. let config_get fail for values with newlines/other problematic chars and 
introduce a config_get_unsafe or similar for those rare cases where such 
values are allowed.


Regards,
Jo



More information about the openwrt-devel mailing list