话说令狐冲在华山职业技术学院习得一身开发好本领,什么客户端、服务器、C++、PHP、JavaScript、后端、数据库通吃, 被同学们推崇为全栈工程师。毕业之后,顺利加入某互联网公司,成为了一名光荣的程序猿。
令狐冲的第一个岗位,Windows客户端开发,可不要小看这个岗位,之前的版本已经有数千万的用户在使用了,而且现在是互联网时代,跟后台、前端都有集成哦。
很快令狐冲负责优化的第一个版本上线了,不巧的是,几天后,公司的安全人员就找上门来。
这时,令狐冲才搞明白,原来教材里面的写法并不是安全上的最佳实践,安全的一个重要原则就是:
不能信任外部提交过来的任何参数!
不能信任外部提交过来的任何参数!
不能信任外部提交过来的任何参数!
重要的事情要说三遍!
按照安全人员的建议,令狐冲紧急修复了客户端的接口,严格检查参数的合法性,并限制了数据类型和长度,发布了第二个版本。
可是好景不长,安全人员又来了!
对服务器证书的验证,目的在于确认所连接的这台服务器就是真正的服务器,而不是劫持者的恶意服务器。劫持者可以通过自签发证书配合DNS劫持,来假冒服务器,如果客户端建立网络连接所使用的函数没有自带证书校验功能,假冒服务器就可以接收用户提交的口令等敏感信息。
令狐冲不禁感叹,黑客的世界还有这么多玩法!
安全人员还告诉他,目前有一种叫做HTTP DNS的东东对付DNS劫持效果很不错,公司已经有了,咱们可以先用上,要是没有这个东东,客户端需要另外开发校验服务器合法性的功能。
令狐冲赶紧用上HTTP DNS,事件数量慢慢降了下来。
网络聊天时,众所周知的名言是:不要轻易相信对方,谁也不知道电脑对面是不是坐着一条狗!
网络通讯也是同样的道理:不要相信你连接的服务器,你需要先验证它究竟是不是!
令狐冲后来又尝试转岗到Web开发岗位。
某在线销售业务上线后的第二天早上,安全人员又找到了他。
提交过程中支付金额被篡改为一分钱,导致公司的业务出现重大资金损失!
安全人员告诉他,如果提交的数据之间存在关联关系(比如价格和商品id之间),那么最好减少提交的数据量(只传递商品id和购买的数量),关联的数据从后台提取(价格从后台提取);如果必须从前台提取的话,则要考虑防篡改措施,比如用服务器的公钥对数据字段加密或其他可以保障完整性的措施。
又一次,后台服务器被入侵:
预编译样例是这样的(以PHP为例):
pdo = new PDO('mysql:host=localhost;dbname=myDB;charset=utf8', dbuser, $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); st = pdo->prepare("select * from userinfo where id =? and name = ?"); st->bindParam(1, st->bindParam(2, $st->execute(); $st->fetchAll();
通过这样的方式,有效的实现了指令与数据的分离;或者引入成熟的ORM框架,不再自己写SQL,避免引入风险。
小结:
不要拼接SQL语句!不要拼接SQL语句!不要拼接SQL语句!
又一次,有用户在浏览时,黑客创建的非法JS脚本把用户的cookie发送到一个第三方网站去了,然后用户的身份被盗了:
安全人员告诉他,用户创建的内容是不可信的,在存储或展示之前,需要转义处理或者禁止提交含有恶意脚本的内容。不能将用户创建的内容直接返回给前端(含Body文本、各种标签内置属性或行内Js代码、Js代码段、样式等)。
哎呀妈呀,这Web安全水也很深呀!令狐冲感觉需要学习的内容还很多,这怎么办呢?
安全人员安抚他说,记住安全技术上的一个重要的“不信任”原则,即可事半功倍:
不信任外部传递过来的任何参数!不能信任用户提交的任何内容!
当然,仅限于技术上,咱们之间还是要加强信任,合作双赢哦!