*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* \file htdocs/waf.inc.php
* \ingroup core
* \brief File with WAF controls
* WARNING: This file must have absolutely no dependency with Dolibarr code.
* It should be usable in any project.
*/
// To disable the WAF for GET and POST and PHP_SELF, uncomment this
//define('NOSCANPHPSELFFORINJECTION', 1);
//define('NOSCANGETFORINJECTION', 1);
//define('NOSCANPOSTFORINJECTION', 1 or 2);
/**
* Return array of Emojis. We can't move this function inside a common lib because we need it for security before loading any file.
*
* @return array> Array of Emojis in hexadecimal
* @see getArrayOfEmojiBis()
*/
function getArrayOfEmoji()
{
$arrayofcommonemoji = array(
'misc' => array('2600', '26FF'), // Miscellaneous Symbols
'ding' => array('2700', '27BF'), // Dingbats
'????' => array('9989', '9989'), // Variation Selectors
'vars' => array('FE00', 'FE0F'), // Variation Selectors
'pict' => array('1F300', '1F5FF'), // Miscellaneous Symbols and Pictographs
'emot' => array('1F600', '1F64F'), // Emoticons
'tran' => array('1F680', '1F6FF'), // Transport and Map Symbols
'flag' => array('1F1E0', '1F1FF'), // Flags (note: may be 1F1E6 instead of 1F1E0)
'supp' => array('1F900', '1F9FF'), // Supplemental Symbols and Pictographs
);
return $arrayofcommonemoji;
}
/**
* Return the real char for a numeric entities.
* WARNING: This function is required by testSqlAndScriptInject() and the GETPOST 'restricthtml'. Regex calling must be similar.
*
* @param array $matches Array with a decimal numeric entity like '/' into key 0, value without the like 'x2f;' into the key 1
* @return string New value
*/
function realCharForNumericEntities($matches)
{
$newstringnumentity = preg_replace('/;$/', '', $matches[1]);
//print ' $newstringnumentity='.$newstringnumentity;
if (preg_match('/^x/i', $newstringnumentity)) { // if numeric is hexadecimal
$newstringnumentity = hexdec(preg_replace('/^x/i', '', $newstringnumentity));
} else {
$newstringnumentity = (int) $newstringnumentity;
}
// The numeric values we don't want as entities because they encode ascii char, and why using html entities on ascii except for hacking ?
if (($newstringnumentity >= 47 && $newstringnumentity <= 59) || ($newstringnumentity >= 65 && $newstringnumentity <= 90) || ($newstringnumentity >= 97 && $newstringnumentity <= 122)) {
return chr((int) $newstringnumentity);
}
// The numeric values we want in UTF8 instead of entities because it is emoji
$arrayofemojis = getArrayOfEmoji();
foreach ($arrayofemojis as $valarray) {
if ($newstringnumentity >= hexdec($valarray[0]) && $newstringnumentity <= hexdec($valarray[1])) {
// This is a known emoji
return html_entity_decode($matches[0], ENT_COMPAT | ENT_HTML5, 'UTF-8');
}
}
return ''.$matches[1]; // Value will be unchanged because regex was /( )/
}
/**
* Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
* Warning: Such a protection can't be enough. It is not reliable as it will always be possible to bypass this. Good protection can
* only be guaranteed by escaping data during output.
*
* @param string $val Brute value found into $_GET, $_POST or PHP_SELF
* @param int<0, 3> $type 0=POST, 1=GET, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
* @return int >0 if there is an injection, 0 if none
*/
function testSqlAndScriptInject($val, $type)
{
// Decode string first because a lot of things are obfuscated by encoding or multiple encoding.
// So