自动转义与安全 Auto Escape Security
DouView 在设计上把「模板只做展示、不承接任意代码」贯彻到每一处,并提供了全局自动转义与一系列编译期 / 运行期安全约束。
一、全局自动 HTML 转义
引擎可开启 escapeHtml 开关(DouView::setEscapeHtml(true),默认关闭)。开启后:
- 所有
{$var}输出自动经htmlspecialchars(..., ENT_QUOTES, 'UTF-8')转义; - 已带
|escape修饰器的输出不重复转义; - 追加
nofilter标志的输出不转义(如{$html nofilter})。
判定公式:escapeHtml && !nofilter && !已含转义修饰器 时才自动转义。{url} 同样受此约束。
二、安全约束总览
| 约束 | 机制 |
|---|---|
| 禁止原生 PHP | {php} 编译期报 php tags not permitted;文本中 <? / ?> / language=php 自动转义为字面 |
| 禁止对象成员 | -> 访问在模板中不允许(编译期报错) |
module 必须字面量 |
{list} / {category} 的 module 必须为字面标识符,禁止运行时变量,防止请求参数注入模块名 |
sort 白名单 |
{list} 的 sort 仅接受 字段 ASC\|DESC 序列,否则回退默认,防 ORDER BY 注入 |
include 资源名校验 |
禁止 .. / 绝对路径 / 盘符,扩展名须在白名单,越界校验 |
{if} 禁函数调用 |
条件中禁止函数调用与变量函数调用 |
| 路径穿越防护 | resolveTemplatePath 统一拦截(见下) |
三、resolveTemplatePath 路径防护
所有模板资源名({include} 的 file、view() 参数)都经 resolveTemplatePath 解析,它依次拦截:
- 包含
..或空字节(含 urldecode 后再查一次); - 扩展名不在白名单(
.tpl/.htm/.html/.dwt); - 绝对路径 / 盘符 / 多连续分隔符;
- 解析后的真实路径不在
template_dir内(带分隔符前缀比较,防同前缀兄弟目录误通过)。
任一命中即返回 false,模板不会被渲染。
四、输出安全的实践建议
- 默认转义优先:若站点开启了
escapeHtml,大多数{$var}无需额外处理即安全; - 只对可信 HTML 用 nofilter:如内容渲染器产出的正文(
{$article.content nofilter}); - 用户输入绝不直出:对任何未经净化的用户数据,切勿
nofilter直出,否则造成 XSS;需要展示时用默认转义或|escape; - 链接用
{url}:不要手工拼接用户输入到 URL;{url}的结果在开启转义时会被正确转义。