session: make rpc_session_get() a pure lookup and add "notouch" to session/access - #39
Open
micpf wants to merge 1 commit into
Open
session: make rpc_session_get() a pure lookup and add "notouch" to session/access#39micpf wants to merge 1 commit into
micpf wants to merge 1 commit into
Conversation
…ssion/access
The rpcd session idle timer (sessiontime) is meant to expire a session
after N seconds of inactivity, but it is currently refreshed by every
"session get" and "session access" ubus call, and by every RPC in every
loadable plugin (uci, luci-rpc, ...) that calls rpc_session_access() to
verify permissions. Because LuCI polls its status pages every few
seconds, the timer is refreshed continuously and never expires: the
"idle timeout" behaves as an absolute session lifetime instead.
Split the two concerns:
* rpc_session_get() becomes a pure AVL lookup with no side effects.
All internal lookups (uci/luci-rpc permission checks, session data
accessors, etc.) no longer keep the session alive on their own.
* The top-level session/access ubus method is the only path that
still touches the session, and it does so only when the new
optional "notouch" boolean argument is absent or false. Callers
that want to distinguish real user activity from background
polling (uhttpd's /ubus/ handler when it sees LuCI's _luci_bg=1
marker) pass notouch=1 and the timer keeps counting down.
The rpcd HTTP entry point (uhttpd) already invokes session/access on
every request to authorise the call, so it stays the single natural
"keep alive" signal for the session -- exactly what an idle timeout
needs -- without duplicating touches from every downstream plugin.
The "notouch" argument is optional and defaults to false, so existing
callers see no behaviour change.
Signed-off-by: Michael Pfeifroth <micpf@westermo.com>
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
option sessiontimeidle timeout in/etc/config/rpcdnever fires when LuCI is open. Every LuCI page runs periodicPollcallbacks that issue ubus RPCs; every RPC goes throughsession/access, and every plugin (uci, luci-rpc, …) that calls the exportedrpc_session_access()for its own ACL checks also touches the session viarpc_session_get(). The idle timer is refreshed continuously, so it behaves as an absolute session lifetime instead.Reproduce (unpatched):
uci set rpcd.@rpcd[0].sessiontime='30'; /etc/init.d/rpcd restart, log in to LuCI, leave the Overview page open. The session never expires.Fix
Split lookup from touch:
rpc_session_get()becomes a pure AVL lookup with no side effects. Internal callers (uci/luci-rpc permission checks, session data accessors) no longer keep the session alive on their own.session/accessubus method remains the single natural "keep alive" signal – it is invoked by uhttpd on every request. It refreshes the idle timer unless the caller passes the new optionalnotouch=trueargument.The companion uhttpd change forwards this hint when LuCI marks the request as a background poll (see openwrt/uhttpd#39), and LuCI marks its own polls (see openwrt/luci#8916).
notouchdefaults to false, so existing callers see no behaviour change.Threat model note
The
notouchhint does not weaken the idle timer's security properties. Any code running with a valid session cookie can already keep the session alive by omitting the hint, or by synthesising fake user activity to trigger real XHRs. The idle timer defends against the "walked-away-from-the-terminal" case (unattended authenticated browser), not against code executing inside the authenticated origin. Today that defence is silently disabled by LuCI's polling; this PR restores it.Related PRs
_luci_bg=1query flag asnotouch_luci_bg=1Land in order rpcd → uhttpd → luci. Each is independently ABI-compatible with older peers (
notouchdefaults to false; unknown query params ignored; unknown blob keys ignored).