很多企业主觉得自己的网站没什么价值,黑客看不上。但现实是,绝大多数攻击是自动扫描的,它不管你是谁,只管你有没有漏洞。网站被拿去发垃圾内容、被挂黑链,等发现时搜索收录已经一团糟。
好消息是,常见的攻击方式就那么几种,防护方法也都是成熟的。
注入攻击:把输入当代码执行了
用户在搜索框里输入一段特殊字符,如果程序把它直接拼进数据库查询语句,就可能被利用来读取甚至删除数据。
防护方法只有一个,但必须严格执行:使用参数化查询,永远不要拼接 SQL 字符串。
// 错误写法db.query("SELECT * FROM products WHERE id = " + id);// 正确写法db.query("SELECT * FROM products WHERE id = ?", [id]);跨站脚本:把内容当代码渲染了
访客在留言里写一段脚本,后台没处理就显示出来,其他用户打开页面时脚本就执行了,可能窃取登录信息。
防护要点是输出到页面时转义,以及对富文本内容做白名单过滤:
- 普通文本输出前转义特殊字符
- 富文本编辑器提交的内容,只允许安全的标签和属性
- 避免使用直接插入 HTML 的接口,改用文本插入
文件上传:最容易被忽视的入口
上传功能如果只检查文件后缀,攻击者传一个伪装成图片的脚本文件,就可能拿到服务器执行权限。要点:
- 检查文件真实类型,不只看扩展名
- 限制大小与格式,只允许业务真正需要的类型
- 重命名存储,不要用原始文件名
- 存储在非执行目录,或通过对象存储隔离
- 禁止脚本执行权限,在上传目录配置层面关掉
权限与会话
后台被入侵,很多时候不是被破解,而是权限设计有漏洞:
- 每个操作都要校验权限,不能只靠隐藏按钮,接口层面必须再查一次
- 密码要加盐哈希存储,明文存储是重大事故
- 后台登录加失败次数限制,防止暴力破解
- 会话有时效,长时间无操作自动退出
- 敏感操作二次确认,比如删除、导出数据
其中接口层面的权限校验最常被遗漏。前端把按钮藏了就以为安全了,接口没校验,直接发请求照样能执行。
基础设施层面
- 全站 HTTPS,防止传输过程被窃听
- 错误信息不暴露细节:生产环境关掉调试模式,数据库报错不要直接显示给用户
- 依赖及时更新:框架和组件的安全公告要关注
- 定期备份:出事之后能恢复,比什么防护都实在
- 留操作日志:谁在什么时候改了什么,事后能追溯
上线前扫一遍
用自动化的漏洞扫描工具跑一次,能发现大部分低级问题。有条件的话,重要系统上线前做一次人工渗透测试。这笔钱对有交易、有用户数据的网站来说,花得值。
安全不是加一个插件就完成的事,它写在每一行处理用户输入的代码里。
—— 一位做过应急响应安全工程师