php.lang.security.injection.echoed-request.echoed-request

profile photo of returntocorpreturntocorp
Author
unknown
Download Count*

Echoing user input risks cross-site scripting vulnerability. You should use htmlentities() when showing data to users.

Run Locally

Run in CI

Defintion

rules:
  - id: echoed-request
    mode: taint
    message: "`Echo`ing user input risks cross-site scripting vulnerability. You
      should use `htmlentities()` when showing data to users."
    languages:
      - php
    severity: ERROR
    pattern-sources:
      - pattern: $_REQUEST
      - pattern: $_GET
      - pattern: $_POST
    pattern-sinks:
      - pattern: echo ...;
    pattern-sanitizers:
      - pattern: isset(...)
      - pattern: empty(...)
      - pattern: $X = $ANYFUNC(...);
      - patterns:
          - pattern-inside: echo <... $ANYFUNC(...) ...>;
          - pattern: $ANYFUNC(...)
    metadata:
      technology:
        - php
      cwe:
        - "CWE-79: Improper Neutralization of Input During Web Page Generation
          ('Cross-site Scripting')"
      owasp:
        - A07:2017 - Cross-Site Scripting (XSS)
        - A03:2021 - Injection
      category: security
      references:
        - https://www.php.net/manual/en/function.htmlentities.php
        - https://www.php.net/manual/en/reserved.variables.request.php
        - https://www.php.net/manual/en/reserved.variables.post.php
        - https://www.php.net/manual/en/reserved.variables.get.php
        - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cross-Site-Scripting (XSS)

Examples

echoed-request.php

<?php

function doSmth() {
    $name = $_REQUEST['name'];
    // ruleid: echoed-request
    echo "Hello :".$name;
}

function doSmth2() {
    // ruleid: echoed-request
    echo "Hello ".$_POST['name']." !";
}

function doSmth3() {
    $name = $_GET['name'];
    if (str_contains($name, 'foobar')) {
        // ruleid: echoed-request
        echo "Hello :".$name;
    }
}

function doSmth4() {
    // ruleid: echoed-request
    echo "Hello ".htmlentities($_POST['name'])." !".$_POST['lastname'];
}


function doOK1() {
    // ok: echoed-request
    echo "Hello ".htmlentities($_POST['name'])." !";
}

function doOK2() {
    $input = $_GET['name'];
    // ok: echoed-request
    echo "Hello ".htmlspecialchars($input)." !";
}

function doOK3() {
    $name = $_GET['name'];
    if (str_contains($name, 'foobar')) {
        $tpl = createSafeTemplate($name);
        // ok: echoed-request
        echo "Hello :".$tpl;
    }
}

function doOK4() {
    // ok: echoed-request
    echo "Hello ".isset($_POST['name'])." !";
}

function doOK5() {
    $safevar = empty($_GET['name']);
    // ok: echoed-request
    echo "Hello $safevar !";
}