Metadata-Version: 2.4
Name: gisweep
Version: 0.2.0
Summary: GIS vulnerability scanner — ArcGIS REST, embedded maps, secret detection, KVKK/GDPR-aware
Project-URL: Homepage, https://github.com/enisgetmez/gisweep
Project-URL: Documentation, https://enisgetmez.github.io/gisweep
Project-URL: Repository, https://github.com/enisgetmez/gisweep
Project-URL: Issues, https://github.com/enisgetmez/gisweep/issues
Author-email: Enis Getmez <enis@enisgetmez.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: arcgis,compliance,gdpr,gis,kvkk,security,vulnerability-scanner
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Security
Requires-Python: >=3.11
Requires-Dist: defusedxml>=0.7
Requires-Dist: httpx>=0.27
Requires-Dist: jinja2>=3.1
Requires-Dist: packaging>=24.0
Requires-Dist: playwright>=1.45
Requires-Dist: pydantic>=2.7
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.7
Requires-Dist: structlog>=24.1
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-playwright>=0.5; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
Requires-Dist: vcrpy>=6.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
Description-Content-Type: text/markdown

# gisweep

[![PyPI](https://img.shields.io/pypi/v/gisweep.svg)](https://pypi.org/project/gisweep/)
[![Python](https://img.shields.io/pypi/pyversions/gisweep.svg)](https://pypi.org/project/gisweep/)
[![CI](https://github.com/enisgetmez/gisweep/actions/workflows/ci.yml/badge.svg)](https://github.com/enisgetmez/gisweep/actions/workflows/ci.yml)
[![Downloads](https://img.shields.io/pypi/dm/gisweep.svg)](https://pypi.org/project/gisweep/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/enisgetmez/gisweep?style=social)](https://github.com/enisgetmez/gisweep)

> **In a six-second passive scan of a publicly indexed Turkish municipal ArcGIS
> REST root, `gisweep` returned 99 findings — 9 critical, 17 high — including
> anonymous write capability on seven feature-service layers, a reachable
> `/arcgis/admin` endpoint, and PII fields (national ID, address, phone)
> exposed on five MapServer layers. Each finding cites the exact KVKK and
> GDPR article it triggers.** That's what this tool does.

![gisweep arcgis demo](docs/demo/demo.gif)

`gisweep` is an open-source CLI that audits GIS surfaces for the
misconfigurations nobody else looks for: ArcGIS REST services exposing
anonymous write capabilities, GeoServer/MapServer endpoints with public
WFS-Transactional, admin directories reachable from the public internet,
embedded web maps leaking API keys, feature services returning PII without
authentication, and outdated server / client-side libraries with public CVEs.
Every finding is mapped to KVKK and GDPR articles so audits are usable
directly in compliance reports.

## Why

ArcGIS REST and the open-source OGC stack (GeoServer, MapServer, QGIS Server)
are everywhere — municipalities, utilities, transport, public health — and they
are *consistently* misconfigured. Existing OSS scanners (nuclei, trivy, semgrep)
do not understand ArcGIS or OGC semantics, and existing compliance tools don't
speak GIS. `gisweep` fills that gap with a protocol-aware engine plus a
Playwright-driven web crawler that finds embedded maps in the wild and follows
their network traffic back to the underlying services. Every finding leaves
the scanner pre-mapped to **KVKK Madde 12 / 9** and **GDPR Art. 32 / 5(1)(f)**
so a compliance officer can route it without translating from CVSS-speak.

## What it covers today

| Subcommand | Targets | Checks |
|---|---|---|
| `gisweep arcgis <url>` | ArcGIS REST root | ARC-001 anonymous enumeration · ARC-002 anonymous write capability · ARC-003 admin endpoint exposed · ARC-011 Sync/Extract enabled · ARC-012 ExportTiles enabled · ARC-013 unbounded query · ARC-014 PII fields exposed · ARC-015 outdated ArcGIS Server CVE |
| `gisweep ogc <url>` | WMS / WFS via GeoServer / MapServer / QGIS Server / deegree | OGC-001 anonymous GetCapabilities · OGC-002 outdated server CVE · OGC-005 WFS-T anonymous write |
| `gisweep web <url>` | Any web page (Playwright headless Chromium) | WEB-001 embedded data-plane endpoint inventory · WEB-002 secret leakage in HTML/JS/XHR · WEB-007 outdated client-side GIS library CVE |
| `gisweep secrets <url-or-path>` | Any URL or local file/directory | SEC-001 hardcoded API keys / tokens / private keys |
| `gisweep scan <url>` | Auto-detect (probes URL, dispatches arcgis / ogc / web) | All of the above |

Cross-cutting **compliance overlay**:

- **COMP-001** KVKK Madde 12 aggregate — ≥5 PII-bearing layers exposed anonymously.
- **COMP-003** GDPR Art. 32 technical-measures gap — admin exposed AND data
  unauthenticated.

Bundled CVE database (regenerable from NIST NVD via `scripts/refresh_cve_db.py`):
ArcGIS Server, GeoServer, MapServer, plus product slots for QGIS Server,
deegree, GeoNetwork, Leaflet, OpenLayers, Mapbox GL JS, Cesium, ArcGIS API for
JavaScript.

## Output formats

- Rich console (default)
- JSON (stable schema `gisweep.report.v1`)
- SARIF 2.1.0 (consumable by GitHub Code Scanning, Azure DevOps)
- HTML (self-contained, embedded CSS, KVKK/GDPR pills)
- Markdown (GitHub-friendly, KVKK/GDPR matrix)

Every format surfaces the KVKK / GDPR / CWE / CVSS metadata of every finding.

## Install

```bash
pip install gisweep
playwright install chromium  # one-time browser download for `gisweep web`
```

Or via Docker (Playwright + Chromium pre-installed):

```bash
docker run --rm ghcr.io/enisgetmez/gisweep:latest arcgis \
    https://example.gov/arcgis/rest/services
```

## Quick start

```bash
gisweep version
gisweep checks list
gisweep checks info ARC-002

# ArcGIS REST passive scan with multi-format report
gisweep arcgis https://example.gov/arcgis/rest/services \
    -o report.json -o report.sarif -o report.html

# OGC scan against a GeoServer instance
gisweep ogc https://geo.example.org/geoserver

# Headless-Chromium audit of a city portal
gisweep web https://city-portal.example/map -o web-report.json

# Secret scan over a build directory
gisweep secrets ./build/static/js/

# Auto-detect: figure out from the URL whether to dispatch ArcGIS / OGC / web
gisweep scan https://opaque.example/something
```

## Active mode

`--active` runs intrusive checks: it actually attempts a write on a discovered
FeatureServer or WFS-T endpoint, exercises SSRF vectors via Geometry/Print
services, and probes default credentials. **It is opt-in twice** — both
`--active` and `--i-own-this-target` (or `--authorized-by <ticket>`) are
required, and every active call is appended to `~/.gisweep/audit.jsonl`.

```bash
gisweep arcgis https://my-server.example/arcgis/rest/services \
    --active --i-own-this-target \
    --ssrf-canary https://my-canary.example/abc123
```

Never run `--active` against infrastructure you do not own or have written
authorization to test. See [SECURITY.md](SECURITY.md).

## Refreshing the CVE database

```bash
uv run python -m scripts.refresh_cve_db --rate-delay 7
```

The script pulls from `services.nvd.nist.gov/rest/json/cves/2.0` for every
tracked CPE, dedupes by CVE id, and rewrites `src/gisweep/data/cve_db.json`.
Pass `--api-key <key>` for the higher NVD rate limit.

## License

[Apache-2.0](LICENSE) — © 2026 Enis Getmez and contributors.
