baspa/larascan 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

baspa/larascan

最新稳定版本:v3.0.0

Composer 安装命令:

composer require baspa/larascan

包简介

A security-focused static analysis package for Laravel applications

README 文档

README

LaraScan — Scan Laravel applications for vulnerabilities, insecure configs and risky code

LaraScan

Latest Version Tests PHPStan Coverage Downloads License

Security-focused static analysis for Laravel applications. One artisan command, 88 checks across config, cookies, headers, auth, routing, models, SQL, XSS, files, injection, crypto, dependencies, ecosystem packages and more — plus an optional runtime probe that verifies headers on the live app.

Why LaraScan? Most Laravel security issues come from misconfiguration or forgotten dev settings in production — debug on, secure cookies off, hardcoded API keys in code. LaraScan scans for them in one shot, AST-based where it matters, with sane defaults and a clean CI workflow.

Example

larascan security scan
════════════════════════════════════════════

  Application configuration
  ─────────────────────────
     ✗ config.app-env
        └─ INFO     APP_ENV is 'local' — leaks development-mode behavior in production.
     ✗ config.env-example-sync
        ├─ LOW      Keys present in .env but missing from .env.example: MISTRAL_API_KEY
        └─ LOW      Keys present in .env.example but missing from .env: RESPONSE_CACHE_*

  Cookies & sessions
  ──────────────────
     ✗ cookies.session-encrypt
        └─ HIGH     session.encrypt is false — session payloads are stored in plaintext.

════════════════════════════════════════════
  Report Card
════════════════════════════════════════════

  Application configuration ███████████░░░░░░░░░  57%   (4/7)
  Cookies & sessions       ██████████████░░░░░░  71%   (5/7)
  HTTP headers             ████░░░░░░░░░░░░░░░░  20%   (1/5)
  ...

  Total: 45 passed   19 failed   6 skipped   0 errored
  Highest severity: CRITICAL

Install

composer require baspa/larascan --dev
php artisan larascan:install

The install command publishes config/larascan.php and optionally .github/workflows/larascan.yml (CI workflow stub).

Usage

php artisan larascan                  # run all enabled checks
php artisan larascan --only-failed    # hide passed + skipped
php artisan larascan --category=config
php artisan larascan --fail-on=high   # CI threshold (exit 1 on findings ≥ high)
php artisan larascan:list             # list all registered checks

Advise (heuristic, non-gating)

php artisan larascan:advise                  # surface heuristic security advisories
php artisan larascan:advise --advice=advise.auth.*
php artisan larascan:advise --category=auth

Advise is intentionally non-gating: exit code is always 0. For architectural items that no scanner can detect, see docs/manual-security-checklist.md.

Output formats

Flag Default for Description
(none) TTY / humans Categorized output with a Report Card at the end
--format=json AI agents Structured JSON. Auto-selected when laravel/agent-detector flags the run as an agent (Claude Code, Cursor, Codex, Copilot, etc.).
--format=sarif GitHub Code Scanning SARIF 2.1.0 report with one result per finding.

Force JSON manually with LARASCAN_AGENT_MODE=1 or --format=json.

Any format can be written to a file with --output=PATH. For --format=json and --format=sarif, stdout still gets the human report (so CI logs stay readable); with --format=human, stdout only gets a Report written to ... confirmation. The exit code is unchanged either way.

Configuration

Published config/larascan.php controls:

  • fail_on — severity threshold for non-zero exit code (critical|high|medium|low|info, default high)
  • checks — per-check enable map ('cookies.session-secure' => ['enabled' => false])
  • ignore — glob patterns to skip during AST scans
  • tools — override binary paths via env vars: LARASCAN_COMPOSER_BIN, LARASCAN_NPM_BIN, LARASCAN_SEMGREP_BIN

See docs/configuration.md for full details.

CI integration

The published workflow runs on PR + push to main + nightly. It uses --only-failed to keep CI logs lean, with the Report Card at the end for the overview.

php artisan larascan:install --workflow

Exit codes: 0 clean, 1 findings ≥ --fail-on, 2 a check errored. See docs/ci-integration.md.

SARIF / GitHub Code Scanning

Findings can show up as Code Scanning alerts on the Security tab and as PR annotations:

php artisan larascan --format=sarif --output=larascan.sarif

The published workflow already does this and uploads the report via github/codeql-action/upload-sarif (the workflow grants security-events: write; private repos need GitHub Advanced Security — remove the upload step if unavailable).

Severity mapping:

Larascan severity SARIF level security-severity
critical error 9.8
high error 8.0
medium warning 5.5
low note 3.0
info note 0.0

Findings without a file (config-level checks like config.app-debug) are anchored to composer.json:1 so GitHub doesn't drop them; those results carry a larascan.synthesizedLocation property.

Adopting LaraScan on an existing app (baseline)

A mature codebase will light up on the first scan. Rather than fixing everything before CI can go green, record the current findings as a baseline so CI only fails on new findings:

php artisan larascan:baseline   # writes larascan-baseline.json
git add larascan-baseline.json && git commit -m "Add larascan baseline"

From then on, plain php artisan larascan runs suppress baselined findings — they're counted (N baselined) rather than hidden, so you can still see them — and only findings that aren't in the baseline count toward the --fail-on threshold. Chip away at the baselined findings over time; re-run larascan:baseline to shrink the file.

Baseline identity is line-insensitive: a finding is matched on a hash of its check id, file and normalized message, so unrelated edits that shift line numbers don't break the baseline. When the source has changed enough that baselined findings no longer occur, the scan reports N stale baseline entries with a hint to re-run the command and prune them.

php artisan larascan --baseline=path/to/baseline.json   # override the path
php artisan larascan --no-baseline                       # ignore the baseline entirely

Path resolution order: --baseline flag, then config('larascan.baseline'), then an implicit larascan-baseline.json in the project root if present. An explicitly named baseline (flag or config) that's missing or invalid is an error; the implicit default may simply be absent.

Runtime probe

Static checks confirm the config is right; they can't tell you whether a middleware actually runs or whether a proxy strips a header on the way out. larascan:probe sends one real HTTP GET to the running app and verifies the security headers and cookie flags are actually present in the response:

php artisan larascan:probe --url=https://staging.example.test

The target URL resolves from --url, then config('larascan.probe.url') (env LARASCAN_PROBE_URL), then app.url. The probe checks HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, CSP, cookie Secure/HttpOnly/SameSite flags, Server/X-Powered-By disclosure, and the http→https redirect. These are reported under probe.* check ids, distinct from the static headers.* checks.

Findings against local targets (localhost, 127.0.0.1, *.test, *.local) are downgraded to Info — probing a dev box shouldn't fail CI.

Flag Description
--url=URL Target URL (overrides config/app.url)
--fail-on=SEVERITY Severity threshold for non-zero exit (default from larascan.fail_on, else high)
--probe=PATTERN Filter probes by id pattern, repeatable (e.g. --probe=probe.cookie*)
--timeout=SECONDS Request timeout (default 5)
--insecure Skip TLS certificate verification
--ignore-errors Exit 0 even when the request fails
--only-failed Hide passed and skipped probes
--format=human|json Output format (json auto-selected for agents)

What's checked?

88 checks across 17 categories. Some require optional packages — those checks self-skip when the package isn't installed.

Show all 88 checks

Config (config.*) — 10

  • config.app-debug — APP_DEBUG must be false in production
  • config.app-key — APP_KEY must be set
  • config.app-env — APP_ENV must not be a development value in production
  • config.env-not-committed — .env must be gitignored and never committed
  • config.env-example-sync — .env and .env.example must share key sets
  • config.env-calls-outside-config — env() calls outside config/ defeat config caching
  • config.log-level — Default log channel must not be at debug in production
  • config.debug-blacklist — debug_blacklist must redact sensitive env keys when debug is on
  • config.trusted-proxies — Trusted proxies must not be wildcard
  • config.mail-smtp-encryption — Remote SMTP mailers must force TLS encryption

Cookies & sessions (cookies.*) — 7

  • cookies.session-secure — SESSION_SECURE_COOKIE must be true in production
  • cookies.session-http-only — SESSION_HTTP_ONLY must be true
  • cookies.session-same-site — SESSION_SAME_SITE must be lax or strict
  • cookies.session-encrypt — session.encrypt should be true
  • cookies.session-lifetime — session.lifetime must be within a reasonable range
  • cookies.encrypt-middleware — EncryptCookies middleware must be registered
  • cookies.encrypt-excludes — Sensitive cookies must not be in EncryptCookies::$except

Headers (headers.*) — 8

  • headers.cors-wildcard — CORS allowed_origins must not be wildcard with credentials enabled
  • headers.hsts — HSTS header middleware must be active in production
  • headers.x-content-type-options — X-Content-Type-Options: nosniff middleware must be active
  • headers.x-frame-options — X-Frame-Options or frame-ancestors must be set
  • headers.referrer-policy — Referrer-Policy header middleware should be active
  • headers.csp-defined — CSP middleware must be active (requires spatie/laravel-csp)
  • headers.csp-unsafe-inline — CSP must not use unsafe-inline or unsafe-eval (requires spatie/laravel-csp)
  • headers.csp-base-uri — Spatie CSP policy must include a base-uri directive

Auth (auth.*) — 10

  • auth.bcrypt-rounds — BCRYPT_ROUNDS must be 12 or higher
  • auth.sanctum-expiration — Sanctum tokens must have an expiration (requires laravel/sanctum)
  • auth.login-throttle — Login routes must have throttle middleware
  • auth.password-column-plain — User model must hide or hash the password column
  • auth.signed-routes-verify — Email verification routes must use signed middleware
  • auth.api-ability-scoping — Sanctum tokens must be created with explicit abilities (requires laravel/sanctum)
  • auth.signed-url-no-params — Signed URLs must include user-bound route parameters
  • auth.otp-rate-limiting — OTP/2FA verification routes must have throttle: middleware
  • auth.registration-rate-limit — Registration routes must have throttle: middleware
  • auth.jwt-missing-expiration — Tymon JWT jwt.ttl must not be null or 0

CSRF (csrf.*) — 2

  • csrf.middleware-disabled — VerifyCsrfToken middleware must be registered
  • csrf.except-suspicious — CSRF except list must not contain wildcard patterns

Routing (routing.*) — 2

  • routing.state-mutating-get — GET routes must not invoke destroy/delete/remove/deactivate/disable controller methods
  • routing.api-http-only — API routes under api/* must enforce HTTPS when APP_URL is http://

Models (models.*) — 4

  • models.unguarded — Eloquent models must not use $guarded = []
  • models.unguard-call — No static Model::unguard() calls in application code
  • models.foreign-key-fillable — Foreign key columns should not be in $fillable
  • models.force-fill-user-inputforceFill() calls bypass mass-assignment protection

SQL (sql.*) — 5

  • sql.raw-user-input — DB::raw / whereRaw / selectRaw with user input
  • sql.raw-order-by — orderByRaw with user input
  • sql.variable-table-column — Variable arguments to DB::table / from / select
  • sql.validation-rule-injection — Validation rules from variable source
  • sql.orwhere-scope-bypass->orWhere(...) must not be chained directly off ->where(...) outside a closure group

XSS (xss.*) — 4

  • xss.blade-unescaped — Blade {!! $var !!} with PHP variables risks XSS
  • xss.html-stringIlluminate\Support\HtmlString produces unescaped HTML
  • xss.url-javascript-protocoljavascript: URLs in href/src are XSS sinks
  • xss.htmlstring-cast — Eloquent $casts / casts() must not cast attributes to HtmlString::class

Files (files.*) — 5

  • files.path-traversal — Storage/File operations with user-controlled paths
  • files.unlink-user-inputunlink()/rmdir() in application code
  • files.upload-mimes-validation — Validation by extension rather than MIME
  • files.public-executable-uploads — Upload rules allowing .php/.phtml/.phar
  • files.disk-visibility — Public-visibility disk with a sensitive name/root, or an s3 disk with no explicit visibility

Injection (injection.*) — 5

  • injection.commandexec/shell_exec/system/passthru calls
  • injection.process-shellProcess::fromShellCommandline() usage
  • injection.unserializeunserialize() of any input
  • injection.open-redirectredirect() with user-controlled URL
  • injection.host-headerapp.url missing or pointing to localhost

Crypto & secrets (crypto.*) — 5

  • crypto.weak-hash — md5/sha1 for security purposes
  • crypto.weak-random — rand/mt_rand/uniqid for security tokens
  • crypto.cipher-not-pinnedconfig/app.php does not pin the cipher
  • crypto.hardcoded-secret — High-entropy secrets or known token patterns in code
  • crypto.password-self-generated — Weak generators (Str::random, md5, uniqid, random_bytes, bin2hex) must not be used in password contexts — use Str::password()

Dependencies (dependencies.*) — 4

  • dependencies.composer-audit — wraps composer audit for PHP CVE detection
  • dependencies.npm-audit — wraps npm audit when a package.json is present
  • dependencies.minimum-stability-dev — composer.json minimum-stability is 'dev' without prefer-stable
  • dependencies.outdated-php — PHP version at or near end-of-life

PHP (php.*) — 5

  • php.expose-php — expose_php must be off
  • php.display-errors — display_errors must be off in production
  • php.allow-url-fopen — allow_url_fopen should be off
  • php.public-sensitive-files — No .env / .git / .sql backups in public/
  • php.phpinfo — No phpinfo() calls in application code

Logging (logging.*) — 3

  • logging.dd-dump-debug — No dd() / dump() / var_dump() in application code
  • logging.custom-error-pagesresources/views/errors/500.blade.php and 503.blade.php must exist
  • logging.sensitive-in-log-context — Log context arrays must not contain password/token/secret keys

Repo & CI (repo.*) — 4

  • repo.dependabot.github/dependabot.yml should exist for automated dep updates
  • repo.gitleaks-history — No high-entropy secrets in git history (last 100 commits)
  • repo.debug-toolbars — Debug packages (debugbar, telescope) must be in require-dev only
  • repo.security-txtpublic/.well-known/security.txt should exist so researchers know how to report issues

Ecosystem packages (ecosystem.*) — 5

  • ecosystem.telescope-production — Telescope must not be enabled in production without an explicit viewTelescope gate (requires laravel/telescope)
  • ecosystem.horizon-gate — Horizon viewHorizon gate must not be trivially true, and must be defined in production (requires laravel/horizon)
  • ecosystem.pulse-gate — Pulse viewPulse gate must not be trivially true, and must be defined in production (requires laravel/pulse)
  • ecosystem.debugbar-enabled — Debugbar must not be enabled at runtime in production (requires barryvdh/laravel-debugbar)
  • ecosystem.livewire-upload-rules — Customized Livewire temporary uploads must keep a max: size rule and not strip throttle middleware (requires livewire/livewire)

Requirements

  • PHP 8.3+
  • Laravel 11 / 12 / 13

Contributing

See CONTRIBUTING.md. Tests must pass, PHPStan must be clean at level 8, Pint must be clean.

Security

If you discover a security issue, please email hello@baspa.dev instead of opening a public issue.

Inspired by

  • Enlightn — the original Laravel performance + security scanner. Its analyzer-per-check pattern and report card concept shaped how LaraScan is structured.
  • Securing Laravel — Stephen Rees-Carter's writing and newsletter, the practical reference for what to check and why it matters.

License

The MIT License (MIT). See LICENSE.md.

统计信息

  • 总下载量: 54
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-02

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固