php.symfony.security.audit.symfony-non-literal-redirect.symfony-non-literal-redirect

profile photo of semgrepsemgrep
Author
unknown
Download Count*

The redirect() method does not check its destination in any way. If you redirect to a URL provided by end-users, your application may be open to the unvalidated redirects security vulnerability. Consider using literal values or an allowlist to validate URLs.

Run Locally

Run in CI

Defintion

rules:
  - id: symfony-non-literal-redirect
    patterns:
      - pattern: $this->redirect(...)
      - pattern-not: $this->redirect("...")
      - pattern-not: $this->redirect()
    message: The `redirect()` method does not check its destination in any way. If
      you redirect to a URL provided by end-users, your application may be open
      to the unvalidated redirects security vulnerability. Consider using
      literal values or an allowlist to validate URLs.
    languages:
      - php
    metadata:
      references:
        - https://symfony.com/doc/current/controller.html#redirecting
        - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html
      owasp:
        - A01:2021 - Broken Access Control
      cwe:
        - "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')"
      category: security
      technology:
        - symfony
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Open Redirect
    severity: WARNING

Examples

symfony-non-literal-redirect.php

<?php
use Symfony\Component\HttpFoundation\RedirectResponse;

class WebAppController
{
    public function test1(): RedirectResponse
    {
        $foobar = $session->get('foobar');
        // ruleid: symfony-non-literal-redirect
        return $this->redirect($foobar);
    }

    public function test2(): RedirectResponse
    {
        $addr = $request->query->get('page', 1);
        // ruleid: symfony-non-literal-redirect
        return $this->redirect('https://'. $addr);
    }

    public function okTest1(): RedirectResponse
    {
        $foobar = $session->get('foobar');
        // ok: symfony-non-literal-redirect
        return $this->redirectToRoute($foobar);
    }

    public function okTest2(): RedirectResponse
    {
        // ok: symfony-non-literal-redirect
        return $this->redirect('http://symfony.com/doc');
    }

    public function okTest3(): RedirectResponse
    {
        // ok: symfony-non-literal-redirect
        return $this->redirect();
    }

}