[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/laminas/laminas-diactoros/src/ -> HeaderSecurity.php (source)

   1  <?php
   2  
   3  /**
   4   * @see       https://github.com/laminas/laminas-diactoros for the canonical source repository
   5   * @copyright https://github.com/laminas/laminas-diactoros/blob/master/COPYRIGHT.md
   6   * @license   https://github.com/laminas/laminas-diactoros/blob/master/LICENSE.md New BSD License
   7   */
   8  
   9  declare(strict_types=1);
  10  
  11  namespace Laminas\Diactoros;
  12  
  13  use function get_class;
  14  use function gettype;
  15  use function in_array;
  16  use function is_numeric;
  17  use function is_object;
  18  use function is_string;
  19  use function ord;
  20  use function preg_match;
  21  use function sprintf;
  22  use function strlen;
  23  
  24  /**
  25   * Provide security tools around HTTP headers to prevent common injection vectors.
  26   *
  27   * Code is largely lifted from the Laminas\Http\Header\HeaderValue implementation in
  28   * Laminas, released with the copyright and license below.
  29   *
  30   * @copyright Copyright (c) 2005-2015 Laminas (https://www.zend.com)
  31   * @license   https://getlaminas.org/license/new-bsd New BSD License
  32   */
  33  final class HeaderSecurity
  34  {
  35      /**
  36       * Private constructor; non-instantiable.
  37       * @codeCoverageIgnore
  38       */
  39      private function __construct()
  40      {
  41      }
  42  
  43      /**
  44       * Filter a header value
  45       *
  46       * Ensures CRLF header injection vectors are filtered.
  47       *
  48       * Per RFC 7230, only VISIBLE ASCII characters, spaces, and horizontal
  49       * tabs are allowed in values; header continuations MUST consist of
  50       * a single CRLF sequence followed by a space or horizontal tab.
  51       *
  52       * This method filters any values not allowed from the string, and is
  53       * lossy.
  54       *
  55       * @see http://en.wikipedia.org/wiki/HTTP_response_splitting
  56       */
  57      public static function filter(string $value) : string
  58      {
  59          $value  = (string) $value;
  60          $length = strlen($value);
  61          $string = '';
  62          for ($i = 0; $i < $length; $i += 1) {
  63              $ascii = ord($value[$i]);
  64  
  65              // Detect continuation sequences
  66              if ($ascii === 13) {
  67                  $lf = ord($value[$i + 1]);
  68                  $ws = ord($value[$i + 2]);
  69                  if ($lf === 10 && in_array($ws, [9, 32], true)) {
  70                      $string .= $value[$i] . $value[$i + 1];
  71                      $i += 1;
  72                  }
  73  
  74                  continue;
  75              }
  76  
  77              // Non-visible, non-whitespace characters
  78              // 9 === horizontal tab
  79              // 32-126, 128-254 === visible
  80              // 127 === DEL
  81              // 255 === null byte
  82              if (($ascii < 32 && $ascii !== 9)
  83                  || $ascii === 127
  84                  || $ascii > 254
  85              ) {
  86                  continue;
  87              }
  88  
  89              $string .= $value[$i];
  90          }
  91  
  92          return $string;
  93      }
  94  
  95      /**
  96       * Validate a header value.
  97       *
  98       * Per RFC 7230, only VISIBLE ASCII characters, spaces, and horizontal
  99       * tabs are allowed in values; header continuations MUST consist of
 100       * a single CRLF sequence followed by a space or horizontal tab.
 101       *
 102       * @param string|int|float $value
 103       * @see http://en.wikipedia.org/wiki/HTTP_response_splitting
 104       */
 105      public static function isValid($value) : bool
 106      {
 107          $value  = (string) $value;
 108  
 109          // Look for:
 110          // \n not preceded by \r, OR
 111          // \r not followed by \n, OR
 112          // \r\n not followed by space or horizontal tab; these are all CRLF attacks
 113          if (preg_match("#(?:(?:(?<!\r)\n)|(?:\r(?!\n))|(?:\r\n(?![ \t])))#", $value)) {
 114              return false;
 115          }
 116  
 117          // Non-visible, non-whitespace characters
 118          // 9 === horizontal tab
 119          // 10 === line feed
 120          // 13 === carriage return
 121          // 32-126, 128-254 === visible
 122          // 127 === DEL (disallowed)
 123          // 255 === null byte (disallowed)
 124          if (preg_match('/[^\x09\x0a\x0d\x20-\x7E\x80-\xFE]/', $value)) {
 125              return false;
 126          }
 127  
 128          return true;
 129      }
 130  
 131      /**
 132       * Assert a header value is valid.
 133       *
 134       * @param mixed $value Value to be tested. This method asserts it is a string or number.
 135       * @throws Exception\InvalidArgumentException for invalid values
 136       */
 137      public static function assertValid($value)
 138      {
 139          if (! is_string($value) && ! is_numeric($value)) {
 140              throw new Exception\InvalidArgumentException(sprintf(
 141                  'Invalid header value type; must be a string or numeric; received %s',
 142                  (is_object($value) ? get_class($value) : gettype($value))
 143              ));
 144          }
 145          if (! self::isValid($value)) {
 146              throw new Exception\InvalidArgumentException(sprintf(
 147                  '"%s" is not valid header value',
 148                  $value
 149              ));
 150          }
 151      }
 152  
 153      /**
 154       * Assert whether or not a header name is valid.
 155       *
 156       * @see http://tools.ietf.org/html/rfc7230#section-3.2
 157       * @param mixed $name
 158       * @throws Exception\InvalidArgumentException
 159       */
 160      public static function assertValidName($name)
 161      {
 162          if (! is_string($name)) {
 163              throw new Exception\InvalidArgumentException(sprintf(
 164                  'Invalid header name type; expected string; received %s',
 165                  (is_object($name) ? get_class($name) : gettype($name))
 166              ));
 167          }
 168          if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) {
 169              throw new Exception\InvalidArgumentException(sprintf(
 170                  '"%s" is not valid header name',
 171                  $name
 172              ));
 173          }
 174      }
 175  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer