[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |