{
  "variant_id": "pruva-cve-2026-50289-variant-search",
  "created_at": "2026-07-16T08:24:00Z",
  "variant_summary": "Negative variant/bypass search for CVE-2026-50289 (systeminformation networkInterfaces() source-directive command injection). The 5.31.7 fix replaces execSync(`cat ${file} | grep ...`) with fs.readFileSync, removing the shell from the source-directive recursion. No bypass on 5.31.7 or latest v5.31.17; the sibling iface-directive name data path does not reach a shell sink.",
  "relation": "newer_version_sibling",
  "origin_kind": "pruva_variant",
  "repository": "sebhildebrandt/systeminformation",
  "submitted_target": {
    "target_kind": "commit",
    "commit_sha": "da1cbf5eb09907cf5c3431f4c9ea441b7a227617",
    "version": "5.31.6",
    "ref": "v5.31.6",
    "display": "sebhildebrandt/systeminformation@v5.31.6 (da1cbf5)"
  },
  "variant_target": {
    "target_kind": "commit",
    "commit_sha": "bbfddde48672d0ee124fefdb3cb4442fd9dd4f03",
    "version": "5.31.7",
    "ref": "v5.31.7",
    "display": "sebhildebrandt/systeminformation@5.31.7 (bbfddde, fixed) and v5.31.17 (9e79988, latest)"
  },
  "same_root_cause_confidence": "high",
  "same_surface_confidence": "high",
  "claimed_surface": "library_api",
  "validated_surface": "library_api",
  "required_entrypoint_kind": "function_call",
  "required_entrypoint_detail": "public si.networkInterfaces() / aggregate callers getStaticData()/getAllData() on Linux -> getLinuxDHCPNics() -> checkLinuxDCHPInterfaces('/etc/network/interfaces')",
  "attacker_controlled_input": "Shell-metacharacter-bearing path in a 'source' directive line within a file reachable through /etc/network/interfaces source recursion (e.g. /etc/network/interfaces.d/*); also tested 'iface'-directive interface name as a sibling data path",
  "trigger_path": "networkInterfaces() -> getLinuxDHCPNics() -> checkLinuxDCHPInterfaces() -> recursive source traversal -> (vulnerable) execSync(`cat ${file} | grep 'iface|source'`) with unquoted ${file} | (fixed) fs.readFileSync(file)",
  "observed_impact_class": "none",
  "exploitability_confidence": "high",
  "evidence_scope": "realistic_harness",
  "runtime_manifest_present": true,
  "end_to_end_target_reached": true,
  "inferred": false,
  "claim_block_reason": null,
  "blocking_mitigation": "Fix in commit bbfddde (5.31.7): replaced execSync(`cat ${file} 2> /dev/null | grep 'iface\\|source'`) with fs.readFileSync(file, { encoding: 'utf8' }) plus in-JS .filter(/iface|source/). Removes the shell from the source-directive recursion; confirmed effective on 5.31.7 and latest v5.31.17. Sibling iface-directive name data path does not reach a shell.",
  "file_path": "lib/network.js",
  "line_start": 549,
  "line_end": 566,
  "secondary_anchors": [
    {
      "file_path": "lib/network.js",
      "line_start": 573,
      "line_end": 588
    },
    {
      "file_path": "lib/network.js",
      "line_start": 614,
      "line_end": 636
    }
  ],
  "review_scope_paths": [
    "lib/network.js",
    "lib/util.js"
  ],
  "artifact_refs": {
    "variant_manifest": "bundle/vuln_variant/variant_manifest.json",
    "validation_verdict": "bundle/vuln_variant/validation_verdict.json",
    "runtime_manifest": "bundle/vuln_variant/runtime_manifest.json",
    "repro_log": "bundle/logs/vuln_variant_reproduction.log",
    "root_cause_equivalence": "bundle/vuln_variant/root_cause_equivalence.json",
    "reproducer": [
      "bundle/vuln_variant/reproduction_steps.sh"
    ]
  }
}
