如何使用AOP拦截File、FileReader、FileWriter、FileInputStream和FileOutputStream的构造函数?

7
我希望能够拦截File、FileReader、FileWriter、FileInputStream和FileOutputStream的构造函数,并防止任何文件名包含“..”(以防止路径遍历攻击)或“\0”(以防止文件名空字符攻击)。
我还有一个关于如何使用SecurityManager做同样事情的开放性问题,但是没有人回答过它,所以我希望这种替代方法能够奏效。
这是为一个在tomcat上的spring webapp。
我知道我可以通过创建自己的SafeFile、SafeFileReader等类并修改代码来使用它们来手动完成此操作。然而,我们的代码中有960个地方使用了这些对象的构造函数,所以除非这是唯一的方法,否则我更愿意避免这样做。

2
你有960个服务接受文件路径作为参数吗?虽然你可能有960个与文件交互的地方,但是路径的来源真的无处不可信吗? - Brett Okken
不使用AOP这样的重型方法,使用工厂创建文件是否更容易呢?修改960个位置以使用该工厂,您可以在没有切面的情况下解决它。修改所有这些位置应该不难重构。当然,您可以使用loadtime weaving(而不是纯Spring AOP)对AspectJ进行任何想要的操作,并修改所提到的类,但感觉就像用大炮打死一只苍蝇。 - M. Deinum
2个回答

3
尽管Sotirios Delimanolis在此处链接的答案是正确的(我自己写的),因为需要使用AspectJ而不是基于代理的Spring AOP,请注意,您不能使用execution(*.new(..))来处理JDK类,因为这些类默认情况下被排除在方面编织之外。为了编织到JDK类中(执行连接点在被调用代码中逻辑上),您需要修改JDK的rt.jar或至少将修改后的JDK类放置在引导类路径上,在JDK本身之前。这是可能的,但并不那么简单。
但是有一个更简单的选择:通过call(*.new(..))编织到调用者(您自己的代码)而不是被调用者-请注意call()execution()之间的区别。这反过来意味着您无法拦截从您自己的编织代码或JDK本身发出的对JDK类的调用。因此,如果您需要100%的解决方案,即使是不受您自己控制的代码,您最终也会编织JDK。但是,如果您只想保护自己的类,则可能不需要这样做。:-)
尽管我非常喜欢AspectJ,但我也要强调我坚定地支持清洁代码和重构。任何像IntelliJ IDEA或Eclipse这样的体面IDE都应该很容易地重构960个调用以使用安全包装类,就像您建议的那样。如果这么重要,为什么不这样做呢?如果没有几秒钟,IDEA的结构搜索和替换就可以为您完成。 AOP可以用来修补自己代码的缺陷,但是不应该使用。因此,请进行重构,之后您会感到更加愉快。

1
就我所知,既然你知道如何使用aop来完成它,然后又说我应该进行重构,那么我就继续进行了重构。我为QA部门感到难过,但这种方式肯定更容易理解。 - HappyEngineer

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接