Sabuj Kundu 18th Aug 2025

Including a CSRF (Cross-Site Request Forgery) token in a GET URL in Laravel (or any web application) is generally considered a security issue for several reasons. Below, I’ll explain why this is problematic and provide reasoning based on web security best practices.

Why Including a CSRF Token in a GET URL is a Security Issue

  1. Exposure in Browser History and Logs:

    • GET requests, including their query parameters, are often logged in browser history, server logs, proxy logs, or other systems. If the CSRF token is included in the URL (e.g., example.com/action?csrf_token=xyz), it becomes visible in these logs, making it easier for an attacker to obtain the token.
    • Unlike POST requests, which typically send data in the request body (not logged by default), GET request URLs are more exposed.
  2. Referrer Header Leakage:

    • When a user navigates to another website or a third-party resource (e.g., clicking a link or loading an image), the browser may include the full URL, including the CSRF token, in the HTTP Referer header. This could inadvertently leak the token to external sites, increasing the risk of it being intercepted by malicious actors.
  3. Bookmarking and Sharing:

    • GET URLs can be bookmarked or shared (e.g., via email, chat, or social media). If the CSRF token is part of the URL, it could be accidentally shared with others or stored in an insecure location, allowing unauthorized access to perform actions on behalf of the user.
  4. CSRF Tokens Are Not Meant for GET Requests:

    • CSRF tokens are designed to protect state-changing operations (e.g., POST, PUT, DELETE requests) that modify server-side data. GET requests, by convention (per HTTP standards), should be idempotent and not cause side effects. Including a CSRF token in a GET request suggests a design flaw, as GET requests should not require CSRF protection in the first place.
  5. Increased Attack Surface:

    • Exposing the CSRF token in the URL makes it easier for attackers to attempt token theft through techniques like XSS (Cross-Site Scripting) or social engineering. While XSS can compromise tokens in other ways, including them in URLs simplifies the process.
  6. Token Reusability:

    • CSRF tokens are typically single-use or time-limited to prevent replay attacks. If a token is exposed in a GET URL and logged or shared, an attacker might attempt to reuse it before it expires, depending on how the application handles token validation.

Laravel-Specific Considerations

In Laravel, CSRF protection is implemented using the VerifyCsrfToken middleware, which automatically checks for a valid CSRF token in non-GET requests (e.g., POST, PUT, DELETE). Laravel does not expect or require CSRF tokens in GET requests because:

  • GET Requests Are Excluded from CSRF Protection: By default, Laravel’s CSRF middleware does not apply to GET, HEAD, or OPTIONS requests, as these are considered safe methods that should not modify server state.
  • Token Handling: Laravel’s CSRF tokens are typically included in forms as hidden input fields (e.g., {{ csrf_field() }}) or sent via headers (e.g., X-CSRF-TOKEN for AJAX requests). Placing the token in a GET URL deviates from this standard and secure practice.

If you’re considering adding a CSRF token to a GET URL to “protect” a GET request, it’s a sign that the request might be performing a state-changing action (e.g., deleting a resource or updating data). In this case, you should redesign the application to use a POST, PUT, or DELETE request instead, as per RESTful conventions.

Best Practices to Avoid Security Issues

  1. Use POST for State-Changing Actions:

    • Any action that modifies server state (e.g., creating, updating, or deleting resources) should use POST, PUT, or DELETE requests, not GET. Include the CSRF token in the request body (e.g., via a hidden form field) or as an HTTP header.
  2. Follow Laravel’s CSRF Protection:

    • Use Laravel’s built-in CSRF protection by including {{ csrf_field() }} in your forms or the X-CSRF-TOKEN header in AJAX requests. Laravel handles token generation and validation securely.
  3. Avoid Sensitive Data in URLs:

    • Never include sensitive information, such as CSRF tokens, session IDs, or other credentials, in GET URLs. Use request bodies or headers instead.
  4. Secure Referrer Policy:

    • Configure a strict Referrer-Policy header (e.g., strict-origin or no-referrer) to reduce the risk of leaking sensitive data via the Referer header.
  5. Use HTTPS:

    • Ensure your application uses HTTPS to encrypt all requests, reducing the risk of token interception in transit. However, this does not mitigate the risks of logging or sharing URLs.
  6. Validate Requests Properly:

    • Ensure that your application enforces proper CSRF token validation and follows HTTP method conventions (e.g., GET for retrieving data, POST for creating/updating).

Example of Proper CSRF Handling in Laravel

Instead of using a GET URL like example.com/delete/123?csrf_token=xyz, use a POST request:

<form method="POST" action="/delete/123">
    @csrf
    <button type="submit">Delete</button>
</form>

This generates a hidden input field with the CSRF token, which Laravel’s middleware will validate automatically.

For AJAX requests, include the token in the header:

$.ajax({
    url: '/delete/123',
    type: 'POST',
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    success: function(response) {
        console.log('Success');
    }
});

With a meta tag in your HTML:

<meta name="csrf-token" content="{{ csrf_token() }}">

Conclusion

Including a CSRF token in a GET URL in Laravel is a security issue due to the risks of exposure, leakage, and misuse. It also indicates a potential design flaw, as GET requests should not require CSRF protection. Instead, use POST, PUT, or DELETE requests for state-changing actions, leverage Laravel’s built-in CSRF protection, and avoid including sensitive data in URLs. If you need further guidance on securing a specific use case in Laravel, feel free to provide more details!