Skip to content

Missing Reflection-Sensitive URLStreamHandler Modeling Breaks HttpURLConnection Dispatch #2283

Description

@mohPYdev

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

Soot does not fully model the runtime resolution and allocation chain behind URL.openConnection(), specifically the creation of protocol-specific URLStreamHandler instances and their role in producing concrete URLConnection objects.

As a result, the receiver of HttpURLConnection.disconnect() may have an empty points-to set during call graph construction. This happens because the concrete URLConnection subtype is created indirectly through reflective class loading (Class.forName(...)) on a non-constant string and subsequent native-assisted handler initialization, which is not resolved by SPARK’s default reflection and native modeling.

Consequently, virtual dispatch on the returned connection object is not resolved, leading to missing call graph edges for disconnect().


Minimal Reproduction

A minimal Java application is provided that opens an HTTP connection using URL.openConnection() and then calls disconnect() on the resulting object.

How to reproduce

Run Soot/SPARK call graph construction on the provided project using the included analysis interface script.
soot version: 4.4.1
java version: 8

Unzip the artifact. The reproducing example is located in reproducing/, and the driver script is in interface/.

attachment.zip

python analysis_interface.py \
  --framework Soot \
  --algorithm SPARK \
  --project reproducing \
  --type static \
  --reproducing_test_case_path ../reproducing \
  --boundary_id 1

Observed Behavior

  • url.openConnection() is modeled, but the returned object lacks a precise concrete type
  • The intermediate URLStreamHandler resolution via Class.forName(...) with a concatenated string is not resolved by SPARK
  • As a result, the allocation of sun.net.www.protocol.http.HttpURLConnection is not propagated into the points-to set
  • The receiver of conn.disconnect() has an empty or incomplete points-to set
  • The call graph does not include the edge:
sun.net.www.protocol.http.HttpURLConnection.disconnect()
  • The failure occurs even though the invokevirtual instruction is present in bytecode

Expected Behavior

For programs that use URL.openConnection():

  • The analysis should model the full protocol handler resolution chain
  • The URLStreamHandler subtype should be resolved to its concrete implementation (e.g., HTTP handler)
  • The resulting URLConnection object should be assigned a concrete type (HttpURLConnection)
  • Virtual dispatch on disconnect() should be resolved
  • The call graph should include:
{
  "caller": "com.example.App.runConnection()V",
  "callee": "sun.net.www.protocol.http.HttpURLConnection.disconnect()"
}

Notes on Implementation (inspected behavior)

From inspection of SPARK and Soot’s call graph construction:

  • The receiver of conn.disconnect() is computed from the return value of URL.openConnection()
  • URL.openConnection() delegates to URLStreamHandler.openConnection()
  • The concrete handler class is instantiated via Class.forName(...) inside URL.getURLStreamHandler()
  • SPARK’s default reflection model only resolves Class.forName() when the argument is a constant string
  • In this case, the handler class name is constructed dynamically (concatenation), so no resolution occurs
  • As a result, the concrete handler (sun.net.www.protocol.http.Handler) is never added to the points-to set
  • Consequently, the allocation of HttpURLConnection inside the handler is not propagated
  • The virtual call resolution for disconnect() fails due to an empty receiver set

Relevant components:

  • OnFlyCallGraphBuilder.java
  • NativeMethodDriver.java
  • virtualedges.xml
  • SPARK reflection handling for Class.forName

The root issue is incomplete modeling of the JDK’s dynamic protocol handler mechanism, specifically the reflection-based loading of URLStreamHandler implementations and their influence on object allocation propagation.


Impact

If this limitation is unintended, it significantly affects precision of call graph construction in network-heavy Java applications.

The URL.openConnection() pattern is widely used in HTTP clients, SDKs, and enterprise systems. Missing its modeling leads to:

  • Loss of virtual dispatch resolution for URLConnection implementations
  • Incomplete call graphs for networking libraries
  • Under-approximation of API usage in security and dependency analysis
  • Missing edges in widely used JDK-based communication flows
  • Reduced accuracy of interprocedural analyses that depend on network behavior modeling

Overall, this results in systematic under-modeling of JDK protocol-based object creation and its downstream effects on call graph construction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions