* @link http://monstra.org * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ class Security { /** * Key name for token storage * * @var string */ protected static $token_name = 'security_token'; /** * Protected constructor since this is a static class. * * @access protected */ protected function __construct() { // Nothing here } /** * Generate and store a unique token which can be used to help prevent * [CSRF](http://wikipedia.org/wiki/Cross_Site_Request_Forgery) attacks. * * * $token = Security::token(); * * * You can insert this token into your forms as a hidden field: * * * echo Form::hidden('csrf', Security::token()); * * * This provides a basic, but effective, method of preventing CSRF attacks. * * @param boolean $new force a new token to be generated?. Default is false * @return string */ public static function token($new = false) { // Get the current token $token = Session::get(Security::$token_name); // Create a new unique token if ($new === true or ! $token) { // Generate a new unique token $token = sha1(uniqid(mt_rand(), true)); // Store the new token Session::set(Security::$token_name, $token); } // Return token return $token; } /** * Check that the given token matches the currently stored security token. * * * if (Security::check($token)) { * // Pass * } * * * @param string $token token to check * @return boolean */ public static function check($token) { return Security::token() === $token; } /** * Encrypt password * * * $encrypt_password = Security::encryptPassword('password'); * * * @param string $password Password to encrypt */ public static function encryptPassword($password) { return md5(md5(trim($password) . MONSTRA_PASSWORD_SALT)); } /** * Create safe name. Use to create safe username, filename, pagename. * * * $safe_name = Security::safeName('hello world'); * * * @param string $str String * @param mixed $delimiter String delimiter * @param boolean $lowercase String Lowercase * @return string */ public static function safeName($str, $delimiter = '-', $lowercase = false) { // Redefine vars $str = (string) $str; $delimiter = $delimiter; $lowercase = (bool) $lowercase; $delimiter = $delimiter; // Remove tags $str = filter_var($str, FILTER_SANITIZE_STRING); // Decode all entities to their simpler forms $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8'); // Reserved characters (RFC 3986) $reserved_characters = array( '/', '?', ':', '@', '#', '[', ']', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' ); // Remove reserved characters $str = str_replace($reserved_characters, ' ', $str); // Set locale to en_US.UTF8 setlocale(LC_ALL, 'en_US.UTF8'); // Translit ua,ru => latin $str = Text::translitIt($str); // Convert string $str = iconv('UTF-8', 'ASCII//TRANSLIT', $str); // Remove characters $str = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $str); if ($delimiter != null) { $str = preg_replace("/[\/_|+ -]+/", $delimiter, $str); $str = trim($str, $delimiter); } // Lowercase if ($lowercase === true) { $str = Text::lowercase($str); } // Return safe name return $str; } /** * Create safe url. * * * $url = Security::sanitizeURL('http://test.com'); * * * @param string $url Url to sanitize * @return string */ public static function sanitizeURL($url) { $url = trim($url); $url = rawurldecode($url); $url = str_replace(array('--', '"', '!', '@', '#', '$', '%', '^', '*', '(', ')', '+', '{', '}', '|', ':', '"', '<', '>', '[', ']', '\\', ';', "'", ',', '*', '+', '~', '`', 'laquo', 'raquo', ']>', '‘', '’', '“', '”', '–', '—'), array('-', '-', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''), $url); $url = str_replace('--', '-', $url); $url = rtrim($url, "-"); $url = str_replace('..', '', $url); $url = str_replace('//', '', $url); $url = preg_replace('/^\//', '', $url); $url = preg_replace('/^\./', '', $url); return $url; } /** * Sanitize URL to prevent XSS - Cross-site scripting */ public static function runSanitizeURL() { $_GET = array_map('Security::sanitizeURL', $_GET); } /** * That prevents null characters between ascii characters. * * @param string $str String */ public static function removeInvisibleCharacters($str) { // Redefine vars $str = (string) $str; // Thanks to ci for this tip :) $non_displayables = array('/%0[0-8bcef]/', '/%1[0-9a-f]/', '/[\x00-\x08]/', '/\x0b/', '/\x0c/', '/[\x0e-\x1f]/'); do { $cleaned = $str; $str = preg_replace($non_displayables, '', $str); } while ($cleaned != $str); // Return safe string return $str; } /** * Sanitize data to prevent XSS - Cross-site scripting * * @param string $str String */ public static function xssClean($str) { // Remove invisible characters $str = Security::removeInvisibleCharacters($str); // Convert html to plain text $str = Html::toText($str); // Return safe string return $str; } }