AloFramework documentation
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo

Namespaces

  • Alo
    • Cache
    • CLI
    • Controller
    • Db
      • Query
    • Exception
    • FileSystem
    • Session
    • Traversables
    • Validators
    • Windows
  • Controller
  • None
  • PHP

Classes

  • Cookie
  • Cron
  • Curl
  • Email
  • Format
  • Handler
  • Locale
  • Profiler
  • Security
  • SFTP
  1 <?php
  2 
  3     namespace Alo;
  4 
  5     use Alo\Session\AbstractSession;
  6 
  7     if (!defined('GEN_START')) {
  8         http_response_code(404);
  9     } else {
 10 
 11         /**
 12          * Handles hashing, tokens, randomising and other security operations
 13          *
 14          * @author Art <a.molcanovas@gmail.com>
 15          */
 16         abstract class Security {
 17 
 18             /**
 19              * Default hash algorithm to use
 20              * @var string
 21              */
 22             const DEFAULT_HASH = 'sha256';
 23 
 24             /**
 25              * Defines the ascii charset subset as "the entire set"
 26              *
 27              * @var int
 28              */
 29             const ASCII_ALL = 0;
 30 
 31             /**
 32              * Defines the ascii charset subset as "only alphanumeric"
 33              *
 34              * @var int
 35              */
 36             const ASCII_ALPHANUM = 1;
 37 
 38             /**
 39              * Defines the ascii charset subset as "only non-alphanumeric"
 40              *
 41              * @var int
 42              */
 43             const ASCII_NONALPHANUM = 2;
 44 
 45             /**
 46              * Array of ASCII alphanumeric characters
 47              *
 48              * @var array
 49              */
 50             protected static $asciiAlphanum = ['a',
 51                                                'b',
 52                                                'c',
 53                                                'd',
 54                                                'e',
 55                                                'f',
 56                                                'g',
 57                                                'h',
 58                                                'i',
 59                                                'j',
 60                                                'k',
 61                                                'l',
 62                                                'm',
 63                                                'n',
 64                                                'o',
 65                                                'p',
 66                                                'q',
 67                                                'r',
 68                                                's',
 69                                                't',
 70                                                'u',
 71                                                'v',
 72                                                'w',
 73                                                'x',
 74                                                'y',
 75                                                'z',
 76                                                'A',
 77                                                'B',
 78                                                'C',
 79                                                'D',
 80                                                'E',
 81                                                'F',
 82                                                'G',
 83                                                'H',
 84                                                'I',
 85                                                'J',
 86                                                'K',
 87                                                'L',
 88                                                'M',
 89                                                'N',
 90                                                'O',
 91                                                'P',
 92                                                'Q',
 93                                                'R',
 94                                                'S',
 95                                                'T',
 96                                                'U',
 97                                                'V',
 98                                                'W',
 99                                                'X',
100                                                'Y',
101                                                'Z',
102                                                0,
103                                                1,
104                                                2,
105                                                3,
106                                                4,
107                                                5,
108                                                6,
109                                                7,
110                                                8,
111                                                9];
112             /**
113              * The rest of the ASCII charset
114              *
115              * @var array
116              */
117             protected static $asciiRest = [' ',
118                                            '!',
119                                            '"',
120                                            '#',
121                                            '$',
122                                            '%',
123                                            '\'',
124                                            '(',
125                                            ')',
126                                            '*',
127                                            '+',
128                                            ',',
129                                            '.',
130                                            '/',
131                                            ':',
132                                            ';',
133                                            '<',
134                                            '=',
135                                            '>',
136                                            '?',
137                                            '@',
138                                            '[',
139                                            '\\',
140                                            ']',
141                                            '^',
142                                            '_',
143                                            '`',
144                                            '-',
145                                            '{',
146                                            '|',
147                                            '}',
148                                            '~'];
149 
150             /**
151              * Escapes a string or array (recursively) from XSS attacks
152              *
153              * @author Art <a.molcanovas@gmail.com>
154              *
155              * @param string|array $item The item to be escaped
156              *
157              * @return string|array
158              */
159             static function unXss($item) {
160                 if (is_array($item)) {
161                     foreach ($item as &$v) {
162                         $v = self::unXss($item);
163                     }
164 
165                     return $item;
166                 } else {
167                     return is_scalar($item) ? htmlspecialchars($item, ENT_QUOTES | ENT_HTML5, 'UTF-8', false) : null;
168                 }
169             }
170 
171             /**
172              * Generates a token and sets it in session
173              *
174              * @author Art <a.molcanovas@gmail.com>
175              *
176              * @param string $tokenName The token name
177              * @param string $hash      Which hash algorithm to use
178              *
179              * @return string The generated token
180              */
181             static function tokenGet($tokenName, $hash = self::DEFAULT_HASH) {
182                 $token = self::getUniqid($hash, 'token_' . $tokenName);
183 
184                 if (!AbstractSession::isActive()) {
185                     phpWarning('A session is not currently active - tokens are unusable.');
186                 } else {
187                     $_SESSION[$tokenName] = $token;
188                 }
189 
190                 return $token;
191             }
192 
193             /**
194              * Generates a unique identifier
195              *
196              * @author Art <a.molcanovas@gmail.com>
197              *
198              * @param string     $hash    Hash algorithm
199              * @param string|int $prefix  Prefix for the identifier
200              * @param int        $entropy Number of pseudo bytes used in entropy
201              *
202              * @return string
203              */
204             static function getUniqid($hash = self::DEFAULT_HASH, $prefix = null, $entropy = 200) {
205                 $str = mt_rand(PHP_INT_MIN, PHP_INT_MAX) .
206                        json_encode([$_COOKIE,
207                                     $_REQUEST,
208                                     $_FILES,
209                                     $_ENV,
210                                     $_GET,
211                                     $_POST,
212                                     $_SERVER],
213                                    true) .
214                        uniqid() .
215                        $prefix .
216                        self::asciiRand($entropy);
217 
218                 if (function_exists('\openssl_random_pseudo_bytes')) {
219                     $str .= \openssl_random_pseudo_bytes($entropy);
220                 } else {
221                     phpWarning('The openssl extension is not enabled, therefore the unique ID is not cryptographically secure.');
222                 }
223 
224                 return hash($hash, $str);
225             }
226 
227             /**
228              * Generates a string of random ASCII characters
229              *
230              * @author Art <a.molcanovas@gmail.com>
231              *
232              * @param int $length The length of the string
233              * @param int $subset Which subset to use - see class' ASCII_* constants
234              *
235              * @return string
236              */
237             static function asciiRand($length, $subset = self::ASCII_ALL) {
238                 switch ($subset) {
239                     case self::ASCII_ALPHANUM:
240                         $subset = self::$asciiAlphanum;
241                         break;
242                     case self::ASCII_NONALPHANUM:
243                         $subset = self::$asciiRest;
244                         break;
245                     default:
246                         $subset = array_merge(self::$asciiAlphanum, self::$asciiRest);
247                 }
248 
249                 $count = count($subset) - 1;
250 
251                 $r = '';
252 
253                 for ($i = 0; $i < $length; $i++) {
254                     $r .= $subset[mt_rand(0, $count)];
255                 }
256 
257                 return $r;
258             }
259 
260             /**
261              * Checks if a token is valid
262              *
263              * @author Art <a.molcanovas@gmail.com>
264              *
265              * @param string $tokenName The token name
266              * @param array  $dataArray Which data array to check. Defaults to $_POST
267              *
268              * @return bool TRUE if the token is valid, false if not
269              */
270             static function tokenValid($tokenName, array $dataArray = null) {
271                 if (!AbstractSession::isActive()) {
272                     phpWarning('Session isn\'t initialised - tokens unavailable.');
273 
274                     return false;
275                 } else {
276                     if ($dataArray === null) {
277                         $dataArray = $_POST;
278                     }
279 
280                     return $_SESSION[$tokenName] &&
281                            \get($dataArray[$tokenName]) &&
282                            $_SESSION[$tokenName] == $dataArray[$tokenName];
283                 }
284             }
285 
286             /**
287              * Removes a token from session data
288              *
289              * @author Art <a.molcanovas@gmail.com>
290              *
291              * @param string $tokenName The token's name
292              *
293              * @return bool TRUE if the session handler was loaded, false if not
294              */
295             static function tokenRemove($tokenName) {
296                 if (AbstractSession::isActive()) {
297                     unset($_SESSION[$tokenName]);
298 
299                     return true;
300                 } else {
301                     phpWarning('Session not initialised - tokens unavailable.');
302 
303                     return false;
304                 }
305             }
306 
307             /**
308              * Returns an unhashed browser/IP fingerprint
309              *
310              * @author Art <a.molcanovas@gmail.com>
311              * @return string
312              */
313             static function getFingerprint() {
314                 return '$%c0hYlc$kn!rZF' .
315                        \get($_SERVER['HTTP_USER_AGENT']) .
316                        \get($_SERVER['HTTP_DNT']) .
317                        '^#J!kCRh&H4CKav' .
318                        \get($_SERVER['HTTP_ACCEPT_LANGUAGE']) .
319                        'h0&ThYYxk4YOD!g' .
320                        \get($_SERVER['REMOTE_ADDR']);
321             }
322 
323         }
324     }
325 
AloFramework documentation API documentation generated byApiGen 2.8.0