mcpField
C
create-pass-through-approximation

create-pass-through-approximation

github.com/seqraSecurity17059 installsUpdated 2d ago
Repository

About create-pass-through-approximation

A security skill for OpenTaint that models how data passes through opaque methods, then records matching passThrough configurations and build tracking. It is intended for analyzing method-level taint propagation from source code.

Key features

  1. 01Trace data through receivers and arguments
  2. 02Model return, argument, and receiver flows
  3. 03Use virtual fields for stored data
  4. 04Write per-package passThrough configs
  5. 05Update build.done tracking

Use cases

  1. 01Restore taint flows lost at opaque calls
  2. 02Model setters and getters sharing stored data
  3. 03Add or repair assigned method approximations

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/seqra/opentaint --skill create-pass-through-approximation

After installing, type/create-pass-through-approximationin Claude Code to confirm it loaded.

Bundled filesreferences/java.md

Details

From the project README

Skill: Create PassThrough Approximation

Model a dropped method's taint propagation as a passThrough approximation — a config that tells the engine how data moves from a method's inputs to its outputs, so a flow the analyzer lost through the opaque call is restored.

Inputs

Provided by the caller, fall back to the default value when omitted. Ask back only when a required input is missing and has no sensible default

  • project-root (optional) — root of the target project. Opentaint keeps all analysis artifacts under the fixed <project-root>/.opentaint/ directory, so every .opentaint/... path below resolves there. Default: current directory
  • language (required) — target language for this project and language-specific instructions
  • batch (required) — the batch id; its passthrough entries live in .opentaint/tracking/approximations/<batch>.yaml, and you append the ones you build to that file's build.done
  • methods (optional) — a specific { method, signature } subset to (re)work instead of the whole passthrough bucket, when the caller needs only those

Workflow

1. Understand the propagation

Take the batch's passthrough methods not yet in build.done (or the specific methods you were handed) and study each from its real code: read the source (per the language reference). Model each method purely from what its own code does, independent of how the project uses it — the config describes the method's intrinsic propagation. Answer: where does the input data go? Data that arrives on the receiver or an argument — does it come back out, through the return value, an argument the method writes into, the receiver, or an object or field it stores into? Note too whether the object holds the data between calls (a setter stashes it and a getter hands it back later, or a builder accumulates it) — that needs a virtual field. That shape is what the config expresses.

2. Write the config

Write one passThrough config per package under .opentaint/pass-through (the format and patterns are in the language reference). A method already in build.done and not explicitly handed in methods is built and trusted — leave it and its config as-is. Repair an explicitly handed method in its existing config; add a new method to its existing package config rather than rewriting the file. Two ideas drive the copy:

  • Cover every position — this and each argument: copy each to where its data flows, or to itself when it flows nowhere
  • When the data lives in the object between calls, route the writer and the reader through a shared virtual field — a nominal storage location both name identically. What the writer stashes there is what the reader pulls back, if the two name it differently, the taint is lost.
3. Re-check your configs

Before returning, confirm you wrote a passThrough for every method you were to model, and that each config's copies actually match how the method moves data in its source — every position covered, and a writer and its reader sharing the identical virtual field. Append each written method not already present to build.done (per Tracking); a repaired method remains recorded there.

Output

Short and concise report of what was done

Artifacts:
  • .opentaint/pass-through/<package-kebab>.yaml — the passThrough config(s); one per package (a dependency can span several), the file named for that package (the whole-file form is in the language reference)
  • the cleanly-built methods present in the batch file's build.done (new methods appended; repaired methods already recorded, per Tracking)
Summary:
  • the config paths written and the methods modeled

Tracking

.opentaint/tracking/approximations/<batch>.yaml — one batch's callable classification, <batch> the plan's filename stem. Every callable sits in exactly one verdict bucket, keyed with the exact language-specific method and signature from the plan so distinct variants stay separate:

  • passthrough, dataflow — modeled carriers; each entry { method, signature }
  • skipped — terminal non-carriers; each { method, signature, reason }
  • engine_issues — a separate bucket for carriers the engine provably can't propagate (built but still dropped); each { method, signature, reason }. Terminal and treated just like skipped — the only difference is the reason. merge-skipped carries it into skipped.yaml as its own engine_issues group alongside the regular skipped methods.

dependencies lists the dependency identifiers a dataflow test project needs. The build block tracks the build — test_project records each dataflow method's test-project status (done if a sample was written into the batch's test project, failed if none could be written so the method was excluded from it), and done holds the finished { method, signature }. Keep it clear from comments

passthrough:
  - { method: "<qualified-member-a>", signature: "<language-signature-a>" }
dataflow:
  - { method: "<qualified-member-b>", signature: "<language-signature-b>" }
skipped:
  - { method: "<qualified-member-c>", signature: "<language-signature-c>", reason: "retains none of its input data" }
engine_issues: []
dependencies: []
build:
  test_project:
    - { method: "<qualified-member-b>", signature: "<language-signature-b>", status: done }
  done: []

This skill only appends each cleanly-built method to build.done as { method, signature } when absent. A newly assigned method that you failed to write stays out, so the loop comes back to it; an explicitly repaired method leaves its existing entry unchanged. Never touch the classification buckets or edit an entry already in build.done.

Constraints

OpenTaint is a whole-program, interprocedural, field-sensitive alias analysis engine. It already propagates through visible application code, calls, aliases, and individual fields; custom rules and approximations model only the assigned source, sink, or opaque-method boundary. Compile-time constants and literals carry no taint, so a source or carrier whose output is only a constant introduces nothing.

  • Model one function per rule — never a regex/wildcard matcher or an all-arguments position to cover many at once; over-modeling copies taint through methods you never vetted and manufactures false positives
  • Keep produced configs comment-free

Comments

Markdown supported