openwrt/luci

luci-base: Bug in resolve_firstchild results in 403 Forbidden

mikma opened this issue · 2 comments

A bug in resolve_firstchild means it may return a page the user hasn't access to causing 403 Forbidden, A patch which fixes the bug is included at the bottom.

The following can reproduce the problem:

  1. Create a user such as test in the openwrt shell, and set the password (the script below expects "test"):
echo "test::0:0:99999:7:::" >> /etc/shadow
echo "test:x:1047:100:Test user:/tmp:/bin/false" >> /etc/passwd
passwd test
  1. Add a login section to rpcd for the user:
uci batch <<EOF
add rpcd login
set rpcd.@login[-1].username='test'
set rpcd.@login[-1].password='\$p\$test'
add_list rpcd.@login[-1].read='unauthenticated'
add_list rpcd.@login[-1].read='luci-base'
commit rpcd
EOF
  1. Add a menu item:
cat > /usr/share/luci/menu.d/test-acl.json <<EOF
{
	"admin/system/test-acl": {
		"title": "Test ACL",
		"order": 100,
		"action": {
			"type": "template",
			"path": "test_acl"
		}
	}
}
EOF
  1. Add a page template:
cat > /usr/share/ucode/luci/template/test_acl.ut <<EOF
{% include('header') %}

<p>Hello World</p>

{% include('footer') %}
EOF
  1. Run the following function with the hostname/IP address as the argument:
run_test() {
        hostname=$1
        tmpfile=$(mktemp)
	cookiefile=$(mktemp)

	curl --silent --cookie-jar $cookiefile --location --data-urlencode "luci_username=test" --data-urlencode "luci_password=test"  "http://$hostname/cgi-bin/luci/" > $tmpfile

	if ! grep "Hello World" $tmpfile >/dev/null; then
		echo "Test FAILED"
	else
		echo "Test PASSED"
	fi

	rm "$tmpfile"
	rm "$cookiefile"
}

run_test 192.168.0.1

Actual behavior:
Test FAILED

Expected behavior:
Test PASSED

Additional Information:

OpenWrt version information from system /etc/openwrt_release

DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='SNAPSHOT'
DISTRIB_REVISION='r27041-7686ce4a91'
DISTRIB_TARGET='x86/64'
DISTRIB_ARCH='x86_64'
DISTRIB_DESCRIPTION='OpenWrt SNAPSHOT r27041-7686ce4a91'
DISTRIB_TAINTS=''

Patch

--- /usr/share/ucode/luci/dispatcher.uc.orig	2024-07-30 19:31:27.890643889 +0000
+++ /usr/share/ucode/luci/dispatcher.uc	2024-07-30 19:31:39.122534632 +0000
@@ -582,7 +582,7 @@
 			session = is_authenticated(node.auth);
 
 		let cacl = child.depends?.acl;
-		let login = login_allowed || child.auth?.login;
+		let login = !session && (login_allowed || child.auth?.login);
 
 		if (login || check_acl_depends(cacl, session?.acls?.["access-group"]) != null) {
 			if (child.title && type(child.action) == "object") {

Another user posted a question about the the same problem in the forum last year:

Luci JS: How to Prevent the Root URL from Opening an ACL-Restricted Item

jow- commented

Fixed, thanks!