How can I use AOP to intercept the constructor of

2019-02-17 09:33发布

问题:

I want to intercept the constructor of File, FileReader, FileWriter, FileInputStream and FileOutputStream and prevent any filenames from containing ".." (to prevent path traversal attacks) or "\0" (to prevent filename null character attacks).

I have another open question about how to do this same thing using SecurityManager, but no one has answered it yet, so I was hoping this alternate method would work.

This is for a spring webapp on tomcat.

I know that I could manually do this by making my own SafeFile, SafeFileReader, etc., classes and modifying the code to use those instead. However, there are 960 places in our code that use the constructors for those objects, so I'd prefer to avoid that unless it's the only way.

回答1:

Even though the answer linked to here by Sotirios Delimanolis is correct (I wrote it myself) insofar as AspectJ instead of proxy-based Spring AOP is necessary, please note that you cannot use execution(*.new(..)) for JDK classes because those are excluded from aspect weaving by default. In order to weave into JDK classes (execution joinpoints are logically in the callee code) you need to modify the JDK's rt.jar or at least put the modified JDK classes on the bootclasspath before the JDK itself. This is possible, but not so trivial.

But there is a simpler option: weave into the callers (your own code), not the callees via call(*.new(..)) - note the difference between call() and execution(). This in turn means that you cannot intercept calls to JDK classes not made from your own woven code or from the JDK itself. So if you need a 100% solution even for code not under your own control, you will end up weaving the JDK. Probably this is not necessary though if you just want to secure your own classes. :-)

As much as I am a huge fan of AspectJ, I want to highlight that I am also a firm proponent of clean code and refactoring. Any decent IDE like IntelliJ IDEA or Eclipse should make it quite simple to refactor 960 calls to use a safe wrapper class like you suggested. Why do you not do this if it is so important? IDEA's structural search and replace does that for you in minutes, if not seconds. AOP can, but should not be used to patch up your own code's deficiencies. So please go refactor, you will be much happier afterwards.



回答2:

Simple Spring AOP (with proxying) does not support constructor join points.

Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans).

If you can go with aspectj, that should do the trick. Otherwise, you'll have to play with bytecode yourself.