3 ms·
> So what if you use a library to do one thing that just happens to do 100 other things (this having a much larger attack surface and bug potential)? I’ve wond
by FridgeSeal 5y ago
> So what if you use a library to do one thing that just happens to do 100 other things (this having a much larger attack surface and bug potential)?
I’ve wondered about this for a while, and one idea that’s crossed my mind is whether compiler stages could be introduced to do this. For example, you add a dependency, you use a few methods and structures. You compile it, the compiler goes through your code, looks at what traits, implementations, etc that you do and don’t use, it grabs just the code required to satisfy these, and proceeds as normal. At the end it spits out a little report for you telling you what specific things it included/excluded from your binary/library. Like tree-shaking in JS but better.
Maybe this already happens during dead-code-elimination passes, or during some other compiler step, maybe most of our libraries are far too interconnected/non-modular to be able to do this without ending up with the whole dependency anyway, maybe it’s computationally infeasible due to some result in Computer Science, I don’t know-and wouldn’t really know where to look to find out-but if it could be done, and if we could go even further to embed this metadata into the resulting binary itself, we’d at least have a provable way of saying “my application is safe from x because it does not include <vulnerable part of lib y>”.
I imagine to do this, you’d need to operate on source code-unless there’s some magic way to do it with precompiled binaries-and runtime dynamism would make things extra difficult, but it’s an interesting idea.
- kelnos 5y agoThis is pretty normal for compiled languages like C, C++, and Rust; the linker will throw out functions and classes that aren't used. In Java it's a bit different, because the compiler doesn't know if some code is using reflection to talk to some other code, so it can't safely throw away stuff that isn't directly referenced. Even then, tools like ProGuard can help you trim out code you don't use, but I don't think they're used all that often outside of mobile. But the log4j thing really isn't in the same class because it's not really "code that wasn't used". It's code that probably users didn't expect was there, and if they knew would probably not want used, but it's there, and the proper functioning of the library included that code path that allowed for JNDI interpolation. Whether or not that code is really "needed" is not something the compiler can really figure out, at least not without teaching the compiler that very very very specific thing (which would be madness). And even then, let's say you bizarrely wanted to be able to do things very much like what the log4j exploits do, there's no way the compiler (or even some kind of specific purpose-built code scanner) can know whether or not some string that might be supplied by a user in the future is going to trigger this JNDI interpolation code.