Partly. Callbacks passed as function values and handlers registered in code can often be followed. Plugins chosen by name from configuration, or loaded at runtime, usually cannot. Where a tool cannot follow the link, it should report unknown or add a cautious edge, and you should supply the missing entry points yourself.
Why these patterns are hard
A static analysis reads code and follows calls. A direct call names its target. A callback or plugin breaks that link: the code says "call whatever is registered", and the registration may happen elsewhere or at runtime.
The reflection entry on Wikipedia describes the core capability: in languages such as Java, reflection lets a program inspect and invoke classes and methods at runtime without knowing their names at compile time. If the name comes from a file or a request, the analysis cannot know it in advance.
Patterns, from easy to hard
| Pattern | Can analysis follow it? | Notes |
|---|---|---|
| Function passed as an argument | Often | Needs alias or points-to reasoning |
| Handler registered in code | Often | If the registration call is visible |
| Interface with several implementations | Yes, with extra edges | Tends to over-approximate |
| Framework annotations and routing | Depends | Needs framework specific knowledge |
| Plugin named in configuration | Rarely | Name resolved at runtime |
| Class loaded from a downloaded file | No | Code is not present at analysis time |
How to keep results honest
- List your entry points explicitly. Routes, message consumers, scheduled jobs and plugin hooks. Anything the framework calls on your behalf should be an entry point.
- Add the plugins you ship. If a plugin directory is part of the product, include those modules in the analysis scope.
- Treat dynamic loading as a flag. Where the code loads a class by name, mark the dependencies on that path as unknown, not unreachable.
- Review the framework model. Ask whether the tool understands your web framework's routing and dependency injection, since those create calls no source line shows.
- Test with a seeded handler. Register a dummy handler that calls a harmless marker function, and check the tool sees it.
What a good report looks like
A trustworthy report says which entry points it assumed and lists the dynamic call sites it could not resolve. If it says nothing about either, you are being asked to trust silence.
A note on third party plugins
If customers can install their own plugins, your application can reach their code and, through it, any dependency they bring. Your reachability result covers what you analysed, not what a customer adds later. Say so in any statement you make.
Safeguard includes reachability analysis alongside SBOM and dependency scanning, and you can run a free scan at gold.safeguard.sh/scan to see the output on your own repository.
Quick check
Are callbacks always a problem?
No. Many are resolvable. The trouble starts when the target is chosen at runtime from data.
What is the quick fix for plugin gaps?
List plugin hooks as entry points and mark runtime-loaded paths as unknown instead of unreachable.
Sources
Last reviewed: 19 October 2026.