Skip to content
This repository was archived by the owner on Nov 21, 2025. It is now read-only.

Commit bfc4a3f

Browse files
committed
CSRF-Token nur in Formulare außerhalb des TinyMCE-Editors integrieren
Fix: Bisher wurde das CSRF-Token z. B. beim Bearbeiten eines Artikels an enthaltene Formulare angehängt. Je Speichervorgang kam dabei immer ein weiteres Feld dazu.
1 parent 463f8c5 commit bfc4a3f

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

interna/all_inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,6 @@
347347
}
348348
$pluginintegrator->output_filter_admin();
349349

350-
$output = str_ireplace('</form>','<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'"/> </form>',$output);
350+
$output = $diverse->injectCsrfTokenIntoForms((string)$output);
351351

352352
print $output;

lib/classes/diverse_class.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,38 @@ public function validateVatId(string $vatId): bool
16011601

16021602
return (bool)preg_match($pattern, $subject);
16031603
}
1604+
1605+
/**
1606+
* @param string $html
1607+
* @return string
1608+
*/
1609+
public function injectCsrfTokenIntoForms(string $html): string
1610+
{
1611+
// Textareas vorübergehend verschleiern, damit das CSRF-Token nicht in TinyMCE-Instanzen inkludiert wird
1612+
$textareas = [];
1613+
$html = preg_replace_callback(
1614+
'~<(?<tag>(?(R)[^\s/>]+|textarea(?=[\s/>])))(?>[^>]*)(?<sc>(?<=/))?>(?<fot>(?>[^<]*)(?(?=<!--)(?>.+?-->)(?>(?&fot)*)))(?(sc)|(?R)*</\g{tag}>(?(R)(?>(?&fot)*)|))~i',
1615+
function ($match) use (&$textareas) {
1616+
$id = uniqid('textarea__');
1617+
$textareas[] = [
1618+
'id' => $id,
1619+
'html' => $match[0],
1620+
];
1621+
return $id;
1622+
},
1623+
$html
1624+
) ?? $html;
1625+
1626+
// CSRF-Token integrieren
1627+
$html = str_ireplace('</form>', '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'"/></form>', $html);
1628+
1629+
// Textareas wiederherstellen
1630+
$html = array_reduce($textareas, function ($html, $textarea) {
1631+
return str_replace($textarea['id'], $textarea['html'], $html);
1632+
}, $html);
1633+
1634+
return $html;
1635+
}
16041636
}
16051637

16061638
$diverse = new diverse_class();

lib/classes/variables_class.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ function __construct()
8888
}
8989
}
9090

91+
if (is_array($_POST)) {
92+
self::removeCsrfTokenFromUserInput($_POST);
93+
}
9194

9295
/*
9396
* Alle $_POST durchloopen die reinkommen
@@ -130,6 +133,26 @@ function __construct()
130133
$this->do_check();
131134
}
132135

136+
/**
137+
* Diese Methode entfernt input[type="hidden"][name="csrf_token"]-Felder, die Formularen
138+
* innerhalb einer TinyMCE-Instanz hinzugefügt wurden.
139+
* @param mixed|array|string $data Call by reference
140+
*
141+
* @deprecated Soll nur noch bereits betroffene Artikel automatisch säubern.
142+
* @see diverse_class::injectCsrfTokenIntoForms()
143+
*/
144+
private static function removeCsrfTokenFromUserInput(&$data): void
145+
{
146+
if (is_string($data)) {
147+
$data = preg_replace('~<input type="hidden" name="csrf_token"[^>]+>~', '', $data);
148+
}
149+
elseif (is_array($data)) {
150+
foreach ($data as &$value) {
151+
self::removeCsrfTokenFromUserInput($value);
152+
}
153+
}
154+
}
155+
133156
/**
134157
* Zwingende Überprüfungen auf int
135158
*/

lib/settings/output_pars.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
$output = preg_replace($find, $replace, $output);
2929
} while($len < strlen($output));
3030
$output = str_replace("&amp;amp;", "&amp;", $output);
31-
$output = str_ireplace('</form>','<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'"/> </form>',$output);
31+
32+
$output = $diverse->injectCsrfTokenIntoForms((string)$output);
3233

3334
// pkalender-Einbindung Cache-Klasse
3435
$cache->cache_speichern();

0 commit comments

Comments
 (0)