How to Fix Web Application Vulnerabilities Found by Wapiti in Laravel

Scans web applications for XSS, XXE, SSRF, and other OWASP vulnerabilities using Wapiti. Requires domain verification.

application security Hard fix 1-3 hours

What This Check Detects

Scans web applications for XSS, XXE, SSRF, and other OWASP vulnerabilities using Wapiti. Requires domain verification.

Full Documentation

What is Wapiti?

Wapiti is a web application vulnerability scanner that crawls your application and tests for XSS (cross-site scripting), XXE (XML external entities), SSRF (server-side request forgery), command injection, file inclusion, and other OWASP Top 10 vulnerabilities.

Security Impact

Severity: Critical

  • XSS: Session hijacking, credential theft, defacement
  • XXE: Server-side file reading, SSRF, denial of service
  • SSRF: Internal network scanning, cloud metadata access
  • Command injection: Full server compromise
  • File inclusion: Source code disclosure, remote code execution

How to Fix

1. Cross-Site Scripting (XSS)

Laravel's Blade templating automatically escapes output. Ensure you use it correctly:

{{-- SAFE - Blade auto-escapes --}}
{{ $user->name }}

{{-- VULNERABLE - Raw output, avoid unless content is trusted --}}
{!! $user->bio !!}

{{-- If you must use raw output, sanitize first --}}
{!! clean($user->bio) !!}

Install HTMLPurifier for sanitizing rich content:

composer require mews/purifier
// Sanitize user HTML input
use Mews\Purifier\Facades\Purifier;

$clean = Purifier::clean($request->input('bio'));

2. XML External Entity (XXE)

Disable external entity loading when processing XML:

// Disable external entities globally
libxml_disable_entity_loader(true);

// When using DOMDocument
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT | LIBXML_NONET);

// When using SimpleXML
$xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOENT | LIBXML_NONET);

3. Server-Side Request Forgery (SSRF)

Validate and restrict URLs that your application fetches:

// Validate URL input
$validated = $request->validate([
    'url' => ['required', 'url', 'regex:/^https?:\/\//'],
]);

// Block internal IPs
function isInternalUrl(string $url): bool
{
    $host = parse_url($url, PHP_URL_HOST);
    $ip = gethostbyname($host);

    $internalRanges = [
        '10.0.0.0/8',
        '172.16.0.0/12',
        '192.168.0.0/16',
        '127.0.0.0/8',
        '169.254.0.0/16',
    ];

    foreach ($internalRanges as $range) {
        if (ip_in_range($ip, $range)) {
            return true;
        }
    }
    return false;
}

// Reject internal URLs
if (isInternalUrl($validated['url'])) {
    abort(422, 'Internal URLs are not allowed');
}

4. Command Injection

Never pass user input to shell commands:

// VULNERABLE
exec("ping -c 1 " . $request->host);

// SAFE - Use escapeshellarg
exec("ping -c 1 " . escapeshellarg($request->host));

// SAFER - Use Laravel's Process class (Laravel 10+)
use Illuminate\Support\Facades\Process;

$result = Process::run(['ping', '-c', '1', $validated['host']]);

// SAFEST - Avoid shell commands entirely, use PHP functions
$ip = gethostbyname($validated['host']);

5. File Inclusion

Prevent path traversal and arbitrary file inclusion:

// VULNERABLE
$page = $request->input('page');
include("pages/{$page}.php");

// SAFE - Whitelist allowed values
$allowed = ['home', 'about', 'contact'];
$page = in_array($request->page, $allowed) ? $request->page : 'home';

// SAFE - Use Laravel's view system
return view('pages.' . $page); // Laravel validates view names

6. Input Validation Best Practices

// Always validate at the controller level
$validated = $request->validate([
    'name' => 'required|string|max:255',
    'email' => 'required|email:rfc,dns',
    'url' => 'nullable|url|max:2048',
    'content' => 'required|string|max:10000',
    'file' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
]);

7. Content Security Policy

Add CSP headers to prevent XSS execution even if injected:

// app/Http/Middleware/SecurityHeaders.php
$response->headers->set(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.bunny.net; font-src 'self' https://fonts.bunny.net; img-src 'self' data:; connect-src 'self'"
);

Verification

After applying fixes, Wapiti should report significantly fewer or no vulnerabilities. Focus on eliminating all critical and high severity findings first.

Related Issues

  • Automated OWASP ZAP Scan
  • SQL Injection Scan
  • Nikto Web Server Scan

Related Security Checks

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup required. Results in 60 seconds.