NAME
webperimeter - check your own web perimeter the way an outsider sees it
SYNOPSIS
webperimeter --scope scope.txt --authorized [options]
webperimeter --scope scope.txt --dry-run
webperimeter --help
Scan every host in scope.txt and print a text report:
webperimeter --scope scope.txt --authorized
See what would be scanned, without sending anything to the hosts:
webperimeter --scope scope.txt --dry-run
Save a JSON report, and fail a deployment job on any medium or worse finding:
webperimeter --scope scope.txt --authorized -f json -o report.json --fail-on medium
A quick check of the web ports only, with no sensitive-path probes:
webperimeter --scope scope.txt --authorized --ports 80,443 --max-urls 1 --no-path-probes
Scan a test server on this machine, and point findings at its files:
webperimeter --scope lab.txt --authorized --allow-private \
--docroot /srv/www/lab --source ~/src/lab/lib
DESCRIPTION
This is the command-line front end to App::WebPerimeterScan. --help lists every option.
The scope file lists the hosts you are allowed to test; its format is described in App::WebPerimeterScan::Scope. Nothing is sent to any host unless you also give --authorized, which states that you have permission to test every host in the file.
Every option is checked before any traffic is sent, so a typo stops the command at once instead of after a long scan.
EXIT STATUS
0 the scan ran, and nothing reached the --fail-on level
(also for --help, --version and --dry-run)
1 the scan ran, and at least one finding reached the --fail-on level
2 the command line or the scope file is wrong, or --authorized is
missing; nothing was sent
The default --fail-on level is high. --fail-on never always exits 0 after a scan.
COMMON PITFALLS
--dry-runstill looks up names. It sends nothing to the hosts, but it resolves each name in DNS to show whether it is private.Exit status 0 is not "secure". It means that no finding reached the
--fail-onlevel. A host that could not be scanned is reported asscan-errororhost-unreachableat high severity, so it fails the default level; with--fail-on criticalit does not.--outputprints one line. With-o FILE, the report goes to the file and "Report written to FILE" goes to STDOUT (not with--verbose).Colour is automatic. The text report is coloured when STDOUT is a terminal and
-ois not given. Use--no-color(or--no-colour) to turn it off, or--color(or--colour) to force it.Private addresses need
--allow-private. Without it, a host that resolves to127.0.0.1,10.0.0.0/8and the like is refused, and the refusal is a high-severity finding.--docrootand--sourcemust be directories on this machine. A path that is not a directory is a usage error (exit 2).
ENCODING
The reports are written as bytes, exactly as the scanner made them. Text from web pages is UTF-8 when the site is, so the report is correct UTF-8 for such sites; view it in a UTF-8 terminal. Save the scope file as UTF-8; international host names may be written as they are, and are reported in their ASCII (Punycode) form. See "ENCODING" in App::WebPerimeterScan::Scope. Messages are in English; error messages from the operating system follow your locale.
STATE DIAGRAM
webperimeter [options]
|
v
+----------------+
| PARSE OPTIONS |
+----------------+
|--- unknown option -> usage; exit 2
|--- --help -> help; exit 0
|--- --version -> version; exit 0
v
+----------------+
| VALIDATE |--- no --scope, bad --format, bad --fail-on,
+----------------+ bad port, docroot or source not a directory
| -> message; exit 2
v
+----------------+
| LOAD SCOPE |--- file unreadable, or no usable line
+----------------+ -> message; exit 2
|
|--- --dry-run -> list hosts, ports and directories; exit 0
v
+----------------+
| AUTHORISED? |--- no --authorized -> explanation; exit 2
+----------------+
|
v
+----------------+
| SCAN | App::WebPerimeterScan->run (traffic is sent)
+----------------+
|
v
+----------------+
| REPORT | text, json or html; to STDOUT or to --output
+----------------+
|
v
+----------------+
| EXIT | 1 if a finding reached --fail-on, else 0
+----------------+
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
LICENCE AND COPYRIGHT
Copyright 2026 Nigel Horne.
Usage is subject to the GPL2 licence terms. If you use it, please let me know.