Skip to main content

sink_reachability_analysis

Function sink_reachability_analysis 

Source
pub fn sink_reachability_analysis(
    graph: &SqliteGraph,
    sources: &[i64],
    sinks: &[i64],
) -> Result<AHashMap<i64, Vec<i64>>, SqliteGraphError>
Expand description

Performs sink reachability analysis for all sinks.

Analyzes each sink to determine which taint sources can reach it. Returns a mapping of vulnerable sinks to their affecting sources.

§Arguments

  • graph - The graph to analyze
  • sources - Source node IDs where taint originates
  • sinks - Sink node IDs to analyze

§Returns

HashMap mapping vulnerable sink -> Vec<affecting_sources> Only includes sinks that have at least one affecting source.

§Complexity

  • Time: O(Sinks × (V + E)) - one backward BFS per sink
  • Space: O(V) for ancestors set (per sink)

§Algorithm

  1. Initialize result = empty HashMap
  2. For each sink:
    • Call propagate_taint_backward(graph, sink, sources)
    • If result.sources is non-empty (vulnerable):
      • Add entry: sink -> Vec<affecting_sources>
  3. Return result mapping

§Example

use sqlitegraph::{SqliteGraph, algo::sink_reachability_analysis};

let graph = SqliteGraph::open_in_memory()?;
// ... build graph with sources and sinks ...

let sources = vec![1, 2, 3];   // User input nodes
let sinks = vec![10, 20, 30];  // SQL query nodes

let vulnerabilities = sink_reachability_analysis(&graph, &sources, &sinks)?;

if vulnerabilities.is_empty() {
    println!("No vulnerabilities found!");
} else {
    println!("Found {} vulnerable sinks:", vulnerabilities.len());
    for (sink, affecting_sources) in vulnerabilities {
        println!("  Sink {} is reachable from sources: {:?}", sink, affecting_sources);
    }
}