StackSentry is open source and contributions are welcome. This guide explains how the codebase is structured and what is required to add a new check.
Adding a New Check
Every check follows the same pattern. Here is the minimum required to add one:
1. Define the check metadata in sec_audit/config.py
"APP-NEWCHECK-001": {
"id": "APP-NEWCHECK-001",
"layer": "app",
"name": "Your check name",
"severity": "HIGH",
"owasp": ["A02:2025"],
"effort": "LOW",
"impact_weight": 1.5,
"recommendation": "What to do to fix it.",
}
2. Write the check function in checks/app_checks.py
def check_your_feature(scanner: HttpScanner, verbose: bool = False) -> CheckResult:
meta = _meta("APP-NEWCHECK-001")
# Guard clause — return WARN if context unavailable
if not scanner.base_url:
return CheckResult(**meta, status=Status.WARN,
details="No target URL provided.")
# Your detection logic
response = scanner.get_root()
if response and "bad_pattern" in response.text:
return CheckResult(**meta, status=Status.FAIL,
details="Bad pattern detected in response body.")
return CheckResult(**meta, status=Status.PASS,
details="No issues detected.")
3. Add the check to sec_audit/cli.py
from checks.app_checks import check_your_feature
# In the scan execution block:
results.append(check_your_feature(http_scanner, verbose=args.verbose))
4. Write at least three tests
# tests/test_branch_logic.py
def test_your_feature_pass(mock_scanner):
mock_scanner.get_root.return_value = Mock(text="clean response")
result = check_your_feature(mock_scanner)
assert result.status == Status.PASS
def test_your_feature_fail(mock_scanner):
mock_scanner.get_root.return_value = Mock(text="bad_pattern found here")
result = check_your_feature(mock_scanner)
assert result.status == Status.FAIL
def test_your_feature_guard(mock_scanner):
mock_scanner.base_url = None
result = check_your_feature(mock_scanner)
assert result.status == Status.WARN
5. Add a patch template
# remediation/templates.py
def _template_app_newcheck_001(stack) -> PatchArtefact:
return PatchArtefact(
check_id="APP-NEWCHECK-001",
filename="fix_app_newcheck_001.py",
file_type="py",
content="# Your fix code here\n",
instructions=["Step 1: ...", "Step 2: ..."],
verify_cmd="python -c 'import yourapp; print(yourapp.check())'",
)
Running Tests
pip install -e ".[dev]"
pytest tests/ -v
All 321 tests must pass. A new check should add at minimum 3 tests (PASS, FAIL, WARN/guard).
Code Style
- Type hints on all function signatures
- Docstrings on all public functions
- No bare
except:clauses — always catch specific exceptions Status.WARNfor missing context,Status.ERRORfor unexpected exceptions
Submitting a Pull Request
- Fork the repository
- Create a branch:
git checkout -b feat/your-check-name - Add your check, tests, and template
- Run the full test suite
- Open a pull request with a description of what the check detects and why it matters All PRs require passing tests and a linked OWASP Top 10:2025 category for the new check.