Community, Contributing & Security

frapAST is an open-source security engine licensed under MIT. Explore open issues, the project roadmap, the full development guide, and our security disclosure policy.

Community & Issue Tracker

We welcome rule contributions, false-positive reports, and performance improvements across the Frappe & ERPNext ecosystem.

Public Project Roadmap

Current Release & Roadmap Milestones

  • v0.1.0 (Current Release): 28 active detectors, 2-tier proof verification, SARIF 2.1.0 export, CLI autofix, and a reusable GitHub Action.
  • v0.2.0 (Planned): Interprocedural taint analysis for FR-INJ-005 (XSS/HTML format string validation) and deeper DocType workflow transition graph modeling.
  • v0.3.0 (Planned): Bi-directional Frappe Bench integration for auto-generating reproducible synthetic bench test cases.
Official Contributing Guide View raw CONTRIBUTING.md on GitHub

Contributing to frapAST

This document covers how to set up a local development environment, run the test suite, add a new rule, and what a pull request must include before it can be merged.


Development Environment Setup

Prerequisites

  • Python 3.10 or higher
  • Git

Install for Development

git clone https://github.com/pratheep-bit/frapast.git
cd frapast
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

This installs frapAST in editable mode with all test and lint dependencies.

Run the Test Suite

pytest

All 200+ tests should pass. This is the minimum bar for any contribution.

Run the Linter

ruff check .

No lint errors are acceptable in a PR — fix all issues before opening one.


Project Layout

scanner/
  cli.py             — CLI entrypoint
  rules/engine.py    — All rule detectors (ALL_RULES tuple)
  rules/*.yaml       — Per-rule metadata (severity, description, references)
  taxonomy/          — Canonical taxonomy definitions
  python/engine.py   — AST and symbol indexer
  schema/engine.py   — DocType JSON schema indexer
  hooks/engine.py    — hooks.py parser
  callgraph/         — Call graph builder for endpoint reachability
  proof/             — Tier 2 runtime HTTP proof synthesis
  suppression.py     — Inline suppression, baseline, and config loader
  web/               — Local web dashboard server
tests/
  test_all_rules.py                     — Core rule regression tests
  test_precision_benchmark.py           — Precision bounds per rule
  test_security_hardening_regression.py — Security regression tests
  test_suppression.py                   — Suppression engine tests

Adding a New Rule

frapAST enforces strict precision and root-cause engineering standards. A rule is not "done" because a basic AST check passes; it must be proven safe against false positives and validated across real Frappe/ERPNext application trees. A complete rule addition follows the eight steps below.

1. Root-Cause Diagnosis and AST Visitor Mechanics

When designing a detector function in scanner/rules/engine.py:

  • Distinguish method invocations from attribute reads: if detecting an unvalidated field access or method call, ensure your AST visitor distinguishes visit_Call from visit_Attribute. Never confuse doc.fieldname with doc.method_name().
  • Fail-closed schema resolution: when querying DocType schemas via SchemaIndex, only assert missing fields if the DocType definition was resolved with 100% confidence. If schema resolution is ambiguous, do not emit spurious findings.
  • Respect reserved framework attributes: always check against _RESERVED_DOC_ATTRS and standard BaseDocument/Document methods before flagging attribute accesses.
  • Follow the standard detector signature:
def fr_perm_007(
    schema: SchemaIndex,
    hooks: HookIndex,
    python: PythonSymbolIndex,
    graph: CallGraph,
) -> list[Candidate]:
    """FR-PERM-007: Short descriptive title.

    Detailed root-cause explanation:
    - Vulnerability class and mechanism.
    - Conditions under which this triggers.
    - Known false-positive edge cases and how they are handled.
    """
    ...

2. Register the Rule in ALL_RULES

Add your detector function to the ALL_RULES tuple at the bottom of scanner/rules/engine.py.

3. Add Rule and Taxonomy YAML Metadata

  1. Rule descriptor (scanner/rules/FR-PERM-007.yaml):
    taxonomy_id: FR-PERM-007
    rule_version: "1.0.0"
    severity: high
    title: "Missing Permission Check on Sensitive DocType Method"
    description: |
      Detailed explanation of what the detector checks and the remediation guidance.
    references:
      - https://frappeframework.com/docs/user/en/api/document
  2. Taxonomy descriptor (scanner/taxonomy/FR-PERM-007.yaml):
    id: FR-PERM-007
    runtime_required: true
    detector_status: implemented
    category: permission
    title: "Missing Permission Check"
    description: |
      Canonical taxonomy entry for this rule class.
    references: []
  3. Registry registration: add the rule ID under the implemented list in scanner/taxonomy/taxonomy_registry.yaml.

4. Mandatory Dual Unit Test Suite (TP & TN Fixtures)

Every rule must have both positive and negative unit tests in tests/test_ast_rule_coverage.py or a dedicated test module:

  • True-positive (TP) test: asserts that vulnerable code patterns produce exact candidates with accurate line numbers, rule IDs, and evidence strings.
  • True-negative (TN) test: asserts that safe, idiomatic Frappe patterns (proper permission checks, whitelisted endpoints with guards, doc.save() with validation) produce zero findings.

5. Real-World Application Revalidation

Before submitting a PR, test your new rule against real open-source Frappe applications (e.g. frappe/erpnext, frappe/hrms):

# Run the scanner against a real Frappe app clone
frapast scan /path/to/cloned/erpnext --rule FR-PERM-007 --format json

Verify that all reported findings are legitimate true positives and that valid business logic is not falsely flagged.

6. Register Precision Benchmark Bounds

Add or update the expected finding count range in RULE_BOUNDS in tests/test_precision_benchmark.py. This ensures automated CI regression gates prevent precision drift across releases:

RULE_BOUNDS = {
    ...
    "FR-PERM-007": (1, 3),  # (min_expected, max_expected) on standard benchmark corpus
}

7. Tier 1 / Tier 2 Runtime Proof Integration (If Applicable)

If the vulnerability class can be proven at runtime:

  • Tier 1: implement shell/bash reproducer generation in scanner/proof/orchestrator.py.
  • Tier 2: implement HTTP RPC proof synthesis in scanner/proof/http_synthesis.py and scanner/proof/bench_runner.py.
  • Security invariant: always sanitize synthesized strings with _reject_if_newline() to eliminate reproducer script injection risks.

8. Full Local Verification

Run the entire verification suite locally:

pytest
ruff check .
python scanner/validate_taxonomy.py

Suppression and Baseline

To suppress a specific finding inline:

frappe.db.sql(query)  # frapast: ignore FR-SQLI-001

To suppress all rules on a line:

frappe.db.sql(query)  # frapast: ignore

To generate a baseline of existing findings (for legacy codebases):

frapast scan ./myapp --generate-baseline .frapast-baseline.json

To run future scans reporting only new findings:

frapast scan ./myapp --baseline .frapast-baseline.json

Integration & GitHub Action Testing

The repository pratheep-bit/frapast-action-test is maintained as a permanent, public smoke-test fixture to verify end-to-end composite action workflows (action.yml), SARIF generation, and Code Scanning alert ingestion against live GitHub infrastructure.


Privacy and Confidentiality

All contributions must comply with AGENTS.md:

  • Do not reference private company names, client identities, or proprietary infrastructure in code, comments, or commit messages.
  • Use only open-source repositories (frappe/erpnext, frappe/hrms) as corpus references.
  • Do not mention proprietary commercial products by name in documentation.

Pull Request Requirements

See .github/PULL_REQUEST_TEMPLATE.md for the full checklist. The short version:

  1. pytest passes with zero failures.
  2. ruff check . reports no errors.
  3. New rules have both positive and negative unit tests.
  4. No private corporate identities are referenced.

Reporting Security Issues

Do not open a public GitHub issue for security vulnerabilities in frapAST itself — see the Security Policy below for the responsible disclosure process.

Security Vulnerability Disclosure Policy View raw SECURITY.md on GitHub

Security Policy

Supported Versions

Version Supported
0.1.x Yes
< 0.1 No

Scope

This security policy applies strictly to vulnerabilities in the frapAST engine itself, including:

  • The local web dashboard server (scanner/web/server.py) — e.g. path traversal, origin validation bypass, command execution.
  • The runtime proof orchestrator and reproducer synthesis pipeline (scanner/proof/) — e.g. shell argument injection or unescaped parameter execution.
  • The AST symbol indexer and rule execution pipeline (scanner/python/, scanner/rules/).
  • The CLI entrypoint and output formatters (scanner/cli.py, scanner/reporting/).

Out of Scope

  • Security vulnerabilities detected by frapAST in third-party Frappe/ERPNext applications or custom apps (report these to the respective application maintainers).
  • Denial of service via pathological or malformed local files provided as scan targets.
  • Issues in optional dependencies not used by the core scan path.

Reporting a Vulnerability

If you discover a security vulnerability in frapAST, please report it privately:

  1. GitHub Security Advisory (preferred): open a private advisory at github.com/pratheep-bit/frapast/security/advisories/new.
  2. Direct email: if GitHub Security Advisories can't be used, email the maintainer at pratheeps2024@gmail.com with the subject [frapAST Security Vulnerability Report].

What to Include

Please provide:

  1. A description of the vulnerability and its potential impact.
  2. Step-by-step reproduction instructions or a minimal proof-of-concept.
  3. The specific version or commit hash where the issue was observed.
  4. Any potential mitigations or suggested fixes.

Response & Maintenance Expectations

As an open-source project maintained by a lean team:

  • Initial acknowledgment: best-effort within 3 business days.
  • Triage & assessment: within 7 to 10 business days.
  • Fix & disclosure: critical vulnerabilities are prioritized for a patch release as soon as practical, followed by a coordinated public release notice crediting the reporter.