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

Csp Builder Laravel Package

paragonie/csp-builder

Build and send Content-Security-Policy headers in PHP from JSON files, JSON strings, or arrays. CSP Builder makes it easy to define directives programmatically and integrate CSP into web apps to improve security.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require paragonie/csp-builder
    

    Add to composer.json if using Laravel’s require-dev for testing.

  2. First Use Case: Create a JSON config file (config/csp.json):

    {
        "default-src": ["'self'"],
        "script-src": ["'self'", "https://cdn.example.com"]
    }
    

    Load and send in a Laravel middleware or service:

    use ParagonIE\CSPBuilder\CSPBuilder;
    
    $csp = CSPBuilder::fromFile(base_path('config/csp.json'));
    $csp->sendCSPHeader();
    
  3. Where to Look First:

    • Documentation: Focus on the README for core methods (addSource, hash, nonce).
    • Laravel Integration: Use app()->make(CSPBuilder::class) or bind the builder in AppServiceProvider for dependency injection.

Implementation Patterns

1. Middleware Integration

Create a dedicated CSP middleware (app/Http/Middleware/CSP.php):

public function handle($request, Closure $next) {
    $csp = app(CSPBuilder::class);
    $response = $next($request);
    $csp->injectCSPHeader($response);
    return $response;
}

Register in app/Http/Kernel.php:

protected $middleware = [
    \App\Http\Middleware\CSP::class,
];

2. Dynamic Policies

Use Cases:

  • Environment-Specific Rules: Load different JSON configs per environment (e.g., config/csp/production.json).
  • Route-Based Policies: Override directives for admin routes:
    Route::middleware(['csp'])->group(function () {
        $csp = app(CSPBuilder::class);
        $csp->addSource('script-src', "'self'", "'unsafe-inline'"); // Admin-only inline scripts
    });
    

3. Nonce and Hash Workflows

  • Inline Scripts:
    $nonce = $csp->nonce('script-src');
    echo "<script nonce=\"$nonce\">console.log('Safe!');</script>";
    
  • Pre-Hashed Assets:
    $hash = $csp->preHash('script-src', file_get_contents('script.js'), 'sha256');
    $csp->addSource('script-src', $hash);
    

4. Reporting Violations

Configure report-uri in JSON:

{
    "report-uri": "/csp-report-endpoint",
    "report-to": "csp-reports"
}

Handle reports in Laravel (routes/web.php):

Route::post('/csp-report-endpoint', [CSPReportController::class, 'store']);

5. PSR-7 Integration

For frameworks like Lumen or custom PSR-7 apps:

$response = new \Zend\Diactoros\Response();
$csp->injectCSPHeader($response);

6. Server Configuration Snippets

Generate Nginx/Apache snippets for static CSP headers:

$csp->saveSnippet(
    storage_path('app/nginx/csp.conf'),
    CSPBuilder::FORMAT_NGINX
);

Include in server config:

location / {
    add_header Content-Security-Policy always;
    include snippets/csp.conf;
}

Gotchas and Tips

Pitfalls

  1. Duplicate Directives:

    • Issue: Calling addSource multiple times for the same directive may cause duplicates.
    • Fix: Use setDirective to overwrite or addSource with unique values.
    • Example:
      $csp->setDirective('script-src', ['self', 'https://cdn.example.com']); // Overwrites
      
  2. Nonce/Hash Scope:

    • Issue: Nonces/hashes must match the directive they’re added to (e.g., script-src nonce won’t work for style-src).
    • Fix: Specify the directive when generating:
      $nonce = $csp->nonce('style-src'); // For CSS
      
  3. Report-To vs. Report-Uri:

    • Issue: Modern browsers prefer report-to over report-uri. Use both for fallback:
      {
          "report-to": "csp-reports",
          "report-uri": "/fallback-report-endpoint"
      }
      
  4. PHP Version:

    • Issue: Requires PHP 7.4+ (v3.0.0+). Older versions may break.
    • Fix: Use paragonie/csp-builder:^2.9 for PHP 7.0–7.3 support.
  5. Semicolon Injection:

    • Issue: Malicious input could inject semicolons into CSP headers (e.g., via addDirective).
    • Fix: Sanitize inputs or use predefined sources:
      $csp->addSource('img-src', ['self', 'https://trusted.cdn.com']);
      

Debugging Tips

  1. Inspect Headers: Use browser dev tools (Network tab) or Laravel’s dd($response->headers) to verify CSP headers.

  2. Test in Report-Only Mode: Temporarily set "report-only": true in JSON to test policies without blocking resources.

  3. CSP Evaluator: Validate policies at CSP Evaluator.

Extension Points

  1. Custom Directives: Extend CSPBuilder to support non-standard directives (e.g., trusted-types):

    $csp->addDirective('trusted-types', ['script']);
    
  2. Hooks for Output: Modify generated CSP before saving:

    $csp->saveSnippet(
        'path/to/snippet.conf',
        CSPBuilder::FORMAT_NGINX,
        fn($output) => str_replace("'self'", "'none'", $output)
    );
    
  3. Laravel Service Provider: Bind the builder with environment-specific configs:

    $this->app->bind(CSPBuilder::class, function ($app) {
        $config = config('csp.' . config('app.env'));
        return new CSPBuilder($config);
    });
    

Performance

  • Caching: Reuse CSPBuilder instances across requests (stateless after initialization).
  • Avoid fromFile in Loops: Load JSON configs once (e.g., in AppServiceProvider boot method).

Security Quirks

  • unsafe-inline/unsafe-eval: Avoid unless absolutely necessary. Use nonces/hashes instead.
  • child-src Deprecation: Use frame-ancestors for modern browsers (v3.0.0+ un-deprecated frame-src as an alias).
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky