old
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

427 lines
11 KiB

<?php
/* ----------
* ! NoCopyright, NoCopyleft for a free world !
* ! PasDeCopyright, PasDeCopyleft pour un monde libre !
* ----------
* Copyright (C) [2014] [Kara.Adrien] <adrien@iglou.eu>
* ----------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* ----------
* http://www.apache.org/licenses/LICENSE-2.0
* ----------
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------
* Beta 0.7.5 - 21 September 2016
* ----------
* LittleSecureLib, est une petite librairie php de securisation general.
* Elle traite les failles d'includes, XSS, InjectSQL, VolDeSession et CSRF.
* Un support de HASH et chiffrement est aussi présent.
---------- */
/* ---------- Configuration ---------- */
// Debug mode
$debug = false; // true | false
// IE Edge, désactiver le mode de "compatibilité" pour Internet Explorer
$ieEdge = true;
// key pour ID Unique du lien de session
//define('SESSION_SINGLE_KEY', 'M@ cléf un!qu€ Et pr|vè');
// key de chiffrement
//define('ENCRYPTION_KEY', 'ma clée aléatoire ...');
// Hash à utiliser
//define('BADHASH', 'sha1'); // Simple
//define('CRYPTHASH', 'haval256,3'); // Pour le chiffrement | strlen = 64 !
//define('BIGHASH', 'whirlpool'); // Complexe
// Le grain de sel du HASH
//define('SEED_A', 'faa');
//define('SEED_B', 'foo');
//Exemple de sel en sha1, conseil d'utiliser une info user inaliénable non privé !
//define('SALT', '78312c77fadb9f35dd5fd7b343a3925ac4cfdaf0');
/* ---------- Dépendances/Debug ---------- */
if ($debug) {
error_reporting(-1);
ini_set('display_errors', 'On');
if (!extension_loaded('openssl')) {
exit('DIE : The openssl lib is not loaded.');
}
if (!extension_loaded('mcrypt')) {
exit('DIE : The mcrypt +2.4.x lib is not loaded.');
}
if (!extension_loaded('iconv')) {
exit('DIE : The iconv lib is not loaded.');
}
if (!in_array(BADHASH, hash_algos())) {
exit('DIE : '.BADHASH.' is not available, check your libs.');
}
if (!in_array(CRYPTHASH, hash_algos())) {
exit('DIE : '.CRYPTHASH.' is not available, check your libs.');
}
if (!in_array(BIGHASH, hash_algos())) {
exit('DIE : '.BIGHASH.' is not available, check your libs.');
}
}
if ($ieEdge) {
header('x-ua-compatible: IE=Edge,chrome=1');
}
/* ---------- Filtres ---------- */
// Parseur de sécurisation
function securityParser($arg, $noUtf8 = false, $type = null)
{
if ((array) $arg === $arg) {
foreach ($arg as $key => &$value) {
charCleaner($arg[$key], $type);
if (!$noUtf8) {
utf8Encode($arg[$key]);
}
}
} else {
charCleaner($arg, $type);
if (!$noUtf8) {
utf8Encode($arg);
}
}
return ($arg);
}
/* -------- Encodage -------- */
// Verification de l'UTF8
function utf8Encode(&$arg)
{
$inCharset = mb_detect_encoding($arg, 'auto');
if (('UTF-8' !== $inCharset) && ('ASCII' !== $inCharset)) {
$mbAllow = mb_list_encodings();
if ('ISO-8859-1' === $inCharset) {
$arg = utf8_encode($arg);
} elseif (in_array($inCharset, $mbAllow)) {
error_log($arg.' ERROR_01');
$arg = mb_convert_encoding($arg, 'UTF-8', $inCharset);
} else {
$arg = iconv($inCharset, 'UTF-8//TRANSLIT', $arg);
}
}
}
/* -------- Clean -------- */
// Filtres de nettoyage - Utilisez $type True, pour un encodage plus soft
function charCleaner(&$arg, &$type)
{
$arg = trim($arg);
if ($type) {
$arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', true);
} else {
$arg = filter_var($arg, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
}
}
// Netoyage db - Pour Oracle utilisez les 'Procédures stockée' !
function dbCleaner($arg, $type = null)
{
$arg = trim($arg);
switch ($type) {
case 'mysql':
$arg = htmlspecialchars($arg, ENT_QUOTES);
break;
case 'sqlite':
$arg = SQLite3::escapeString($arg);
break;
case 'pg':
$arg = pg_escape_string($arg);
break;
case 'xml':
$arg = strtr($arg, array('\\' => '\\\\', "'" => "\'", '"' => '\"', "{" => '\{', "}" => '\}', "<" => '\<', ">" => '\>'));
break;
case 'json':
$arg = strtr($arg, array('\\' => '\\\\', '"' => '\"'));
break;
default:
exit('DIE : LittleSecureLib --> dbCleaner | Bad type.');
break;
}
return ($arg);
}
// Filtre pour shell
function shellCleaner($arg, $char = false)
{
if ($char) {
$arg = escapeshellcmd($arg);
} else {
$arg = escapeshellarg($arg);
}
return ($arg);
}
/* -------- Global -------- */
// Filtre pour fichier
function fileExist($arg, $path)
{
$arg = securityParser($arg);
if ('/' !== strstr($path, '/')) {
$path = $path.'/';
}
if (strstr($arg, "..")) {
$arg = false;
} else {
if (is_link($path.$arg) or !file_exists($path.$arg)) {
$arg = false;
}
}
return ($arg);
}
// Verif email/télèphone/url/ipv4/ipv6
function multiCheck($arg, $type = null)
{
switch ($type) {
case 'email':
$arg = filter_var($arg, FILTER_SANITIZE_EMAIL);
if (!filter_var($arg, FILTER_VALIDATE_EMAIL)) {
$arg = false;
}
break;
case 'phone':
$arg = filter_var($arg, FILTER_SANITIZE_NUMBER_INT);
if (!preg_match("#^\+?[0-9\./, -]{6,20}$#", $arg)) {
$arg = false;
}
break;
case 'url':
$arg = filter_var($arg, FILTER_SANITIZE_URL);
if (!filter_var($arg, FILTER_VALIDATE_URL)) {
$arg = false;
}
break;
case 'ip':
if (!filter_var($arg, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE)) {
$arg = false;
}
break;
default:
exit('DIE : LittleSecureLib --> multiCheck | Bad type.');
break;
}
return ($arg);
}
/* ---------- Sessions ---------- */
/* *
* Start safe session
*
* Check session is not started
* Https cookie
* regen id and fingerprint
*
* @return void
* */
function sessionStart($secure = null, $onlyHttp = true, $target = '/')
{
if (session_is_start())
return;
session_set_cookie_params(0, $target, null, $secure, $onlyHttp);
session_start();
sessionRegenId();
sessionFingerprint();
}
/* *
* Check if session is started
*
* @return boolean
* */
function sessionIsStart()
{
if (PHP_SESSION_ACTIVE === session_status())
return true;
return false;
}
/* *
* Regenerate ID
*
* @return void
* */
function sessionRegenId()
{
if (!isset($_SESSION['idTime']) || empty($_SESSION['idTime']))
$_SESSION['idTime'] = time();
if (time() >= $_SESSION['idTime'] + 600) {
//New ID all 10mn
session_regenerate_id(true);
$_SESSION['idTime'] = time();
}
}
/* *
* Destroy session
*
* Check if session exist befor erase
*
* @return void
* */
function sessionDestroy()
{
sessionStart();
$_SESSION = array();
session_destroy();
session_write_close();
if (isset($_COOKIE['PHPSESSID'])) {
unset($_COOKIE['PHPSESSID']);
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
}
/* *
* Make a fingerprint
*
* "Avoid" session hijacking
*
* @return void
* */
function sessionFingerprint()
{
$userInfo = SESSION_SINGLE_KEY;
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
$userInfo .= $_SERVER['HTTP_ACCEPT_ENCODING'];
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$userInfo .= ','.$_SERVER['HTTP_ACCEPT_LANGUAGE'];
if (isset($_SERVER['HTTP_USER_AGENT']))
$userInfo .= ','.$_SERVER['HTTP_USER_AGENT'];
if (isset($_SERVER['REMOTE_ADDR']))
$userInfo .= ','.$_SERVER['REMOTE_ADDR'];
$userInfo = filter_var($userInfo, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if (isset($_SESSION['userInfo'])) {
if ($_SESSION['userInfo'] !== $userInfo) {
error_log('|- FINGERPRINT ERROR -> || VALID: '.$_SESSION['userInfo'].' || REJECTED: '.$userInfo);
sessionDestroy();
return false;
}
} else {
$_SESSION['userInfo'] = $userInfo;
}
return true;
}
/* ---------- CSRF ---------- */
// Token
function token($arg = null)
{
if ($arg) {
if ((isset($_SESSION['token'])) && ($_SESSION['token'] === $arg)) {
$arg = true;
} else {
$arg = false;
}
$_SESSION['token'] = '';
} else {
$arg = bin2hex(openssl_random_pseudo_bytes(32));
$_SESSION['token'] = $arg;
}
return ($arg);
}
// Variable aléatoire
function randVar($arg)
{
$rand = bin2hex(openssl_random_pseudo_bytes(8));
$_SESSION[$arg] = $rand;
return ($rand);
}
/* ---------- chiffrement et hash ---------- */
function leBoucher($arg, $type = null)
{
if ('BADHASH' === $type) {
$arg = hash(BADHASH, $arg, false);
} elseif ('CRYPTHASH' === $type) {
$arg = hash(CRYPTHASH, $arg, true);
} else {
//BIGHASH est utilisé par défault
$lenMax = strlen(SALT);
$lenMid = $lenMax / 2;
$arg = SEED_A.$arg.SEED_B;
$arg = hash(BIGHASH, $arg, false);
$arg = substr(SALT, 0, $lenMid).$arg.substr(SALT, $lenMid, $lenMax);
}
return ($arg);
}
function encrypt($arg, $action)
{
$key = leBoucher(ENCRYPTION_KEY, 'CRYPTHASH');
$ivSi = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB);
if ('cry' === $action) {
$iv = mcrypt_create_iv($ivSi, MCRYPT_RAND);
$arg = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $arg, MCRYPT_MODE_CFB, $iv);
$arg = $iv.$arg;
$arg = base64_encode($arg);
} elseif ('dec' === $action) {
$arg = base64_decode($arg);
$ivDe = substr($arg, 0, $ivSi);
$arg = substr($arg, $ivSi);
$arg = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $arg, MCRYPT_MODE_CFB, $ivDe);
} else {
exit('DIE : LittleSecureLib --> encrypt | Mauvaise action.');
}
return ($arg);
}