今天看了公司内部的《python安全编码》课程,就顺手总结一下课程中讲到的web攻击以及防范措施
注入攻击
1、SQL注入
方式:注入能够允许攻击者操控发送至数据库的SQL查询字符串
解决方案:
- 使用白名单验证用户所有输入
- 将用户输入转换为正确类型
- 不可基于用户输入直接引用数据库,表格或者列
- 应该始终在用户上下文中运行有限权限的查询
- 使用预处理语句或参数化查询创建动态查询
2、跨站脚本xss
定义:攻击者向网页中注入客户端代码,这些代码可能会向服务器发送请求,攻击者就会从返回的响应中窃取cookie、劫持对话、或者将页面重定向到新页面等。
解决方案:
- 使用有效的库
- 假定所有的输入不可信
- 转移所有输出(尤其是javascript的一些标签)
- 使用HTTPOnly标志,防止js访问cookie内容
- 使用内容安全策略(CSP),确定处理脚本和其他内容的细粒度规则
- 表单修改或者提交时,使用POST请求
- 使用可防范跨站脚本的X-XSS-Protection HTTP响应头,启用基于浏览器的防护措施。
3、命令注入
攻击者在web应用中注入操作系统命令,比如下面这段代码:
def listdirectory(directory):
return subprocess.check_output('ls %s' % directory,shell=True)
//如果攻击者在表单中提交'rm -rf,那么上端代码最后执行 subprocess.check_output("ls;rm -rf/"),就会删除所有文件
解决方案:
- 避免使用shell=True,shell只执行单一字符串无法区分命令参数或其他单一字符,因此应将其设为False,如果必须设为True,应将命令拆分成单个字符串
- 将数值转为列表的形式传递,
def listdirectory(directory):
return subprocess.check_output(['ls' ,directory],shell=False)`
- 使用严格的白名单过滤
- 确保web服务器以低权限用户身份运行
- 设置合适的文件权限
- 在虚拟环境下运行服务器
会话攻击
会话劫持: 攻击者以某种方式获得浏览器向服务器传递的会话令牌,就可以以已或权限的用户身份运行web应用程序,从而劫持会话信息
防范措施:
- 始终在web应用程序中使用TLS,任何非加密的请求可能会暴露会话令牌
- 将secret_key_base设置为一个强健的随机数在启用加密
- 始终为用户提供注销的选项,以手动终止会话
- 将所有cookie的HttpOnly属性设置为true,使其只能通过TLS连接发送
- 在会话cookie上设置合理的失效日期
跨站请求伪造CSRF 利用跨站脚本、浏览器缺陷等使用户在当前认证的用户环境中提交恶意请求,攻击者利用跨站请求伪造,不必盗取会话令牌,而是诱骗用户执行一些他们设定的操作,比较熟悉的就是之前的qq盗取密码操作
- 双提交cookie,在隐藏表单字段中包含CSRF令牌,当用户提交表单时,cookie中的令牌必须和CSRF令牌一致,否则就不传递
- 对每个请求生成随机数,在每次向用户发送的表单中生成随机的一次性令牌
- 使用Non-GET请求,对处罚用户状态更改或修改数据的操作请求,不要使用GET
- 更多的用户交互,比如短信验证码等操作
- Django有一个防范CSRF的内置机制
- Pyramid:将配置文件中set_default_csrf_options设置为_csrf=True