Skip to content

fix(security): anchor Lua-supplied script paths inside game dir#49

Open
Taure wants to merge 5 commits into
mainfrom
security/path-traversal-2026-05-19
Open

fix(security): anchor Lua-supplied script paths inside game dir#49
Taure wants to merge 5 commits into
mainfrom
security/path-traversal-2026-05-19

Conversation

@Taure
Copy link
Copy Markdown
Contributor

@Taure Taure commented May 19, 2026

Closes the single High finding from the 2026-05-19 security audit.

Summary

asobi_lua_config:build_modes_from_manifest/2 and maybe_add_bots/3 both fed Lua-supplied path strings (config.lua mode->script entries, match.lua's bots.script) into filename:join then on to file:read_file + Lua eval. A stray "../" in those strings could load any readable file as Lua. The body still runs under the sandbox so OS syscalls are blocked, but it has full game.* access and can exfiltrate state via broadcast/storage.

The new safe_join/2 helper:

  • Rejects empty / absolute / /-starting / .. / . / empty-segment paths.
  • Normalises via filename:absname and asserts the result is prefixed by the absolute base directory + /.
  • Returns {ok, AbsPath} on success, {error, Reason} otherwise.

Applied at both call sites. maybe_add_bots now logs and skips the bot config when the path is rejected, rather than crashing the loader.

Test plan

  • 9 new tests in asobi_lua_config_path_tests.erl covering: valid relative, nested, .., nested-.., absolute, empty, ., //, trailing slash on base
  • rebar3 eunit — 225 tests, 0 failures
  • rebar3 fmt --check, xref, dialyzer clean
  • elp eqwalize-all — no new errors from this change (45 pre-existing remain across other modules)
  • elp lint --module asobi_lua_config — no new warnings

What is NOT in this PR

The audit's 3 Medium and 4 Low findings are deferred. Top items:

  • M2 — strip debug.* from the sandbox (one-line addition to strip_dangerous_globals/1)
  • M3 — do_with_timeout_results/3 should use spawn_opt with max_heap_size like bounded_eval/2
  • M1 — soft reduction cap on handle_input (needs benchmarking vs ADR 0002)

Taure added 5 commits May 19, 2026 22:59
H1 (2026-05-19 audit): asobi_lua_config:build_modes_from_manifest/2 and
maybe_add_bots/3 both fed unmodified config.lua/match.lua path strings
into filename:join, then to file:read_file + Lua eval. A stray "../" in
config.lua's mode->script table (or in match.lua's bots.script) could
load any readable file as Lua. Body runs under the sandbox so OS syscalls
are still blocked, but the file body has full game.* access and can
exfiltrate state via broadcast/storage.

Fix: new safe_join/2 helper that

  * rejects empty / absolute / "/"-starting / ".." / "." / empty-segment paths
  * normalises via filename:absname and asserts the result is prefixed by
    the absolute base directory + "/"
  * returns {ok, AbsPath} on success, {error, Reason} otherwise

Applied at both call sites. maybe_add_bots now logs and skips the bot
config when the path is rejected, rather than crashing the loader.

Audit doc: docs/security_audit_2026_05_19.md.
LOW-severity advisory against cow_cookie:cookie/1 with no upstream
patch. asobi_lua only pulls cowboy transitively for the lua_match HTTP
hand-off and never calls cow_cookie:cookie/1 directly. Tracked in
docs/security_audit_2026_05_19.md.

Requires Taure/erlang-ci#62 (audit-ignores input). Temporarily pinned
to the feature branch SHA.
GHSA-jfc2-q6qh-g5x8 (HIGH, multipart header buffer accumulation) hits
cowboy versions >= 2.0.0, < 2.15.0. asobi_lua was inheriting the stale
2.13.0 pin transitively. Direct-pin cowboy 2.15.0 plus the standard
cowlib/ranch override so rebar3 can resolve the package's "and"-syntax
dep declarations.

rebar3 audit -i GHSA-g2wm-735q-3f56 now reports 0 vulnerabilities (was
1: cowboy 2.13.0 HIGH).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant