精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● 计算机安全>>◇网络安全◇>>编程安全>>UNIX安全编程FAQ

主题:UNIX安全编程FAQ
发信人: devin()
整理人: williamlong(1999-12-21 18:34:37), 站内信件
如欲看更多的好文章,请去我们的知识库(http://openunix.org/cgi-bin/fom)
原文:http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html
     翻译:devin ( [email protected] )

     UNIX安全编程FAQ
     n 安全设计原则,编程和测试方法的技巧

     概述
     在当前的软件行业里,太多的程序有安全问题,代码在被发布前只
     是经过很少的测试,有些测试甚至不关心安全编程技巧,本FAQ将尝
     试成为程序员的工具,使写安全程序的过程变得轻松起来。

     运用好的编程技巧是非常重要的,甚至你的代码只是将运行在限制的
     时期和限制的条件下。许多程序员的程序常超越其最初的设计范围,
     Ivan Krsul发现,在他的论文里指出,大部分的安全漏洞出现的环境
     是当初程序员不知道或没有想到的。举例,程序员也许相信当前的系
     统调用永不会失败,或者程序不可能被以非文本的参数方式被调用,
     因而,程序员能做到最好的事情就是对问题进行假定编程,仔细分析
     它们是否正确,和想象可以使其失败的条件。

     本FAQ尝试将想法,技巧,步骤和系统调用等可能影响系统安全的技
     巧记录下来。

     1. 什么时候用的这些方法?
     如果这些安全编程方法能适用所有程序那当然很好,毕竟,不管程序
     是与安全相关的还是无关的,多数是又好又简单的编程技巧。然而,
     将这些技巧用在所有的程序上将消耗许多时间和精力,所以,如果这
     些技巧可以用在所有地方,它们也至少也应该用在"重要"的程序上,
     特别指出,这些方法可以用在下面的地方:
     l 所有的setuid和setgid程序
     l 所有的网络服务程序
     l 所有有原子级安全要求的程序(例,检查文件访问权限和打开文件)
     l 需要从外部接收输入或使用外部环境信息的程序(如,用户的邮件
       代理,为衍生子进程的PATH变量)
     l 用于系统管理的程序

     2. 系统设计法则
     不管使用何种编程语言、程序用途、和什么技巧写的,下面的法则可
     以帮助你断定程序是否是bug-free的

     1. 最小权限. 编制和使用最少且足够的权限去完成任务,问自己,
         "软件*必需*要什么权限?",而不是"软件需要什么权限"。
     2. 结构经济. 短,简单的代码产生的Bug当然比长和复杂的少,用尽
        可能少的代码实现系统。
     3. 完全检测. 检查访问对象的所有途径,所有调用的返回代码,和关
        键点的变量值。
     4. 开放设计. 不要用隐晦的方法来保证安全
     5. 特权分开. 在不同的程序或函数里不同时间只给出最需要的权限。
     6. 最少公用机制. 应该给用户最少的共享资源。
     7. 心理可接受性. 安全控制必须容易使用,否则容易被用户绕过去不
        去使用安全特性。
     8. 默认的错误防护.  默认拒绝,和错误关闭
     9. 代码重用. 尽可能使用以前测试过的代码
     10. 不信任未知的. 所有从用户那里得到的信息,或者从外面的程序都
        是可以怀疑的.
     11. 在问题出现前作出预测. 在开始写程序之前确定你的程序功能和设
         计可能会出现什么安全问题。

     3. 安全编程方法
        用下列好的编程习惯和安全软件指导来写软件,在设计技巧、系统调用
     和库调用上使用合适的信息,在Simson Garfinkle和Gene Spafford的
     Practical Unix and Internet Securiy》一书的第23章里有许多关于
       安全编程和非安全编程技巧的信息。下面是其精髓所在.
     l 检查所有的命令行参数
     l 检查所有的系统调用参数和返回代码
     l 检查环境参数,不要依靠Unix环境变量
     l 确定所有的缓存都被检查过
     l 在变量的内容被拷贝到本地缓存之前对变量进行边界检查
     l 如果创建一个新文件,使用O_EXCL和O_CREATE标志来确定文件没有已经存在
     l 使用lstat()来确定文件不是一个符号连接
     l 使用下面的这些库调用: fgets(), strncpy(), strncat(), snprintf()
        而不是其它类似的函数,可以说,只使用检查了长度的函数.
     l 同样的,小心的使用execve(),如果你必须衍生一个进程
     l 在程序开始时显式的更改目录(chdir())到适当的地方
     l 限制当程序失败时产生的core文件,core文件里有可能含有密码和其它
       内存状态信息.
     l 如果使用临时文件,考虑使用系统调用tmpfile()或mktemp()来创建它们
       (虽然很多mktemp()库调用可能有race condition的情况)
     l 内部有完整性检查的代码
     l 做大量的日志记录,包括日期,时间,uid和effective uid,gid和effe
       ctive gid,终端信息,pid,命令行参数,错误和主机名
     l 使程序的核心尽可能小和简单
     l 永远用全路径名做文件参数
     l 检查用户的输入,确保只有"好"的字符
     l 使用好的工具如lint
     l 理解race conditions,包括死锁状态和顺序状态
     l 在网络读请求的程序里设置timeouts和负荷级别的限制.
     l 在网络写请求里放置timeouts
     l 使用会话加密来避免会话抢劫和隐藏验证信息
     l 尽可能使用chroot()设置程序环境
     l 如果可能,静态连接安全程序
     l 当需要主机名时使用DNS逆向解释
     l 在网络服务程序里分散和限制过多的负载
     l 在网络的读和写里放置适当的timeout限制
     l 如果合适,防止服务程序运行超过一个以上的拷贝

     4. 不安全的编程方法
     l 防止使用在处理字符串时不检查buffer边界的函数,如gets(), 
       strcpy(), strcat(), sprintf(),fscanf(), scanf(), vsprin
       tf(), realpath(), getopt(), getpass(), streadd(),
       strecpy(),和strtrns()
     l 同样,避免使用execlp()和execvp()
     l 永远不要用system()和popen()系统调用
     l 不要将文件创建文件在全部人可写的目录里
     l 通常,不要设置setuid或者setgid的shell scripts
     l 不要假想端口号码,应该用getservbyname()函数
     l 不要假设来自小数字的端口号的连接是合法和可信任的
     l 不要相信任何IP地址,如果要验证,用密码算法
     l 不要用明文方式验证信息
     l 不要常识从严重的错误中恢复,要输出详细信息然后中断
     l  考虑使用perl -T或taintperl写setuid的perl程序

     5. 测试程序安全
     用cracker的方法来做软件测试:
     l 尝试使程序里的所有缓存溢出
     l 尝试使用任意的命令行选项
     l 尝试建立可能的race condition
     l 设计者做代码重阅和测试
     l 读所有的代码,象cracker一样思维来找漏洞

     使用这些技巧应该可以提高软件质量,减少代码bug,特别是安全漏洞。
--
devin<[email protected]>
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+
+    Welcome to Network Studio   +
+    ~~~~~~~~~~~~~~~~~~~~~~~~~   +
+ Http|Ftp://studio.openunix.org +
+________________________________+

※ 修改:.devin 于 May  7 00:04:31 修改本文.[FROM: 202.96.191.124]
※ 来源:.网易 BBS bbs.netease.com.[FROM: 202.96.191.124]

[关闭][返回]