Development · ExploitCraft/ReconNinja Wiki · GitHub
Skip to content

Development

ExploitCraft edited this page May 5, 2026 · 1 revision

Development

Everything you need to contribute to ReconNinja — setup, project structure, code style, adding phases, and the test policy.


Dev Setup

git clone https://github.com/ExploitCraft/ReconNinja.git
cd ReconNinja
chmod +x install.sh && ./install.sh

# Run the full test suite
python3 -m pytest tests/ -v

# Or with unittest
python3 -m unittest discover -s tests -v

Project Structure

ReconNinja/
├── reconninja.py        # Entry point — CLI parsing + interactive mode
├── info/
│   ├── version          # Single source of truth for the version string
│   └── __init__.py      # Exposes __version__
├── core/
│   ├── orchestrator.py  # Phase pipeline engine — the brain
│   ├── ports.py         # RustScan, AsyncTCP, Masscan, Nmap
│   ├── subdomains.py    # Passive recon
│   ├── web.py           # httpx, WhatWeb, Nikto, dir scan
│   ├── vuln.py          # Nuclei, screenshots
│   ├── ai_analysis.py   # Groq / Ollama / Gemini / OpenAI
│   ├── ai_enhanced.py   # Consensus mode, attack paths, remediation
│   ├── resume.py        # Checkpoint save / load
│   ├── updater.py       # Self-update from GitHub
│   └── ...              # One file per module (cors_scan, jwt_scan, etc.)
├── output/
│   ├── report_html.py   # Dark-mode HTML report generator
│   ├── reports.py       # JSON + Markdown report generators
│   ├── sarif_export.py  # SARIF 2.1.0 exporter
│   └── integrations.py  # PDF, Jira, GitHub Issues, SIEM
├── utils/
│   ├── models.py        # All dataclasses — ScanConfig, ReconResult, etc.
│   ├── helpers.py       # Shared utility functions
│   ├── logger.py        # Rich terminal logger
│   ├── notify.py        # Webhook notifications
│   └── parser.py        # Argparse wrapper
├── gui/
│   └── app.py           # Flask GUI application
├── plugins/             # Drop .py plugins here
└── tests/               # Full test suite

Versioning

Version is stored in info/version (plain text, one line). All source files import from info:

from info import __version__

To cut a release: edit info/version, commit, tag.


Code Style

  • Python 3.10+ — use match/case, X | Y unions
  • Type hints on all function signatures
  • Dataclasses for all data — no raw dicts passed between modules
  • safe_print() not print() — respects the thread lock in concurrent phases
  • log.warning() / log.debug() for non-critical messages
  • No bare except: — always catch specific exceptions
  • No hardcoded paths — use pathlib.Path throughout
  • Imports at top of file — no inline imports except inside if TYPE_CHECKING:

Adding a New Phase

  1. Implement logic in a new core/my_module.py
  2. Add a phase name to the Phase enum in utils/models.py
  3. Add the result field to ReconResult in utils/models.py
  4. Add the config flag to ScanConfig in utils/models.py
  5. Add the CLI flag to parse_args() in reconninja.py
  6. Wire the phase into core/orchestrator.py with the standard skip guard:
if cfg.run_my_phase and "my_phase" not in result.phases_completed:
    console.print(Panel.fit("[phase] PHASE N — My Phase [/]"))
    # ... do work ...
    result.my_phase_results = my_module.run(target, out_folder, cfg)
    result.phases_completed.append("my_phase")
    save_state(result, cfg, out_folder)
elif "my_phase" in result.phases_completed:
    safe_print("[dim]Phase N — My Phase: already completed, skipping[/]")
  1. Add resume support to core/resume.py (_dict_to_config and _dict_to_result)
  2. Write tests in tests/test_orchestrator.py

Adding a New AI Provider

Add an entry to the PROVIDERS dict in core/ai_analysis.py:

PROVIDERS = {
    "groq":   {...},
    "ollama": {...},
    "gemini": {...},
    "openai": {...},
    "my_provider": {
        "base_url": "https://api.myprovider.com/v1",
        "model":    "my-model-name",
        ...
    },
}

Test Policy

Every code change ships with tests. No exceptions.

# Full suite
python3 -m pytest tests/ -v

# Specific file
python3 -m pytest tests/test_orchestrator.py -v

# Specific test
python3 -m pytest tests/test_orchestrator.py::TestPhaseSkipLogic::test_rustscan -v

Test File Ownership

File What to test here
tests/test_models.py New fields on ScanConfig, ReconResult, etc.
tests/test_resume.py Changes to core/resume.py
tests/test_orchestrator.py Changes to core/orchestrator.py
tests/test_ports.py Changes to core/ports.py
tests/test_cve_lookup.py Changes to core/cve_lookup.py
tests/test_ai_analysis.py Changes to core/ai_analysis.py
tests/test_report_html.py Changes to output/report_html.py

Submitting a Pull Request

  1. Fork the repo and create a branch: git checkout -b fix/my-fix
  2. Make your changes following the code style above
  3. Write tests — all passing
  4. Update README.md if you added features or changed flags
  5. Open a PR against main

PR title format:

fix: what was broken and how you fixed it
feat: what new capability was added
test: what coverage was added
docs: what documentation was updated

What We Accept

  • Bug fixes with regression tests
  • New scan phases (core/ module + orchestrator wiring)
  • New report formats (output/)
  • New AI providers
  • Plugin contributions (plugins/)
  • Test improvements
  • Documentation fixes

What We Reject

  • Features with no tests
  • Changes that break existing tests
  • Code that enables unauthorized scanning
  • Hardcoded credentials or API keys
  • Changes to the plugin contract without updating CONTRIBUTING.md

Security Issues in ReconNinja Itself

Open a private GitHub security advisory — do not open a public issue.


Related

Clone this wiki locally