From vulnerability to proof: continuous, automated pentesting in monsys
Your inventory knows which software runs. The new attack-surface layer looks from the outside and proves what is actually reachable: opt-in, only against proven-owned scope, detect-only, and signed for your NIS2 audit.
A vulnerability alert always asks the same question nobody can answer quickly: is this running somewhere, and can anyone reach it from outside? The package inventory says "this version of PHP is vulnerable". What you need on that day is the next line: which of your sites respond to it, from the internet, right now.
So we added an attack-surface layer to monsys: continuous, automated pentesting that complements the inside-out inventory with an outside-in view. The scope is deliberately tight: a scanner pointed at customer systems must never leave scope, never break anything, and never run without proof of ownership.
What it answers
- What is actually reachable? Open ports, public panels, TLS configuration,
missing security headers, exposed files like .git and .env.
- Is a CVE exploitable? A detection that confirms a vulnerability from your
inventory lifts that exposure from "monitor" to exploitable confirmed: with an alert.
- What did nobody register as a CVE? Weak ciphers, expired certificates per
domain, default logins, directory listings.
Safe by design
The whole layer is built around one principle: scope is proven ownership. A scanner only touches an asset you demonstrably own: a domain an agent serves on your own host (confirmed via the Let's Encrypt certificate), a DNS-TXT verification, or a manual addition with TOTP. There is no free-form field that starts a scan.
On top of that:
- Opt-in. Scanning is off by default. Enabling requires TOTP. Scans run in
your own maintenance window.
- Detect-only. No exploitation, no brute force, no DoS-like tests, nothing
written to a target. We use only self-hosted open source: nmap, testssl.sh, nuclei and OWASP ZAP: no external cloud service in the path.
- Isolated. Each scanner runs in a pinned, hardened Docker container:
read-only, no capabilities, non-root, with the hostname pinned to the vetted IP so DNS rebinding is impossible.
- Stoppable. A kill-switch stops a running scan within seconds.
Built the way an attack tool should be
Because one wrong call on a customer system is company-ending, we had this feature guarded by a separate adversarial team that, during the build, hunted for scope escape, SSRF, command injection and a kill-switch that doesn't take. That team found real problems: a kill-switch that didn't stop a container, DNS rebinding, a forgeable ownership proof, and each was fixed and re-verified before rollout. That is not a footnote; it is why you dare to turn this on against your own infrastructure.
Evidence for your audit
Every scan run is Ed25519-signed and lands in the monthly audit pack: who scanned, when, which scope, which findings. NIS2 asks for policies and procedures that assess the effectiveness of your measures. A monthly, reproducible, signed scan report per asset is exactly that. monsys measures; the auditor judges.
Turning it on
Go to Security → Attack surface, import your domains from the agents, enable the policy with TOTP and pick a maintenance window. The first scan finds your open ports, TLS status and misconfigurations within minutes, and then every week, with a comparison against the week before.
From "there is a CVE" to "this host, this domain, reachable, confirmed": in one continuous line.