Skip to content

Commit f440dfa

Browse files
author
jie
committed
2 parents 272e910 + 6517103 commit f440dfa

2 files changed

Lines changed: 72 additions & 1 deletion

File tree

internal/processor/executor.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,15 @@ func (e *LuaExecutor) setupSandbox(L *lua.LState) {
186186
// PreloadModule 需要访问 package.preload 表
187187
L.PreloadModule("json", luajson.Loader)
188188

189+
// 兼容旧脚本中的 os.time(),但不开放 os.execute、os.remove 等危险能力。
190+
originalOS := L.GetGlobal("os")
191+
safeOS := L.NewTable()
192+
if osTable, ok := originalOS.(*lua.LTable); ok {
193+
safeOS.RawSetString("time", osTable.RawGetString("time"))
194+
}
195+
189196
// 禁用危险的标准库
190-
L.SetGlobal("os", lua.LNil) // 禁用 os 库(操作系统操作)
197+
L.SetGlobal("os", safeOS) // 仅保留安全且向后兼容的 os.time
191198
L.SetGlobal("io", lua.LNil) // 禁用 io 库(文件 IO)
192199
L.SetGlobal("dofile", lua.LNil) // 禁用 dofile
193200
L.SetGlobal("loadfile", lua.LNil) // 禁用 loadfile
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package processor
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"testing"
7+
)
8+
9+
func TestExecuteEncodeAllowsLegacyOSTime(t *testing.T) {
10+
const script = `
11+
function encodeInp(msg,topic)
12+
local json = require("json")
13+
local originCmd = json.decode(msg)
14+
15+
local output = string.format(
16+
'{"method":"%s","params":{"params":%s,"id":"%s","version":"1.0","method":"thing.service.property.set"}}',
17+
originCmd.method,
18+
json.encode(originCmd.params),
19+
tostring(os.time())
20+
)
21+
22+
return output
23+
end`
24+
25+
result, err := NewLuaExecutor().ExecuteEncode(
26+
context.Background(),
27+
script,
28+
[]byte(`{"method":"CO2","params":{"CO2":2223}}`),
29+
)
30+
if err != nil {
31+
t.Fatalf("legacy script execution failed: %v", err)
32+
}
33+
34+
var output struct {
35+
Method string `json:"method"`
36+
Params struct {
37+
ID string `json:"id"`
38+
} `json:"params"`
39+
}
40+
if err := json.Unmarshal([]byte(result), &output); err != nil {
41+
t.Fatalf("result is not valid JSON: %v", err)
42+
}
43+
if output.Method != "CO2" {
44+
t.Fatalf("unexpected method: %q", output.Method)
45+
}
46+
if output.Params.ID == "" {
47+
t.Fatal("os.time() returned an empty id")
48+
}
49+
}
50+
51+
func TestSandboxDoesNotExposeDangerousOSFunctions(t *testing.T) {
52+
const script = `
53+
function encodeInp(msg,topic)
54+
return tostring(os.execute == nil and os.remove == nil and os.getenv == nil)
55+
end`
56+
57+
result, err := NewLuaExecutor().ExecuteEncode(context.Background(), script, []byte(`{}`))
58+
if err != nil {
59+
t.Fatalf("sandbox check failed: %v", err)
60+
}
61+
if result != "true" {
62+
t.Fatalf("dangerous os functions are exposed: %q", result)
63+
}
64+
}

0 commit comments

Comments
 (0)