服务端模板注入(SSTI)防护与代码审计指南概述SSTI源于在模板引擎中拼接不可信输入。通过白名单、表达式禁用与安全渲染封装,可有效降低风险。安全渲染封装type TemplateEngine = { render: (tpl: string, data: Record<string, any>) => string }
const allowedTemplates = new Set(['welcome', 'invoice'])
function safeRender(engine: TemplateEngine, name: string, data: Record<string, any>): string {
if (!allowedTemplates.has(name)) throw new Error('template_not_allowed')
return engine.render(name, sanitizeData(data))
}
function sanitizeData(data: Record<string, any>): Record<string, any> {
const out: Record<string, any> = {}
for (const [k, v] of Object.entries(data)) {
out[k] = typeof v === 'string' ? v.replace(/[<>$`]/g, '') : v
}
return out
}
表达式禁用示例(以Jinja/Twig类引擎为例)禁止模板中使用:eval、exec、system、include不受控路径、反射访问
禁用过滤器:attr、tojson(未经处理情况下)
上下文隔离type RenderContext = { user: { id: string; role: string }; vars: Record<string, string> }
function buildContext(userId: string, role: string, vars: Record<string, string>): RenderContext {
return { user: { id: userId, role }, vars: allowVars(vars) }
}
function allowVars(vars: Record<string, string>): Record<string, string> {
const allow = ['orderId', 'date']
const out: Record<string, string> = {}
for (const k of allow) if (vars[k]) out[k] = vars[k]
return out
}
代码审计清单搜索不可信输入直接拼接到模板:`render(… userInput …)`检查模板指令与过滤器使用是否在白名单内对动态模板选择与路径进行白名单与签名校验运维要点模板选择与变量来源全部白名单与签名校验禁用危险表达式与反射访问,开启沙箱模式在CI进行静态审计,并在运行时记录渲染上下文与异常通过白名单封装、表达式禁用与上下文隔离,可在常见后端模板场景下有效防护SSTI。

发表评论 取消回复