Skip to main content

recon-orchestrator

ci license python

English | Türkçe


English

What is this?

recon-orchestrator is a command-line tool that checks a website, API, or domain for common, well-known security misconfigurations — the kind of issues that show up in almost every real-world penetration test: missing security headers, exposed databases, outdated TLS, weak SPF/DMARC email records, leaky API endpoints, pages that should require login but don't, and more.

It does not reinvent scanning from scratch. Instead it orchestrates battle-tested, industry-standard open-source tools — nmap (port scanning), nuclei (vulnerability templates), testssl.sh (TLS auditing) — plus its own lightweight Python checks, runs them all against one target, merges every result into one consistent format, and hands you a single report instead of six different tool outputs to cross-reference by hand.

Who it's for: developers and small teams who want a free, repeatable security check of their own site before shipping, in CI, or on a schedule — without paying for a commercial scanning platform or learning six separate tools.

Why use it instead of running the tools yourself?

You could run nmap, nuclei, and testssl.sh by hand — many people do. This tool exists because that gets tedious fast:

  • One command, one report. Instead of six terminal windows and six output formats, you get one Markdown/HTML report (for humans) and one JSON/SARIF report (for machines and CI).
  • Noise reduction. Raw tool output is full of false-positive-prone, terminology-heavy lines. This project turns each one into a plain-language finding with a severity and a recommendation.
  • CI-friendly out of the box. --fail-on-new high fails your build only when a new high-severity issue appears, not every time because of an old, already-known, accepted issue — so it's realistic to run on every pull request without constant red builds.
  • No vendor lock-in, no subscription, no LLM cost. Everything here runs with free, open tools. An optional AI "executive summary" exists, but it is off by default and the tool is fully useful without it.

How it works

When you run recon <target> --authorized, four things happen in order:

  1. Scope is locked. The tool resolves your target's hostname and builds an allow-list (by default: just that one host). Every HTTP request any module makes — including following a redirect — is checked against this list first. This exists so that a redirect on the target site can never make the tool silently start probing some unrelated third-party domain.

  2. Modules run, in parallel, under a shared speed limit. Each check (headers, ports, tls, …) is an independent Python module. They run concurrently so the slow ones (nmap, nuclei, testssl — these can take minutes) overlap instead of stacking up, which roughly halves total scan time. All modules that send real HTTP traffic share one request-rate budget (--rate, requests/second) so running things in parallel never increases load on the target beyond what you set.

  3. Results are merged and de-duplicated. Every single finding gets a stable identifier (rule_id) and a fingerprint, independent of wording or language. If two modules happen to report the same underlying issue, it's only counted once. This same fingerprint is what makes run-to-run diffing possible (see below).

  4. Reports are written. Four files land in recon_runs/<host>_<timestamp>/: a Markdown report to read, a JSON report for scripting, a SARIF file for GitHub's "Code scanning" UI, and a self-contained HTML page you can open in a browser or attach to an email — with no external resources loaded (your scan results never leave your machine unless you choose to send them somewhere).

On every subsequent scan of the same host, the tool automatically looks at your last run and tells you what's new versus what you already knew about — so a CI pipeline using --fail-on-new only turns red when something actually changed for the worse.

Installation

You need Python 3.9 or newer. Everything else is optional depending on which modules you want:

You want... You need
The core checks (headers, CORS, content discovery) Just Python + pip
DNS/email security (dns) and mail (mail) checks the [dns] extra
Port scanning, TLS audit, nuclei templates (ports/tls/web) Docker or the tools installed natively
Subdomain inventory (--discover) nothing extra; the [dns] extra adds CNAME/takeover checks, and subfinder (Docker or native) adds more sources
Endpoint crawl (crawl module) katana (Docker or native); --crawl-headless also needs Chromium
Injection fuzzing (--dast) nuclei (Docker or native); an OpenAPI/Swagger spec or a crawl of the site

Option A — install from PyPI (recommended):

pip install "recon-orchestrator[dns]"            # omit [dns] if you don't need dns/mail
pip install "recon-orchestrator[dns]==1.2.0"     # or pin an exact version (e.g. in CI)
pip install -U "recon-orchestrator[dns]"         # upgrade an existing install

This installs a recon command on your PATH; recon --version shows which version you have.

Option B — clone and install (to read or change the code):

git clone https://github.com/m0Corut/recon-orchestrator
cd recon-orchestrator
pip install ".[dns]"

Option C — Docker image (zero local setup, tools included):

If you don't want to install Python packages or Docker-pull individual tool images, use the all-in-one image. It bundles nmap, nuclei, testssl.sh and subfinder as native binaries inside the container, so it needs only Docker itself:

docker run --rm -v "$PWD:/work" ghcr.io/m0corut/recon-orchestrator:1.2.0 \
  https://example.com --authorized

Use a version tag such as :1.2.0 so a scan does not change underneath you; :latest always points at the newest release.

Tool versions. When the tools run through Docker, recon uses pinned images (nmap 7.98, nuclei v3.11.1, testssl.sh 3.2, subfinder v2.17.0), so the same recon version always scans with the same tools. Tools you installed natively are used as they are, whatever their version. With the default --runner auto, native binaries are used when nmap, nuclei and testssl.sh are all installed; otherwise Docker is used. subfinder is optional either way.

Checking your setup: after installing, run recon doctor — it tells you exactly which tools and optional packages it can see, so you know in advance which modules will actually run.

Upgrading from 1.0. Nothing breaks: every new feature in 1.1 is off until you ask for it (--discover, --dast, --notify-env, --resume), with one exception: if a .reconignore.yml file exists in the directory you scan from, it is now read automatically. Scans also keep a small checkpoint in recon_runs/.partial/ while they run, and remove it when they finish.

Your first scan, step by step

recon https://example.com --authorized
  • https://example.com — your own site, or one you have written permission to test. The tool refuses to run without...
  • --authorized — ...this flag, which is your explicit confirmation that you are allowed to test this target. There is no way around this check; it is intentional friction.

What you'll see: a progress line per module as it starts, then a summary line like 3 info, 2 low, 1 medium and the path to your report folder. Open recon_runs/example.com_<timestamp>/report.html in a browser — it has a severity breakdown at the top, a filterable findings table, and a plain-English explanation and fix recommendation under each one.

If Docker isn't running or isn't installed, you'll see [~] ports: skipped for the Docker-based modules — the scan still completes with whatever modules could run, it never hard-fails just because one tool is missing.

A gentler first run — only the checks that need nothing but Python, which is a good way to try the tool with zero setup:

recon example.com -m headers,cors,content,dns --authorized

Using it continuously (CI)

The real value shows up when you run this regularly instead of once. Two pieces make that practical:

# Only fail the build when something NEW and at least "high" severity appears.
# The previous run for the same host is used as the baseline automatically.
recon https://example.com --authorized --fail-on-new high

Or drop in the reusable GitHub Action:

- uses: m0Corut/recon-orchestrator@main
  with:
    target: https://staging.example.com
    modules: "headers,cors,content,dns"
    fail-on-new: "high"

.github/workflows/scan.yml in this repo is a working example (weekly schedule + manual trigger) you can copy into your own project.

Accepted risks. Some findings are known and deliberately accepted. List them in .reconignore.yml (picked up automatically, or pass --suppress-file). Each entry needs a reason; an optional expires date makes the finding come back, and fail CI again, once the review date passes. Suppressed findings are left out of counts and --fail-on* gates but still listed in every report under "Suppressed".

- rule_id: headers.missing-csp        # glob allowed: "headers.*"
  reason: "CSP rollout tracked in JIRA-123"
  expires: 2027-01-31
- rule_id: ports.notable
  reason: "Redis is firewalled to the VPN"
  fingerprint: 3f2a9c...              # optional: just this one instance

Whole attack surface. --discover adds the discover module: it lists subdomains from Certificate Transparency and subfinder (when available), probes which in-house ones serve HTTP, and flags dangling CNAMEs. Each live host is a finding, so the next run reports new subdomains through the normal baseline diff. Discovered hosts are only listed by default; add --scan-discovered to run the other modules against each of them too, and only if you are authorized for all of them. Hosts that CNAME to a third-party service (Shopify, Heroku, …) are never probed or scanned, only checked in DNS.

recon example.com --authorized --discover                    # inventory
recon example.com --authorized --discover --scan-discovered  # inventory + scan each

Notifications. A scheduled scan is only useful if someone sees it. --notify-env RECON_WEBHOOK reads one or more webhook URLs (comma-separated) from an environment variable and posts a short message only when there are NEW findings at --notify-min-severity (default medium) or above. Slack, Discord and Telegram (https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<ID>) URLs are detected automatically; anything else receives a generic JSON payload. Messages contain titles and rule ids, never evidence.

What each module actually checks

Module Needs What it looks for
headers nothing Missing security headers (HSTS, CSP, X-Frame-Options, …), insecure cookie flags, and server/framework version leaks
cors nothing A CORS policy that reflects an attacker-controlled Origin back, especially combined with credentials
content nothing Accidentally exposed files and paths (.env, .git/config, backup dumps, debug endpoints)
dns [dns] extra Missing or weak SPF/DMARC (email spoofing protection), missing DKIM, missing CAA
ports Docker or nmap Which ports are open and whether a risky service (database, Redis, RDP, …) is reachable from the internet
tls Docker or testssl.sh Outdated TLS versions and weak cipher suites
web Docker or nuclei Thousands of community-maintained signatures for known CVEs, exposed panels, and misconfigurations
authz a session cookie/token you provide Whether pages that should require login are actually reachable without one (read-only — GET/HEAD only, never submits forms)
openapi an OpenAPI/Swagger spec Whether endpoints the spec marks as requiring authentication are reachable without it
mail [dns] extra Whether your mail server offers STARTTLS, and whether MTA-STS/TLS-RPT are configured
discover nothing ([dns] extra recommended; subfinder optional) Subdomain inventory from Certificate Transparency (crt.sh, Cert Spotter) and subfinder, live web hosts, and dangling CNAMEs that may allow a subdomain takeover. Opt-in via --discover
crawl katana Maps the attack surface: endpoints and query parameters, parsing linked JS; --crawl-headless drives a browser for single-page apps. Opt-in
cms nothing Detects the CMS (WordPress/Joomla/Drupal) and version, and for WordPress checks REST user enumeration, an exposed debug log, xmlrpc.php and readme. Opt-in (-m cms)
idor nothing (--auth-header recommended) Heuristic IDOR / broken object-level authorization probe: fetches a neighbouring object id and flags when a distinct object comes back (read-only, GET only). Opt-in (-m idor)
csrf nothing State-changing HTML forms without an anti-CSRF token or SameSite session cookie; login forms reported separately. Passive. Opt-in (-m csrf)
jsrecon nothing Same-origin JS: hard-coded secrets (masked), outdated/vulnerable libraries (retire.js-style), exposed .js.map source maps. Opt-in (-m jsrecon)
graphql nothing GraphQL introspection enabled, exposed IDE, debug errors, GET queries — one fixed probe. Opt-in (-m graphql)
redirect nothing (crawl recommended) Open redirect on redirect-style params, using a reserved canary; never follows. Opt-in (-m redirect)
passive nothing JWT hygiene (decode-only), missing SRI, session id in URL, internal IP/host/path/stack-trace disclosure, mixed content, robots/security.txt. Opt-in (-m passive)
hostinject nothing Host-header injection / cache-poisoning signals (verify manually); cache-buster on every probe. Opt-in (-m hostinject)

Run recon modules any time to see this list with each module's current description.

Useful flags at a glance

--lang tr                     # Turkish report text (default: English)
--format html,json            # choose which report files to write
--scope "api.x.com,*.cdn.x.com"  # allow extra hosts beyond the target itself
--rate 10                     # be gentler on a production target
--jobs 2 / --serial           # limit or disable module parallelism
--config recon.yaml           # load targets/options from a YAML file (recon init to generate one)
--runner native|docker|auto   # how external tools are executed
--analyst anthropic           # optional AI executive summary (opt-in, needs an API key)
--github-issues org/repo      # optional: file a GitHub issue per new finding
--discover [--scan-discovered]  # subdomain inventory (+ scan each live host)
-m cms,idor                    # CMS/WordPress checks and the IDOR probe (opt-in modules)
--idor-url https://s/x/1001    # an id-bearing URL for the idor module to test
-m csrf,jsrecon,graphql,redirect,passive,hostinject  # more opt-in detection modules
--nuclei-profile panels        # nuclei: also run panel/exposure/tech templates (web module)
--suppress-file ignore.yml    # accepted risks (default: .reconignore.yml)
--notify-env RECON_WEBHOOK    # Slack/Discord/Telegram/webhook on NEW findings
--resume                      # continue an interrupted scan; finished modules are reused
--dast                        # nuclei fuzzing on the API spec's GET operations only

Full detail on every flag: recon --help.

The rate limit adapts on its own: if the target answers 429/503, every module slows down (and honours Retry-After), then speeds back up to --rate. The run says so, because findings may be incomplete.

--dast sends real attack payloads, so it is opt-in and deliberately narrow. If an OpenAPI/Swagger spec is found, nuclei receives a copy that keeps only GET operations and whose server is rewritten to your target. With no spec, the site is crawled (katana) and only the discovered GET URLs that carry query parameters, on the target host, are fuzzed — nothing that changes data. The crawl module (-m crawl) runs the same crawl on its own to map the attack surface. Crawling parses linked JavaScript for endpoints. A JavaScript-heavy single-page app builds its API calls at runtime, so add --crawl-headless to drive a real headless browser and discover those too (needs Chromium; the all-in-one image ships it). Headless is slower, so it is opt-in.

History across runs. recon trend (or recon trend <output_dir>) writes trend.html: per host, a stacked bar of findings by severity for each run plus the same numbers in a table with new/resolved counts. It is a single file with no external resources, like the report.

Your own checks. Another package can add modules without forking this one:

# pyproject.toml of your package
[project.entry-points."recon_orchestrator.modules"]
mycheck = "my_package.mycheck"   # a module with NAME, NEEDS_DOCKER, run(target, ctx)

Plugins appear in recon modules, run only when named (-m headers,mycheck), and can never replace a built-in module.

Architecture (for contributors)

recon/
├── cli.py              # argument parsing, config merging, writing reports
├── engine.py           # schedules modules, runs them in parallel, de-duplicates
├── context.py          # ScanContext: typed options shared with every module
├── scope.py            # the allow-list + the redirect-safe HTTP helper
├── ratelimit.py         # the shared, aggregate rate limiter
├── runner.py            # abstracts "run this external tool" over Docker or native binaries
├── diff.py              # fingerprint-based comparison between two runs
├── config.py            # YAML config file loading/validation
├── findings.py          # the Finding/ScanResult data model (rule_id, fingerprint, severity)
├── i18n.py              # English text + Turkish translation catalogue
├── report.py / report_html.py   # Markdown / JSON / SARIF / HTML renderers
├── analyst/             # optional LLM summarization (opt-in, plain HTTP, no SDKs)
├── integrations/github.py       # optional GitHub issue creation
└── modules/             # one file per check; each exposes NAME, NEEDS_DOCKER, run()

To add a module: create recon/modules/<name>.py exposing NAME, NEEDS_DOCKER, and run(target, ctx) -> list[Finding]; register it in recon/modules/__init__.py; write finding text in English with a stable rule_id, add the Turkish translation to recon/i18n.py; keep any tool-output parsing in a separate pure function so it's testable without Docker or the network; add tests under tests/.

Stability, development, license

CLI flags and the report.json schema (docs/report.schema.json) are stable from v1.0 onward; breaking changes get a new major version and a CHANGELOG entry.

pip install -e ".[dev]"
ruff check recon/ tests/ && mypy recon/ && pytest -q

Every push/PR runs this same check on Python 3.9–3.13. See CONTRIBUTING.md to add a module or fix a bug.

Licensed under Apache-2.0 — see LICENSE. Built on top of nmap, nuclei and testssl.sh; this project orchestrates these tools, it does not replace them.

This tool sends real network requests to whatever target you give it. Only use it against systems you own or have written authorization to test. Unauthorized scanning is illegal in most jurisdictions — responsibility is entirely yours. The --authorized flag exists specifically so you cannot run a scan by accident without consciously confirming this.


Türkçe

Bu proje ne işe yarıyor?

recon-orchestrator, bir web sitesini, API'yi veya alan adını yaygın ve bilinen güvenlik yanlış yapılandırmalarına karşı kontrol eden bir komut satırı aracıdır — gerçek sızma testlerinin neredeyse hepsinde çıkan türden sorunlar: eksik güvenlik başlıkları, internete açık veritabanları, güncel olmayan TLS, zayıf SPF/DMARC e-posta kayıtları, bilgi sızdıran API endpoint'leri, giriş gerektirmesi gerekirken gerektirmeyen sayfalar ve benzerleri.

Taramayı sıfırdan yeniden icat etmez. Onun yerine, sektörde kanıtlanmış açık kaynak araçları — nmap (port taraması), nuclei (zafiyet şablonları), testssl.sh (TLS denetimi) — ve kendi hafif Python kontrollerini orkestre eder, hepsini tek bir hedefe karşı çalıştırır, tüm sonuçları tek, tutarlı bir biçimde birleştirir ve sana elle karşılaştırman gereken altı farklı araç çıktısı yerine tek bir rapor verir.

Kimler için: kendi sitelerini yayına almadan önce, CI'da veya düzenli aralıklarla ücretsiz ve tekrarlanabilir bir güvenlik kontrolü isteyen geliştiriciler ve küçük ekipler — ticari bir tarama platformuna para ödemeden ya da altı ayrı aracı öğrenmeden.

Araçları kendim çalıştırmak yerine neden bunu kullanayım?

nmap, nuclei ve testssl.sh'ı elle de çalıştırabilirsin — çoğu kişi öyle yapıyor. Bu proje, o işin hızla sıkıcı hale gelmesi yüzünden var:

  • Tek komut, tek rapor. Altı terminal penceresi ve altı farklı çıktı biçimi yerine, insan için tek bir Markdown/HTML raporu ve makine/CI için tek bir JSON/SARIF raporu alırsın.
  • Gürültü azaltma. Ham araç çıktısı, yanlış-pozitife meyilli ve jargon dolu satırlarla doludur. Bu proje her birini önem seviyesi ve öneri içeren sade bir bulguya çevirir.
  • Kutudan çıktığı gibi CI uyumlu. --fail-on-new high, build'i yalnızca yeni bir yüksek önem seviyeli sorun çıktığında durdurur — eski, bilinen, kabul edilmiş bir sorun yüzünden her seferinde değil. Bu sayede her pull request'te çalıştırmak, sürekli kırmızı build'e boğulmadan gerçekçi olur.
  • Tedarikçi bağımlılığı yok, abonelik yok, LLM maliyeti yok. Buradaki her şey ücretsiz, açık araçlarla çalışır. Opsiyonel bir AI "yönetici özeti" vardır ama varsayılan olarak kapalıdır ve araç onsuz da tam olarak kullanılabilir.

Nasıl çalışır?

recon <hedef> --authorized çalıştırdığında, sırayla dört şey olur:

  1. Kapsam kilitlenir. Araç, hedefinin host adını çözer ve bir izin listesi (allow-list) kurar (varsayılan: sadece o tek host). Herhangi bir modülün yaptığı her HTTP isteği — bir yönlendirmeyi takip etmek dahil — önce bu listeye karşı kontrol edilir. Bunun amacı, hedef sitedeki bir yönlendirmenin aracı sessizce ilgisiz bir üçüncü taraf alan adını yoklamaya başlatmasını kesinlikle engellemektir.

  2. Modüller paralel ve ortak bir hız sınırı altında çalışır. Her kontrol (headers, ports, tls, …) bağımsız bir Python modülüdür. Eşzamanlı çalışırlar, böylece yavaş olanlar (nmap, nuclei, testssl — dakikalar sürebilir) üst üste binmek yerine örtüşür, bu da toplam tarama süresini kabaca yarıya indirir. Gerçek HTTP trafiği gönderen tüm modüller tek bir istek-hızı bütçesini (--rate, istek/saniye) paylaşır, böylece paralel çalışma hedefe binen yükü senin belirlediğinin üzerine çıkarmaz.

  3. Sonuçlar birleştirilir ve tekilleştirilir. Her bulgu, kelime seçiminden veya dilden bağımsız kararlı bir kimlik (rule_id) ve bir parmak izi alır. İki modül aynı temel sorunu bildirirse, yalnızca bir kez sayılır. Bu aynı parmak izi, taramadan taramaya karşılaştırmayı (aşağıda) mümkün kılan şeydir.

  4. Raporlar yazılır. recon_runs/<host>_<zaman>/ altına dört dosya düşer: okumak için bir Markdown raporu, scriptleme için bir JSON raporu, GitHub'ın "Code scanning" arayüzü için bir SARIF dosyası, ve tarayıcıda açabileceğin veya e-postaya ekleyebileceğin, dışarıya hiçbir kaynak yüklemeyen (tarama sonuçların, sen göndermeyi seçmedikçe makinenden çıkmaz) bağımsız bir HTML sayfası.

Aynı host'u sonraki her taramada, araç otomatik olarak son çalıştırmana bakar ve sana neyin yeni olduğunu, neyi zaten bildiğini söyler — böylece --fail-on-new kullanan bir CI hattı yalnızca gerçekten bir şey kötüye gittiğinde kırmızıya döner.

Kurulum

Python 3.9 veya üstü gerekir. Gerisi, hangi modülleri istediğine bağlı olarak opsiyoneldir:

İstediğin... Gereken
Temel kontroller (headers, CORS, içerik keşfi) Sadece Python + pip
DNS/e-posta güvenliği (dns) ve mail (mail) kontrolleri [dns] extra
Port taraması, TLS denetimi, nuclei şablonları (ports/tls/web) Docker ya da araçların native kurulu olması
Alt alan adı envanteri (--discover) ek bir şey gerekmez; [dns] extra CNAME/takeover kontrollerini, subfinder (Docker ya da native) ek kaynakları ekler
API fuzzing (--dast) nuclei (Docker ya da native) ve bir OpenAPI/Swagger şeması

Seçenek A — PyPI'dan kur (önerilen):

pip install "recon-orchestrator[dns]"            # dns/mail gerekmiyorsa [dns]'i çıkar
pip install "recon-orchestrator[dns]==1.2.0"     # ya da tam sürümü sabitle (ör. CI'da)
pip install -U "recon-orchestrator[dns]"         # mevcut kurulumu güncelle

Bu, PATH'ine bir recon komutu kurar; hangi sürümün kurulu olduğunu recon --version gösterir.

Seçenek B — klonla ve kur (kodu okumak ya da değiştirmek için):

git clone https://github.com/m0Corut/recon-orchestrator
cd recon-orchestrator
pip install ".[dns]"

Seçenek C — Docker imajı (yerel kurulum sıfır, araçlar dahil):

Python paketleri kurmak veya tek tek araç imajlarını çekmek istemiyorsan, hepsi-bir-arada imajı kullan. nmap, nuclei, testssl.sh ve subfinder'ı container içinde native binary olarak barındırır, yani sadece Docker'ın kendisi gerekir:

docker run --rm -v "$PWD:/work" ghcr.io/m0corut/recon-orchestrator:1.2.0 \
  https://ornek.com --authorized

Taramanın habersizce değişmemesi için :1.2.0 gibi bir sürüm etiketi kullan; :latest her zaman en yeni sürümü gösterir.

Araç sürümleri. Araçlar Docker üzerinden çalıştığında recon sabitlenmiş imajlar kullanır (nmap 7.98, nuclei v3.11.1, testssl.sh 3.2, subfinder v2.17.0); böylece aynı recon sürümü hep aynı araçlarla tarar. Native kurduğun araçlar ise sürümü ne olursa olsun olduğu gibi kullanılır. Varsayılan --runner auto ayarında nmap, nuclei ve testssl.sh'ın üçü de native kuruluysa onlar, değilse Docker kullanılır. subfinder her iki durumda da isteğe bağlıdır.

Kurulumunu kontrol etmek: kurduktan sonra recon doctor çalıştır — tam olarak hangi araçları ve opsiyonel paketleri görebildiğini söyler, böylece hangi modüllerin gerçekten çalışacağını önceden bilirsin.

1.0'dan yükseltme. Hiçbir şey bozulmaz: 1.1'deki yeni özelliklerin hepsi sen istemedikçe kapalıdır (--discover, --dast, --notify-env, --resume). Tek istisna: tarama yaptığın dizinde bir .reconignore.yml dosyası varsa artık otomatik okunur. Ayrıca taramalar çalışırken recon_runs/.partial/ altında küçük bir checkpoint tutar ve bitince siler.

Adım adım ilk tarama

recon https://ornek.com --authorized
  • https://ornek.com — kendi siten, ya da test etmek için yazılı iznin olan bir site. Araç şu olmadan çalışmayı reddeder:
  • --authorized — bu hedefi test etmeye yetkili olduğunun açık onayı. Bu kontrolün etrafından dolanmanın bir yolu yok; bilerek konmuş bir engeldir.

Göreceğin şey: her modül başlarken bir ilerleme satırı, sonra 3 info, 2 low, 1 medium gibi bir özet satırı ve rapor klasörünün yolu. recon_runs/ornek.com_<zaman>/report.html'i tarayıcıda aç — üstte önem dağılımı, filtrelenebilir bir bulgu tablosu, ve her bulgunun altında sade dilde açıklama ve düzeltme önerisi var.

Docker çalışmıyorsa veya kurulu değilse, Docker tabanlı modüller için [~] ports: atlandı göreceksin — tarama, çalışabilen modüllerle birlikte yine tamamlanır, sadece bir araç eksik olduğu için asla tamamen durmaz.

Daha yumuşak bir ilk deneme — sadece Python dışında hiçbir şey gerektirmeyen kontroller, aracı sıfır kurulumla denemek için iyi bir yol:

recon ornek.com -m headers,cors,content,dns --authorized

Sürekli kullanım (CI)

Gerçek değer, bunu bir kere değil düzenli çalıştırdığında ortaya çıkar. Bunu pratik kılan iki parça var:

# Build'i yalnızca YENİ ve en az "high" önemde bir şey çıktığında durdur.
# Aynı host için önceki çalıştırma otomatik olarak baz alınır.
recon https://ornek.com --authorized --fail-on-new high

Ya da yeniden kullanılabilir GitHub Action'ı ekle:

- uses: m0Corut/recon-orchestrator@main
  with:
    target: https://staging.ornek.com
    modules: "headers,cors,content,dns"
    fail-on-new: "high"

Bu repodaki .github/workflows/scan.yml, kendi projene kopyalayabileceğin çalışan bir örnektir (haftalık zamanlama + elle tetikleme).

Kabul edilen riskler. Bazı bulgular bilinir ve bilerek kabul edilir. Bunları .reconignore.yml dosyasına yaz (otomatik okunur, ya da --suppress-file ver). Her girdi bir gerekçe ister; isteğe bağlı expires tarihi geçince bulgu geri gelir ve CI'ı yeniden kırar. Bastırılan bulgular sayımlara ve --fail-on* kapılarına girmez ama her raporda "Bastırılanlar" başlığı altında listelenir.

- rule_id: headers.missing-csp        # glob kullanılabilir: "headers.*"
  reason: "CSP geçişi JIRA-123'te takip ediliyor"
  expires: 2027-01-31
- rule_id: ports.notable
  reason: "Redis yalnızca VPN'e açık"
  fingerprint: 3f2a9c...              # isteğe bağlı: yalnızca bu örnek

Tüm saldırı yüzeyi. --discover, discover modülünü ekler: sertifika şeffaflığı kayıtlarından ve (varsa) subfinder'dan alt alan adlarını listeler, sana ait olanlardan hangilerinin HTTP sunduğunu yoklar ve sahipsiz CNAME'leri işaretler. Her canlı host bir bulgudur, bu yüzden sonraki tarama normal baseline karşılaştırmasıyla yeni alt alan adlarını bildirir. Keşfedilen host'lar varsayılan olarak yalnızca listelenir; diğer modülleri her birinde de çalıştırmak için --scan-discovered ekle, ama yalnızca hepsi için yetkin varsa. Üçüncü taraf bir servise (Shopify, Heroku, …) CNAME veren host'lar asla yoklanmaz ve taranmaz, yalnızca DNS'te kontrol edilir.

recon ornek.com --authorized --discover                    # envanter
recon ornek.com --authorized --discover --scan-discovered  # envanter + her birini tara

Bildirimler. Zamanlanmış tarama ancak biri sonucu görürse işe yarar. --notify-env RECON_WEBHOOK bir ortam değişkeninden bir veya daha fazla webhook adresi okur (virgülle ayrılmış) ve yalnızca --notify-min-severity (varsayılan medium) ve üstünde YENİ bulgu varsa kısa bir mesaj gönderir. Slack, Discord ve Telegram (https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<ID>) adresleri otomatik tanınır; diğerlerine genel bir JSON gönderilir. Mesajlarda başlık ve rule_id bulunur, kanıt asla bulunmaz.

Her modül tam olarak ne kontrol ediyor

Modül Gereken Ne arıyor
headers hiçbir şey Eksik güvenlik başlıkları (HSTS, CSP, X-Frame-Options, …), güvensiz cookie bayrakları, sunucu/framework sürüm sızıntıları
cors hiçbir şey Saldırgan kontrolündeki bir Origin'i geri yansıtan CORS politikası, özellikle credentials ile birlikte
content hiçbir şey Yanlışlıkla açık bırakılmış dosya ve yollar (.env, .git/config, yedek dump'ları, debug endpoint'leri)
dns [dns] extra Eksik/zayıf SPF/DMARC (e-posta sahteciliği koruması), eksik DKIM, eksik CAA
ports Docker ya da nmap Hangi portların açık olduğu ve riskli bir servisin (veritabanı, Redis, RDP, …) internetten erişilebilir olup olmadığı
tls Docker ya da testssl.sh Eski TLS sürümleri ve zayıf şifreleyici setleri
web Docker ya da nuclei Bilinen CVE'ler, açık paneller ve yanlış yapılandırmalar için binlerce topluluk imzası
authz senin verdiğin bir session cookie/token Giriş gerektirmesi gereken sayfaların gerçekten girişsiz erişilip erişilemediği (salt-okunur — sadece GET/HEAD, form göndermez)
openapi bir OpenAPI/Swagger şeması Şemanın kimlik doğrulama gerektirdiğini söylediği endpoint'lerin gerçekten kimliksiz erişilip erişilemediği
mail [dns] extra Mail sunucunun STARTTLS sunup sunmadığı, MTA-STS/TLS-RPT'nin yapılandırılıp yapılandırılmadığı
discover hiçbir şey ([dns] extra önerilir; subfinder isteğe bağlı) Sertifika şeffaflığı (crt.sh, Cert Spotter) ve subfinder ile alt alan adı envanteri, canlı web host'ları ve subdomain takeover'a açık sahipsiz CNAME'ler. --discover ile açılır
crawl katana Saldırı yüzeyini haritalar: endpoint ve sorgu parametreleri, bağlı JS'i ayrıştırır; SPA'lar için --crawl-headless tarayıcı sürer. Opt-in
cms hiçbir şey CMS'i (WordPress/Joomla/Drupal) ve sürümü tespit eder; WordPress için REST kullanıcı sayımı, açık debug log, xmlrpc.php ve readme kontrolü. Opt-in (-m cms)
idor hiçbir şey (--auth-header önerilir) Sezgisel IDOR / nesne düzeyi yetki taraması: komşu nesne id'sini getirip farklı bir nesne dönerse işaretler (salt-okunur, yalnızca GET). Opt-in (-m idor)
csrf hiçbir şey Anti-CSRF token'ı veya SameSite oturum çerezi olmayan durum değiştiren formlar; giriş formları ayrı raporlanır. Pasif. Opt-in (-m csrf)
jsrecon hiçbir şey Same-origin JS: gömülü sırlar (maskeli), eski/açıklı kütüphaneler (retire.js tarzı), açık .js.map source map'ler. Opt-in (-m jsrecon)
graphql hiçbir şey GraphQL introspection açık, açık IDE, debug hataları, GET sorgusu — tek sabit probe. Opt-in (-m graphql)
redirect hiçbir şey (crawl önerilir) Yönlendirme parametrelerinde açık yönlendirme; rezerve canary, asla takip etmez. Opt-in (-m redirect)
passive hiçbir şey JWT hijyeni (yalnız decode), eksik SRI, URL'de session id, iç IP/host/yol/stack-trace ifşası, mixed content, robots/security.txt. Opt-in (-m passive)
hostinject hiçbir şey Host-header injection / cache poisoning sinyalleri (manuel doğrula); her probe'da cache-buster. Opt-in (-m hostinject)

Bu listeyi ve her modülün güncel açıklamasını görmek için istediğin an recon modules çalıştır.

Göz atılacak kullanışlı bayraklar

--lang tr                     # Türkçe rapor metni (varsayılan: İngilizce)
--format html,json            # hangi rapor dosyalarının yazılacağını seç
--scope "api.x.com,*.cdn.x.com"  # hedefin dışında ek host'lara izin ver
--rate 10                     # production hedefte daha nazik ol
--jobs 2 / --serial           # modül paralelliğini sınırla veya kapat
--config recon.yaml           # hedefleri/ayarları bir YAML dosyasından oku (üretmek için recon init)
--runner native|docker|auto   # dış araçların nasıl çalıştırılacağı
--analyst anthropic           # opsiyonel AI yönetici özeti (opt-in, API anahtarı gerekir)
--github-issues org/repo      # opsiyonel: her yeni bulgu için bir GitHub issue aç
--discover [--scan-discovered]  # alt alan adı envanteri (+ her canlı host'u tara)
-m cms,idor                    # CMS/WordPress kontrolleri ve IDOR taraması (opt-in modüller)
--idor-url https://s/x/1001    # idor modülünün test edeceği id içeren URL
-m csrf,jsrecon,graphql,redirect,passive,hostinject  # daha fazla opt-in tespit modülü
--nuclei-profile panels        # nuclei: panel/exposure/tech şablonlarını da çalıştır (web)
--suppress-file ignore.yml    # kabul edilen riskler (varsayılan: .reconignore.yml)
--notify-env RECON_WEBHOOK    # YENİ bulguda Slack/Discord/Telegram/webhook
--resume                      # yarıda kalan taramayı sürdür; biten modüller yeniden çalışmaz
--dast                        # nuclei fuzzing, yalnızca API şemasının GET işlemlerinde

Her bayrağın tam detayı: recon --help.

Hız sınırı kendini ayarlar: hedef 429/503 dönerse tüm modüller yavaşlar (Retry-After'a da uyar), sonra yeniden --rate değerine çıkar. Sonuçlar eksik olabileceği için tarama bunu ayrıca bildirir.

--dast gerçek saldırı yükleri gönderir; bu yüzden isteğe bağlıdır ve bilerek dar tutulmuştur: nuclei, API şemasının yalnızca GET işlemlerini içeren (veri değiştiren hiçbir şey fuzz edilmez) ve sunucu adresi senin hedefine yeniden yazılmış bir kopyasını alır. Böylece production'ı gösteren bir şema fuzzer'ı başka yere yönlendiremez.

Taramalar arası geçmiş. recon trend (veya recon trend <çıktı_dizini>) trend.html üretir: her host için, her taramadaki bulguların önem derecesine göre yığılmış çubuğu ve aynı sayıları yeni/çözülen bilgisiyle bir tabloda gösterir. Rapor gibi, dış kaynak yüklemeyen tek bir dosyadır.

Kendi kontrollerin. Başka bir paket, bu projeyi fork'lamadan modül ekleyebilir:

# kendi paketinin pyproject.toml dosyası
[project.entry-points."recon_orchestrator.modules"]
mycheck = "my_package.mycheck"   # NAME, NEEDS_DOCKER, run(target, ctx) içeren bir modül

Eklentiler recon modules listesinde görünür, yalnızca adıyla çağrılınca çalışır (-m headers,mycheck) ve hiçbir zaman yerleşik bir modülün yerine geçemez.

Mimari (katkıda bulunanlar için)

recon/
├── cli.py              # argüman ayrıştırma, config birleştirme, rapor yazımı
├── engine.py           # modülleri zamanlar, paralel çalıştırır, tekilleştirir
├── context.py          # ScanContext: her modülle paylaşılan tipli ayarlar
├── scope.py            # izin listesi + redirect-güvenli HTTP yardımcısı
├── ratelimit.py         # ortak, toplam hız sınırlayıcı
├── runner.py            # "bu dış aracı çalıştır" işlemini Docker ya da native binary üzerinden soyutlar
├── diff.py              # iki çalıştırma arasında parmak izi tabanlı karşılaştırma
├── config.py            # YAML yapılandırma dosyası yükleme/doğrulama
├── findings.py          # Finding/ScanResult veri modeli (rule_id, fingerprint, önem)
├── i18n.py              # İngilizce metin + Türkçe çeviri kataloğu
├── report.py / report_html.py   # Markdown / JSON / SARIF / HTML üreticiler
├── analyst/             # opsiyonel LLM özeti (opt-in, düz HTTP, SDK yok)
├── integrations/github.py       # opsiyonel GitHub issue oluşturma
└── modules/             # her kontrol için bir dosya; her biri NAME, NEEDS_DOCKER, run() verir

Modül eklemek için: recon/modules/<ad>.py içinde NAME, NEEDS_DOCKER ve run(target, ctx) -> list[Finding] sağla; recon/modules/__init__.py'ye kaydet; bulgu metnini İngilizce ve kararlı bir rule_id ile yaz, Türkçe çeviriyi recon/i18n.py'ye ekle; araç çıktısı ayrıştırmasını ayrı bir saf fonksiyonda tut (Docker ya da ağ olmadan test edilebilsin); tests/ altına test ekle.

Kararlılık, geliştirme, lisans

CLI bayrakları ve report.json şeması (docs/report.schema.json) v1.0'dan itibaren kararlıdır; kırıcı değişiklikler yeni bir ana sürümle ve CHANGELOG girdisiyle gelir.

pip install -e ".[dev]"
ruff check recon/ tests/ && mypy recon/ && pytest -q

Her push/PR bu aynı kontrolü Python 3.9–3.13'te çalıştırır. Bir modül eklemek veya hata düzeltmek için CONTRIBUTING.md'ye bak.

Apache-2.0 altında lisanslıdır — bkz. LICENSE. nmap, nuclei ve testssl.sh üzerine kuruludur; bu proje bu araçları yönetir, yerlerine geçmez.

⚠️ Yasal

Bu araç, verdiğin hedefe gerçek ağ istekleri gönderir. Yalnızca sahibi olduğun veya test etmek için yazılı iznin olan sistemlerde kullan. Yetkisiz tarama çoğu ülkede yasa dışıdır — sorumluluk tamamen sana aittir. --authorized bayrağı, bu onayı bilinçli vermeden yanlışlıkla bir tarama çalıştıramayasın diye özellikle oraya konmuştur.

Metadata

Release files for recon-orchestrator 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for recon-orchestrator 1.2.0
File Size Uploaded
recon_orchestrator-1.2.0.tar.gz 172.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for recon-orchestrator 1.2.0
File Interpreter ABI Platform
recon_orchestrator-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 307.0 kB

Release files / recon_orchestrator-1.2.0.tar.gz

Download URL recon_orchestrator-1.2.0.tar.gz
Size 172.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ed878a872fdb0c91bf2fbf8ffcf5ca0ffb5dc23a7484e31399d491f39db7003d
BLAKE2b-256 checksum
How to use checksums
d8e709f84f32278ff49e316612c69bc15a92d3b540fd86070b618833dcb21e00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / recon_orchestrator-1.2.0-py3-none-any.whl

Download URL recon_orchestrator-1.2.0-py3-none-any.whl
Size 134.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b067835bfebd042487abee9a97555070c2f6ce191b3ee83fd8cabf706a4f0555
BLAKE2b-256 checksum
How to use checksums
52676a92d87dafca5e49e4c4bcaa80a429c65296768f8a663a90823297d31773
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.1

2 release files

This release

1.2.0 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page