我有TeX Live 2019安装在我的服务器上并从乳胶-使用服务器端脚本语言(PHP 7)的模板。我必须从数据库插入数据(不可信数据)以及一些来自用户的数据(也不可信数据)到该模板(动态乳胶文档)然后将其编译为 PDF。这些数据用于表格、标题和文本等。我不能对字符使用黑名单/白名单方法,因为用户应该能够使用全部其中。
我该如何逃避不可信数据这样,所有 UTF-8 字符以及在乳胶仍然有效(ä、ö、ü、á、ß、°、\、%`...)?有没有类似的东西原产地保护组织适用于 LaTeX?我熟悉verbatim
软件包,但根据我的经验,它不能 100% 保证人们无法绕过这种保护(在“防御攻击”中纸)。
以下是我想出的角色替换列表(不完整):
您可能已经可以想象到替换字符存在问题 - 因为它应该按照正确的顺序进行,并且需要非常小心地进行,这样才无法绕过它。
LaTeX-Injection 文章:
答案1
您所描述的基本上只是逐字输入,没有用户可访问的分隔符。您可以使用逐字参数定义命令,例如使用xparse
。(使用编译LuaLaTeX为了避免编码问题):
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\untrustedInput{+v}{#1}
\begin{document}
\untrustedInput|Do don't have to trust this input. This can be \something_evil
and everything is just interpreted as text.|
\end{document}
在此示例中,逐字块由 分隔,+
这当然是不安全的,因为不受信任的数据可能包含+
。但您可以使用任何代码点作为分隔符,因此只需选择输入中不允许的代码点。无效的 Unicode 代码点就是一个很好的候选者,如U+D800
(UTF-8 编码为0xED 0xA0 0x80
)您可以先扫描输入以查找此字节序列。如果出现,则编码无效,您可以直接发出错误。(U+D800 是 UTF-16 高代理,在 UTF-8 数据中绝不允许使用)否则,将三个字节放在0xED 0xA0 0x80
输入的两侧,并将文本作为 的参数传递\untrustedInput
给 LuaTeX。(只要您不尝试实际排版它,LuaTeX 就不会关心 D800 是否无效。)
该命令\untrustedInput
将无法在其他参数中使用。这无法直接避免,因为其他参数会首先尝试解释文本,可能会解释危险字符。但您可以使用该命令将不受信任的文本保存到可以自由使用的宏中:(再次使用 示例+
)
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\defineWithUntrustedInput{m +v}{\newcommand#1{#2}}
\begin{document}
\defineWithUntrustedInput\theText+Do don't have to trust this input. This can be \something_evil
and everything is just interpreted as text.+
\textit{\theText}
\end{document}
答案2
LuaLaTeX 的简单入门:
请注意,这有很多注意事项:除空格(catcode 10)外,所有内容都是 catcode 12。正如您将在此示例中看到的,段落将被忽略。许多字符将取决于您使用的字体。但同样,这只是一个入门级示例。
% arara: lualatex
\documentclass{article}
\newcommand\getmyevildatabase{%
\directlua{
local file = io.open("evil.txt")
if file then
local content = file:read("*all")
file:close()
tex.print(-2, content)
end
}}
\begin{document}
Test here
\getmyevildatabase
Another test
\end{document}
使用 evil.txt:
This \bye test is evil ? ^ ²³¼ þ Þ ’¢“„ % {quack}
¿?