如何安全地提取不受信任的 tar 文件?

如何安全地提取不受信任的 tar 文件?

我希望能够提取一个 tar 文件,以便所有提取的文件都放置在某个前缀目录下。 tar 文件写入外部目录的任何尝试都会导致提取失败。

正如您可能想象的那样,这样我就可以安全地提取不受信任的 tar 文件。

我怎样才能用 GNU 做到这一点tar

我想出了:

tar --exclude='/*' --exclude='*/../*' --exclude='../*' -xvf untrusted_file.tar

但我不确定这是否足够偏执。

答案1

你根本不需要偏执。 GNU——tar事实上任何过去 30 年左右编写的精心设计的tar程序 —— 默认情况下,将拒绝提取 tarball 中以斜杠开头或包含..元素的文件。

您必须竭尽全力强制现代tar程序提取此类潜在恶意的 tarball:GNU 和 BSD 都tar需要-P选项来禁用此保护。参见 参考资料 部分绝对文件名在 GNU tar 手册中。

-P不过,POSIX 并未指定该标志,因此其他tar程序可能有不同的方式来处理此问题。例如,Schily 工具star程序使用-/-..禁用这些保护。

您可能考虑向简单命令添加的唯一内容tar是一个-C标志,以强制其将内容提取到安全的临时目录中,因此您不必先到cd那里。


旁白:

  1. 从技术上讲,tarPOSIX 不再指定它。他们试图告诉 Unix 计算世界,我们应该使用pax现在代替tarcpio,但计算世界很大程度上忽略了它们。

    这里需要注意的是,POSIX 规范并pax没有说明它应该如何处理前导斜杠或嵌入..元素。有一个非标准--insecure标志BSDpax抑制针对嵌入..路径元素的保护,但显然没有针对前导斜杠的默认保护; BSDpax手册页间接建议编写-s替换规则来处理绝对路径风险。

    当事实上的标准仍在积极使用而法律上的标准在很大程度上被忽视时,就会发生这种情况。

答案2

使用 GNU tar,这很简单

tar -xvf untrusted_file.tar

在一个空目录中。 GNU tar 在提取时会自动去除前导/成员名称,除非使用--absolute-names选项。 GNU tar 还检测何时使用../会导致文件被提取到顶级目录之外,并将这些文件放入顶级目录中,例如,组件foo/../../bar/qux将在顶级目录中提取,bar/qux而不是bar/qux在顶级目录的父目录中提取。 GNU tar 还负责指向顶级目录之外的符号链接,例如,foo -> ../..并且foo/bar不会导致bar在顶级目录之外提取。

请注意,这仅适用于(足够新的版本)GNU tar(以及一些其他实现,例如 *BSD tar 和 BusyBox tar)。其他一些实现没有这样的保护。

由于符号链接的存在,您使用的保护是不够的:存档可能包含指向树外部目录的符号链接并提取该目录中的文件。纯粹根据成员名称无法解决该问题,您需要检查符号链接的目标。

请注意,如果您提取到已包​​含符号链接的目录,则保证可能不再成立。

答案3

为了涵盖其他答案没有涵盖的几点:

  1. 首先,在解压之前查看文件中的内容:

    tar -tvf untrusted_tar_file.tar
    

    如果其中有任何您不信任或不想提取的内容,请不要提取 tarball。

  2. 其次,以非根用户身份提取 tarball,该用户仅对要将 tarball 提取到的一个目录具有写入权限。例如,从非 root 用户的主目录中提取 tarball。

相关内容