如何防止从系统目录中包含文件?
How do I prevent an include of files out of system directories?
出于安全原因,我必须防止 #include
系统目录外的任何文件。是否有任何限制可以防止 #include<...>
和 #include"..."
包含 #include </dev/tty>
或 #include "/dev/random"
等不安全文件?
我已经阅读了 Docs of C Preprocessor as well as a similar question How do I prevent a quoted include from searching the directory of the current source file? 的头文件章节,但找不到合适的方法。
由于-I-
命令已经过时,并且没有其他方法可以完成相同的功能,我可以使用jailkit作为低权限用户编译代码吗?还是有其他方法可以保证编译过程的安全?
godbolt.org solves a similar problem by forbidding absolute and relative paths 在 #include
秒内:
输入:
#include "/etc/passwd"
输出:
<stdin>:1:1: no absolute or relative includes please
Compilation failed
这可以通过 运行 在调用编译器之前对源代码进行简单检查来实现。检查器只需要 grep #include
指令并检查路径是否违反此类限制。此类脚本的草稿版本(可与单个源文件一起使用)如下:
check_includes:
#!/bin/bash
if (( $# != 1 ))
then
echo "Usage: $(basename "[=12=]") source_file"
exit 1
fi
join_lines()
{
sed '/\$/ {N;s/\\n//;s/^/\n/;D}' ""
}
absolute_includes()
{
join_lines ""|grep '^\s*#\s*include\s*["<]\s*/'
}
relative_includes()
{
join_lines ""|grep '^\s*#\s*include'|fgrep '../'
}
includes_via_defines()
{
join_lines ""|grep '^\s*#\s*include\s*[^"< \t]'
}
show_and_count()
{
tee /dev/stderr|wc -l
}
exit_status=0
if (( 0 != $(absolute_includes ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains absolute includes"
exit_status=1
fi
if (( 0 != $(relative_includes ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains relative includes"
exit_status=1
fi
if (( 0 != $(includes_via_defines ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains includes via defines"
exit_status=1
fi
exit $exit_status
假设可以正确编译输入文件,此脚本会识别 #include
包含绝对路径或相对路径的文件。它还检测通过如下宏完成的包含(这可以被滥用来绕过路径检查):
#define HEADER "/etc/password"
#include HEADER
出于安全原因,我必须防止 #include
系统目录外的任何文件。是否有任何限制可以防止 #include<...>
和 #include"..."
包含 #include </dev/tty>
或 #include "/dev/random"
等不安全文件?
我已经阅读了 Docs of C Preprocessor as well as a similar question How do I prevent a quoted include from searching the directory of the current source file? 的头文件章节,但找不到合适的方法。
由于-I-
命令已经过时,并且没有其他方法可以完成相同的功能,我可以使用jailkit作为低权限用户编译代码吗?还是有其他方法可以保证编译过程的安全?
godbolt.org solves a similar problem by forbidding absolute and relative paths 在 #include
秒内:
输入:
#include "/etc/passwd"
输出:
<stdin>:1:1: no absolute or relative includes please
Compilation failed
这可以通过 运行 在调用编译器之前对源代码进行简单检查来实现。检查器只需要 grep #include
指令并检查路径是否违反此类限制。此类脚本的草稿版本(可与单个源文件一起使用)如下:
check_includes:
#!/bin/bash
if (( $# != 1 ))
then
echo "Usage: $(basename "[=12=]") source_file"
exit 1
fi
join_lines()
{
sed '/\$/ {N;s/\\n//;s/^/\n/;D}' ""
}
absolute_includes()
{
join_lines ""|grep '^\s*#\s*include\s*["<]\s*/'
}
relative_includes()
{
join_lines ""|grep '^\s*#\s*include'|fgrep '../'
}
includes_via_defines()
{
join_lines ""|grep '^\s*#\s*include\s*[^"< \t]'
}
show_and_count()
{
tee /dev/stderr|wc -l
}
exit_status=0
if (( 0 != $(absolute_includes ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains absolute includes"
exit_status=1
fi
if (( 0 != $(relative_includes ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains relative includes"
exit_status=1
fi
if (( 0 != $(includes_via_defines ""|show_and_count) ))
then
echo 1>&2 "ERROR: contains includes via defines"
exit_status=1
fi
exit $exit_status
假设可以正确编译输入文件,此脚本会识别 #include
包含绝对路径或相对路径的文件。它还检测通过如下宏完成的包含(这可以被滥用来绕过路径检查):
#define HEADER "/etc/password"
#include HEADER