如何防止文件包含在系统目录之外?

时间:2016-09-01 17:11:00

标签: c++ c gcc include-path jail

出于安全原因,我必须阻止系统目录中的#include个文件。是否有任何限制可以阻止#include<...>#include"..."包含#include </dev/tty>#include "/dev/random"等不安全文件?

我已阅读Docs of C Preprocessor的标题文件章节以及类似问题How do I prevent a quoted include from searching the directory of the current source file?,但找不到合适的方法。

由于-I-命令已过时,并且没有其他方法可以完成相同的功能,我可以使用jailkit将代码编译为低权限用户吗?或者还有其他方法来确保编译过程的安全性吗?

1 个答案:

答案 0 :(得分:3)

godbolt.org#include s中forbidding absolute and relative paths解决了类似的问题:

输入:

#include "/etc/passwd"

输出:

<stdin>:1:1: no absolute or relative includes please
Compilation failed

这可以通过在调用编译器之前在源上运行简单的检查器来实现。检查器只需要查找#include指令并检查违反此类限制的路径。这样的脚本的草稿版本(可与单个源文件一起使用)如下:

<强> check_includes

#!/bin/bash

if (( $# != 1 ))
then
    echo "Usage: $(basename "$0") source_file"
    exit 1
fi

join_lines()
{
    sed '/\\$/ {N;s/\\\n//;s/^/\n/;D}' "$1"
}

absolute_includes()
{
    join_lines "$1"|grep '^\s*#\s*include\s*["<]\s*/'
}

relative_includes()
{
    join_lines "$1"|grep '^\s*#\s*include'|fgrep '../'
}

includes_via_defines()
{
    join_lines "$1"|grep '^\s*#\s*include\s*[^"< \t]'
}

show_and_count()
{
    tee /dev/stderr|wc -l
}

exit_status=0
if (( 0 != $(absolute_includes "$1"|show_and_count) ))
then
    echo 1>&2 "ERROR: $1 contains absolute includes"
    exit_status=1
fi
if (( 0 != $(relative_includes "$1"|show_and_count) ))
then
    echo 1>&2 "ERROR: $1 contains relative includes"
    exit_status=1
fi
if (( 0 != $(includes_via_defines "$1"|show_and_count) ))
then
    echo 1>&2 "ERROR: $1 contains includes via defines"
    exit_status=1
fi
exit $exit_status

假设输入文件可以无错误地编译,此脚本标识包含绝对路径或相对路径的#include。它还通过下面的宏检测包含(这可能会被滥用以解决路径检查):

#define HEADER "/etc/password"
#include HEADER