Repository navigation
fix: Lua m.setvar() returned -1 or a status, handing the script stack values (v2) - #3736
Conversation
… values
l_setvar() returned -1 on its error paths (wrong number of arguments,
no collection in the name) and the status of
msre_action_setvar_execute() otherwise. A lua_CFunction returns the
number of values it pushed, so Lua handed the script whatever was on
the stack; on success m.setvar("tx.a", "x") returned "x". Always return
0 so the script gets nil.
Also drop the NULL check after luaL_checkstring(), which raises a Lua
error instead of returning NULL, and fix the typo in the debug message.
v2 counterpart of owasp-modsecurity#3731.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RiUJuqXNvvpytiGRiDFyTy
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
|
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for the Lua m.setvar() return-handling fix.
No open issues 🎉
What changed in this PR
Fixes ModSecurity v2’s Lua m.setvar() return handling, addressing the v2 counterpart of #3731 without changing variable-setting behavior.
Changes:
- Returns zero Lua results on success and validation failures, preventing stack values from reaching scripts.
- Removes an unreachable null check and corrects the argument-count diagnostic.
- Adds regression coverage for missing collections, incorrect argument counts, and successful TX variable updates.
| File | Description |
|---|---|
tests/regression/server_root/conf/setvar-tx.lua |
Logs the return value and updated TX variable for verification. |
tests/regression/server_root/conf/setvar-error-onearg.lua |
Exercises a call with a missing argument. |
tests/regression/server_root/conf/setvar-error-nodot.lua |
Exercises a variable name without a collection. |
tests/regression/rule/00-script.t |
Adds assertions for all three Lua regression cases. |
apache2/msc_lua.c |
Corrects return counts, removes the unreachable check, and fixes diagnostic wording. |
Review effort: Balanced

what
Fixes the return values of
l_setvar()(apache2/msc_lua.c), the v2 implementation of Luam.setvar():0instead of-1.0instead of the status ofmsre_action_setvar_execute().NULLcheck afterluaL_checkstring()is removed: it can't trigger, becauseluaL_checkstring()raises a Lua error instead of returningNULL.why
A
lua_CFunctionreturns the number of values it pushed, so Lua handed the script whatever was on the stack.msre_action_setvar_execute()returns1. On unpatched v2/master,local r = m.setvar("tx.a", "x")therefore givesr == "x".-1is undefined behaviour in Lua's call machinery. v3: Lua m.setvar() returns -1 on errors, so the script gets stack garbage #3731 shows the v3 equivalent handing the script the transaction pointer.The
lua_pop(L, 2)stays. Unlike in v3, it pops the__msrand__ruleglobals thatl_setvar()pushed, not the arguments, sovar_valuestays valid.tests
There are three new cases in
tests/regression/rule/00-script.t, with the scripts inserver_root/conf/(force-added, liketest.luaandmatch.lua, because that directory is in.gitignore):nil;nil;TXset, which must returnniland settx.a.Tested in Docker (Ubuntu 24.04, Apache 2.4.58, Lua 5.1.5):
rule/00-script.tgives 6 passed and 0 failed. With themsc_lua.cchange reverted, all three new cases fail.references
🤖 Generated with Claude Code