PHPackages                             hryagstn/laravel-scalpel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. hryagstn/laravel-scalpel

ActiveLibrary[File &amp; Storage](/categories/file-storage)

hryagstn/laravel-scalpel
========================

Filesystem intrusion evidence scanner for Laravel applications

v1.1.0(2w ago)04MITPHPPHP ^8.1CI passing

Since May 23Pushed 2w agoCompare

[ Source](https://github.com/hryagstn/laravel-scalpel)[ Packagist](https://packagist.org/packages/hryagstn/laravel-scalpel)[ RSS](/packages/hryagstn-laravel-scalpel/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (7)Versions (3)Used By (0)

[![Build Status](https://camo.githubusercontent.com/93e21d51c8338097fb286a57e7a55ff1c74009a9d8e59e22f79321f390e9af2a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f687279616773746e2f6c61726176656c2d7363616c70656c2f74657374732e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265)](https://github.com/hryagstn/laravel-scalpel/actions)[![Latest Version on Packagist](https://camo.githubusercontent.com/5200f0598f2919a88737cd41e243299f49419156bf257ad40b15773df551e4c4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f687279616773746e2f6c61726176656c2d7363616c70656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hryagstn/laravel-scalpel)[![PHP Version](https://camo.githubusercontent.com/80352c675dfff188f9954871e05ee0780f857d0f269c19f8a9aa9062bfd5ee69/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f687279616773746e2f6c61726176656c2d7363616c70656c3f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hryagstn/laravel-scalpel)[![Laravel Version](https://camo.githubusercontent.com/9ec06dfc291a2326d223cc6e5d130812e278c9ff785587fb35b632eefabf5705/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31302e7825323025374325323031312e7825323025374325323031322e7825323025374325323031332e782d626c75653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hryagstn/laravel-scalpel)[![License](https://camo.githubusercontent.com/7a34c44bfe7efd9b73713b9144bdddd0d67e018a65165474e6611c42af502671/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f687279616773746e2f6c61726176656c2d7363616c70656c3f7374796c653d666c61742d737175617265)](LICENSE)

🔪 laravel-scalpel
=================

[](#-laravel-scalpel)

**Intrusion Evidence Scanner for Laravel**

A zero-dependency, filesystem-level forensic scanner that detects signs of compromise in your Laravel application — obfuscated backdoors, rogue PHP files, tampered `.htaccess` directives, missing `.env` files, and unexpected filesystem changes.

---

🚨 The Problem
-------------

[](#-the-problem)

It often starts the same way: a production Laravel app is quietly compromised. Obfuscated PHP backdoors appear in directories like `public/icons/` or `storage/`. An `.htaccess` file is modified to allow Python script execution. The `.env` file is deleted or tampered with to disable error reporting and cover tracks.

These attacks don't trigger your WAF. They don't show up in your application logs. The malicious files sit silently on disk, waiting.

**laravel-scalpel is not a WAF, firewall, or runtime protection layer.** It is a *forensic filesystem scanner* — a post-incident or preventive tool that examines your project's file structure and contents for evidence of intrusion. Think of it as a security audit you can run on-demand or in CI/CD.

Unlike configuration auditors that check for *potential* vulnerabilities, laravel-scalpel looks for *evidence that a compromise has already occurred* — making it the tool you reach for when something feels wrong, not just as a preventive checklist.

---

📦 Installation
--------------

[](#-installation)

```
composer require hryagstn/laravel-scalpel
```

Publish the configuration file:

```
php artisan vendor:publish --tag=scalpel-config
```

This creates `config/scalpel.php` where you can customize scan behavior, exclusion lists, and severity thresholds.

> **Requirements:** PHP 8.1+ · Laravel 10.x, 11.x, 12.x, or 13.x

---

⚡ Quick Start
-------------

[](#-quick-start)

Run all scanners at once:

```
php artisan scalpel:scan
```

Create a filesystem baseline snapshot:

```
php artisan scalpel:baseline
```

Compare current state against the baseline:

```
php artisan scalpel:diff
```

That's it. Three commands to audit your entire project for intrusion evidence.

> **Important:** Always run `vendor:publish` and complete your initial setup **before** running `scalpel:baseline`. The baseline should capture your application's known-good state after all configuration is in place.

---

📖 Command Reference
-------------------

[](#-command-reference)

### `scalpel:scan`

[](#scalpelscan)

Run one or more scanners against your project.

```
# Run all scanners
php artisan scalpel:scan

# Run specific scanners only
php artisan scalpel:scan --only=structural,obfuscated

# Output results as JSON (for machine consumption)
php artisan scalpel:scan --format=json
```

**Options:**

OptionDescription`--only`Comma-separated list of scanners to run: `structural`, `obfuscated`, `htaccess`, `env``--format`Output format: `table` (default) or `json`**Exit codes:**

CodeMeaning`0`No findings (clean)`1`Findings detected (CRITICAL or HIGH)`2`Findings detected (MEDIUM or LOW only)---

### `scalpel:baseline`

[](#scalpelbaseline)

Create a snapshot of your project's current filesystem state. This snapshot is stored at the path configured in `scalpel.baseline_path` (default: `storage/app/private/scalpel/baseline.json`).

```
# Create a baseline (fails if one already exists)
php artisan scalpel:baseline

# Overwrite an existing baseline
php artisan scalpel:baseline --force
```

**Options:**

OptionDescription`--force`Overwrite an existing baseline file---

### `scalpel:diff`

[](#scalpeldiff)

Compare the current filesystem state against a previously created baseline snapshot. Reports added, removed, and modified files.

```
# Compare against baseline
php artisan scalpel:diff

# Output diff as JSON
php artisan scalpel:diff --format=json
```

**Options:**

OptionDescription`--format`Output format: `table` (default) or `json`**Exit codes:** Same as `scalpel:scan`.

---

🔍 How It Works
--------------

[](#-how-it-works)

laravel-scalpel ships with five independent scanners. Each focuses on a specific class of intrusion evidence.

### Structural Anomaly Scanner

[](#structural-anomaly-scanner)

Detects PHP files in directories where they should never exist — `public/`, `storage/`, `bootstrap/cache/`, and any other paths you define as "non-PHP zones."

Attackers commonly drop webshells into public-facing directories disguised as image folders (e.g., `public/icons/shell.php`). This scanner catches them.

- Scans all configured `non_php_zones` for `.php` files
- Automatically excludes known legitimate files (`public/index.php`) and directories (`public/vendor/`)
- Configurable allow-lists for both files and directories

### Obfuscated Code Scanner

[](#obfuscated-code-scanner)

Detects common PHP obfuscation patterns used in backdoors and webshells. Scans all `.php` files in the project for:

PatternDescriptionSeverity`eval(base64_decode)`Classic obfuscation — decode and executeCRITICAL`eval(gzinflate)`Compressed payload executionCRITICAL`eval(str_rot13)`ROT13 obfuscation with evalCRITICAL`eval(gzuncompress)`Compressed payload execution (variant)CRITICAL`eval(gzdecode)`Compressed payload execution (variant)CRITICAL`assert()` with varsDynamic code execution via assertHIGHVariable functions`$var()` style dynamic function callsMEDIUM`preg_replace` `/e`Code execution via deprecated regex modifierHIGHLong encoded stringsSuspiciously long base64/hex strings (≥500 chars)MEDIUMEach pattern can be individually toggled in the configuration.

### Htaccess Scanner

[](#htaccess-scanner)

Scans all `.htaccess` files in your project for dangerous directives that could allow execution of non-PHP scripts. Attackers often modify `.htaccess` to register Python, Perl, or CGI handlers, enabling them to run arbitrary scripts through the web server.

Detects:

- `AddHandler` directives mapping to dangerous script types
- `AddType` directives mapping to dangerous MIME types
- Custom handler registrations for `cgi-script`, `python-program`, `perl-script`, etc.

### Baseline Diff Scanner

[](#baseline-diff-scanner)

Creates a cryptographic snapshot of your entire project filesystem and detects changes over time. This is your "known good state" mechanism.

**Workflow:**

1. Run `php artisan scalpel:baseline` after a clean deployment
2. Run `php artisan scalpel:diff` periodically or in CI to detect unauthorized changes
3. Added, removed, or modified files are reported with severity ratings

Baseline snapshots exclude volatile directories like `storage/logs/`, `storage/framework/cache/`, and other paths configured in `baseline_excluded_paths`.

### Env Integrity Scanner

[](#env-integrity-scanner)

Verifies the existence and basic integrity of your `.env` file. Attackers sometimes delete or truncate the `.env` file to disable error reporting, remove debug information, or reset application keys.

Checks:

- `.env` file exists
- `.env` file is not empty
- `.env` file is readable

---

⚙️ Configuration Reference
--------------------------

[](#️-configuration-reference)

After publishing, the configuration file lives at `config/scalpel.php`. Below is a reference for every key.

### `non_php_zones`

[](#non_php_zones)

Directories where PHP files should not exist. Relative to the project root.

```
'non_php_zones' => [
    'public',
    'storage',
    'bootstrap/cache',
],
```

### `structural_allowed_files`

[](#structural_allowed_files)

Individual files within non-PHP zones that are known to be legitimate. Relative to the project root.

```
'structural_allowed_files' => [
    'public/index.php',
],
```

### `structural_allowed_directories`

[](#structural_allowed_directories)

Subdirectories within non-PHP zones where PHP files are expected (e.g., published assets).

```
'structural_allowed_directories' => [
    'public/vendor',
],
```

### `excluded_paths`

[](#excluded_paths)

Paths to exclude from **all** scanners. Relative to the project root.

```
'excluded_paths' => [
    'vendor',
    'node_modules',
    '.git',
],
```

### `obfuscation_patterns`

[](#obfuscation_patterns)

Toggle individual obfuscation detection patterns on or off.

```
'obfuscation_patterns' => [
    'eval_base64_decode'  => true,
    'eval_gzinflate'      => true,
    'eval_str_rot13'      => true,
    'eval_gzuncompress'   => true,
    'eval_gzdecode'       => true,
    'assert_dynamic'      => true,
    'variable_functions'  => true,
    'preg_replace_e'      => true,
    'long_encoded_string' => true,
],
```

### `long_string_threshold`

[](#long_string_threshold)

Minimum character length for a string to be flagged as a suspiciously long encoded payload.

```
'long_string_threshold' => 500,
```

### `htaccess_dangerous_handlers`

[](#htaccess_dangerous_handlers)

Script handlers and MIME types that are flagged when found in `.htaccess` directives.

```
'htaccess_dangerous_handlers' => [
    'cgi-script',
    'python-program',
    'perl-script',
    'ruby-script',
    'application/x-httpd-python',
    'application/x-httpd-perl',
    'application/x-httpd-ruby',
    'application/x-httpd-cgi',
],
```

### `baseline_excluded_paths`

[](#baseline_excluded_paths)

Additional paths excluded from baseline snapshots and diff comparisons (on top of `excluded_paths`).

```
'baseline_excluded_paths' => [
    'storage/logs',
    'storage/framework/cache',
    'storage/framework/sessions',
    'storage/framework/views',
    'storage/app/private/scalpel',
],
```

### `baseline_path`

[](#baseline_path)

Where the baseline snapshot JSON file is stored, relative to `storage/app/private/` (or `storage/app/` depending on your local disk configuration).

```
'baseline_path' => 'scalpel/baseline.json',
```

### `severity_threshold`

[](#severity_threshold)

Minimum severity level to include in results. Findings below this level are silently filtered out. Options: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`.

```
'severity_threshold' => 'LOW',
```

---

🔄 CI/CD Integration
-------------------

[](#-cicd-integration)

laravel-scalpel uses exit codes to signal results, making it straightforward to integrate into CI/CD pipelines.

### GitHub Actions Example

[](#github-actions-example)

```
name: Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * *'  # Daily at 6 AM UTC

jobs:
  scalpel-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      - name: Install Dependencies
        run: composer install --no-interaction --prefer-dist

      - name: Run Scalpel Scan
        run: php artisan scalpel:scan --format=json

      - name: Run Baseline Diff
        run: php artisan scalpel:diff --format=json
```

> **Tip:** Store a baseline snapshot in your repository (or generate it during deployment) so `scalpel:diff` can detect unauthorized post-deployment changes.

Known False Positives
---------------------

[](#known-false-positives)

**`bootstrap/cache/` files modified or deleted**These files are regenerated by Laravel when running `php artisan optimize`or `php artisan optimize:clear`. If you see changes here after running these commands, it is expected. If you see changes without having run these commands, investigate immediately.

Recommended Workflow
--------------------

[](#recommended-workflow)

1. Deploy new code
2. Run `php artisan optimize`
3. Run `php artisan scalpel:baseline --force`

This ensures the baseline always reflects the post-deployment known-good state.

Automation &amp; Monitoring
---------------------------

[](#automation--monitoring)

Pair laravel-scalpel with [n8n-bastion](https://github.com/hryagstn/n8n-bastion)for automated scheduled scanning and real-time Telegram alerts when CRITICAL or HIGH findings are detected on your VPS.

---

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Here's how to get started:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Write tests for your changes
4. Ensure all tests pass (`composer test`)
5. Commit your changes (`git commit -m 'Add my feature'`)
6. Push to your branch (`git push origin feature/my-feature`)
7. Open a Pull Request

Please make sure your code follows the existing style and includes appropriate tests.

---

📄 License
---------

[](#-license)

laravel-scalpel is open-sourced software licensed under the [MIT License](LICENSE).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance97

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

2

Last Release

15d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/af56733738c9a9dd43633fbfd1ee9dab4c09ea41182bf5d18701af52b1e2fb0a?d=identicon)[hryagstn](/maintainers/hryagstn)

---

Top Contributors

[![hryagstn](https://avatars.githubusercontent.com/u/204626097?v=4)](https://github.com/hryagstn "hryagstn (5 commits)")

---

Tags

filesystemlaravelsecurityscannerobfuscationbackdoorintrusion-detection

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hryagstn-laravel-scalpel/health.svg)

```
[![Health](https://phpackages.com/badges/hryagstn-laravel-scalpel/health.svg)](https://phpackages.com/packages/hryagstn-laravel-scalpel)
```

###  Alternatives

[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[unisharp/laravel-filemanager

A file upload/editor intended for use with Laravel 5 to 10 and CKEditor / TinyMCE

2.1k3.4M80](/packages/unisharp-laravel-filemanager)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[tightenco/jigsaw

Simple static sites with Laravel's Blade.

2.2k449.3k30](/packages/tightenco-jigsaw)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[propaganistas/laravel-disposable-email

Disposable email validator

6012.9M7](/packages/propaganistas-laravel-disposable-email)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
