Security Standards

What Is OWASP Top 10?

A regularly updated list of the ten most critical security risks to web applications, published by the OWASP Foundation. The current version (2021) includes: A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable and Outdated Components, A07 Identification and Authentication Failures, A08 Software and Data Integrity Failures, A09 Security Logging and Monitoring Failures, A10 Server-Side Request Forgery.

How It Works

Each OWASP Top 10 category represents a distinct class of vulnerability with specific attack mechanics relevant to Laravel applications.

A01 Broken Access Control — The most common OWASP issue. Attackers exploit missing authorization checks to access unauthorized resources. In Laravel, the attack is simple: an authenticated user requests /api/invoices/1, sees it works, then changes the ID to 2, 3, 4 and finds they can access any user's invoice. The application calls Invoice::find($id) without checking $invoice->user_id === auth()->id(). IDOR is the canonical Broken Access Control example.

A03 Injection — Attackers insert malicious code into interpreter inputs. In Laravel, this is SQL injection via DB::raw() string interpolation, OS command injection via shell_exec() or system() with user input, and LDAP injection in directory queries. Eloquent's parameterized queries prevent most SQL injection by default.

A05 Security Misconfiguration — The category most commonly exploited against Laravel specifically. Attackers probe /.env, trigger errors to check for APP_DEBUG=true, visit /telescope, and check response headers for missing security controls. All of these are detectable externally in seconds and are the primary focus of EASM tools like StackShield.

A07 Identification and Authentication Failures — Attackers exploit weak authentication: no rate limiting on login endpoints (enables brute force), password reset tokens that do not expire (enables account takeover days later), session IDs that persist after logout (enables session replay), or credentials stored as unsalted MD5 hashes (trivially cracked after database breach).

A09 Security Logging and Monitoring Failures — Without adequate logging, attacks go undetected for weeks. Attackers rely on defenders not knowing an attack occurred. Laravel's default logging (single channel to a file that is often not monitored externally) makes this category a frequent failure.

Types of OWASP Top 10

A01 Broken Access Control (IDOR)

Attacker changes resource identifiers in API calls to access data belonging to other users — the most common OWASP finding in Laravel applications.

# Authenticated as user 5 — access user 3's order:
GET /api/orders/342  HTTP/1.1
Authorization: Bearer USER5_TOKEN
# Returns user 3's order data if authorization check is missing

A05 Security Misconfiguration

Attacker probes known sensitive paths and error triggers to find exposed configuration data that provides entry points for deeper attacks.

# Simple probe sequence — takes under 30 seconds:
curl https://yourapp.com/.env         # Check for exposed secrets
curl https://yourapp.com/telescope    # Check for unprotected debug tool
curl https://yourapp.com/nonexistent  # Check if APP_DEBUG=true shows stack trace

A07 Authentication Failures

Attacker exploits weak authentication controls — no rate limiting, weak password policy, tokens that never expire, or sessions that persist after logout.

# Brute force test — send 20 rapid login attempts:
for i in {1..20}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
    -X POST https://yourapp.com/login \
    -d "email=admin@test.com&password=test$i"
done
# All 200 responses = no rate limiting

A06 Vulnerable and Outdated Components

Attacker checks the application's Composer package versions against known CVEs and targets applications running versions with public exploit code.

# Check for vulnerable dependencies:
composer audit
# Example: guzzlehttp/psr7 < 1.8.4 CVE-2022-24775 (High)

In Laravel Applications

Every item in the OWASP Top 10 has specific implications for Laravel applications. Security Misconfiguration (A05) alone covers debug mode, exposed .env files, default credentials, and missing security headers, which are among the most common Laravel security issues.

Code Examples

A01 Broken Access Control: IDOR vs. Policy Protection

Vulnerable

// VULNERABLE: A01 Broken Access Control — no ownership verification
// Any authenticated user can read any invoice by changing the ID
public function show(Invoice $invoice): JsonResponse
{
    // Route model binding finds the invoice — but never checks ownership
    return response()->json($invoice->load('lineItems'));
}

Secure

// SECURE: A01 Fixed — policy enforces ownership before returning data
public function show(Invoice $invoice): JsonResponse
{
    $this->authorize('view', $invoice); // 403 if auth user != invoice owner
    return response()->json($invoice->load('lineItems'));
}

// app/Policies/InvoicePolicy.php
public function view(User $user, Invoice $invoice): bool
{
    return $user->id === $invoice->user_id
        || $user->hasRole('admin');
}

A05 Security Misconfiguration: .env and Debug Mode

Vulnerable

# .env — VULNERABLE: debug enabled, local env config in production
APP_NAME="My App"
APP_ENV=local        # Wrong for production
APP_KEY=base64:abc123
APP_DEBUG=true       # Exposes stack traces with env vars and DB credentials

# Nginx document root points to /var/www/app (not /var/www/app/public)
# Result: https://yourapp.com/.env returns all secrets above

Secure

# .env — SECURE production configuration
APP_NAME="My App"
APP_ENV=production
APP_KEY=base64:abc123
APP_DEBUG=false       # Never expose internal details

# config/app.php — safe default in case .env is missing
'debug' => (bool) env('APP_DEBUG', false),

# Nginx: root /var/www/app/public; — .env is never web-accessible

Real-World Example

A05 Security Misconfiguration is the most common OWASP Top 10 issue in Laravel apps. Leaving APP_DEBUG=true in production exposes stack traces, environment variables, and database credentials.

Why It Matters

The OWASP Top 10 is not just a list — it is a prioritized guide to where real breaches happen. Every item on the list represents a category of vulnerabilities that caused actual incidents at real companies. For Laravel developers, it provides a concrete checklist of what to verify before shipping to production.

A01 Broken Access Control is the top category and the most common in Laravel. It covers Insecure Direct Object References (accessing /api/users/1 when you are user 2), function-level access control failures (accessing /admin routes without admin privileges), and missing authorization checks on API endpoints. Gate::authorize(), Laravel policies, and middleware-based route protection are the defenses.

A05 Security Misconfiguration covers the majority of Laravel-specific quick wins: APP_DEBUG=true in production, exposed .env files, Telescope/Horizon without authentication, missing security headers, and default or weak APP_KEY. These are all detectable via external scanning.

A06 Vulnerable and Outdated Components maps directly to composer audit and keeping Composer dependencies updated. A09 Security Logging and Monitoring Failures is addressed by configuring config/logging.php with appropriate log levels and external log aggregation so anomalies can be detected.

Common Misconceptions

Myth: We only need to address Top 10 items with "High" CVSS scores.

Reality: OWASP Top 10 categories include both high and low CVSS severity issues. A02 Cryptographic Failures can include low-CVSS configuration issues (weak cipher suites, missing HTTPS) that are still critical to address.

Myth: The OWASP Top 10 is updated every year.

Reality: The OWASP Top 10 is updated every 3-4 years based on industry data collection. The current version is 2021. Check owasp.org for the latest version before using it as a compliance standard.

Myth: Passing an automated scan against the OWASP Top 10 means we have addressed all items.

Reality: Automated scanners cannot reliably detect A01 Broken Access Control or A04 Insecure Design. These require code review and understanding of business logic. Manual assessment is essential for these categories.

How to Detect This

Map your Laravel application against each OWASP Top 10 category manually. For A01 (Broken Access Control), run `php artisan route:list` and verify every route has appropriate middleware. For A03 (Injection), grep for `whereRaw\|DB::raw` in your application code. For A05 (Security Misconfiguration), use `curl -I https://yourdomain.com` to check headers and `curl -s https://yourdomain.com/.env | head -5` to verify `.env` is not exposed. StackShield maps its checks directly to OWASP Top 10 categories, providing a continuous report of which categories have active findings in your production application. For A06 (Outdated Components), run `composer audit` and `composer outdated --direct`.

How to Prevent This in Laravel

  1. 1

    Address A01 by generating policies with `php artisan make:policy ModelPolicy --model=Model` and calling `$this->authorize()` at the top of every controller method that accesses user-owned resources.

  2. 2

    Address A03 by running `grep -rn "whereRaw\|DB::raw\|DB::select" app/` and ensuring all results pass user input as bound parameter arrays, never as interpolated strings.

  3. 3

    Address A05 by running `curl -s https://yourapp.com/.env | head -1` (should return empty or 403), checking that `APP_DEBUG=false` in production, and verifying security headers with `curl -sI https://yourapp.com`.

  4. 4

    Address A06 by running `composer audit` in CI and setting up Dependabot alerts on your GitHub repository to receive automatic PRs for Composer security updates.

  5. 5

    Address A09 by configuring `config/logging.php` with a stack driver that sends `warning`+ logs to an external service (Papertrail, Logtail, Datadog) and registering listeners for `Illuminate\Auth\Events\Failed`.

Frequently Asked Questions

Which OWASP Top 10 item is most common in Laravel applications?

A01 Broken Access Control and A05 Security Misconfiguration are the most common findings in Laravel applications. A05 is particularly prevalent because Laravel's default `.env` has `APP_DEBUG=true` and `APP_ENV=local`, which many developers forget to change for production. A01 is common because Laravel makes it easy to retrieve model instances via route model binding without enforcing that the authenticated user owns the resource.

Does Laravel address any OWASP Top 10 categories automatically?

Yes — Laravel addresses parts of A03 (Injection) through Eloquent's parameterized queries, A07 (Authentication) through the authentication scaffolding in Breeze/Fortify which includes password hashing, session regeneration, and CSRF protection. However, A01 (Broken Access Control), A05 (Security Misconfiguration), A06 (Vulnerable Components), and A09 (Logging) require explicit developer attention — Laravel does not automatically authorize resource access or set production-safe configuration defaults.

How do I test for A01 Broken Access Control in Laravel?

Write a feature test that authenticates as user A, then attempts to access user B's resources: `$this->actingAs($userA)->getJson("/api/invoices/{$userBInvoice->id}")->assertStatus(403)`. If the test passes (returns 200 instead of 403), you have an IDOR vulnerability. Run this pattern for every resource endpoint. OWASP ZAP cannot automatically test IDOR because it requires understanding the application's data model — this must be tested with purpose-written feature tests.

How do I remediate A05 Security Misconfiguration in one deployment?

Set `APP_DEBUG=false` and `APP_ENV=production` in your production `.env`, point Nginx `root` to `public/`, add a security headers middleware to `app/Http/Kernel.php`, restrict Telescope access to specific emails in `config/telescope.php`, and run `php artisan config:cache` to apply changes. Verify with: `curl -s https://yourapp.com/.env | head -1` (empty/403), trigger a 404 and verify no stack trace appears, and check `curl -sI https://yourapp.com` for security headers.

Related Terms

Related Articles

Monitor Your Laravel Application's Security

StackShield continuously checks your Laravel application from the outside, catching security issues before attackers find them.

Start Free Trial