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.
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_Callfromvisit_Attribute. Never confusedoc.fieldnamewithdoc.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_ATTRSand standardBaseDocument/Documentmethods 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
-
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 -
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: [] - Registry registration: add the rule ID under the
implementedlist inscanner/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.pyandscanner/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:
pytestpasses with zero failures.ruff check .reports no errors.- New rules have both positive and negative unit tests.
- 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 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:
- GitHub Security Advisory (preferred): open a private advisory at github.com/pratheep-bit/frapast/security/advisories/new.
- Direct email: if GitHub Security Advisories can't be used, email the
maintainer at
pratheeps2024@gmail.comwith the subject[frapAST Security Vulnerability Report].
What to Include
Please provide:
- A description of the vulnerability and its potential impact.
- Step-by-step reproduction instructions or a minimal proof-of-concept.
- The specific version or commit hash where the issue was observed.
- 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.