一个程序可以通过以下2种方式以特权方式运行:
1.程序在一个特权用户ID下启动,很多 daemon 以 root 身份运行。
2.程序设置了set-user-ID 或 set-group-ID 权限位。当一个设置了 set-uesr-ID程序被
执行后,它会将进程的有效用户ID修改为程序文件的所有者一样的ID。
1.是否需要一个 set-user-ID 或 set-group-ID程序
应该避免。
2.以最小权限操作
在无需权限的时候,永久的删除权限。
3.小心的执行程序
1.在执行另外一个程序之前永久的删除权限
2.避免执行一个拥有权限的shell
运行与用户控制之下的特权程序永远都不应该直接或者间接的执行shell。shell的复杂性和强大的功能意味着不可能
消除所有的安全隐患。
3.在 exec() 之前关闭所有用不到的文件描述符。
4.避免暴露敏感信息
当一个程序读取密码或者其他敏感信息时,应该在执行完所有的处理之后立即从内存中删除这些信息。在内存中保留这些信息
是一种安全隐患。
1.包含这些数据的虚拟内存页可能会被换出(除非使用 mlock() 类似的函数将它们锁在内存中),这样交换区域中的数据可能会
被一个特权程序读取。
2.如果进程收到一个能够导致它产生 core dump 的信号,那么就有可能从该文件中获取这类信息。
编写程序时,应该避免产生 core dump 。可以使用 setrlimit() 将 RLIMIT_CORE 设置为 0 。
5.确定进程的边界
1.考虑使用能力
2.考虑使用一个 chroot 监牢
3.虚拟服务器
6.小心信号和竞争条件
7.执行文件操作和文件IO的缺陷
8.不要完全相信输入和环境
1.不要信任环境列表
2.防御性的处理不可信用户的输入
3.避免对进程的运行时环境进行可靠性假设
9.小心缓冲区溢出
恶意用户可以通过诸如缓冲区溢出(也被称为栈粉碎)之类的技术,将精心编写的字节放入一个栈帧中以强制特权程序执行任意代码。
10.小心拒绝服务攻击
11.检查返回状态和安全地处理失败情况
geteuid();
seteuid();
setreuid();
setresuid();
getresuid();
getresgid();