Skip to main content

Changelog

Real entries from every ShieldCI surface: the SaaS platform, the free open-source package, and the pro package. Filter by product to narrow in.

0
entries
0
major versions
0
in the last 90 days
Free Packagev1.19.0

shieldci/laravel v1.19.0

Added

  • •DetectsErrorTracking shares the error-tracking package list, now including Flare, Inspector and Nightwatch (#494)

Fixed

  • •missing-error-tracking no longer passes on a tracker installed only under require-dev (#494)
  • •asset-cache-headers warns about an asset it could not fetch, instead of failing at High (#495)
  • •asset-cache-headers probes assets under app.asset_url or app.mix_url rather than app.url (#495)
Pro Packagev1.7.0

shieldci/laravel-pro v1.7.0

Added

  • •alerting-config counts an installed Laravel Nightwatch as alerting, unless config/nightwatch.php disables it (#396)

Changed

  • •alerting-config credits monitoring packages only from composer.lock production dependencies, not require-dev (#396)
  • •compression-headers verifies TLS certificates, so a self-signed staging certificate now warns (#397)
  • •Requires shieldci/laravel ^1.18 (was ^1.15.1), for the shared origin probe compression-headers now uses (#397)

Fixed

  • •eager-loading follows a model through foreach or a hand-off to a method or resource, rather than reporting its relations unused (#395)
  • •eager-loading credits relations read inside the model's own methods and accessors (#395)
  • •eager-loading reports a once for with(['a', 'a.b']), rather than twice (#395)
  • •eager-loading no longer exhausts memory on $query = $query->where(...), which ended the whole run (#395)
  • •compression-headers warns, naming the URL, when a probe fails, returns non-2xx or the wrong Content-Type, rather than passing (#397)
  • •compression-headers follows same-host redirects and accepts text/javascript as JavaScript (#397)
Free Packagev1.18.0

shieldci/laravel v1.18.0

Added

  • •OriginReachabilityChecker takes an optional ProbeRequest, so a probe can send Accept-Encoding and keep the origin's Content-Encoding (#488)

Changed

  • •login-throttling reports each unthrottled login route in routes/auth.php, replacing the single file-level Breeze or Jetstream finding (#483, #491)

Fixed

  • •login-throttling ignores commented-out code, so a commented-out route or throttle no longer changes the result (#482)
  • •login-throttling scans routes/web.php, which every install registers in the web group, so an unthrottled POST /login is reported (#483)
  • •login-throttling no longer lets an api-group throttle, such as the stock throttle:api, clear web login routes or skip the Fortify check (#483)
  • •login-throttling no longer reports a login controller whose route carries throttle middleware or whose FormRequest throttles, such as $request->authenticate() (#484, #486)
  • •login-throttling reads a route's throttle to the end of its statement, so a one-line route no longer borrows the next route's throttle (#490)
  • •login-throttling credits a login route only with its own controller's or middleware's throttling, so a throttled web controller no longer hides an unthrottled API route (#491)
  • •login-throttling detects a login route chained after another call, such as Route::middleware('guest')->post() (#491)
  • •login-throttling no longer reports Fortify without a limiters config or after Fortify::ignoreRoutes(), since neither leaves an unthrottled Fortify login route (#491)
  • •login-throttling checks Fortify even when the app calls RateLimiter itself, and reports a login pipeline that leaves out EnsureLoginIsNotThrottled (#491)
Pro Packagev1.6.0

shieldci/laravel-pro v1.6.0

Changed

  • •audit-logging finds admin controllers by privileged route middleware such as can: or role:, rather than by directory name (#392)
  • •audit-logging may name a different admin file than v1.5.0, so its dont_report entry can stop matching (#392)
  • •arbitrary-file-upload no longer reports eval(), assert() or call_user_func(), leaving them to rce and eval-usage (#379)
  • •Requires shieldci/analyzers-core ^2.8.1 (was ^2.8), so two imports on one alias no longer error Filament analyzers, middleware-misuse, octane-config or lazy-collection-opportunity (#391)

Fixed

  • •arbitrary-file-upload reads rules only from validation sites, so a message or field named file or image is not a rule (#379, #384)
  • •arbitrary-file-upload limits a FormRequest type hint to its own method rather than the whole file (#379)
  • •arbitrary-file-upload judges each Filament FileUpload separately, so one constrained component no longer masks another (#379)
  • •arbitrary-file-upload reports an original-filename storeAs() or move() line once, not twice (#379)
  • •arbitrary-file-upload accepts Livewire's #[Rule] attribute alongside #[Validate] (#379)
  • •octane-config skips its config checks when config/octane.php does not parse, rather than reporting keys as missing (#382)
  • •octane-config and cdn-configuration name an unparsable config/octane.php or config/app.php in the report rather than losing it (#382)
  • •dead-routes accepts every verb the router declares, so Route::any() is not flagged on Laravel 13.35 (#388)
  • •audit-logging counts a write through a LogsActivity or observed model as logged (#386)
  • •audit-logging reports Skipped, naming the file, when a controller or model it relies on does not parse (#386)
  • •audit-logging reads listeners from every provider, models from app/Models subdirectories, and channels named like audit_trail (#392)
  • •policy-authorization, audit-logging and filament-table-optimization resolve a relative name such as Models\Post as PHP does (#389)
  • •filament-resource-authorization judges a resource whose base class is aliased, rather than skipping it (#389)
  • •filament-tenancy names the first withoutGlobalScopes() file in path order, so baselines match between local and CI (#390)
  • •lazy-collection-opportunity resolves an aliased model before ->pluck(), so an accessor gets no query-pluck advice (#391)
Free Packagev1.17.0

shieldci/laravel v1.17.0

Added

  • •The report lists files the parser could not read under parse_failures, and the console warns that a pass does not cover them (#457)
  • •The report includes parser_compatibility, and the console warns when the installed php-parser is older than the running PHP (#457)
  • •phpstan reports declarations PHP refuses to compile, such as a colliding import, under a new Critical compile-errors category (#474)
  • •phpstan reports every used void result under a new High used-void-result category, rather than as Critical or High by call type (#479)

Changed

  • •Requires shieldci/analyzers-core ^2.8 (was ^2.6), for parse-failure reporting (#457)
  • •chunk-missing no longer exempts a fetch because its select uses DB::raw() (#458)
  • •service-container-resolution names an enum it reports, such as App\Enums\Status::label, rather than Unknown::label (#454)
  • •service-container-resolution names an anonymous class such as LabelService@anonymous::label, rather than a non-existent App\Services\Anonymous::label (#454)
  • •missing-database-transactions names an anonymous class after its resolved parent, such as App\Support\Handler@anonymous (#470)
  • •phpstan reports compile errors and used void results as Compile Errors detected and Used Void Results detected, so a baselined row is reported once more (#474, #479)

Fixed

  • •chunk-missing no longer flags a fetch bounded by a key list, such as whereIn('id', $ids), unless the list is a subquery (#458, #471)
  • •chunk-missing no longer flags a fetch grouped only by columns its whereIn() or where() filters pin, since it returns one row per combination (#458)
  • •chunk-missing reports a loop over a fetch captured by a closure's use (#454)
  • •missing-database-transactions tells apart same-named methods of different classes in one file (#466)
  • •missing-database-transactions no longer treats a helper as protected when only a class declared inside DB::transaction() calls it (#454)
  • •mixed-query-builder-eloquent no longer drops a file with two imports on one alias and reports a pass (#452)
  • •mixed-query-builder-eloquent counts connection-qualified writes and further write methods, such as updateFrom(), against its withoutGlobalScope() exemption (#460)
  • •mixed-query-builder-eloquent keeps a table reported as mixed after a later query-builder read (#464)
  • •authentication-authorization no longer errors on a file with two imports on one alias (#463)
  • •service-container-resolution and missing-docblock no longer error on a file with two imports on one alias (#473)
  • •framework-override, fat-model and logic-in-routes no longer skip a file with two imports on one alias (#473)
  • •eloquent-n-plus-one recognises a model referenced in a different case, such as product::get() (#465)
  • •eloquent-n-plus-one flags a relationship registered through parent::resolveRelationUsing() (#468)
  • •fillable-foreign-key and mass-assignment-vulnerabilities recognise a model whose parent is a relative name, such as Catalog\Record (#467)
  • •phpstan fails the build and lists the files under stopped_at when PHPStan stops at a file it cannot parse or reflect, instead of warning (#474, #478)
  • •collection-call-optimization returns an error instead of a pass when PHPStan stops at a file (#474)
Pro Packagev1.5.0

shieldci/laravel-pro v1.5.0

Added

  • •filament-panel-security, filament-resource-authorization, filament-custom-pages, filament-widget-security and audit-logging report a Filament file whose syntax error stopped it parsing, one analyzer owning each kind (#377)

Changed

  • •A panel provider's declared discoverResources(), discoverPages(), discoverWidgets() and discoverClusters() roots are read, so a file outside app/Filament is judged rather than invisible (#375)
  • •The Filament analyzers report Skipped where discovery finds no files, rather than Passed, apart from filament-panel-security and audit-logging (#375)
  • •filament-tenancy reports Skipped where no panel provider exists, apart from the Passed it keeps for panels configuring no tenancy (#375)
  • •filament-tenancy's withoutGlobalScopes() finding can name a different file, now that a second panel's and a cluster's resources are searched, so regenerate the baseline once (#375)
  • •audit-logging's unlogged-surface finding is reworded and names a file it read rather than a hardcoded path, so it rehashes; regenerate the baseline once (#376)
  • •The Filament analyzers report Skipped where a file in their input could not be read, rather than Passed, so an unparsable file no longer passes (#377)
  • •Requires shieldci/analyzers-core ^2.8 (was ^2.7), for a failed parse that is never cached, so a second run in one process records it again (#377)

Fixed

  • •The Filament analyzers judge a resource, page or widget inside a cluster, which previously passed unopened (#375)
  • •filament-form-validation, filament-navigation, filament-resource-authorization, filament-table-optimization and filament-tenancy judge a second panel's resources, which a hardcoded app/Filament/Resources missed (#375)
  • •filament-widget-security finds a widget nested in a subdirectory below its root, which was skipped entirely (#375)
  • •filament-widget-security recognises a widget extending an aliased base class, so its missing canView() is reported (#375)
  • •filament-resource-authorization, filament-navigation and filament-tenancy judge a resource by what it extends, not a *Resource.php filename (#375)
  • •filament-panel-security, filament-navigation and filament-tenancy find a panel provider at any depth under app/Providers (#375)
  • •filament-panel-security reads app/Models recursively, so a FilamentUser model under app/Models/Auth/ no longer reports that none implements it (#375)
  • •filament-table-optimization reads a custom page's table(), so an N+1 in a page built with InteractsWithTable is reported (#376)
  • •filament-tenancy judges only the resources of panels declaring tenancy, so a non-tenant panel's are no longer flagged for missing scoping (#375)
  • •filament-tenancy keeps the resources of a panel that shares a directory with another, rather than losing them to it (#375)
  • •filament-tenancy no longer puts a panel through the tenancy audit for a ->tenant( in a string or heredoc, the check now reading the AST (#375)
  • •audit-logging counts every Filament resource, page, widget and cluster as an admin surface, so logging in one is credited and its absence reported (#375, #376)
  • •audit-logging requires an activity() call to reach ->log() across all six of its logging checks, so a widget or observer that only reads the log no longer declares a surface audited (#376)
  • •audit-logging credits activity('security') and other named log channels, which the old activity() needle missed and reported as unlogged (#376)
  • •filament-panel-security finds a panel provider whose file will not parse, reading the class out of the source rather than reporting that no panel is configured (#377)
  • •filament-resource-authorization keeps a resource whose file will not parse, rather than dropping it to a support file and out of its input (#377)
  • •audit-logging no longer reports an admin surface as unlogged when a file on it could not be read, rather than counting an unread file as evidence (#376, #377)
Free Packagev1.16.1

shieldci/laravel v1.16.1

Changed

  • •Issue messages name an anonymous class the way PHP does, such as Migration@anonymous, rather than Unknown (#435)

Fixed

  • •missing-database-transactions recognises DB::connection(...)->transaction() and a fully qualified or aliased DB::transaction() (#421, #446)
  • •missing-database-transactions no longer counts a cache, filesystem or queue client call as a database write, including one declared on a parent or trait (#421, #427, #441)
  • •chunk-missing no longer reports a facade read such as Cache::get() as an unchunked query (#421)
  • •eloquent-n-plus-one, chunk-missing and missing-database-transactions no longer exempt an app model named like a facade, such as App\Models\Event (#424, #428, #436, #446)
  • •missing-database-transactions, missing-docblock, service-container-resolution, mixed-query-builder-eloquent and chunk-missing analyze a method correctly when it declares a nested class (#435)
  • •eloquent-n-plus-one inherits a parent model's relationships when extends uses different case or a relative name (#448)
  • •mixed-query-builder-eloquent tracks a model assigned through an imported name, such as $query = User::query() (#439)
Pro Packagev1.4.1

shieldci/laravel-pro v1.4.1

Added

  • •filament-panel-security judges canAccessPanel() on every FilamentUser model, reporting an outright grant, an authentication-only check, or a body that ignores its Panel (#372)

Changed

  • •filament-panel-security drops the per-panel authGuard finding, which flagged Filament's own generated configuration (#372)
  • •Weak Filament gate findings name the defect, so they rehash; regenerate the baseline once (#372)
  • •Requires shieldci/analyzers-core ^2.7 (was ^2.2), for the shared parser's recordRecovery() (#371)

Fixed

  • •filament-panel-security reads ->authMiddleware() and ->path() from the call arguments, so a commented-out call no longer hides an unprotected panel (#372)
  • •filament-panel-security, filament-navigation and filament-tenancy find a panel provider in app/Providers/ too, rather than skipping every check (#372)
  • •The five Filament access-method checks credit a gate that denies through abort_unless() or throw_unless() before granting, rather than reading it as a blanket grant (#372)
Pro Packagev1.4.0

shieldci/laravel-pro v1.4.0

Added

  • •horizon-security, nova-security, pulse-security and telescope-security check the same five weak gates: authentication-only, a ?? true fallback, an environment bypass, a callback that ignores its parameters, and a denyIf() that can never fire (#366, #367)

Changed

  • •Weak-gate findings are graded by the registration's reach rather than a flat High: the full grade unconditional, two lower inside local, one lower behind a wider guard (#367)
  • •Gate findings name their guard and carry a line, so they rehash; regenerate the baseline once (#366, #367)

Fixed

  • •The four gate analyzers judge the callback from the AST, so fn () => true, a first-class callable, [$class, 'method'] and 'Class@method' are read, where the old regex needed a literal return true; (#364, #366)
  • •The gate is resolved from every provider plus bootstrap/app.php rather than one hardcoded file (#366)
  • •nova-security stops reporting a sound gate as wide open, having fallen back to scanning the whole provider where an unrelated return true; matched (#366)
  • •A permissive fallback counts only in the fallback position, and an environment check only where it can grant by itself (#367)
Free Packagev1.16.0

shieldci/laravel v1.16.0

Added

  • •OriginReachabilityChecker probes each origin the app declares once and names the outcome, so an unreachable host cannot read as a clean result (#404)

Changed

  • •env-http-accessibility verifies TLS certificates on its probes, so a staging origin with a self-signed certificate warns rather than passing (#408)
  • •Requires shieldci/analyzers-core ^2.6 (was ^2.5), for the shared AST parser every analyzer now resolves through (#412)

Fixed

  • •logic-in-blade and eloquent-n-plus-one analyze Blade views containing a multi-line directive, an inline @php, a @switch or a raw <?php tag, rather than skipping them and reporting a pass (#407, #409, #413, #414, #416)
  • •logic-in-blade no longer reports blade-unclosed-php-block for a @php that is not a directive, such as one written in prose or inside {{-- --}} (#414)
  • •logic-in-blade no longer reports blade-inline-php for a <?php occurring inside a @php block body, such as one in a string or heredoc (#416)
  • •env-http-accessibility warns when a location produced no response, instead of reporting the web server properly configured from zero replies (#408)
Free Packagev1.15.3

shieldci/laravel v1.15.3

Changed

  • •Requires shieldci/analyzers-core ^2.5 (was ^2.3), so a failed analyzer's stack trace no longer records each frame's arguments (#398)

Fixed

  • •method-length no longer loses a method's declarative exemption to a leading assignment or a trailing comment (#394)
  • •method-length exempts up to 15 declarative statements rather than 5, so six RateLimiter::for() blocks are no longer flagged (#394)
  • •An analyzer that catches its own failure truncates and redacts the message, so database-status no longer reports a raw PDO error (#401)
Free Packagev1.15.2

shieldci/laravel v1.15.2

Fixed

  • •phpstan and collection-call-optimization run on projects that require a newer PHP than the php first on PATH, instead of aborting with "PHPStan produced no analysable output" (#390)
Pro Packagev1.3.0

shieldci/laravel-pro v1.3.0

Changed

  • •Every analyzer's severity badge matches the findings it emits; the exit code grades findings, so builds are unaffected (#341)
  • •horizon-security, telescope-security, nova-security and pulse-security report a missing dashboard gate as Medium rather than Critical, an undefined gate denying access outside local (#346)
  • •Stock-install states drop off Critical: four telescope-security findings and an ssrf cloud-metadata string to Medium, and extract-usage's EXTR_OVERWRITE to Low (#348)
  • •validation-sql-injection, arbitrary-file-upload and directory-traversal report High where nothing proves user control (#349)
  • •eval-usage, rce and cryptographic-weakness report High for calls PHP removed below 8.1 (#350)
  • •pcntl-extension and redis-status raise a broken Redis to Critical, while the horizon-reliability, cache-busting and dead-routes static checks drop below it (#351)
  • •cdn-configuration and policy-authorization report High and begin failing a default fail_on: high build (#351, #352, #354)
  • •xdebug-enabled reports High rather than Critical (#342)
  • •test-data-management returns to Low (#343)
  • •Requires shieldci/laravel ^1.15.1 and shieldci/analyzers-core ^2.2, and declares guzzlehttp/guzzle ^7.0|^8.0 and psr/http-message ^1.0|^2.0 (#355, #358, #359)

Fixed

  • •Thirteen analyzers stop naming config files the app never published, Laravel merging the framework's copy; these findings rehash, so regenerate the baseline once (#355)
  • •cookie-domain reports a relative path with a line per setting, so a local baseline matches in CI and @shieldci-ignore works on it (#355)
  • •redis-throttling and clickjacking name the middleware file the scanned project has, rather than the one the installed Laravel version implies (#359)
  • •cookie-domain and cors-config explanations are corrected: a public-suffix cookie is rejected outright, and a credentialed wildcard echoes the request Origin (#343, #347)
Free Packagev1.15.1

shieldci/laravel v1.15.1

Fixed

  • •logic-in-blade, csrf-protection and xss-vulnerabilities honour excluded_paths when scanning Blade views and JavaScript files (#385)
  • •unused-global-middleware and cookie name the middleware file the project actually has, app/Http/Kernel.php or bootstrap/app.php, instead of choosing by Laravel version or naming a file that is not there (#387)
  • •phpstan and collection-call-optimization run on projects whose phpstan.neon or phpstan/extension-installer already loads Larastan, instead of aborting with "This file is included multiple times" (#388)
Free Packagev1.15.0

shieldci/laravel v1.15.0

Added

  • •report.snippet_plain_mode and report.snippet_syntax_highlighting now govern a real code preview rendered under each console finding (#380)

Changed

  • •fat-model, nesting-depth, method-length, helper-function-abuse and env-example-documented warn instead of failing a default fail_on: high build, and authentication-authorization reports an unprotected route as Critical, after every analyzer's severity metadata was audited against the findings it emits (#347)
  • •php-side-filtering reports High rather than Critical, since Critical is reserved for security exposure, data loss, or an app that cannot serve requests (#349)
  • •shield:analyze exits 1 when an analyzer could not complete; add the analyzer id to dont_report in config/shieldci.php to waive one (#351)
  • •Requires guzzlehttp/guzzle ^7.0|^8.0 (was ^7.0), so installing on a Laravel 13 app no longer fails or downgrades the app's guzzle (#359)
  • •A malformed config value is now a suppressible finding rather than an analysis error, and a missing prerequisite reports skipped, across cache-driver, queue-driver, session-driver, mysql-single-server-optimization, view-caching, config-caching, collection-call-optimization and phpstan (#362)
  • •Requires shieldci/analyzers-core ^2.3 (was ^2.1) for the config-location helpers the unpublished-config fixes now resolve through (#373)

Fixed

  • •logic-in-blade flags file_get_contents() as an API call only when the argument spells out a remote target, so {!! file_get_contents(public_path('img/logo.svg')) !!} is no longer reported (#341)
  • •phpstan reports an error instead of a clean pass when a run does not finish, such as an internal error or a configured path that does not exist (#342)
  • •collection-call-optimization works in an installed package at all: its shipped config included Larastan by a path resolving inside vendor/shieldci/laravel/vendor, so PHPStan aborted and the analyzer reported a pass on every real install (#345)
  • •phpstan no longer reports the Larastan 2.9.0 env-call finding twice, once under Other PHPStan Issues and once through env-call-outside-config (#350)
  • •phpstan no longer reads the unmatched ignore patterns in a project's own phpstan.neon as an analysis that did not complete (#354)
  • •cache-driver assesses the driver when config/cache.php has not been published, instead of erroring out on a stock Laravel 11+ skeleton (#356)
  • •Eight analyzers omit the issue location when the config file they report on is not published, rather than pointing into a file merged from the framework or fabricating line 1 (#361)
  • •The exit-code gate now sees a failure that names no issue, waives dont_report analyzers under fail_threshold, and falls back to the documented default on an unrecognised fail_on (#363)
  • •shield:baseline no longer waives an analyzer that could not run by writing it into the baseline's dont_report, and names the analyzers the baseline does not cover (#365)
  • •A failed analyzer's exception class and stack trace survive into the JSON report, and timeToFix reaches --format=json (#366)
  • •shieldci.report.format and SHIELDCI_REPORT_FORMAT take effect: --format declared a default of its own, so the config fallback behind it was unreachable (#370)
  • •shield:analyze writes no ANSI escapes to a piped or redirected run, and honours --no-ansi, NO_COLOR and FORCE_COLOR throughout rather than for a handful of messages (#372)
  • •shield:analyze --format=json keeps advisories such as a baseline notice or an unmapped APP_ENV on stderr, so the report on stdout stays parseable (#374)
  • •--output writes to the path it validated, resolved against base_path(), and always as JSON rather than console art (#379)
  • •An empty or missing shieldci.paths.analyze falls back to the shipped paths, instead of leaving 108 file analyzers scanning nothing and reporting a pass (#382)