) auf die Platte geschrieben -> Webshell.
// Bewusst nicht auf "pearcmd" als Keyword eingeschraenkt, da sich das Angriffsziel (jede per
// Path Traversal erreichbare, includebare Datei) aendern kann -> generisch auf "../.." und "".
$mc_waf_pearLang = isset($_GET['lang']) && is_string($_GET['lang']) ? $_GET['lang'] : '';
$mc_waf_pearQs = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
if (
$mc_waf_pearLang !== ''
&& strpos($mc_waf_pearLang, '../..') !== false
&& (
strpos($mc_waf_pearQs, '') !== false
|| strpos(urldecode($mc_waf_pearQs), '') !== false
)
) {
file_put_contents("/tmp/mc-microwaf.log",
date('Y-m-d H:i:s')
. " - CVE-2026-87902: Blocked pearcmd LFI/RCE attempt"
. " from " . $_SERVER['REMOTE_ADDR']
. " (X-Forwarded-For: " . $mc_waf_xForwardedFor . ") "
. "to " . $_SERVER['REQUEST_URI']
. "\n", FILE_APPEND | LOCK_EX);
mc_waf_block('CVE-2026-87902');
}
//StyleSmuggler: https://sansec.io/research/stylesmuggler
// Portierung der nginx-/VCL-Regeln (accord_rce).
// 1. Block "/paypal/transparent/response/"
if (stripos($_SERVER['REQUEST_URI'], '/paypal/transparent/response/') !== false) {
mc_waf_block('StyleSmuggler', 'VCL');
}
// Layer 0/1: Query-String, routenunabhaengig.
// Keine Admin-Ausnahme wie in der VCL, weil der Admin-Frontname pro Installation
// individuell ist und sich nicht generisch erkennen laesst.
$mc_waf_ssQs = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
if ($mc_waf_ssQs !== '') {
// drei Paesse kollabieren bis zu 3-fach-Encoding, qs2 dient als Rest-%-Detektor fuer >=4x
$mc_waf_ssQs2 = urldecode(urldecode($mc_waf_ssQs));
$mc_waf_ssQs3 = urldecode($mc_waf_ssQs2);
// Layer 0: PHP-Open-Tag im QS (Stage-1A File-Plant)
if (strpos($mc_waf_ssQs3, '') !== false) {
mc_waf_block('StyleSmuggler-L0', 'VCL');
}
// Layer 1a: styles[] in jeder Encoding-Tiefe.
// $_GET-Key deckt einfaches Encoding ab, weil PHP vor dem Klammer-Parsing dekodiert.
if (
isset($_GET['styles'])
|| preg_match('@styles\s*\[@i', $mc_waf_ssQs3)
|| preg_match('@styles\s*%@i', $mc_waf_ssQs2)
) {
mc_waf_block('StyleSmuggler-L1a', 'VCL');
}
// Layer 1b: Template-Direktive in text-Parametern (text=, text[]=, text[0]=, ...)
// [\s+]* statt \s*, weil ein Leerzeichen im QS als '+' ankommt
if (
stripos($mc_waf_ssQs3, '{{') !== false
&& preg_match('@(^|[&;])text[^=&;]*=[^&;]*\{\{[\s+]*(block|widget|layout|config|template|store|trans|media|view|var|if|depend|inlinecss|css|customvar|for|protocol)\b@i', $mc_waf_ssQs3)
) {
mc_waf_block('StyleSmuggler-L1b', 'VCL');
}
}
// Layer 2: Request-Body
if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'PUT') {
$mc_waf_ssBody = $mc_waf_input;
if ($mc_waf_ssBody === '' && !empty($_POST)) {
// php://input ist bei multipart/form-data leer
$mc_waf_ssBody = http_build_query($_POST);
}
// ohne ^-Anker: faengt Store-Code-Praefixe, /index.php/... und Unterverzeichnis-Installationen
// zweite Alternative deckt JSON-Notation ab, auch mit escapten Quotes in verschachtelten Strings
if (
preg_match('@(^|/)(graphql|paypal|rest|sales|multishipping|newsletter)(/|\?|$)@i', $_SERVER['REQUEST_URI'])
&& preg_match('@styles\s*(\[|%5b)|\\\\?"styles\\\\?"\s*:\s*\[@i', $mc_waf_ssBody)
) {
mc_waf_block('StyleSmuggler-L2b', 'VCL');
}
// engere Routenliste als bei L2b: /rest, /sales und /newsletter fuehren im Backend
// legitim Direktiven im Body (CMS-API, Newsletter-Templates, Order-Comments)
if (
preg_match('@(^|/)(graphql|paypal|multishipping)(/|\?|$)@i', $_SERVER['REQUEST_URI'])
&& stripos($mc_waf_ssBody, '{{') !== false
&& preg_match('@\{\{[\s+]*(block|widget|layout|config|template|store|trans|media|view|var|if|depend|inlinecss|css|customvar|for|protocol)\b@i', $mc_waf_ssBody)
) {
mc_waf_block('StyleSmuggler-L2a', 'VCL');
}
}
An error occurred
An error occurred
What's the matter?
An error occurred while executing this script. Something does not work properly.
How can I fix the issue?
Open the current log file in the var/logs or app/logs directory and find the associated error message (usually the last one).
Tell me more, please
The script execution stopped, because something does not work properly. The actual error message is hidden by this notice for security reasons and can be found in the current log file (see above). If you do not understand the error message or do not know how to fix the problem, search the Contao FAQs or visit the Contao support page.