1
0
mirror of https://github.com/monstra-cms/monstra.git synced 2025-07-07 14:52:45 +02:00
Files
php-monstra/engine/Security.php
2015-10-16 18:09:58 +03:00

240 lines
6.4 KiB
PHP

<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
/**
* Monstra
*
* @package Monstra
* @author Romanenko Sergey / Awilum <awilum@msn.com>
* @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.
*
* <code>
* $token = Security::token();
* </code>
*
* You can insert this token into your forms as a hidden field:
*
* <code>
* echo Form::hidden('csrf', Security::token());
* </code>
*
* 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.
*
* <code>
* if (Security::check($token)) {
* // Pass
* }
* </code>
*
* @param string $token token to check
* @return boolean
*/
public static function check($token)
{
return Security::token() === $token;
}
/**
* Encrypt password
*
* <code>
* $encrypt_password = Security::encryptPassword('password');
* </code>
*
* @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.
*
* <code>
* $safe_name = Security::safeName('hello world');
* </code>
*
* @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.
*
* <code>
* $url = Security::sanitizeURL('http://test.com');
* </code>
*
* @param string $url Url to sanitize
* @return string
*/
public static function sanitizeURL($url)
{
$url = trim($url);
$url = rawurldecode($url);
$url = str_replace(array('--', '&quot;', '!', '@', '#', '$', '%', '^', '*', '(', ')', '+', '{', '}', '|', ':', '"', '<', '>',
'[', ']', '\\', ';', "'", ',', '*', '+', '~', '`', 'laquo', 'raquo', ']>', '&#8216;', '&#8217;', '&#8220;', '&#8221;', '&#8211;', '&#8212;'),
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;
}
}