Skip to content
sparkrewPublic

About

Mapping runtime access privileges to third-party dependencies

Resources

Stars

1 star

Watchers

6 watching

Forks

Repository files navigation

Build Status

Theo

Theo monitors access privileges originating from third-party dependencies via static analysis. It identifies sensitive Java API calls (filesystem, network, reflection, process execution, etc.) made by each dependency, determines which of those are reachable from the client project's code, detects changes across runs, and checks dependencies for known CVEs.

Modules

Module Description
theo-commons Shared utilities: sensitive API definitions (sensitive_apis.json), package matching
theo-static-maven-plugin Maven plugin with preprocess, analyze, cve-check, snapshot, and history goals
package-static-analyzer CLI tool that analyzes a single package JAR for sensitive API usage
package-miner Batch analysis tool for mining Maven Central packages

Quick start

Build all modules:

mvn clean install

Add the plugin to the target project's pom.xml:

<build>
  <plugins>
    <plugin>
      <groupId>io.github.sparkrew</groupId>
      <artifactId>theo-static-maven-plugin</artifactId>
      <version>1.0-SNAPSHOT</version>
    </plugin>
  </plugins>
</build>

Run the analysis:

mvn theo-static:analyze -Dtheo.packageNames=com.example.app

Run the analysis with CVE checking:

mvn theo-static:cve-check -Dtheo.packageNames=com.example.app

Goals

  • preprocess -- Builds a package-to-dependency map from Maven's resolved dependencies.
  • analyze -- Analyzes all dependencies for sensitive API usage, determines client project reachability, detects changes from the previous run, and generates HTML reports.
  • cve-check -- Runs the full analysis (everything analyze does) and then queries OSV.dev for known vulnerabilities, augmenting reports with CVE badges and unaudited capability indicators.
  • snapshot -- Saves the current analysis as a named snapshot in the history folder (~/.theo/history/).
  • history -- Generates a history.html table showing the presence of reachable sensitive APIs across all saved snapshots.

Configuration

Property Default Description
theo.packageNames (required) Comma-separated package names of the client project
theo.skipSameGroupId true Skip dependencies that share the client project's groupId
theo.directOnly false When true, only analyze direct dependencies (skip transitive)
theo.reachableOnly false When true, only generate the reachable report
theo.verbose true Show all changes in CLI output; when false, only reachable changes
theo.cacheDir ~/.theo/cache Persistent cache directory
theo.reportDir target/theo-report Report output directory
theo.analyzerJarPath (auto-resolved) Path to the package-static-analyzer JAR
theo.historyDir ~/.theo/history History folder for snapshots
theo.snapshotLabel (auto: version-N) Custom label for a snapshot
theo.compareWith 0 Compare against the Nth most recent snapshot (0 = use last run)
theo.failOnChange false Fail the build if reachable sensitive APIs have additions or modifications

To include same-groupId dependencies in the analysis:

mvn theo-static:analyze -Dtheo.packageNames=com.example.app -Dtheo.skipSameGroupId=false

Reports

The analyze goal generates three HTML reports in target/theo-report/. Sensitive APIs are grouped by category (Filesystem, Network, Process) and subcategory, based on the categorization from Table II of the paper.

  • all-dependencies.html -- Every sensitive API from every dependency, grouped by category, with access type (direct/indirect) and reachable api highlighting.
  • reachable.html -- Only sensitive APIs reachable from the client project's code, with full call paths and decompiled source. Includes a breakdown of direct vs transitive dependencies, and transitive deps show which direct dependency pulled them in.
  • changes.html -- What changed since the last run (added, modified, removed dependencies and their sensitive API changes).
  • history.html -- (generated by the history goal) Table showing reachable sensitive APIs across all saved snapshots, with D/I access type and dependency versions.
  • pom-theo-suggestions.xml -- (generated alongside the project POM when changes are detected) Contains <dependencyManagement> entries to revert version-changed dependencies that introduced new reachable sensitive APIs. Includes dependency trail comments for transitive deps.

When running cve-check, the reports are augmented with CVE badges (linked to advisories) placed under the relevant category using CWE-based mapping. APIs reachable from the client with no known CVE in their category get an "unaudited capability" badge indicating the associated CWE.

Snapshots

To track how reachable sensitive APIs evolve over time, save snapshots after analysis runs:

mvn theo-static:analyze -Dtheo.packageNames=com.example.app
mvn theo-static:snapshot

By default snapshots will be named according to the project version. A custom name can be passed with the flag snapshotLabel as given below.

mvn theo-static:snapshot -Dtheo.snapshotLabel=v2.3.0-release

Generate the history table from all saved snapshots:

mvn theo-static:history

To compare the current run against a specific snapshot instead of the automatic last-run:

mvn theo-static:analyze -Dtheo.packageNames=com.example.app -Dtheo.compareWith=2

Build gate

Use theo.failOnChange to enforce a review gate in CI. When enabled, the build fails if reachable sensitive APIs have additions or modifications (removals are allowed):

mvn theo-static:analyze -Dtheo.packageNames=com.example.app -Dtheo.failOnChange=true

When the build fails, Theo generates pom-theo-suggestions.xml next to the project POM. This file contains <dependencyManagement> entries that pin dependencies back to their previous versions. For transitive dependencies, it includes comments showing the dependency trail and which direct dependency pulled them in.

To accept the changes and update the baseline, run a snapshot:

mvn theo-static:snapshot

Cache

Analysis results are cached in ~/.theo/cache/ by default (configurable via theo.cacheDir). The cache survives mvn clean and avoids re-analyzing unchanged dependencies.

The first run can take a few minutes to complete becuase it analyzes all the dependencies one by one, but the subsequent runs will be faster with caching.

Change detection compares the current run against the previous one stored in the cache. For accurate diffs, use the same mode consistently. Switching between reachableOnly and full analysis between runs will produce misleading changes because the two summaries have different scopes.

Like many other tools with caches, Theo also suffers from the age-old problem of cache invalidation. If you see any weird results between runs, please clear the cache (rm -rf ~/.theo/cache/) and try again.

Design

For design decisions and architecture details, see Design.md.

About

Mapping runtime access privileges to third-party dependencies

Resources

Stars

1 star

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages