diff --git a/src/Integrations/Divi/Design/VariableValue.php b/src/Integrations/Divi/Design/VariableValue.php index 9b0cfd6..38fd702 100644 --- a/src/Integrations/Divi/Design/VariableValue.php +++ b/src/Integrations/Divi/Design/VariableValue.php @@ -33,7 +33,8 @@ final class VariableValue private const URL = '/^(?:https?:\/\/[^\s<>"]+|\/(?![\/\\\\])[^\s<>"]*|mailto:[^\s<>"]+|tel:[^\s<>"]+)$/iD'; - private const WEB_URL = '/^https?:\/\/[^\s<>"]+$/iD'; + /** No ' ( ) ; { } \ either (audit L7): Divi writes an image value unescaped into url(...) inside the :root rule. */ + private const WEB_URL = '/^https?:\/\/[^\s<>"\'(){};\\\\]+$/iD'; /** @return string|null Null when $value is valid for $type, else a German message. */ public static function check(string $type, string $value): ?string diff --git a/tests/Unit/Integrations/Divi/Design/VariableValueTest.php b/tests/Unit/Integrations/Divi/Design/VariableValueTest.php index fbd03f1..d465c93 100644 --- a/tests/Unit/Integrations/Divi/Design/VariableValueTest.php +++ b/tests/Unit/Integrations/Divi/Design/VariableValueTest.php @@ -70,6 +70,10 @@ final class VariableValueTest extends TestCase 'images relative path' => ['images', '/wp-content/a.jpg'], 'images text' => ['images', 'Werkstattbild'], 'images javascript' => ['images', 'javascript:alert(1)'], + // Audit L7: Divi wraps the value as url(...) inside the :root rule, so these end the declaration. + 'images css injection' => ['images', 'https://x.test/a.png);}body{display:none}a{b:url(x'], + 'images quote' => ['images', "https://x.test/a'b.png"], + 'images backslash' => ['images', 'https://x.test/a\\b.png'], 'fonts empty' => ['fonts', ''], 'fonts semicolon' => ['fonts', 'Lato; color: red'], 'fonts quote' => ['fonts', "Lato'"],