[]Lendf.Me被盗是ERC-777之过吗?从协议、标准与兼容性思考( 二 )


关于兼容性的例子
SQL 注入
「SQL 注入是一种将 SQL 代码添加到输入参数中 , 传递到服务器解析并执行的一种攻击手法 。 」
简单说 , 用户可以通过公开的接口来实现对数据库的攻击 。 例如:
我们在登录网站时 , 会输入用户名和密码 , 服务器后台会判断用户名密码是否匹配 , 来决定是否能让用户登录 。
假设我们在输入时 , 用户名输入:user'-- (注意--后面有个空格 , 单引号闭合 user 左边的单引号) , 密码随意输入 , 如:111 , 然后点击提交按钮 。 等价于 SQL 语句:
SELECT * FROM user WHERE username = 'user'-- 'AND password = '111'
参见:https://blog.csdn.net/github_36032947/article/details/78442189
由于「--」之后的部分被注释掉了 , 无论密码是正确或者是错误的 , 用户都可以成功登录 。
当然 , 实际上的代码没有这么简单 。 你如果看了这段话尝试去攻击网站 , 是不会成功的 。
这和兼容性有什么关系呢?解释一下 。
假设 一个网站遵循用户协议 U20 , 只允许用户名是字母 , 因此用户无法输入 ' 和-这两个符号 。 当然不仅前端输入框限制 , 后端也会检查每个字符是否都符合条件 。 换句话说 , 在接口传递参数的时候 , 不允许这两个符号出现 , 这个接口是符合 U20 的 。 这时 , 不会出现示例中的 SQL 注入问题 。 (但不确定是否其它注入可能 。 )
某天 , 网站的用户协议进行了升级 , 变成了 U777 , 新的用户可以使用 ' 和- 作为用户名了 , 接口也需要进行升级 。 U777 对 U20 当然是回溯兼容的 , 因为旧的用户仍然可以使用用户名登录 , 也可以使用旧的界面和接口登录 。 而新的用户则需要前端和后端代码升级后才能登录 。
如果前端和后端只是简单地对上述两个字符不加限制 , 势必会导致上述 SQL 注入问题 。 但这个要怪罪接口升级吗?
很显然 , 不是的 。 协议只是保证符合规范地将用户的输入传递给后端 , 协议升级后 , 这仍然正确地完成了 。 而新的字符带来的风险 , 是需要后端代码重新评估的 , 也可以认为后端代码与新的协议不兼容 。
这是后端代码的问题吗?这是协议升级的问题吗?都不是 。 而是因为协议升级后 , 让用户产生了足以摧毁系统的超能力 。
再把话题扯远一点 , 列车的最高速度从 20km/h 提到 100km/h , 铁轨仍然和列车兼容 。 但噪音是否会造成沿途居民的影响 , 道口是否需要提高安全等级呢?这显然是要重新审视的 。
应该怎么做?
回溯兼容不代表安全 , 因为新的特性必然具有外部性 , 而这个外部性是让其它实体很难预期的 , 所谓「安全是动态的」 。 回到刚才的例子 , 有两种做法 。
一是提前对各种外部性进行判断 。 后端代码非常谨慎 , 假装不知道用户的输入是受限的 , 按照全字符集来进行处理 , 这样无论协议怎么升级 , 后端都是安全的 。
二是灵活但审慎的策略 。 在协议升级时前 , 重新评估安全性 , 并做好修改和测试工作后重新部署 。
根据例子的复杂度 , 两种做法都是可行的 。 更重要的是 , 为了避免重复劳动 , 提高效率 , 减少安全问题出现的可能 , 应当对共性问题进行标准化尝试 。
例如 , 用户登录是个逻辑简单 , 且非常普遍的场景 。 为了防止 SQL 注入 , 就有例如 Prepared Statement 之类的标准化做法 , 完全不需要闭门造车 。 而回到开头的那个问题 , 我更想引用慢雾的一段话「第三方 DeFi 平台在接入的时候 , 应需要充分考虑平台本身的业务逻辑与接入代币之间的兼容性 , 才能避免因兼容性发生不必要的安全问题 。 而不是简单的将问题归咎于协议和代币提供方 。 」
为什么 ERC777 难以得到推广
为什么 ERC777 兼容了 ERC20 , 且提供了比 ERC20 更强大的功能 , 仍然不能得到广泛的应用呢?除了 ERC20 代币已经广泛使用 , 大家宁肯忍受它的缺点 , 使用 approve and transferFrom 这种并不那么安全的方法 , 也不愿或无法升级外 , 还有一个重要的原因是:光兼容 ERC20 是不够的 , 还需要兼容现有的其它协议 。 如果每个协议都要单独评估应用 ERC777 的风险 , 成本太高 , 且容易造成误解 , 这显然不利于它的推广 。