Product 7 min read Markdown

A Free, Open Source Laravel Security Scanner You Run With Artisan

stackshield/scanner checks your booted Laravel app for debug mode, exposed Telescope and Horizon, weak session cookies, CSRF exemptions, missing rate limits and vulnerable dependencies. One composer require, one artisan command, no account needed.

Matt King
Matt King
October 13, 2026
Last updated: October 13, 2026
A Free, Open Source Laravel Security Scanner You Run With Artisan

Most Laravel security incidents we see are not clever. Debug mode left on after a config change. Telescope reachable because a middleware refactor dropped the gate. A CSRF exemption added for one webhook that quietly covers half the API. Each one is a single line of configuration, and none of them shows up in tests.

We have released a free, open source scanner that checks for exactly these, from inside your application:

composer require --dev stackshield/scanner
php artisan stackshield:scan

It supports Laravel 10, 11, 12 and 13 on PHP 8.2 or later, needs no account, and the source is on GitHub.


What it checks

The scanner boots your application and inspects what Laravel actually resolved, not what the files on disk suggest. The current checks:

  • Debug mode: APP_DEBUG and APP_ENV, judged against the environment the scan runs in
  • Session cookies: HttpOnly, Secure and SameSite flags, plus the session driver and encryption
  • Security headers as your application actually emits them
  • Telescope, Horizon and Ignition: installed, enabled, and whether they are gated
  • Debugbar and Clockwork left installed or enabled
  • CSRF: the middleware is in place, and what the exemption list covers
  • Cookie encryption middleware
  • CORS: wildcard origins combined with credentials
  • APP_KEY: set, and not a known default
  • HTTPS posture in production: secure cookies and APP_URL
  • Rate limiting on login, registration and password reset routes
  • End of life: framework and PHP versions past security support
  • Dependency advisories: composer.lock checked against Packagist's advisory data

Because it reads the booted app, it can answer questions a file scan cannot. A Telescope gate defined in a service provider, middleware applied through a route group, or an exemption added in bootstrap/app.php are all resolved the way Laravel resolves them.


Environment-aware results

A scan on your laptop will find APP_DEBUG=true, and that is fine. Every result records the environment it was evaluated in, and severity follows from it: debug mode is critical in production or staging and informational in local. The report states the environment at the top so nobody misreads a local run.

To check what production will actually run with, run the scanner where production environment variables are composed, which for most teams is the deploy pipeline.


Output formats and exit codes

php artisan stackshield:scan                     # readable report
php artisan stackshield:scan --format=json       # for scripts
php artisan stackshield:scan --format=sarif --output=stackshield.sarif
php artisan stackshield:scan --offline           # skip the dependency audit
php artisan stackshield:scan --fail-on=high      # stricter CI gate

The command exits non-zero when it finds anything at or above the fail_on severity (critical by default), so it works as a CI gate with no extra scripting. SARIF output contains failures and warnings only, so a clean run produces an empty report instead of annotating every pull request with checks that passed.


Running it in GitHub Actions

The published action runs the scan, uploads SARIF to the repository's Security tab and fails the build at your chosen threshold:

name: security
on: [push, pull_request]

permissions:
  contents: read
  security-events: write

jobs:
  stackshield:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with: { php-version: '8.3' }
      - run: composer install --no-interaction --prefer-dist
      - uses: stack-shield/scanner@v1
        with:
          fail-on: high

Findings then show up in the Security tab and as annotations on the pull request that introduced them. For other CI systems, run the artisan command directly and use its exit code.

For more on where security checks belong in a pipeline, see Securing Your Laravel CI/CD Pipeline.


What it cannot see

The scanner is the inside view. It sees your configuration, not your infrastructure. It cannot tell you whether port 3306 is open to the internet, whether your TLS setup is weak at the load balancer, whether a subdomain points at a deleted cloud resource, or whether a proxy is stripping the headers your application sets.

Those are the outside view, and the two can disagree. Your app may set Strict-Transport-Security while your CDN drops it, or APP_DEBUG may be false in the pipeline but true on the server because someone edited .env by hand. That gap is what StackShield checks from the outside, against the deployed application.

It is also not a static analyser. For SQL injection patterns, unescaped Blade output and mass assignment, use Larastan, Psalm's taint analysis or semgrep alongside it. roave/security-advisories is a good companion too: it stops known-vulnerable packages from being installed at all.


Optional: send results to StackShield

Nothing is sent anywhere by default. If you use StackShield, you can report inside-view results to your dashboard and trigger an outside scan of a deployed URL in one step:

STACKSHIELD_TOKEN=sk_... php artisan stackshield:scan --url=https://staging.example.com --report

The payload is the list of check results: slug, status, severity and a short summary. No source code, no environment variables, no secrets. --no-report always wins.


Try it

composer require --dev stackshield/scanner
php artisan stackshield:scan

If it finds something, the report includes how to fix it. If you want to see the outside view of the same application, run a free external scan: it takes under a minute and needs no signup.

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue, and most teams do not find out until something breaks. The free scan checks your live app in 60 seconds. Then StackShield re-runs every check after each deploy, so a fix you ship today does not quietly regress next week.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup for the scan. Continuous monitoring on a 14-day trial, no card.

Frequently Asked Questions

Is the StackShield Laravel scanner free?

Yes. stackshield/scanner is open source and free to use. Install it with composer require --dev stackshield/scanner and run php artisan stackshield:scan. It needs no StackShield account and sends nothing to StackShield unless you give it a token and ask it to report.

Which Laravel versions does it support?

Laravel 10, 11, 12 and 13, on PHP 8.2 or later. It recognises the CSRF middleware and bootstrap-level exemptions used by Laravel 11 and later as well as the older Kernel-based setup.

Is it a static analysis tool?

No. It inspects the booted application: resolved configuration, registered middleware, routes and installed packages. That is how it can tell whether Telescope is actually gated or whether a CSRF exemption covers a real route. For code-level patterns such as SQL injection or unsafe Blade output, pair it with Larastan, Psalm taint analysis or semgrep.

Will it flag APP_DEBUG=true on my laptop?

Not as a problem. Every result records the environment it was evaluated in and severity depends on it: debug mode is critical in production or staging and informational in local. To check production settings, run it in your deploy pipeline where production environment variables are set.

Does it make network calls?

Only one by default: the dependency audit compares composer.lock against advisories from Packagist. Use --offline to skip it. Nothing goes to StackShield unless you set STACKSHIELD_TOKEN and pass --report.

Stay Updated on Laravel Security

Get actionable security tips, vulnerability alerts, and best practices for Laravel apps.