代码精进之路
范学雷
前 Oracle 首席软件工程师,Java SE 安全组成员,OpenJDK 评审成员
38234 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
结束语 (1讲)
代码精进之路
15
15
1.0x
00:00/00:00
登录|注册

36 | 继承有什么安全缺陷?

问题的解决方法
难以察觉的潜在问题
安全漏洞示例
为父类添加新方法
变更父类或者父类方法的规范
改变未继承方法的实现
问题分析
MyFilePermission类
涉及敏感信息的类的可扩展性
可扩展的类的影响
使用代理模式
变更可扩展类时的谨慎小心
Hashtable类的例子
影响类型
问题代码示例
OpenJDK为何放弃可扩展性
可扩展性的衡量标准
欢迎分享经验和看法
代理模式的缺陷
设计模式的优点和缺陷
个人看法
防范此类风险的方法
类库升级的影响
父类对子类行为的影响
FilePermission类的final声明
一起来动手
小结
麻烦的继承
继承安全缺陷
继承安全缺陷

该思维导图由 AI 生成,仅供参考

有时候,为了解决一个问题,我们需要一个解决办法。可是,这个办法本身还会带来更多的问题。新问题的解决带来更新的问题,就这样周而复始,绵延不绝。
比如上一篇文章,我们说到的敏感信息通过异常信息泄露的问题,就是面向对象设计和实现给我们带来的小困扰。再比如前面还有一个案例,说到了共享内存或者缓存技术带来的潜在危害和挑战,这些都是成熟技术发展背后需要做出的小妥协。只是有时候,这些小小的妥协如果没有被安排好和处理好,可能就会带来不成比例的代价。

评审案例

我们一起来看一段节选的 java.io.FilePermission 类的定义。你知道为什么 FilePermission 被定义为 final 类吗?
package java.io;
// <snipped>
/**
* This class represents access to a file or directory. A
* FilePermission consists of a pathname and a set of actions
* valid for that pathname.
* <snipped>
*/
public final class FilePermission
extends Permission implements Serializable {
/**
* Creates a new FilePermission object with the specified actions.
* <i>path</i> is the pathname of a file or directory, and
* <i>actions</i> contains a comma-separated list of the desired
* actions granted on the file or directory. Possible actions are
* "read", "write", "execute", "delete", and "readlink".
* <snipped>
*/
public FilePermission(String path, String actions);
/**
* Returns the "canonical string representation" of the actions.
* That is, this method always returns present actions in the
* following order: read, write, execute, delete, readlink.
* <snipped>
*/
@Override
public String getActions();
/**
* Checks if this FilePermission object "implies" the
* specified permission.
* <snipped>
* @param p the permission to check against.
*
* @return <code>true</code> if the specified permission
* is not <code>null</code> and is implied by this
* object, <code>false</code> otherwise.
*/
@Override
public boolean implies(Permission p);
// <snipped>
}
FilePermission 被声明为 final,也就意味着该类不能被继承,不能被扩展了。我们都知道,在面向对象的设计中,是否具备可扩展性是一个衡量设计优劣的好指标。如果允许扩展的话,那么想要增加一个“link”的操作就会方便很多,只要扩展 FilePermission 类就可以了。 但是对于 FilePermission 这个类,OpenJDK 为什么放弃了可扩展性?

案例分析

如果我们保留 FilePermission 的可扩展性,你来评审一下下面的代码,可以看出这段代码的问题吗?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文通过分析Java中的FilePermission类为例,探讨了继承带来的潜在安全风险。文章指出,FilePermission被定义为final类,禁止继承的主要原因是为了避免子类改变父类的规范和行为,从而绕过安全机制。通过一个案例分析,文章展示了如果允许FilePermission类可被继承,可能导致子类改变父类行为,绕过安全机制的问题。文章强调了在面向对象设计中,是否允许继承是一个需要仔细权衡的问题,final关键字的使用可以减轻对未来安全风险的担忧。最后,文章提醒读者在设计公共类或方法时,需要谨慎考虑是否允许继承,以避免潜在的安全风险。文章还讨论了可扩展类对子类和父类的相互影响,以及涉及敏感信息的类增加可扩展性可能带来的问题。同时,文章提出了谨慎变更可扩展类和使用代理模式来降低父类对子类的影响的建议。文章以此引发读者对设计模式的思考和讨论。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《代码精进之路》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • LDxy
    代理模式就完全丧失了继承带来的好处

    作者回复: 不使用继承,当然就没有了继承的好处,也没有了继承的坏处。 不同场景的不同选择,离开场景,我们就没有办法识别好与坏。

    2019-08-29
    2
    5
  • 轻歌赋
    有个问题,案例中hashtable增加了一个entryset后,攻击者如何直接访问对象的entryset呢? 以web程序为例的话,我想不出用户如何传入可以执行的代码,能过直接让权限检查的调用对象直接执行entryset,也看不出对方如何能够重写我服务端的代码或者继承并且被jvm加载 老师能给个实际的例子吗

    作者回复: 访问不了对象当然不行。你先找找对象可以访问的场景。 换种场景你可能就熟悉了,比如说浏览器,访问一个页面的用户名密码,怎么不被正在访问的另一个页面窃取?

    2019-03-27
    2
  • hua168
    如果是web程序的话,攻击者是怎么查看我们内部程序? 如果是API接口的话,这些方法我们不是隐藏起来,不公开,它怎么绕过漏洞攻击?

    作者回复: 没太明白这两个问题。 无法访问,当然就没问题。 公开接口的问题是,公开了,就可以被使用,使用场景什么样的,我们不知道。 有没有场景,漏洞无法被攻击者利用,当然有的。一个场景没问题,不代表另一个场景就没问题。多用户、多应用、多类库的场景,这些用户之间、应用之间、类库之间,彼此可以不信任,可以参考现代编程语言和操作系统的domain的概念,或者虚拟机、云计算、远程调用等的技术架构。

    2019-03-27
    1
  • 思君满月
    这篇文章真的太棒了。 对于文中提到的final类,我深有体会。以前只是从语法层面知道final不能被继承,至于有什么使用场景不是很清楚,也几乎没用过final类。直到最近开始在公司里写一些标准库,才意识到它的重要性。 除了使用final类防止继承外,还有个更“狠”的方式,就是non public类。non public不同的包无法访问,完全杜绝了用户代码对这个类的使用。用来保护框架或库的核心逻辑,Spring的源码中就有大量的non public。

    作者回复: 嗯,能不public,就不要public;永远只赋予最小的权限。

    2023-03-18归属地:上海
  • 刚毅坚卓
    另一方面,当我们扩展一个类时,如果涉及到敏感信息的授权与保护,可以考虑使用代理的模式,而不是继承的模式 想问一下什么是代理模式

    作者回复: 可以看看这个: https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming)

    2022-05-01
  • 天佑
    嗯,子类会把父类的安全实现改的不安全 父类扩展新方法时,会给子类添乱,比如子类费劲心机防绕行,父类却悄悄加了个“后门”。。。
    2019-03-27
    4
  • ifelse
    一方面,当我们变更一个可扩展类时,要极其谨慎小心;另一方面,当我们扩展一个类时,如果涉及到敏感信息的授权与保护,可以考虑使用代理的模式,而不是继承的模式。--记下来
    2022-07-31归属地:浙江
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部