最近读了吴翰清先生的《白帽子讲Web安全》书籍,备有收益,于是就想到把一些内容搬到网上来,也算是一种读书总结吧。在此感谢吴翰清先生的用心著作。
安全原则
- 白名单和黑名单,如果更多使用白名单思想,系统就会变得更安全。
- 最小权限原则,要求系统只授予主体必要的权限,这样能有效地减少系统,网络,应用,数据库出错的机会。
客服端脚本安全
浏览器安全
同源策略
- 同源策略:浏览器的同源策略,限制了来自不同源的“document”或脚本,对当前“document”读取或设置某些属性。
- 影响“源”的因素有:host(域名或IP地址)、子域名、端口、协议。
- 对于当前页面来说,页面内存放js文件的域并不重要,重要的是加载js页面所在的域是什么。如:a.com通过以下代码:
<script src="http://b.com/b.js"></script>
- 加载了b.com上的b.js,但是b.js是运行在a.com页面中的,因此对于当前打开的页面(a.com页面)来说,b.js的Origin就应该是a.com而非b.com。
- 在浏览器中,
跨站脚本攻击(XSS)
- 跨站脚本攻击,Cross Site Script
- 类型:
- 反射型XSS:只是简单地把用户输入的数据“反射”给浏览器。
- 存储型XSS:存储型XSS会把用户输入的数据“存储”在服务器端。
- DOM Based XSS:通过修改页面的DOM节点形成的XSS。
XSS Payload
- 用以完成各种具体功能的恶意脚本,被称为“XSS Payload”。
- 可以Cookie劫持
- 构造GET与POST请求
- XSS钓鱼,伪造登陆框
- 识别用户浏览器
- 识别用户安装的软件
- CSS History Hack:通过css,来发现一个用户曾经访问过的网站。
- 获取用户的真实IP地址:借助第三方软件来完成。比如,客户端安装了Java环境(JRE),那么XSS就可以通过调用Java Applet的接口获取客户端的本地IP地址。
XSS构造技巧
- 利用字符编码
- 绕过长度限制
- 使用标签,的作用是定义页面上的所有使用“相对路径”标签的hosting地址。如:,
XSS防御
- HttpOnly:设置cookie为httponly
- 输入检查:根据语境不同,设置不同的检查。如手机号则11位数字,用户名则过滤特殊字符。
- 输出检查:将字符转换成HTMLEntities,php可使用htmlspecialchars()函数。
- 处理富文本:在标签的选择上,使用白名单。比如,只允许,,
等比较“安全”的标签。尽可能禁止用户自定义CSS和style,或者使用过滤css中的危险代码。
跨站点请求伪造(CSRF)
- CSRF的全名是Cross Site Request Forgery,则跨站点请求伪造。
- CSRF能够攻击成功,本质是重要操作的所有参数都是可以被攻击者猜测到的。
CSRF的防御
- 验证码
- Referer Check,用来检查请求是否来自合法的“源”。
- Anti CSRF Token:参数中新增一个Token,值为随机不可预测的。
点击劫持(ClickJacking)
- 点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在该网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。
防御CickJacking
- X-Frame-Options:一个HTTP头,DENY拒绝当前页面加载任何frame页面;SAMEORIGIN则frame页面的地址只能为同源域名下的页面;ALLOW-FROM则可以定义frame加载的页面地址。
服务端应用安全
注入攻击
SQL注入
- select * from table where id = ‘变量’
- 危险句子:变量=a’;drop table OrdersTable–
- 最终句子呈现:select * from table where id = ‘a’;drop table OrdersTable–
盲注(Blind Injection)
- 通过 where id = 2 and 1 = 2(1 = 1) 来观察页面不同,进而判断id参数是否存在SQL注入漏洞。
Timing Attack
- 利用BENCHMARK()函数,让同一个函数执行若干次,使得结果返回的时候比平时要长;通过时间长短的变化,可以判断出注入语句是否执行成功。
sqlmap.py是一个非常好的自动化注入工具,可用来测试
防御SQL注入
- 使用预编译语句:防御SQL注入的最佳方式,就是使用预编译语句,绑定变量。
- 使用安全的存储过程对抗SQL注入。
- 检查数据类型:邮箱,手机,数字类型检测
- 使用安全函数:各种web语言是实现了一下编码函数,可以帮助对抗SQL注入。
- 从数据库自身的角度来说,应该使用最小权限原则,避免web应用直接使用、dbowner等高权限账户直接来连接数据库。
其他注入
- XML注入
- 代码注入
- CRLF注入
文件上传漏洞
- 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。
设计安全的文件上传功能
- 文件上传的目录设置为不可执行
- 判断文件类型
- 使用随机数改写文件名和文件路径
- 单独设置文件服务器的域名
认证与会话管理
密码
- 大小写字母,数字,特殊符号两种以上组合更好
- 密码必须以不可逆的加密算法,或者是单向散列函数算法,加密后存储在数据库中。
- md5加密中,可以增加一个“Salt”之,作用是增加明文的复杂度。
多因素认证
- 除了支付密码外,手机动态口令、数字证书、宝令、支付盾、第三方证书等都可用于用户认证。
Session与认证
- Session Fixation攻击:这个没有换“锁”而导致的安全问题,就是Session Fixation问题。登陆完成后,重写SessionID。
- Session保持攻击:通过不停地发起访问请求,让Session一直“活”下去。
单点登陆(SSO)
- 单点登录(Single Sign On)。它希望用户只需要登陆一次,就可以访问所有的系统。
访问控制
- 权限控制:都是某个主体(subject)对某个客体(object)需要实施某种操作(operation),而系统对这种操作的限制就是权限控制。
垂直权限管理
- 基于角色的访问控制(Role-Base Access Control),简称RBAC。
水平权限管理
- 用户A和用户B可能都属于同一个角色RoleX,但是用户A与用户B都各自拥有一些私有数据,在正常情况下,应该只有用户自己才能访问自己的私有数据。水平权限管理又称为“基于数据的访问控制”。
OAuth
- OAuth是一个在不提供用户名和密码的情况下,授权第三方应用访问Web资源的安全协议。
- 遵循最小权限原则
加密算法与随机数
密钥管理
- 密钥管理中最常见的错误,就是将密钥硬编码在代码里。常见的作法是将密钥(包括密码)保存在配置文件或者数据库中。
应用层拒绝服务攻击
- DDOS又称为分布式拒绝服务,全称是Distributed Denial of Service。DDOS是利用合理的请求造成资源过载,导致服务不可用。
攻击类型
应用层DDOS
- CC攻击:Challenge Collapasar,意为在黑洞(Collapasar 一款绿盟开发的软件)的防御下,仍能有效完成拒绝服务攻击。原理为对一些消耗资源较大的应用页面不断发起正常的请求,以达到消耗服务端资源的目的。在Web应用中,查询数据库、读写硬盘文件等操作,相对都会消耗比较多的资源。
资源耗尽攻击
- Slowloris攻击:原理是以极低的速度往服务器发送HTTP请求。由于Web Server对于并发的连接数都有一定的上限,因此若是恶意地占用住这些连接不释放,那么Web Server的所有连接都将被恶意连接占用,从而无法接受新的请求,导致拒绝服务。
- HTTP POST DOS:原理是发送HTTP POST包时,指定一个非常大的Content-Length指,然后以很低的速度发包,比如1~100s发一个字节,保持住这个连接不断开。这样当客户端连接数多了以后,占用住了Web Server的所有可用连接,从而导致DOS。
- Server Limit DOS:Web Server对HTTP包头都有长度限制,如果客户端发送的HTTP包头超过这个大小,服务器就会返回一个4xx错误。如往客户端写入一个超长的cookie。
ReDOS
- 正则写得不好,就有可能消耗大量资源,从而造成DOS。如
^(a+)+$
防御DDOS
- 应用代码要做好性能优化。将数据库的压力尽可能转移到内存中。此外还需要及时地释放资源,比如及时关闭数据库连接,减少空连接等消耗。
- 在网络架构上做好优化。善于利用负载均衡分流,避免用户流量集中在单台服务器上。同时可以充分利用好CDN和镜像站点的分流作用,缓解主站的压力。
- 实现一些对抗手段,比如限制每个IP地址的请求频率。
- 使用验证码
PHP安全
文件包含漏洞
- include(),require(),include_once(),require_once(),当这四个函数包含一个新的文件时,该文件将作为PHP代码执行,PHP内核并不会在意该被包含的文件是什么类型。
- 本地文件包含:会访问到系统文件,如/etc/passwd文件。在连接字符串时,0字节(\x00)将作为字符串结束符。
- 目录遍历漏洞是一种跨越目录读取文件的方法,但当PHP配置了open_basedir时,将很好地保护服务器。open_basedir的作用时限制在某个特定目录下PHP能打开的文件。
- 远程文件包含:PHP的配置选项allow_url_include为ON的话,则include/require函数是可以加载远程文件的。
变量覆盖漏洞
- 首先,确保register_globals=OFF。若不能自定义php.ini,则应该在代码中控制。
- 其次,熟悉可能造成变量覆盖的函数和方法,检查用户是否能控制变量的来源。
- 最后,养成初始化变量的好习惯。
代码执行漏洞
- php中有不少可以直接执行代码的函数,比如:eval(),assert(),system(),exec(),shell_exec(),passthru(),escapeshellcmd(),pcntl_exec()等。一般来说,最好在PHP中禁用这些函数。
定制安全的PHP环境
- register_globals:设置为 off
- open_basedir:设置只能操作制定目录下的文件。
- allow_url_include:设置为off,对抗远程文件包含。
- allow_url_fopen:设置为off,对抗远程文件包含。
- display_errors:设置为off,错误回显,生产环境需关闭。
- log_errors:设置为on,记录错误日志
- magic_quotes_gpc:设置为off,注入攻击已有多种方法绕过它,关闭它还能提高性能。
- cgi.fix_pathinfo:若php以CGI方式安装,则需要关闭此项。
- session.cookie_httponly:设置为开启
- session.cookie_secure:若是全站HTTPS则开启此项。
- safe_mode:安全模式,可开可不开。
- disbale_function:禁用危险函数
Web Server配置安全
Apache安全
- 检查Apache的Module安装情况,根据“最小权限原则”,应该尽可能地减少不必要的Module,对于要使用的Module,则检查其对应版本是否存在已知的安全漏洞。
- Apache以root身份或者admin身份运行是一个非常糟糕的决定