17

We implemented the online service where it is possible to generate PDF with predefined structure. The user can choose a LaTeX template and then compile it with an appropriate inputs.

The question we worry about is the security, that the malicious user was not able to gain shell access through the injection of special instruction into latex document.

We need some workaround for this or at least a list of special characters that we should strip from the input data.

Preferred language would be PHP, but any suggestions, constructions and links are very welcomed.

PS. in few word we're looking for mysql_real_escape_string for LaTeX

4

5 回答 5

17

这是一些实现 Geoff Reedy 答案的代码。我将此代码放在公共领域。

<?

$test = "Test characters: # $ % & ~ _ ^ \ { }.";
header( "content-type:text/plain" );
print latexSpecialChars( $test );
exit;

function latexSpecialChars( $string )
{
    $map = array( 
            "#"=>"\\#",
            "$"=>"\\$",
            "%"=>"\\%",
            "&"=>"\\&",
            "~"=>"\\~{}",
            "_"=>"\\_",
            "^"=>"\\^{}",
            "\\"=>"\\textbackslash",
            "{"=>"\\{",
            "}"=>"\\}",
    );
    return preg_replace( "/([\^\%~\\\\#\$%&_\{\}])/e", "\$map['$1']", $string );
}
于 2011-03-24T17:00:07.827 回答
3

使用 LaTeX 执行有害操作的唯一可能性(AFAIK)是启用使用\write18. 这仅在您使用 --shell-escape 或 --enable-write18 参数(取决于您的发行版)运行 LaTeX 时才有效。

因此,只要您不使用这些参数之一运行它,您就应该是安全的,无需过滤掉任何部分。

除此之外,您仍然可以使用\newwrite,\openout\write命令写入其他文件。让用户创建和(覆盖)写入文件可能是不需要的?因此,您可以过滤掉这些命令的出现。但是保留某些命令的黑名单很容易失败,因为不怀好意的人可以通过混淆输入文档来轻松隐藏实际命令。

编辑:使用受限帐户运行 LaTeX 命令(即不写入非乳胶/项目相关目录)结合禁用\write18可能比保留“危险”命令的黑名单更容易和更安全。

于 2010-03-29T22:46:04.617 回答
3

一般来说,纯粹通过转义命令序列来实现安全性很难在不大大降低表达性的情况下实现,因为没有原则性的方法可以区分安全的 cs 和不安全的 cs:Tex 不是一种足够干净的编程语言来允许这样做。我会说放弃这种方法,以消除安全漏洞的存在。

Veger 对 Latex 中的安全漏洞的总结与我的一致:即问题是 shell 转义和文件创建。覆盖,尽管他错过了一个 shell 转义漏洞。以下是一些附加点,然后是一些建议:

  1. 避免主动调用是不够的--shell-escape,因为它可以在 texmf.cnf 中隐式启用。您应该显式传递--no-shell-escape以覆盖 texmf.cnf;
  2. \write18是 Etex 的原语,而不是 Knuth 的 Tex。所以你可以避免实现它的乳胶(不幸的是,大多数乳胶都是);
  3. 如果您使用 Dvips,还有另一个风险:\special命令可以创建 .dvi 文件,要求 dvips 执行 shell 命令。因此,如果您使用 dvips,则应该传递-R2命令以禁止调用 shell 命令;
  4. texmf.cnf 允许你指定 Tex 可以在哪里创建文件;
  5. 如果您希望您的客户在创建字体时有很大的自由度,您可能无法避免禁用字体的创建。查看Kpathsea 的安全说明;默认行为对我来说似乎是合理的,但是您可以拥有一个每个用户的字体树,以防止一个用户踩到另一个用户的脚趾。

选项:

  1. 将客户的 Latex 调用沙箱化,并允许他们在沙箱中自由地行为不端;
  2. 信任 kpathsea 的默认设置,并禁止在 Latex 和任何其他用于构建 PDF 输出的可执行文件中进行 shell 转义;
  3. 大幅降低表现力,禁止您的客户创建字体文件或任何新的客户指定文件。将latex作为只能写入某些已经存在的文件的进程运行;
  4. 您可以创建一个格式文件,其中\write18不绑定 cs 和文件创建 css,并且只存在安全调用它们的宏,例如用于创建 font/toc/bbl 的宏。这意味着你必须决定你的客户有什么功能:他们不能自由选择他们导入的包,但必须利用你强加给他们的选择。根据您想到的“模板”类型,这可能是一个不错的选择,允许使用使用 shell 转义的包,但您需要审核进入格式文件的 Tex/Latex 代码。

后记

有一篇 TUGBoat 文章,基于 LATEX 模板的服务器端 PDF 生成,解决了我所采取的另一个问题,即使用 Latex 从表单输入生成 PDF。

于 2010-03-30T08:17:30.137 回答
2

根据http://www.tug.org/tutorials/latex2e/Special_Characters.html,乳胶中的特殊字符是# $ % & ~ _ ^ \ { }. 大多数可以用一个简单的反斜杠转义,但_ ^需要\特殊处理。

用于插入符号\^{}(或\textasciicircum)、用于波浪号\~{}(​​或\textasciitilde)和用于反斜杠\textbackslash

如果您希望用户输入显示为打字机文本,还有\verb可以使用的命令,如\verb+asdf$$&\~^++可以是任何字符但不能在文本中。

于 2010-03-29T22:46:57.907 回答
0

You'd probably want to make sure that your \write18 is disabled.

See http://www.fceia.unr.edu.ar/lcc/cdrom/Instalaciones/LaTex/MiKTex/doc/ch04s08.html and http://www.texdev.net/2009/10/06/what-does-write18-mean/

于 2010-03-29T22:26:50.487 回答