diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 13358074514..da93b01fc26 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -778,12 +778,16 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = do { $oldstringtoclean = $out; + // Ckeditor use the numeric entitic for apostrophe so we force it to text entity (all other special chars are correctly + // encoded using text entities). This is a fix for CKeditor. + $out = preg_replace('/'/i', ''', $out); + // We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step. // No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are // using a non coventionnel way to be encoded, to not have them sanitized just after) $out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $out); - // Now we remove all remaining HTML entities staring with a number. We don't want such entities. + // Now we remove all remaining HTML entities starting with a number. We don't want such entities. $out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have javascript with an entities without the ; to hide the 'a' of 'javascript'. $out = dol_string_onlythesehtmltags($out, 0, 1, 1); diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 08d4ec88703..d75ec962020 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -321,6 +321,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase $test="XSS"; $result=testSqlAndScriptInject($test, 0); $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject lll'); + + $test="Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)"; + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject mmm'); } /** @@ -358,6 +362,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_POST["param12"]='aaa'; $_POST["param13"]='n n > < " XSS'; $_POST["param13b"]='n n > < " XSS'; + $_POST["param14"]="Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)"; //$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)'; //$_POST["param14"]='javascripT&javascript#x3a alert(1)'; @@ -494,6 +499,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals('n n > < " XSS', $result, 'Test 13b that HTML entities are decoded with restricthtml, but only for common alpha chars'); + $result=GETPOST("param14", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)", $result, 'Test 14'); + // Special test for GETPOST of backtopage, backtolist or backtourl parameter $_POST["backtopage"]='//www.google.com';