Note: This is the artifact of a research project designed to help static analysis developers reason about and localize the unsoundness issues of their tool.
Description
Summary
WALA does not model the return value of java.lang.reflect.Proxy.newProxyInstance(...) when constructing the call graph. As a result, dynamically generated proxy objects are not assigned any corresponding InstanceKey, causing the receiver points-to set to remain empty at subsequent proxy method invocations.
Consequently, method calls performed on proxy instances are omitted from the generated call graph.
Minimal Reproduction
I have attached a Maven-based minimal project that creates a dynamic proxy using Proxy.newProxyInstance(...) and subsequently invokes a method on the proxy instance.
How to reproduce
Run WALA call graph on the attached project using the provided Maven setup. WALA is run with 0-cfa algorithm, full reflection support and default configuration. version: 1.5.7
The script to run the tool using JCG interface as attached.
Unzip the compressed file. The reproducing test case is in reproducing/ directory and the script to run the analysis is in the interface/ directory.
attachment.zip
python analysis_interface.py --framework WALA --algorithm 0-CFA --project reproducing --type static --reproducing_test_case_path [path to test case directory ../reproducing] --boundary_id 1
Observed Behavior
-
WALA analyzes the call to Proxy.newProxyInstance(...) but does not model the dynamically generated proxy object returned by the method
-
No InstanceKey is created for the returned proxy instance
-
The receiver variable corresponding to the proxy object therefore has an empty points-to set
-
When processing the invocation on the proxy object, WALA does not resolve any target methods because the receiver points-to set is empty
-
Consequently, the call graph contains no edge to:
com/sun/proxy/$Proxy0.bar(Ljava/lang/Object;)V
Expected Behavior
For programs that create objects using Proxy.newProxyInstance(...) and invoke methods through those proxy instances:
-
The analysis should model the returned proxy object
-
The receiver variable should be associated with an appropriate InstanceKey
-
A call graph edge should exist for the invoked proxy method, for example:
{"caller": "com.example.Main.main([Ljava/lang/String;)V", "callee": "com.sun.proxy.$Proxy0.bar(Ljava/lang/Object;)V"}
Notes on Implementation (inspected behavior)
From code inspection:
- WALA does not appear to provide a dedicated
SSAContextInterpreter or synthetic summary for Proxy.newProxyInstance(...)
- The call to
Proxy.newProxyInstance(...) is treated as an opaque operation with respect to the returned proxy object
- During invoke processing,
SSAPropagationCallGraphBuilder iterates over the receiver points-to set to resolve targets
- Since the receiver points-to set for the proxy instance is empty, the target resolution logic is never executed and no call edge is added
Relevant locations:
ReflectionContextInterpreter.java
SSAPropagationCallGraphBuilder.java (invoke processing around receiver points-to propagation)
BypassMethodTargetSelector.java
Impact
If the omission of this edge is unintended, it may affect analyses that rely on sound modeling of reflection and dynamically generated proxy objects. Dynamic proxies are commonly used in Java frameworks and middleware (e.g., dependency injection frameworks, RPC systems, AOP frameworks, and testing utilities). Missing these proxy-related edges could reduce call graph completeness and impact downstream analyses that depend on accurate interprocedural information, such as vulnerability detection, impact analysis, and reasoning about application behavior under reflection.
Note: This is the artifact of a research project designed to help static analysis developers reason about and localize the unsoundness issues of their tool.
Description
Summary
WALA does not model the return value of
java.lang.reflect.Proxy.newProxyInstance(...)when constructing the call graph. As a result, dynamically generated proxy objects are not assigned any correspondingInstanceKey, causing the receiver points-to set to remain empty at subsequent proxy method invocations.Consequently, method calls performed on proxy instances are omitted from the generated call graph.
Minimal Reproduction
I have attached a Maven-based minimal project that creates a dynamic proxy using
Proxy.newProxyInstance(...)and subsequently invokes a method on the proxy instance.How to reproduce
Run WALA call graph on the attached project using the provided Maven setup. WALA is run with 0-cfa algorithm, full reflection support and default configuration. version: 1.5.7
The script to run the tool using JCG interface as attached.
Unzip the compressed file. The reproducing test case is in reproducing/ directory and the script to run the analysis is in the interface/ directory.
attachment.zip
Observed Behavior
WALA analyzes the call to
Proxy.newProxyInstance(...)but does not model the dynamically generated proxy object returned by the methodNo
InstanceKeyis created for the returned proxy instanceThe receiver variable corresponding to the proxy object therefore has an empty points-to set
When processing the invocation on the proxy object, WALA does not resolve any target methods because the receiver points-to set is empty
Consequently, the call graph contains no edge to:
Expected Behavior
For programs that create objects using
Proxy.newProxyInstance(...)and invoke methods through those proxy instances:The analysis should model the returned proxy object
The receiver variable should be associated with an appropriate
InstanceKeyA call graph edge should exist for the invoked proxy method, for example:
{"caller": "com.example.Main.main([Ljava/lang/String;)V", "callee": "com.sun.proxy.$Proxy0.bar(Ljava/lang/Object;)V"}Notes on Implementation (inspected behavior)
From code inspection:
SSAContextInterpreteror synthetic summary forProxy.newProxyInstance(...)Proxy.newProxyInstance(...)is treated as an opaque operation with respect to the returned proxy objectSSAPropagationCallGraphBuilderiterates over the receiver points-to set to resolve targetsRelevant locations:
ReflectionContextInterpreter.javaSSAPropagationCallGraphBuilder.java(invoke processing around receiver points-to propagation)BypassMethodTargetSelector.javaImpact
If the omission of this edge is unintended, it may affect analyses that rely on sound modeling of reflection and dynamically generated proxy objects. Dynamic proxies are commonly used in Java frameworks and middleware (e.g., dependency injection frameworks, RPC systems, AOP frameworks, and testing utilities). Missing these proxy-related edges could reduce call graph completeness and impact downstream analyses that depend on accurate interprocedural information, such as vulnerability detection, impact analysis, and reasoning about application behavior under reflection.