Skip to content

Commit 092a8d6

Browse files
alex40724fwolf-ilias
authored andcommitted
46643: Exercise: Stored XSS with TinyMCE/Rich Text Editor (RTE) input
Signed-off-by: Releasemanager <webmaster@ilias.de>
1 parent 4d01c0e commit 092a8d6

8 files changed

Lines changed: 67 additions & 6 deletions

File tree

components/ILIAS/Exercise/Assignment/class.ilExAssignment.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ public function getInstruction(): string
341341
public function getInstructionPresentation(): string
342342
{
343343
$inst = $this->getInstruction();
344+
345+
$purifier = new ilExcInstructionPurifier();
346+
$inst = $purifier->purify($inst);
347+
344348
if (trim($inst)) {
345349
$is_html = (strlen($inst) != strlen(strip_tags($inst)));
346350
if (!$is_html) {

components/ILIAS/Exercise/Assignment/class.ilExAssignmentListTextTableGUI.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
class ilExAssignmentListTextTableGUI extends ilTable2GUI
2727
{
2828
protected SubmissionManager $subm;
29+
protected \ILIAS\Exercise\InternalGUIService $gui;
2930
protected ilExAssignment $ass;
3031
protected bool $show_peer_review;
3132
protected ilExPeerReview $peer_review;
@@ -45,6 +46,8 @@ public function __construct(
4546
$lng = $DIC->language();
4647

4748
$this->subm = $DIC->exercise()->internal()->domain()->submission($a_ass->getId());
49+
$this->gui = $DIC->exercise()->internal()->gui();
50+
4851
$this->ass = $a_ass;
4952
$this->show_peer_review = $a_show_peer_review;
5053
$this->setId("excassltxt" . $this->ass->getId());
@@ -105,7 +108,7 @@ protected function parse(): void
105108
"uid" => $file["user_id"],
106109
"uname" => ilUserUtil::getNamePresentation($file["user_id"]),
107110
"udate" => $file["ts"],
108-
"utext" => ilRTE::_replaceMediaObjectImageSrc($file["atext"], 1) // mob id to mob src
111+
"utext" => $this->gui->getUIUtil()->formatTextInput($file["atext"]) // mob id to mob src
109112
);
110113

111114
if (isset($peer_data[$file["user_id"]])) {
@@ -161,6 +164,6 @@ protected function fillRow(array $a_set): void
161164
"USER_DATE",
162165
ilDatePresentation::formatDate(new ilDate($a_set["udate"], IL_CAL_DATETIME))
163166
);
164-
$this->tpl->setVariable("USER_TEXT", nl2br($a_set["utext"]));
167+
$this->tpl->setVariable("USER_TEXT", $a_set["utext"]);
165168
}
166169
}

components/ILIAS/Exercise/PeerReview/class.ilExPeerReviewGUI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ protected function getSubmissionContent(
934934
if ($sub) {
935935
if (trim($sub->getText()) !== '' && trim($sub->getText()) !== '0') {
936936
// mob id to mob src
937-
return nl2br(ilRTE::_replaceMediaObjectImageSrc($sub->getText(), 1));
937+
return $this->gui->getUIUtil()->formatTextInput($sub->getText());
938938
}
939939
}
940940
return "";

components/ILIAS/Exercise/Service/classes/UIUtil.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public function __construct(
3535

3636
public function formatTextInput(string $text): string
3737
{
38+
$purifier = new \ilExcTextSubmissionPurifier();
39+
$text = $purifier->purify($text);
3840
$text = \ilRTE::_replaceMediaObjectImageSrc($text, 1);
3941
if (!str_contains($text, "<p>")) {
4042
$text = nl2br($text);

components/ILIAS/Exercise/classes/BackgroundTasks/class.ilExerciseManagementCollectFilesJob.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,10 @@ protected function collectAssignmentData(int $assignment_id): void
561561
//Get the submission Text
562562
if (!in_array($assignment_type, $this->ass_types_with_files)) {
563563
foreach ($submissions as $sub) {
564+
$purifier = new ilExcTextSubmissionPurifier();
565+
$atext = $purifier->purify($sub->getText());
564566
$this->excel->setCell($row, self::SUBMISSION_DATE_COLUMN, $sub->getTimestamp());
565-
$this->excel->setCell($row, self::FIRST_DEFAULT_SUBMIT_COLUMN, $sub->getText());
567+
$this->excel->setCell($row, self::FIRST_DEFAULT_SUBMIT_COLUMN, $atext);
566568
}
567569
} else {
568570
$col = self::FIRST_DEFAULT_SUBMIT_COLUMN;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/**
4+
* This file is part of ILIAS, a powerful learning management system
5+
* published by ILIAS open source e-Learning e.V.
6+
*
7+
* ILIAS is licensed with the GPL-3.0,
8+
* see https://www.gnu.org/licenses/gpl-3.0.en.html
9+
* You should have received a copy of said license along with the
10+
* source code, too.
11+
*
12+
* If this is not the case or you just want to try ILIAS, you'll find
13+
* us at:
14+
* https://www.ilias.de
15+
* https://github.com/ILIAS-eLearning
16+
*
17+
*********************************************************************/
18+
19+
declare(strict_types=1);
20+
21+
class ilExcTextSubmissionPurifier extends ilHtmlPurifierAbstractLibWrapper
22+
{
23+
// corresponds to "mini" tagset of ilTextAreaInputGUI
24+
protected const TAGSET = ["strong", "em", "u", "ol", "li", "ul", "blockquote", "a", "p", "span", "br"];
25+
26+
public function __construct()
27+
{
28+
parent::__construct();
29+
}
30+
31+
protected function getPurifierConfigInstance(): HTMLPurifier_Config
32+
{
33+
$config = HTMLPurifier_Config::createDefault();
34+
$config->set('HTML.DefinitionID', 'ilias exercise instruction');
35+
$config->set('HTML.DefinitionRev', 1);
36+
$config->set('Cache.SerializerPath', ilHtmlPurifierAbstractLibWrapper::_getCacheDirectory());
37+
$config->set('HTML.Doctype', 'XHTML 1.0 Strict');
38+
39+
$tags = ilObjAdvancedEditing::_getUsedHTMLTags("exc_ass");
40+
$tags = $this->makeElementListTinyMceCompliant($tags);
41+
$config->set('HTML.AllowedElements', $this->removeUnsupportedElements($tags));
42+
$config->set('HTML.ForbiddenAttributes', 'div@style');
43+
44+
if ($def = $config->maybeGetRawHTMLDefinition()) {
45+
$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');
46+
}
47+
48+
return $config;
49+
}
50+
}

components/ILIAS/Exercise/classes/class.ilExerciseManagementGUI.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,6 @@ public function listTextAssignmentObject(): void
590590
{
591591
$this->initFilter();
592592
$this->setBackToMembers();
593-
594593
/** @var $button_print \ILIAS\UI\Component\Component */
595594
$button_print = $this->ui_factory->button()->standard($this->lng->txt('print'), "#")
596595
->withOnLoadCode(function ($id) {

components/ILIAS/Exercise/classes/class.ilObjExercise.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ public function sendAssignment(ilExAssignment $a_ass, array $a_members): void
441441

442442
// body
443443

444-
$body = $a_ass->getInstruction();
444+
$purifier = new ilExcInstructionPurifier();
445+
$body = $purifier->purify($a_ass->getInstruction());
445446
$body .= "\n\n";
446447

447448
$body .= $lng->txt("exc_edit_until") . ": ";

0 commit comments

Comments
 (0)