How it works
Once a day, we request paths that should never be public and check whether they return the real file:
- configuration and secrets:
/.env,/.htpasswd; - version control:
/.git/HEAD,/.git/config; - database dumps:
/backup.sql,/dump.sql; - logs and debug tools:
/storage/logs/laravel.log,/phpinfo.php, the Ignition health check, the Symfony profiler, Laravel Telescope and Horizon; - directory listings:
/uploads/,/storage/,/backup/; - API descriptions and schemas:
/swagger.json,/openapi.json, and a GraphQL introspection query on/graphql; /.DS_Storefiles, which list a folder's contents.
A path only counts when its content matches the file's signature. Sites that answer every path with their normal page (single-page apps, catch-all routes) are not flagged.
Statuses
| Status | Meaning |
|---|---|
| OK | None of these files are publicly readable. |
| Failed | At least one sensitive file is publicly readable. The report lists each one. |
By default you are notified of warnings and failures.
Fixing common problems
.envor.gitexposed: your web server's document root is the project folder instead of its public folder (public/in Laravel). Point it to the public folder, then change every secret in the exposed file: assume it has been read.- Debug tools exposed: disable Telescope, Horizon and the profiler in production, or protect them with authentication.
- Directory listings: turn off auto-indexing (
autoindex off;in nginx,Options -Indexesin Apache). - GraphQL introspection: disable introspection in production.