Skip to content
AuditCode Research · Technical report

Discovery, verification, disclosure.

A three-stage research engine combines automated static analysis with manual review. Findings move from source code, through cross-module data-flow analysis, to a coordinated disclosure with the project maintainer. Engine output never reaches a maintainer's inbox without human review.

§ 01 — Engine architecture

A three-stage pipeline.

The analysis pipeline has three sequential stages. Each stage has a defined input and output. Downstream stages query the structured map produced upstream; they do not re-read raw source.

Figure 01 · Research pipelineauditcode-research / engine
01Declaration extraction
Structural map

Parse source. Emit a structured map of declarations, types, and module-level relationships.

02Per-module review
Candidate findings

Score each module against known vulnerability classes. Produce candidates with confidence scores.

03Cross-module flow
Traced vulnerabilities

Follow data from sources to sinks across file boundaries. Output: ranked, taint-tracked findings.

Input source tree (read-only)Output ranked findings and data-flow traceFailure mode degraded findings are flagged
§ 1.1

Declaration extraction

Source files are parsed into a structured map of the codebase — declarations, types, and module-level relationships. Tree-sitter parses identical source into identical maps; subsequent reconnaissance over the parsed map enriches it with semantic context. The map is the substrate that downstream stages query without re-reading raw source.

§ 1.2

Per-module review

Each module is evaluated against a vulnerability taxonomy generated for the target project's threat model, with categories tagged against the CWE and OWASP standards[1] for cross-reference. Stage 1's structural map provides full context. Output: a ranked list of candidates, each tied to its originating declaration with a confidence score.

§ 1.3

Cross-module data flow

Candidates from § 1.2 are traced across module boundaries. The engine follows data from external sources through intermediate transformations to security-relevant sinks. Where an untrusted source crosses an authorization boundary unsanitized into a sink that can be coerced into an attacker-useful action, the path is surfaced as a verified candidate finding.

This is the class of vulnerability that spans multiple files — the class per-file static analysis tools routinely fail to detect, because the attack surface lives in the relationships between modules rather than within any single function.

Worked example: a bug-class shape

To illustrate the class of bug Stage 3 surfaces, consider an abstract example with three modules:

  • Module A — a configuration loader that reads a key path from a user-supplied source.
  • Module B — a payload verifier that validates incoming objects against a signing key fetched from the path supplied by Module A.
  • Module C — an ingestion function that calls Module B's verifier on an artifact downloaded over the network.

Each module, examined alone, looks legitimate. Module A reads configuration; Module B verifies signatures; Module C processes incoming payloads. A per-file static analysis tool sees three reasonable functions. The vulnerability lives in the chain: the key path that drives signature verification is user-controllable, so an attacker who can influence Module A's input can replace the trust anchor and bypass Module B's defence.

Stage 3 surfaces this as a candidate by tracing the untrusted source (Module A's input) through the intermediate transformation (path resolution) into the security-relevant sink (Module B's signature check). The shape — source unsanitized transformationtrusted sink — is the analysis primitive; the specific projects and CVE identifiers are published only after coordinated disclosure with the affected maintainer.

pythonBug-class shape · simplified
# Module A — config loader
def load_config(path: str) -> Config:
    return parse(read(path))  # path is user-supplied

# Module B — payload verifier
def verify(payload: bytes, key_path: str) -> bool:
    key = load_key(key_path)            # key_path comes from caller
    return cryptographic_check(payload, key)

# Module C — ingestion
def ingest(artifact_url: str, config: Config):
    payload = http_get(artifact_url)
    # ─ chained trust ───────────────────────────────────────
    # config.signing_key_path is reachable from user input via
    # Module A. The attacker controls the trust anchor.
    if verify(payload, config.signing_key_path):
        process(payload)
§ 02 — Manual verification

Every finding, by hand.

Every engine finding is reviewed manually before disclosure. Findings that fail verification are discarded.

Verification has three required steps.

  • Re-read the cited source. The reviewer reads the function and its call graph to independently verify the data flow inferred by the engine.
  • Construct a proof-of-concept. The reviewer reproduces the vulnerability against a running instance of the target software. If no PoC can be constructed, the finding does not advance.
  • Document affected versions. Affected version ranges, attack prerequisites, and suggested remediation are documented. Remediation is provided as a diff-format patch where the surrounding code permits.

The reason for the manual gate is operational rather than aesthetic. False positives consume maintainer time and erode trust across the disclosure ecosystem; both compound across reports. AuditCode Research is accountable for every advisory it submits, and the verification step is where that accountability lives.

Verified findings then enter coordinated disclosure under the principles documented on the research page — 90-day window, maintainer-first communication, diff-format patches where possible, and minimum necessary public detail.

§ 03 — Validation

Reproduce before publication.

The engine is language-agnostic and domain-agnostic: it parses 11 programming languages via tree-sitter — Python, TypeScript, JavaScript, Go, Java, Rust, Ruby, PHP, C, C++, and C# — and applies the same cross-module data-flow analysis to projects of any category.

Research targets are selected by analysis yield, not by application domain. The cross-module data-flow primitive surfaces findings wherever multi-module trust boundaries are dense — a structural property found in web frameworks, data platforms, infrastructure tooling, cloud control planes, ML/AI systems, and developer tooling alike. The engine does not treat any category as primary.

Findings are manually reproduced in an isolated environment, then submitted to the project maintainer under coordinated embargo.

Each advisory references the exact commit and the version range against which the vulnerability was demonstrated. Where a finding does not reproduce on the latest release, that fact is recorded. The advisory's patched_versions field is the source of truth for remediation status.

§ 04 — References

Cited material.

External references cited in this report.

Footnotes
  1. Vulnerability class taxonomy follows the OWASP Top 10 and CWE Top 25, with categories normalized to align with GHSA's advisory schema. See owasp.org/Top10 and cwe.mitre.org/top25.
  2. Advisories are scored using CVSS v3.1 unless the affected ecosystem requires a more recent revision; see first.org/cvss/v3.1.
  3. Coordinated disclosure timelines follow CERT/CC guidance, ISO/IEC 29147:2018, and the GHSA program's published disclosure policy.
§ 05 — Contact

Contact.

Methodology questions, joint research proposals, and academic correspondence go to research@auditcode.ai.

Active disclosures on an open embargo go to security@auditcode.ai.

Cite this report
@techreport{auditcode_research_methodology_2026,
  author      = {Hashimov, Ibrahim},
  title       = {Methodology — AuditCode Research},
  institution = {AuditCode Research},
  year        = {2026},
  version     = {1.0},
  url         = {https://auditcode.ai/research/methodology}
}