简单总结一下日常 web 开发中会出现的一些安全问题,以 Flask 框架为例
注入攻击 (Injection)
注入攻击主要包括系统命令注入,SQL 注入,NoSQL 注入,和 ORM 注入等,这里我们简单介绍一下 SQL 注入
攻击原理
在编写 SQL 语句时,如果直接将用户传入的输入作为参数使用字符串拼接的方式插入到 SQL 查询中的话,攻击者则可以利用 SQL 语句篡改,窃取数据库的信息。
攻击实例
@app.route(‘/student’)
def get_table():
password = request.args.get(‘password’)
cur = db.execute(‘SELECT * FROM students WHERE password=’%s;’
% password)
results = cur.fetchall()
return results
如果攻击者输入的值为 ”or 1=1–“,这意味着会返回 students 表中的所有数据;或者输入 ”; drop table users; –“,会删除 students 表中的所有数据。
主要防范方法
使用 ORM
验证输入类型
转义特殊字符
XSS 攻击
XSS(Cross-Site Scripting) 即跨站脚本攻击,为了避免与 CSS 层叠样式表产生命名冲突,用 X 来表示 Cross(交叉)
攻击原理
XSS 其实是注入攻击的一种,通过将代码注入被攻击者的网站中,用户一旦访问便会执行被注入的恶意脚本。其中,XSS 攻击主要分为反射型 XSS 攻击和存储型 XSS 攻击两种。
攻击示例
反射型 XSS 攻击
反射型 XSS 又称为非持久型 XSS,当某个站点存在 XSS 漏洞时,可以通过 URL 注入恶意脚本,当用户访问这个 URL 时,就会执行攻击脚本。
@app.route(‘hello’)
def hello():
name = request.args.get(‘name’)
response = ‘<h1>Hello, %s</h1>’ % name
return response
如果用户输入一段 javascript 代码,如访问 http://example.com/hello/<script>alert(‘hahah’);</script>,客户端介绍到响应后,浏览器就会执行这段代码,当然这个示例代码不会构成任何威胁,但这意味着可以执行任意的 js 代码,鬼知道攻击者会做些什么!
存储型 XSS 攻击
存储型 XSS 也被称为持久型 XSS,它和反射型 XSS 的行为类似,不过会把植入的恶意代码存储到数据库中,如在留言区写入一段重定向代码,这会导致用户在访问留言区页面时被重定向到一些恶意站点。
防范措施
HTML 转义
验证用户输入
CSRF 攻击
CSRF(Cross Site Request Forgery) 指跨域请求伪造,这是一种近年来才逐渐被大众了解的攻击方式。
攻击原理
攻击者利用用户在浏览器中保存的认证信息,向对应的站点发送伪造请求。如用户登录了 A 网站,认证信息保存在 cookie 中,当用户访问恶意网站 B 时,攻击者通过 B 网站发送一个伪造的请求提交到 A 网站服务器上,这会让 A 网站误以为请求来自于自己的网站,从而可以让攻击者成功篡改某些信息。
攻击示例
假设服务器端删除用户账户的视图操作为
@app.route(‘/account/delete’)
def delete_account():
if not current_user.authenticated:
abort(401)
current_user.delete()
return ‘deleted!’
当用户登录后,只要访问 https://example.com/account/delete 就会删除账户,那么在攻击者的网站上,只要创建一个显示图片的 img,其中的 src 的属性加入删除账户的 URL,当用户访问 B 网站时,浏览器解析网页会自动向该链接发送请求,此时你的登录信息就保存在浏览器的 cookie 中,因此,仅仅是访问 B 网站就会导致删除账户。
防范措施
正确使用 HTTP 方法
CSRF 令牌效验
其中 CSRF 令牌是比较常用的方法,具体做法是在表单提交中添加一些伪随机数,即 CSRF 令牌 (token),这里我们就不详细展开。