hfryan / php-cop
PHP Cop checks composer.lock and flags outdated or suspicious packages.
Installs: 12
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 0
Forks: 0
Open Issues: 0
Type:project
pkg:composer/hfryan/php-cop
Requires
- php: >=8.2
- composer/semver: ^3.4
- guzzlehttp/guzzle: ^7.8
- symfony/console: ^7.3
- symfony/process: ^7.3
README
Dependency Patrol â PHP Security Scanner
PHPCop is a powerful PHP security scanner that analyzes your composer.lock file to identify vulnerabilities, outdated packages, and maintenance issues in your dependencies. Keep your applications secure with comprehensive dependency health monitoring.
Why PHPCop? đ¤
- đĄī¸ Security First - Detect known CVEs and security vulnerabilities before they impact your application
- đ Professional Reports - Generate beautiful HTML and Markdown reports for stakeholders
- âī¸ CI/CD Ready - Perfect exit codes and quiet modes for automated pipelines
- đ¯ Zero Configuration - Works out of the box, configure only what you need
- đ Fast & Efficient - Minimal overhead with intelligent caching and parallel processing
- đĨ Team Friendly - Share security policies via committed configuration files
Features
- đ¨ Security Vulnerability Detection - Scans for known CVEs using
composer audit - âŦī¸ Outdated Package Detection - Identifies packages with newer versions available
- đĢ Abandoned Package Detection - Flags packages that are no longer maintained
- â Stale Package Detection - Finds packages that haven't been updated in months
- đĨ Laravel Integration - Automatic Laravel detection with framework-specific security recommendations
- đ Multiple Output Formats - Table, JSON, Markdown, and HTML output
- đ¯ Advanced Filtering - Filter by dependency type, licenses, and vulnerability severity
- đī¸ Configurable Thresholds - Set custom severity levels and staleness periods
- ⥠High Performance - Parallel API calls and intelligent caching for fast scans
- đ CI/CD Ready - Returns appropriate exit codes for automation
Quick Start đ
# Install PHPCop globally composer global require hfryan/php-cop # Scan your project (run in any PHP project directory) phpcop scan # Generate a beautiful HTML report phpcop scan --format=html > security-report.html
That's it! PHPCop will analyze your composer.lock and show you any security issues, outdated packages, or maintenance concerns.
Installation
Method 1: Global Installation (Recommended for regular use)
# Install globally composer global require hfryan/php-cop # Run the setup helper to configure PATH php ~/.composer/vendor/hfryan/php-cop/bin/phpcop.php setup
Alternative manual setup: If you prefer to configure PATH manually:
On macOS/Linux:
# Add to your shell profile (~/.zshrc, ~/.bash_profile, etc.) export PATH="$HOME/.composer/vendor/bin:$PATH" # Then restart your terminal or run: source ~/.zshrc # Now you can use: phpcop.php scan
On Windows:
# Add this directory to your Windows PATH environment variable: C:\Users\{YourUsername}\AppData\Roaming\Composer\vendor\bin # Or use the full path directly: php C:\Users\{YourUsername}\AppData\Roaming\Composer\vendor\hfryan\php-cop\bin\phpcop.php scan
Method 2: Per-Project Installation (Simplest)
# Install in your PHP project composer require --dev hfryan/php-cop # Run from project directory php vendor/bin/phpcop.php scan
Method 3: PHAR Download (Recommended for CI/CD)
Download the latest PHAR release for zero-dependency deployment:
# Download from GitHub releases wget https://github.com/hfryan/php-cop/releases/latest/download/phpcop.phar chmod +x phpcop.phar # Run directly php phpcop.phar scan # Or make it executable (Linux/macOS) ./phpcop.phar scan
Benefits:
- â No Composer or dependencies required
- â Single file deployment
- â Perfect for CI/CD pipelines
- â Works in Docker containers
- â Consistent across environments
Usage
Basic Scan
phpcop scan
Output Formats
# Terminal-friendly table (default) phpcop scan --format=table # JSON for automation/CI phpcop scan --format=json # Markdown for documentation phpcop scan --format=md > security-report.md # HTML for web viewing phpcop scan --format=html > report.html
Custom Options
# Custom staleness threshold (12 months) phpcop scan --stale-months=12 # Fail on moderate vulnerabilities instead of high phpcop scan --fail-on=moderate # Ignore specific packages phpcop scan --ignore-packages=vendor/package,psr/log # Use custom config file phpcop scan --config=custom-config.json # Silent mode for automation phpcop scan --quiet # Only scan dev dependencies phpcop scan --only-dev # Exclude dev dependencies from scan phpcop scan --exclude-dev # Filter by allowed licenses phpcop scan --license-allowlist=MIT,Apache-2.0 # Exclude packages with specific licenses phpcop scan --license-denylist=GPL-3.0 # Only show critical vulnerabilities phpcop scan --min-severity=critical # Disable response caching (force fresh API calls) phpcop scan --no-cache # Use legacy exit codes for backwards compatibility phpcop scan --exit-code=legacy
CI/CD Integration đ
PHPCop is designed for seamless CI/CD integration with intelligent exit codes and automation-friendly features.
Enhanced Exit Codes (Default)
PHPCop uses granular exit codes to provide precise information for automated pipelines:
0 = SUCCESS - No issues found, all dependencies secure 1 = WARNINGS - Minor issues (stale packages, low-severity vulnerabilities) 2 = ERRORS - Moderate issues (outdated packages, abandoned dependencies, moderate vulnerabilities) 3 = CRITICAL - High-priority issues (high/critical security vulnerabilities)
CI/CD Examples
# Basic CI check - fail on any vulnerabilities phpcop scan --fail-on=low --quiet echo "Exit code: $?" # Production deployment - fail only on high/critical vulnerabilities phpcop scan --fail-on=high --format=json > security-report.json echo "Exit code: $?" # Security-focused scan - exclude dev dependencies phpcop scan --exclude-dev --min-severity=moderate --exit-code=enhanced echo "Exit code: $?" # Legacy compatibility mode (simple 0/1 exit codes) phpcop scan --exit-code=legacy --fail-on=high echo "Exit code: $?"
GitHub Actions Integration
PHPCop provides a pre-built GitHub Action for seamless CI/CD integration:
Quick Setup (Recommended)
name: Security Scan on: [push, pull_request] jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Dependencies run: composer install --no-dev - name: PHPCop Security Scan uses: hfryan/php-cop@main with: fail-on: 'high' exclude-dev: true comment-pr: true
Advanced Configuration
- name: Comprehensive Security Scan uses: hfryan/php-cop@main with: format: 'json' fail-on: 'moderate' stale-months: 12 min-severity: 'moderate' exclude-dev: true ignore-packages: 'symfony/polyfill-*,psr/log' license-allowlist: 'MIT,Apache-2.0,BSD-3-Clause' comment-pr: true upload-artifacts: true working-directory: './backend'
Action Inputs
| Input | Default | Description |
|---|---|---|
format |
table |
Output format: table, json, md, html |
fail-on |
high |
Minimum severity to fail: low, moderate, high, critical |
stale-months |
18 |
Months to flag packages as stale |
exclude-dev |
false |
Exclude dev dependencies from scan |
only-dev |
false |
Only scan dev dependencies |
min-severity |
low |
Minimum vulnerability severity to report |
ignore-packages |
'' |
Comma-separated packages to ignore |
license-allowlist |
'' |
Comma-separated allowed licenses |
license-denylist |
'' |
Comma-separated denied licenses |
exit-code |
enhanced |
Exit code behavior: legacy, enhanced |
comment-pr |
true |
Post scan results as PR comment |
upload-artifacts |
true |
Upload reports as artifacts |
working-directory |
. |
Directory to run scan in |
Action Outputs
| Output | Description |
|---|---|
exit-code |
The exit code from PHPCop scan |
issues-found |
Number of issues found |
vulnerabilities-found |
Number of vulnerabilities found |
report-file |
Path to the generated report file |
Using Outputs
- name: PHPCop Scan id: phpcop uses: hfryan/php-cop@main with: fail-on: 'critical' - name: Handle Results run: | echo "Exit code: ${{ steps.phpcop.outputs.exit-code }}" echo "Issues found: ${{ steps.phpcop.outputs.issues-found }}" echo "Vulnerabilities: ${{ steps.phpcop.outputs.vulnerabilities-found }}"
Manual PHAR Download (Alternative)
- name: Security Scan run: | wget https://github.com/hfryan/php-cop/releases/latest/download/phpcop.phar php phpcop.phar scan --format=json --quiet - name: Handle Security Results if: ${{ failure() }} run: echo "Security issues found - check the logs"
Docker Integration
RUN wget https://github.com/hfryan/php-cop/releases/latest/download/phpcop.phar && \
php phpcop.phar scan --exclude-dev --fail-on=high
Sample Output
đ PHP Cop: Dependency Patrol â Case File
--------------------------------------------------------------------------------
âĸ guzzlehttp/psr7 2.7.1 [âŦī¸ Outdated â 2.8.0]
âĸ psr/container 2.0.2 [â Stale]
âĸ symfony/console v7.3.2 [âŦī¸ Outdated â v7.3.3]
ââ đ¨ high CVE-2023-12345 https://cve.mitre.org/...
Laravel Integration đĨ
PHPCop automatically detects Laravel projects and provides framework-specific security insights!
Automatic Detection
PHPCop detects Laravel projects automatically by looking for:
artisanfile in project rootlaravel/frameworkin composer dependencies
When a Laravel project is detected, PHPCop provides:
Laravel-Specific Features
đ¯ Framework Version Display
đ PHP Cop: Dependency Patrol â Case File Project Type: Laravel 11.35.1
đĨ Laravel Package Highlighting Laravel ecosystem packages are highlighted with a đĨ badge:
laravel/frameworklaravel/sanctum,laravel/passportlivewire/livewirelaravel/horizon,laravel/telescope- And more!
â ī¸ Laravel Security Recommendations Automatic security checks for common Laravel issues:
- .env file protection - Warns if .env might be committed to git
- EOL version detection - Flags Laravel 10 and earlier as end-of-life
- Critical CVE awareness - Highlights known Laravel vulnerabilities:
- CVE-2025-54068 (Livewire v3 RCE)
- CVE-2024-52301 (Environment variable manipulation)
đĻ Laravel Package Context Get specific security guidance for Laravel packages:
âĸ livewire/livewire 3.5.0 [âŦī¸ Outdated â 3.6.4] đĨ Laravel
âšī¸ Critical: Check for Livewire v3 RCE vulnerability (CVE-2025-54068)
Example Output
For a Laravel 11 Project:
đ PHP Cop: Dependency Patrol â Case File
Project Type: Laravel 11.35.1
Laravel Security Recommendations:
đ¨ Add .env to .gitignore to prevent leaking APP_KEY
--------------------------------------------------------------------------------
âĸ laravel/framework 11.35.0 [âŦī¸ Outdated â 11.35.1] đĨ Laravel
âĸ livewire/livewire 3.5.0 [âŦī¸ Outdated â 3.6.4] đĨ Laravel
âšī¸ Critical: Check for Livewire v3 RCE vulnerability (CVE-2025-54068)
JSON Output with Laravel Data:
{
"generatedAt": "2025-10-21T14:30:00Z",
"projectType": "Laravel 11.35.1",
"isLaravel": true,
"laravelVersion": "11.35.1",
"laravelRecommendations": [
"Add .env to .gitignore to prevent leaking APP_KEY"
],
"issues": [...]
}
Laravel Best Practices
PHPCop helps enforce Laravel security best practices:
- â Keep Laravel framework updated
- â Monitor Laravel ecosystem packages (Livewire, Sanctum, etc.)
- â Prevent APP_KEY leaks
- â Stay on supported Laravel versions (11+)
- â Watch for framework-specific CVEs
Advanced Filtering đ¯
PHPCop provides powerful filtering options to focus your security analysis:
Dependency Type Filtering
# Scan only development dependencies phpcop scan --only-dev # Exclude development dependencies (production only) phpcop scan --exclude-dev
License Filtering
# Only scan packages with specific licenses phpcop scan --license-allowlist=MIT,Apache-2.0,BSD-3-Clause # Exclude packages with unwanted licenses phpcop scan --license-denylist=GPL-3.0,AGPL-3.0 # Combine with other options phpcop scan --exclude-dev --license-allowlist=MIT --format=json
Vulnerability Severity Filtering
# Show only high and critical vulnerabilities phpcop scan --min-severity=high # Focus on critical issues only phpcop scan --min-severity=critical --format=html > critical-report.html
Combined Filtering Examples
# Production security audit: exclude dev deps, only critical vulns phpcop scan --exclude-dev --min-severity=critical # License compliance check: only MIT/Apache packages, exclude dev deps phpcop scan --exclude-dev --license-allowlist=MIT,Apache-2.0 # Development workflow: dev packages only, moderate+ vulnerabilities phpcop scan --only-dev --min-severity=moderate --format=md > dev-security.md
Performance & Caching âĄ
PHPCop is optimized for speed with intelligent caching and parallel processing:
Parallel API Calls
- Concurrent requests - Fetches package data in parallel instead of sequentially
- Significant speedup - 10-50x faster for projects with many dependencies
- Automatic batching - Groups API calls for maximum efficiency
Intelligent Caching
- Multi-level cache - Memory cache + persistent file cache
- Smart TTL - 1-hour default cache lifetime (configurable)
- Automatic cleanup - Expired cache files are removed automatically
- Cross-run persistence - Subsequent scans use cached data for speed
Cache Control
# Disable caching for fresh data phpcop scan --no-cache # Configure cache in .phpcop.json { "cache-enabled": true, "cache-ttl": 1800 // 30 minutes }
Cache Location: {system-temp}/phpcop-cache/
Performance Tips
- First run: May take longer as cache is populated
- Subsequent runs: Near-instant for unchanged dependencies
- CI environments: Consider
--no-cachefor fresh builds - Development: Keep caching enabled for faster iteration
Configuration
Configuration File
Create a .phpcop.json file in your project root for persistent settings:
{
"format": "table",
"stale-months": 18,
"fail-on": "high",
"composer-bin": "composer",
"quiet": false,
"ignore-packages": [
"symfony/polyfill-*",
"psr/log"
],
"dependency-type": "exclude-dev",
"license-allowlist": ["MIT", "Apache-2.0"],
"license-denylist": ["GPL-3.0"],
"min-severity": "moderate",
"cache-enabled": true,
"cache-ttl": 3600
}
Command Options
| Option | Default | Description |
|---|---|---|
--format |
table |
Output format: table, json, md, html |
--stale-months |
18 |
Months to flag packages as stale |
--fail-on |
high |
Minimum severity to fail: low, moderate, high, critical |
--composer-bin |
composer |
Path to composer executable |
--quiet, -q |
false |
Disable progress bar and animations |
--config, -c |
.phpcop.json |
Path to configuration file |
--ignore-packages |
[] |
Comma-separated packages to ignore |
--only-dev |
false |
Only scan dev dependencies |
--exclude-dev |
false |
Exclude dev dependencies from scan |
--license-allowlist |
[] |
Comma-separated list of allowed licenses |
--license-denylist |
[] |
Comma-separated list of denied licenses |
--min-severity |
low |
Minimum vulnerability severity: low, moderate, high, critical |
--no-cache |
false |
Disable response caching (force fresh API calls) |
--exit-code |
enhanced |
Exit code behavior: legacy, enhanced |
Note: Command-line options override configuration file settings.
Requirements
- PHP 8.2 or higher
- Composer 2.x
- A
composer.lockfile in your project
Building from Source đ§
Building the PHAR
To build your own PHAR archive:
# Install dependencies composer install --no-dev --optimize-autoloader # Build PHAR (requires phar.readonly=0) php -d phar.readonly=0 build-phar.php # Or use make (if available) make phar
The generated phpcop.phar file is self-contained and can be distributed independently.
Development Commands
# Install dev dependencies composer install # Run from source php bin/phpcop.php scan # Build PHAR make phar # Clean build artifacts make clean
Contributing đ¤
We welcome contributions! Here's how you can help:
- đ Bug Reports - Open an issue with details and reproduction steps
- đĄ Feature Requests - Share your ideas for new functionality
- đ§ Code Contributions - Submit a pull request with your improvements
- đ Documentation - Help improve our docs and examples
- đ Spread the Word - Star the repo, share with colleagues, write blog posts
Support
- đ Documentation - Check our comprehensive README and examples
- đ Issues - Report bugs on GitHub Issues
- đŦ Discussions - Join conversations in GitHub Discussions
- đĻ Packagist - View package details on Packagist
License
Released under the MIT License. Free for personal and commercial use.
Built with â¤ī¸ for the PHP community
Keep your dependencies secure, one scan at a time! đ
