构建安全的Web应用
sql注入
下述表单提交,不知道用户密码也能登录成功
成因:
登录过程中进行数据库查询操作时,没有对参数进行检查或转义
1 | def get_user2(name, passwd): |
修复:
使用execute拼接sql,既对参数进行转义
1 | def get_user2(name, passwd): |
why:
MySQLdb中对字符串进行转义,因此sql执行器不会去解析字符串
xss攻击
下述表单提交后,重载页面就会弹出’xss’的框
成因:
index渲染的时候没有对用户输入的数据做检查或转义
1 | def render(file_path, data={}): |
修复:
jinja2渲染模版开启自动转义(autoescape=True)
1 | def render(file_path, data={}): |
why:
转义之后浏览器不会去解析html标签或js代码等,因此可以防止用户内嵌其他页面(如广告),或提交有风险的js脚本
csrf攻击
在攻击页面写入以下代码,若用户在此前已成功登录demo站点,则会自动向bob账户转账200
1 | <form id="form" action="http://www.demo.com/transfer" method="POST" style="display:none;"> |
成因
在transfer接口没有对请求做任何校验
1 | class Transfer(lib.AuthHandler): |
修复
app/home.py
在访问表单页时记录当前的时间戳到cookie中,并在提交表单时校验ticket
1 | class Home(lib.AuthHandler): |
common/lib.py
相关检查
1 | # 检查正整数 |
templates/home.html
在表单中增加一个ticket,ticket由在cookie里记录的时间戳生成
1 | <input type="hidden" name="ticket" id="ticket" value=""> |
why
攻击者要求用户访问demo站点时虽然可以携带cookie,但攻击者并不能获取cookie,所以无法生成有效的ticket