<feed xmlns='http://www.w3.org/2005/Atom'>
<title>luci/modules/luci-base/ucode, branch master</title>
<subtitle>Lua Configuration Interface (mirror)</subtitle>
<id>https://git.openwrt.org/project/luci/atom?h=master</id>
<link rel='self' href='https://git.openwrt.org/project/luci/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/'/>
<updated>2026-08-08T01:29:57Z</updated>
<entry>
<title>luci-base: fix lookup of non-present menu nodes</title>
<updated>2026-08-08T01:29:57Z</updated>
<author>
<name>Packet Please</name>
</author>
<published>2026-08-05T23:28:07Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=f35e6f6b7c78d62c1c3fe5584e65f6967df93861'/>
<id>urn:sha1:f35e6f6b7c78d62c1c3fe5584e65f6967df93861</id>
<content type='text'>
This surfaced when I tried developing based purely on luci-base,
without any of the status, system, or network modules.
The menu entries for these modules live in luci-base,
while the actions (templates/views) live in the respective modules.

The header.ut template renders links to these menu entries,
which fails because lookup() expects them to be present
in the menu_json structure, which they are not.
The template already anticipates that lookup() might fail,
just lookup() itself didn't seem to yet.

The resulting exception:

    Reference error
    Unhandled exception during request dispatching
    left-hand side expression is null

    In lookup(), file /usr/share/ucode/luci/dispatcher.uc, line 762, byte 24:
      called from function main (/usr/share/ucode/luci/template/themes/bootstrap/header.ut:61:51)
      called from function call ([C])
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:80:36)
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:127:40)
      called from function [arrow function] (/usr/share/ucode/luci/runtime.uc:183:57)
      called from function main (/usr/share/ucode/luci/template/header.ut:7:34)
      called from function call ([C])
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:80:36)
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:127:40)
      called from function [arrow function] (/usr/share/ucode/luci/runtime.uc:183:57)
      called from function main (/usr/share/ucode/luci/template/view.ut:1:20)
      called from function call ([C])
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:80:36)
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:127:40)
      called from function [arrow function] (/usr/share/ucode/luci/runtime.uc:141:63)
      called from function render ([C])
      called from function [anonymous function] (/usr/share/ucode/luci/runtime.uc:141:64)
      called from function run_action (/usr/share/ucode/luci/dispatcher.uc:815:47)
      called from function [anonymous function] (/usr/share/ucode/luci/dispatcher.uc:1107:48)
      called from anonymous function (/usr/share/ucode/walter/web/index.uc:47:15)

              node = node.children[name];
      Near here -------------------^

Signed-off-by: Packet Please &lt;pktpls@systemli.org&gt;
</content>
</entry>
<entry>
<title>themes: fix custom CSS via menu.d node</title>
<updated>2026-08-07T23:33:25Z</updated>
<author>
<name>Packet Please</name>
</author>
<published>2026-08-07T16:27:26Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=7c6d8ff7f8b894d1c8c3382af4b79b7cea68c709'/>
<id>urn:sha1:7c6d8ff7f8b894d1c8c3382af4b79b7cea68c709</id>
<content type='text'>
The themes have supported custom CSS via menu.d nodes since they
were first ported to ucode. There were two little problems though:

- The css property wasn't added to the node schema in luci.dispatcher.
- The themes used the wrong variable name.

The advantage is that the client will load the custom CSS right away,
instead of later when the view initializes. In my local development,
it has prevented visual flickering on page load.

Example menu.d entry:

    "falter": {
      "title": "Settings",
      "order": 5,
      "action": {
        "type": "view",
        "path": "falter/settings"
      },
      "css": "view/falter/falter.css"
    }

There are lots of potential users for this, since many Luci applications
inject their CSS via client-side JS. Even luci-mod-network does.

Signed-off-by: Packet Please &lt;pktpls@systemli.org&gt;
</content>
</entry>
<entry>
<title>luci-base: drop init_action() and the luci.setInitAction ubus method</title>
<updated>2026-08-03T09:58:22Z</updated>
<author>
<name>Julius Bairaktaris</name>
</author>
<published>2026-08-02T00:41:03Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=4440b267ddef05b13b09c7c31ef7eba2401d2651'/>
<id>urn:sha1:4440b267ddef05b13b09c7c31ef7eba2401d2651</id>
<content type='text'>
Both duplicate rpcd's rc ubus namespace, which exposes the same
enable/disable/start/stop/restart/reload set through rc.init and is what
downstream code wishing to control services should be using.

The duplicate was also the weaker of the two. init_action() interpolated
both of its arguments into a shell command run as root:

    system(`env -i /etc/init.d/${basename(name)} ${action} &gt;/dev/null`);

basename() kept name inside /etc/init.d, but it strips directory
components only - `;`, backticks, `$(`, `|` and newlines survive it -
and action reached the shell with nothing checking it at all. Nothing
untrusted got there: setInitAction switched on a fixed action list, and
for name the stat() gate required the interpolated string to exist as a
file under /etc/init.d, an existence check rather than a validation.
But init_action() was exported from luci-base, so any future caller
forwarding an RPC argument straight through inherited root command
execution.

rc.init has no shell to escape from - it execs the script - and it
additionally refuses scripts that are not root-owned or that are
world-writable.

The in-tree users are ported in the preceding commits.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris &lt;julius@bairaktaris.de&gt;
</content>
</entry>
<entry>
<title>luci-base: dispatcher: derive session token from /dev/urandom</title>
<updated>2026-08-01T15:19:39Z</updated>
<author>
<name>Julius Bairaktaris</name>
</author>
<published>2026-08-01T02:27:18Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=df71c660192bae5d4d0c2102bba121f3c916b6a5'/>
<id>urn:sha1:df71c660192bae5d4d0c2102bba121f3c916b6a5</id>
<content type='text'>
randomid() built the session token from math.rand(). ucode seeds that generator
on first use with the wall-clock time in milliseconds and then uses libc rand():

    if (!ucv_boolean_get(uc_vm_registry_get(vm, "math.srand_called"))) {
        gettimeofday(&amp;tv, NULL);
        srand((tv.tv_sec * 1000) + (tv.tv_usec / 1000));

Each request is served by a fresh process, so the seed is the millisecond the
request was handled, and randomid() is the first consumer of the generator in
that process. The resulting token is predictable to anyone who knows the
approximate time it was issued.

Read the bytes from /dev/urandom instead, via readfile() + hexenc() - the same
shape luci.sys.uniqueid() already uses. readfile() switches the stream to
_IONBF for a limit below BUFSIZ, so it issues a single 16-byte read rather than
draining a 4096-byte stdio buffer out of the pool.

Return null on a short or failed read so callers fail closed rather than fall
back to a weak value: session_retrieve() requires a string token, so a session
created without one is rejected.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris &lt;julius@bairaktaris.de&gt;
</content>
</entry>
<entry>
<title>luci-base: update timezone data to 2026c</title>
<updated>2026-07-28T20:27:58Z</updated>
<author>
<name>Hannu Nyman</name>
</author>
<published>2026-07-28T20:25:41Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=77046b7d002ee3c4dcc10548e6ae10fce3115757'/>
<id>urn:sha1:77046b7d002ee3c4dcc10548e6ae10fce3115757</id>
<content type='text'>
Update timezone data to 2026c.
  Alberta moved to permanent -06 on 2026-06-18.
  Morocco moves to permanent +00 on 2026-09-20.

Signed-off-by: Hannu Nyman &lt;hannu.nyman@iki.fi&gt;
</content>
</entry>
<entry>
<title>luci-base: dispatcher.uc: escape URL path and username when logging</title>
<updated>2026-07-20T19:24:28Z</updated>
<author>
<name>Liangbin Lian</name>
</author>
<published>2026-07-01T13:14:09Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=4021b549d77bf197923aecb6329381304c99d34d'/>
<id>urn:sha1:4021b549d77bf197923aecb6329381304c99d34d</id>
<content type='text'>
Prevent maliciously crafted login requests from polluting the logs.

Signed-off-by: Liangbin Lian &lt;jjm2473@gmail.com&gt;
</content>
</entry>
<entry>
<title>luci-base: fix redirect after login when request path is empty</title>
<updated>2026-06-27T23:17:20Z</updated>
<author>
<name>Maxim Skokov</name>
</author>
<published>2026-06-27T13:16:31Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=a9cddc1e18b1d5730954f7b3e2727c944fe583ce'/>
<id>urn:sha1:a9cddc1e18b1d5730954f7b3e2727c944fe583ce</id>
<content type='text'>
When accessing LuCI via /cgi-bin/luci/ without a full path,
ctx.request_path is empty and login redirects back to the root
URL instead of the resolved page. Fall back to ctx.path which
holds the resolved firstchild route.

Fixes openwrt/luci#8534.

Signed-off-by: Maxim Skokov &lt;skokov.m020709@gmail.com&gt;
</content>
</entry>
<entry>
<title>luci-base: update timezone data to 2026b</title>
<updated>2026-06-04T18:36:06Z</updated>
<author>
<name>Hannu Nyman</name>
</author>
<published>2026-06-04T18:36:06Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=b1edcd15c742226b5c76d78d341983e7e098ae76'/>
<id>urn:sha1:b1edcd15c742226b5c76d78d341983e7e098ae76</id>
<content type='text'>
Update timezone data to 2026b.

* British Columbia moved to permanent -07 on 2026-03-09.

Signed-off-by: Hannu Nyman &lt;hannu.nyman@iki.fi&gt;
</content>
</entry>
<entry>
<title>luci-base: add authentication plugin mechanism</title>
<updated>2026-04-09T12:26:09Z</updated>
<author>
<name>Han Yiming</name>
</author>
<published>2026-01-29T09:23:37Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=4a308bab378851272d1795d14c624bc0a2250491'/>
<id>urn:sha1:4a308bab378851272d1795d14c624bc0a2250491</id>
<content type='text'>
This commit introduces a generic authentication plugin mechanism
to the LuCI dispatcher, enabling multi-factor authentication
(MFA/2FA) and other custom verification methods without
modifying core files.

This implementation integrates with the new plugin UI architecture
introduced in commit 617f364 (luci-mod-system: implement plugin UI
architecture), allowing authentication plugins to be managed
through the unified System &gt; Plugins interface.

Signed-off-by: Han Yiming &lt;moebest@outlook.jp&gt;
</content>
</entry>
<entry>
<title>luci-base: implement http header plugins</title>
<updated>2026-03-30T22:13:54Z</updated>
<author>
<name>Paul Donald</name>
</author>
<published>2026-03-15T18:18:33Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/luci/commit/?id=ba0051729a283c69daae0671418ae0e2b563081c'/>
<id>urn:sha1:ba0051729a283c69daae0671418ae0e2b563081c</id>
<content type='text'>
This implements the injection of custom http headers via
the new plugin architecture.

Signed-off-by: Paul Donald &lt;newtwen+github@gmail.com&gt;
</content>
</entry>
</feed>
