Constants
CAKEPHP_PATTERNS = [{/\$this->Authentication->/, "CakePHP Authentication component"}, {/\$this->Authorization->authorize/, "CakePHP Authorization"}, {/\$this->loadComponent\s*\(\s*['"]Authentication['"]/, "CakePHP Authentication component"}]
GENERIC_PATTERNS = [{/(?:isset|empty|!\s*isset)\s*\(\s*\$_
SESSION\s*\[\s*['"]user/, "
PHP session user guard"}, {/\$_
SERVER\[['"]
PHP_AUTH_USER['"]/, "
PHP HTTP Basic Auth"}]
Generic PHP auth patterns
LARAVEL_AUTH_CHECKS = [{/Gate::allows\s*\(/, "Laravel Gate authorization"}, {/Gate::authorize\s*\(/, "Laravel Gate authorization"}, {/\$this->authorize\s*\(/, "Laravel Policy authorization"}, {/auth\(\)->check\(\)/, "Laravel auth check"}, {/Auth::check\(\)/, "Laravel Auth::check"}, {/\$request->user\(\)/, "Laravel request user check"}]
Laravel Gate/Policy checks in action body
LARAVEL_CONTROLLER_MIDDLEWARE = [{/\$this->middleware\s*\(\s*['"]auth['"]/, "Laravel controller auth middleware"}, {/\$this->middleware\s*\(\s*['"]auth:/, "Laravel controller auth middleware"}, {/\$this->authorizeResource\s*\(/, "Laravel authorizeResource"}]
Laravel controller middleware
LARAVEL_ROUTE_MIDDLEWARE = [{/(?:->|::)middleware\s*\(\s*['"]auth['"]/, "Laravel auth middleware"}, {/(?:->|::)middleware\s*\(\s*['"]auth:api['"]/, "Laravel auth:api middleware"}, {/(?:->|::)middleware\s*\(\s*['"]auth:sanctum['"]/, "Laravel Sanctum auth"}, {/(?:->|::)middleware\s*\(\s*['"]auth:web['"]/, "Laravel web auth"}, {/(?:->|::)middleware\s*\(\s*['"]verified['"]/, "Laravel verified middleware"}, {/(?:->|::)middleware\s*\(\s*\[.*['"]auth['"]/, "Laravel auth middleware"}]
Laravel middleware patterns.
(?:->|::) so the leading form is recognized too: Route::middleware('auth') ->get('/x', …) is as common as the chained ->middleware('auth'), and
only the chained one used to match. That gap was invisible while the
±3-line window happened to reach the previous route's ->middleware(…)
— a route tagged correctly by accident is still a tagger that cannot read
the form in front of it.
SLIM_YII_CI_PATTERNS = [{/\->add\s*\(\s*['"]?auth/i, "Slim auth middleware"}, {/\bAuthorization\b.*header/i, "Slim Authorization header check"}, {/\bAccessControl\b/, "Yii AccessControl filter"}, {/\bAuthMethod\b/, "Yii AuthMethod"}, {/\bHttpBearerAuth\b/, "Yii HttpBearerAuth"}, {/\bCompositeAuth\b/, "Yii CompositeAuth"}, {/\bbeforeAction\b.*auth/i, "Yii beforeAction auth"}, {/->before\s*\(\s*['"]?auth/i, "CodeIgniter before auth filter"}, {/\$this->beforeFilter/i, "CodeIgniter beforeFilter"}, {/\bauthFilter\b/i, "CodeIgniter authFilter"}]
Slim / Yii / CodeIgniter additional patterns
STATEMENT_BOUNDARY = /(?:Route|Router)::(?:get|post|put|patch|delete|options|head|any|query|match|addRoute|resource|apiResource)\s*\(|\$\w+\s*->\s*(?:get|post|put|patch|delete|options|head|any|query|map|group)\s*\(\s*['"]\/|\bfunction\s+\w+\s*\(/i
A line that starts a different route or method than the one being
inspected: Route::get('/x', …), $app->post('/x', …), Route::resource,
a named function foo( declaration. Anonymous closures (function () {)
are deliberately excluded — those are part of the current route statement.
Every window this tagger scans is bounded by it. A fixed ±N-line window is
not a statement: two one-line routes stacked on top of each other put the
second's ->middleware('auth') inside the first's window, and the public
route came back tagged as protected.
The $app->get(…) form requires a path literal starting with / so that
an ordinary body call — $request->get('id') — is not mistaken for the
start of the next route and does not cut a scan short.
SYMFONY_PATTERNS = [{/#\[IsGranted\s*\(/, "Symfony #[IsGranted]"}, {/#\[Security\s*\(/, "Symfony #[Security]"}, {/@Security\s*\(/, "Symfony @Security annotation"}, {/@IsGranted\s*\(/, "Symfony @IsGranted annotation"}, {/\$this->denyAccessUnlessGranted\s*\(/, "Symfony denyAccessUnlessGranted"}, {/\$this->isGranted\s*\(/, "Symfony isGranted check"}]
Symfony security attributes/annotations