定制 andreapollastri/checkpoint 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

andreapollastri/checkpoint

Composer 安装命令:

composer require andreapollastri/checkpoint

包简介

Laravel security scanner — checks CVEs, hardcoded secrets, SQL injection, XSS and more via a single Artisan command.

README 文档

README

A Laravel security scanner that audits your application for common vulnerabilities — from known CVEs to hardcoded secrets — via a single Artisan command.

php artisan checkpoint:scan

What it checks

# Check Severity
1 Composer CVE Audit — runs composer audit and reports known advisories FAIL
2 NPM CVE Audit — runs npm audit and flags critical/high vulnerabilities FAIL / WARN
3 Environment ConfigurationAPP_DEBUG, APP_KEY, APP_URL, SESSION_SECURE_COOKIE WARN
4 .gitignore Sensitive Files — ensures .env, *.key, *.pem are excluded; detects if .env is tracked by git FAIL
5 File Permissions — flags world-readable .env or world-writable storage/ WARN
6 Hardcoded Secrets — scans PHP/JS files for API keys, Stripe tokens, AWS keys, GitHub PATs, PEM headers FAIL
7 SQL Injection Risks — detects raw queries with variable interpolation (DB::select("… $var"), ->whereRaw(…)) FAIL
8 Mass Assignment Vulnerabilities — finds $guarded = [] or Model::unguard() WARN
9 XSS (Cross-Site Scripting) Risks — flags unescaped {!! $var !!} in Blade views and raw echo of request input WARN
10 CSRF Protection — detects forms with POST/PUT/PATCH/DELETE missing @csrf, and checks middleware is present FAIL
11 Open Redirect Risks — spots redirect($request->…) or header('Location: ' . $var) with unvalidated input WARN
12 Command Injection Risks — finds exec, shell_exec, system, passthru, proc_open called with unescaped variables FAIL
13 Insecure Deserialization — detects unserialize($userInput) and the classic unserialize(base64_decode(…)) exploit chain FAIL
14 Debug Functions in Production Code — finds var_dump, dd, dump, ray left outside of test files WARN
15 Sensitive Data Exposure — flags display_errors = 1, logging of passwords/tokens, and Telescope always-on config WARN
16 SSRF Risks — detects Http::get($request->…), Guzzle/cURL/file_get_contents called with user-controlled URLs FAIL
17 TLS Certificate Verification — flags withoutVerifying(), 'verify' => false, CURLOPT_SSL_VERIFYPEER => false FAIL
18 CORS Configuration — flags allowed_origins => ['*'] combined with supports_credentials => true and other loose configs FAIL / WARN
19 Package Freshness (Supply Chain) — fails the scan if any Composer package was released within the last N days (default 3); whitelist via config FAIL
20 Supply Chain Tooling — when package.json is present, warns if no npm install-time guard (Safe-Chain, Socket CLI) is on PATH WARN
21 Path Traversal Risks — detects Storage::get($request->…), file_get_contents/include/require with user-controlled paths FAIL
22 Weak Cryptography — flags mcrypt_*, ECB mode, DES/3DES/RC4, and md5/sha1 used near password/token/HMAC keywords FAIL / WARN
23 Insecure RNG — detects rand/mt_rand/uniqid used in security contexts (tokens, CSRF, password reset, OTP) FAIL
24 Session & Cookie Security — audits config/session.php for http_only=false, same_site=null/none, secure=false, encrypt=false WARN
25 EOL Versions — flags Composer-locked Laravel and the running PHP when they are past or approaching upstream security cutoff FAIL / WARN
26 Suspicious Vendor Autoload — flags packages under vendor/ that register PHP via autoload.files outside a baked-in whitelist (the mechanism abused by the May 2026 Laravel-Lang supply-chain attack) WARN

Requirements

  • PHP ^8.1 is the package floor. Newer Laravel versions may require a higher PHP, so your effective minimum is whatever your Laravel major demands.
  • Laravel 813 (same major as illuminate/* 8.x–13.x used by your app)

Installation

composer require --dev andreapollastri/checkpoint

The package auto-discovers itself via Laravel's package discovery — no manual registration needed.

Recommended companion tools

Checkpoint is a static scanner — it inspects your codebase but doesn't intercept package installs. To harden the npm install path against the next event-stream/ua-parser-js/chalk-style supply-chain attack, pair Checkpoint with defense in depth: run installs inside containers and add a runtime guard on the host when you must install locally.

Docker (recommended)

Run composer install, npm install, and php artisan checkpoint:scan inside a container, not directly on your laptop or server shell. Supply-chain malware often executes during a package's post-install script — if that runs on your host, it has access to your SSH keys, browser cookies, and filesystem. A disposable dev container limits blast radius to an isolated filesystem that you can throw away.

Typical workflow:

docker compose up -d
docker compose exec app composer install
docker compose exec app npm install
docker compose exec app php artisan checkpoint:scan

Use whatever Docker setup fits your project — Docker Compose, a devcontainer, or a CI image such as composer:2 with Node in the same job. The goal is the same: never let untrusted install scripts run on bare metal; treat the host as a control plane only.

Checkpoint's CI scaffolds (GitHub Actions, GitLab CI) already run the scan inside ephemeral containers. Mirror that pattern locally.

Safe-Chain (recommended)

Safe-Chain by Aikido is a free shell shim that blocks known-malicious npm packages before their install scripts run. Install it once, globally:

npm install -g @aikidosec/safe-chain
safe-chain setup

When you do run npm on the host (CI runners, one-off scripts), Safe-Chain blocks known-malicious packages before their install scripts run. Checkpoint's Supply Chain Tooling check verifies whether Safe-Chain (or an equivalent like Socket CLI) is on your PATH and emits a WARN if no protection is present.

Why Checkpoint doesn't install it for you: Safe-Chain works as a global shell shim, not a project dependency. A composer require should never invoke another ecosystem's package manager (and can't reliably do so on hosts without Node). Installing it explicitly keeps the install path auditable. Prefer Docker for day-to-day installs; keep Safe-Chain as a safety net where containers aren't practical.

Usage

Run all checks

php artisan checkpoint:scan

Run only specific checks

php artisan checkpoint:scan --only="SQL Injection Risks,CSRF Protection"

Skip specific checks

php artisan checkpoint:scan --skip="NPM CVE Audit,Debug Functions in Production Code"

JSON output (for CI/CD pipelines)

php artisan checkpoint:scan --json

The command exits with code 1 if any check returns FAIL, making it suitable as a pipeline gate.

Configuration

Checkpoint works out of the box with sensible defaults. Publish the config file when you need to toggle individual checks or tune the freshness gate:

php artisan vendor:publish --tag=checkpoint-config

This creates config/checkpoint.php with two sections:

Enabling / disabling checks

Every default check is listed and enabled. Set any entry to false to exclude it from the scan:

'checks' => [
    Checks\ComposerAuditCheck::class      => true,
    Checks\NpmAuditCheck::class           => false, // skip npm audit on a PHP-only project
    Checks\EnvironmentCheck::class        => true,
    // …
    Checks\PackageFreshnessCheck::class   => true,
    Checks\SupplyChainToolingCheck::class => true,
],

Checks not listed in the map fall back to enabled. When you upgrade Checkpoint and new checks are added, you keep the protection without re-publishing the config — re-publish only when you want to see the full updated list.

Package Freshness tuning

'package_freshness' => [
    'minimum_age_days' => 3,
    'whitelist' => [
        'andreapollastri/checkpoint', // bundled — see note below
        // 'laravel/framework',
        // 'symfony/console',
    ],
],
  • minimum_age_days — packages released more recently than this fail the scan. Default 3. Set to 0 to bypass the freshness gate entirely without removing the check from the scanner.
  • whitelist — fully-qualified package names (vendor/package) exempt from the freshness check. Use sparingly and ideally with an inline comment explaining why each entry is allowed.

Checkpoint ships with andreapollastri/checkpoint already whitelisted by default — a fresh release of the scanner itself should never block its own user's deploy. Remove the entry if you want to gate even Checkpoint upgrades through the freshness window.

Suppressing individual findings

Every WARN or FAIL finding is shown with a stable 12-character hash:

FAIL  Hardcoded Secrets
      3 potential hardcoded secret(s) found.
        ✗ app/Services/PaymentService.php:14 — 'api_key' => 'sk_live_…' [a1b2c3d4e5f6]
        ✗ config/services.php:8 — $secret = 'super…'                    [9f8e7d6c5b4a]

To silence one — false positive, accepted legacy code, internal test fixture — copy the bracketed hash into config/checkpoint.php:

'suppressed' => [
    'a1b2c3d4e5f6',
    '9f8e7d6c5b4a',
],

On the next run those findings are filtered out. If every finding of a given check ends up suppressed, the check is downgraded to PASS with an explicit "All N finding(s) suppressed via config." message — so the suppression is visible in the output, not silently ignored.

The hash is content-stable: refactors that only shift line numbers within the same file will not invalidate the suppression. The hash does change if you alter the file path or the finding content itself, which is the intended safety net.

The --only / --skip CLI flags still work and override the config for the current run, which is handy for ad-hoc scans without editing the config.

Excluding folders from file scans

File-based checks (Hardcoded Secrets, SQL Injection, XSS, and others) skip built-in paths such as vendor/, node_modules/, and storage/. Add your own paths when you have mounted data directories or other folders that are not part of your application source:

'exclude_paths' => [
    'storage/app/mounted-data',
    'data/external',
],

Paths are relative to the project root. Leading and trailing slashes are optional. Unreadable directories are skipped automatically so permission errors on mounted volumes do not abort the scan.

Example output

  ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗██████╗  ██████╗ ██╗███╗  ██╗████████╗
 ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝██╔══██╗██╔═══██╗██║████╗ ██║╚══██╔══╝
 ██║     ███████║█████╗  ██║     █████╔╝ ██████╔╝██║   ██║██║██╔██╗██║   ██║
 ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗ ██╔═══╝ ██║   ██║██║██║╚████║   ██║
  ╚█████╗██║  ██║███████╗ ╚█████╗██║  ██╗██║      ╚█████╔╝██║██║ ╚███║   ██║
   ╚════╝╚═╝  ╚═╝╚══════╝  ╚════╝╚═╝  ╚═╝╚═╝       ╚════╝ ╚═╝╚═╝  ╚══╝   ╚═╝

  Laravel Security Scanner — andreapollastri/checkpoint
  Scanning: /var/www/my-app

  PASS  Composer CVE Audit
        No known CVEs in Composer dependencies.

  FAIL  Hardcoded Secrets
        3 potential hardcoded secret(s) found.
          ✗ app/Services/PaymentService.php:14 — 'api_key' => 'sk_live_abc123…' [a1b2c3d4e5f6]
          ✗ config/services.php:8 — $secret = 'supersecretvalue'             [9f8e7d6c5b4a]
          ✗ app/Http/Controllers/WebhookController.php:31 — 'api_key' => 'ghp_…' [3e2d1c0b9a8f]

  FAIL  Path Traversal Risks
        1 potential path traversal risk(s) found.
          ✗ app/Http/Controllers/DownloadController.php:24 — Storage::get($request->path) [7b6a5f4e3d2c]

  WARN  Environment Configuration
        3 environment issue(s) found.
          ⚑ APP_DEBUG is true — full stack traces will be exposed to end users. [5c4b3a2d1e0f]
          ⚑ SESSION_SECURE_COOKIE is not enabled.                               [1a2b3c4d5e6f]
          ⚑ APP_URL is set to "http://localhost" — update it for production.    [6e5d4c3b2a1f]

  ─────────────────────────────────────────────────────────
  Summary  19 passed  4 warning(s)  2 failed  (25 checks total)

  Scan result: FAIL — fix the issues above before deploying.

Extending with custom checks

Create a class that extends AbstractCheck and return a CheckResult:

use Checkpoint\Checks\AbstractCheck;
use Checkpoint\Checks\CheckResult;

class MyCustomCheck extends AbstractCheck
{
    public function name(): string
    {
        return 'My Custom Check';
    }

    public function run(): CheckResult
    {
        // your logic here
        return CheckResult::pass('Everything looks good.');
        // or: CheckResult::warn('Something to review.', ['detail one', 'detail two']);
        // or: CheckResult::fail('Critical issue found.', ['detail']);
    }
}

Then register it by building a Scanner manually instead of using the default:

use Checkpoint\Scanner;

$scanner = Scanner::withDefaultChecks(base_path())
    ->add(new MyCustomCheck());

CI/CD integration

Checkpoint can scaffold a ready-to-use pipeline for either provider in one command.

GitHub Actions

php artisan checkpoint:github

Creates .github/workflows/checkpoint.yml — triggers on push to main/master and on every pull request. Uses actions/checkout@v4, shivammathur/setup-php@v2 (PHP 8.2), Composer cache, and runs php artisan checkpoint:scan. Pass --force to overwrite an existing file.

GitLab CI

php artisan checkpoint:gitlab

Creates .gitlab-ci.yml — runs on merge requests and default-branch pushes using the composer:2 image with a Composer cache. If you already have a .gitlab-ci.yml, the command refuses to overwrite and prints the snippet to stdout so you can paste it into your existing pipeline. Use --force to overwrite.

Custom usage

If you prefer to wire Checkpoint into a pipeline you already maintain, just call:

- name: Security audit
  run: php artisan checkpoint:scan --json | tee checkpoint-report.json

Composer hooks

Run Checkpoint automatically after every composer install / composer update:

php artisan checkpoint:install-hooks

This appends @php artisan checkpoint:scan to scripts.post-update-cmd and scripts.post-install-cmd in your composer.json. The command:

  • Confirms interactively before touching composer.json (skip the prompt with --no-interaction for CI).
  • Is idempotent: re-running on an already-installed setup is a no-op.
  • Preserves any existing hooks (append-only); does not overwrite scripts owned by other tools.
  • Supports --remove to cleanly uninstall and --force to replace stale Checkpoint entries.

Why only post-*, not pre-*? Composer's pre-update-cmd fires before dependencies are resolved, so the scanner would only see the codebase pre-update — useless against a malicious package that's about to be installed. And on a fresh clone there is no vendor/, so php artisan does not exist yet and pre-install-cmd would crash. Real-time interception of malicious installs is the job of Docker (preferred) and Safe-Chain on the host.

Exit codes

Code Meaning
0 All checks passed (or warnings only)
1 At least one check returned FAIL

Architecture

src/
├── CheckpointServiceProvider.php   # auto-registers the command
├── Scanner.php                     # orchestrates all checks
├── Commands/
│   ├── ScanCommand.php             # php artisan checkpoint:scan
│   ├── GithubPipelineCommand.php   # php artisan checkpoint:github
│   ├── GitlabPipelineCommand.php   # php artisan checkpoint:gitlab
│   └── InstallHooksCommand.php     # php artisan checkpoint:install-hooks
└── Checks/
    ├── AbstractCheck.php           # base class
    ├── CheckResult.php             # pass / warn / fail value object
    ├── ComposerAuditCheck.php
    ├── NpmAuditCheck.php
    ├── EnvironmentCheck.php
    ├── GitIgnoreCheck.php
    ├── FilePermissionsCheck.php
    ├── HardcodedSecretsCheck.php
    ├── SqlInjectionCheck.php
    ├── MassAssignmentCheck.php
    ├── XssCheck.php
    ├── CsrfCheck.php
    ├── OpenRedirectCheck.php
    ├── CommandInjectionCheck.php
    ├── InsecureDeserializationCheck.php
    ├── DebugFunctionsCheck.php
    ├── SensitiveExposureCheck.php
    ├── SsrfCheck.php
    ├── TlsVerificationCheck.php
    ├── CorsConfigCheck.php
    ├── PackageFreshnessCheck.php
    ├── SuspiciousVendorAutoloadCheck.php
    ├── SupplyChainToolingCheck.php
    ├── PathTraversalCheck.php
    ├── WeakCryptographyCheck.php
    ├── InsecureRngCheck.php
    ├── SessionSecurityCheck.php
    └── EolVersionCheck.php

License

MIT — Andrea Pollastri

andreapollastri/checkpoint 适用场景与选型建议

andreapollastri/checkpoint 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 19.54k 次下载、GitHub Stars 达 106, 最近一次更新时间为 2026 年 04 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 andreapollastri/checkpoint 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 andreapollastri/checkpoint 我们能提供哪些服务?
定制开发 / 二次开发

基于 andreapollastri/checkpoint 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 19.54k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 106
  • 点击次数: 46
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 106
  • Watchers: 1
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-26