Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Plugin Laravel Laravel Package

psalm/plugin-laravel

Psalm plugin for Laravel that adds deep framework-aware static analysis plus taint-based security scanning. Detects SQL injection, XSS, SSRF, shell injection, file traversal, and open redirects by tracking user input flows across functions and services.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require --dev psalm/plugin-laravel
    

    Add to your composer.json under require-dev if not using global CLI.

  2. Initialize Psalm

    ./vendor/bin/psalm --init
    

    This generates a psalm.xml config file in your project root.

  3. Enable the Plugin

    ./vendor/bin/psalm-plugin enable psalm/plugin-laravel
    

    Verify the plugin is active in psalm.xml under <plugins>.

  4. Run Analysis

    ./vendor/bin/psalm
    

    Security taint analysis runs automatically with no additional flags.

First Use Case

Detect SQL Injection in Routes

// app/Http/Controllers/UserController.php
Route::get('/search', function (Request $request) {
    $query = $request->input('q'); // Taint source: user input
    DB::statement("SELECT * FROM users WHERE name = '$query'"); // Taint sink: SQL injection
});

Run Psalm and observe the TaintedSql error. This highlights how the plugin tracks data flow across function boundaries.


Implementation Patterns

Core Workflows

  1. Type Analysis + Security Scanning

    • Run ./vendor/bin/psalm to analyze both types and security.
    • Use --error-format=github for CI-friendly output:
      ./vendor/bin/psalm --error-format=github
      
  2. Baseline Management

    • For existing projects, create a baseline to suppress legacy issues:
      ./vendor/bin/psalm --set-baseline=psalm-baseline.xml
      
    • Gradually tighten errorLevel (start at 4, aim for 1) to reduce false positives.
  3. Integration with CI

    # .github/workflows/psalm.yml
    jobs:
      psalm:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: composer install
          - run: ./vendor/bin/psalm --init
          - run: ./vendor/bin/psalm --no-cache
    

Laravel-Specific Patterns

  1. Facade Method Analysis The plugin auto-generates stubs for Laravel facades (e.g., DB::, Cache::). No manual stubs needed for most cases.

  2. Model Type Inference

    • Parse migrations (php artisan schema:dump) to infer column types.
    • Example: Psalm will infer User::where('email', $value) expects $value to match the email column type.
  3. Taint Flow Across Layers

    // app/Services/UserService.php
    class UserService {
        public function getQuery(Request $request): string {
            return "SELECT * FROM users WHERE name = '" . $request->input('name') . "'";
        }
    }
    

    Psalm detects taint flow from RequestUserService::getQuery()DB::statement() in the controller.

  4. Custom Issue Suppression Suppress specific issues in psalm.xml:

    <suppress>
        <error name="Psalm\Code\Security\TaintedSql" />
    </suppress>
    

Advanced Patterns

  1. Custom Taint Sources/Sinks Extend the plugin by adding stubs in stubs/common/ (see contribution guide). Example: Add a taint sink for a custom query builder:

    /**
     * @psalm-taint-sink sql $query
     */
    public function raw($query) {}
    
  2. Taint Escape for Safe Functions Mark functions that sanitize input as escapes:

    /**
     * @psalm-taint-escape html
     * @psalm-flow ($value) -> return
     */
    function cleanHtml($value) {}
    
  3. Integration with Larastan Use both tools in CI:

    ./vendor/bin/psalm && ./vendor/bin/larastan analyze
    

Gotchas and Tips

Pitfalls

  1. False Positives in Legacy Code

    • Issue: Psalm flags legitimate but unsafe patterns in old code (e.g., env() outside config/).
    • Fix: Use baselines and suppress specific issues:
      <suppress>
          <error name="Psalm\Plugin\Laravel\NoEnvOutsideConfig" />
      </suppress>
      
  2. Missing Taint Sources

    • Issue: User input from non-standard sources (e.g., custom request classes) may not be detected.
    • Fix: Add @psalm-taint-source annotations to stubs or extend the plugin.
  3. Performance Overhead

    • Issue: Large codebases may slow down analysis.
    • Fix: Exclude directories in psalm.xml:
      <file_list>
          <directory name="storage" />
          <directory name="tests" />
      </file_list>
      
  4. Version Mismatches

    • Issue: Plugin version incompatible with Laravel/Psalm versions.
    • Fix: Check supported versions and pin versions in composer.json:
      "require-dev": {
          "psalm/plugin-laravel": "4.x-dev"
      }
      
  5. Taint Escape Misconfiguration

    • Issue: Incorrect @psalm-taint-escape without @psalm-flow drops all taints, causing false negatives.
    • Fix: Always pair escapes with flows:
      /**
       * @psalm-taint-escape sql
       * @psalm-flow ($value) -> return
       */
      function sanitize($value) {}
      

Debugging Tips

  1. Inspect Taint Flow Use --show-taint-flow to visualize how taint propagates:

    ./vendor/bin/psalm --show-taint-flow
    
  2. Verify Stub Generation Check if facades/models are stubbed correctly:

    ./vendor/bin/psalm --generate-stubs
    
  3. Isolate Issues Run Psalm on a single file to debug:

    ./vendor/bin/psalm app/Http/Controllers/UserController.php
    

Configuration Quirks

  1. Opt-In Checks

    • MissingView: Enable with:
      <plugin_class>Psalm\Plugin\Laravel\Plugin</plugin_class>
      <configuration>
          <check_missing_views>true</check_missing_views>
      </configuration>
      
    • MissingTranslation: Enable with:
      <check_missing_translations>true</check_missing_translations>
      
  2. Custom Error Levels Adjust errorLevel in psalm.xml to balance strictness and noise:

    <errorLevel>1</errorLevel> <!-- Strict -->
    <errorLevel>4</errorLevel> <!-- Lenient -->
    
  3. Excluding Files Ignore specific files (e.g., third-party libraries):

    <file_list>
        <exclude_name>vendor/</exclude_name>
    </file_list>
    

Extension Points

  1. Add Custom Taint Kinds Extend Psalm\Type\TaintKind in a custom plugin to support domain-specific taints (e.g., api_key).

  2. Override Stub Generation Disable auto-generated stubs and provide your own in stubs/:

    <stub_files>
        <directory name="stubs/" />
    </stub_files>
    
  3. Integrate with IDE Use Psalm’s IDE plugin (e.g., PHPStorm) for real-time feedback:

    • Install the Psalm plugin in PHPStorm.
    • Configure it to use your project’s psalm.xml.
  4. Custom Rules Create a custom Psalm rule to enforce business logic (e.g., "never use Model::make()"):

    // ruleset.xml
    <rule ref="Psalm\Plugin\Laravel\ModelMakeDiscouraged" />
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport