Skip to content

Commit 98ab86e

Browse files
AngelFQCclaude
andcommitted
Security: sanitize message content at render time via DOMPurify
Refs GHSA-jvrf-c7q2-qghg Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b1f548d commit 98ab86e

3 files changed

Lines changed: 5 additions & 58 deletions

File tree

assets/vue/components/usergroup/MessageItem.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</div>
1818
<div
1919
class="message-content"
20-
v-html="message.content"
20+
v-html="sanitizeHtml(message.content)"
2121
></div>
2222
<div
2323
v-if="message.attachment && message.attachment.length"
@@ -84,6 +84,7 @@
8484
import BaseButton from "../basecomponents/BaseButton.vue"
8585
import { useFormatDate } from "../../composables/formatDate"
8686
import { useI18n } from "vue-i18n"
87+
import { sanitizeHtml } from "../../utils/sanitizeHtml"
8788
8889
const { t } = useI18n()
8990

assets/vue/views/message/MessageShow.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115

116116
<div
117117
class="tiny-content"
118-
v-html="item.content"
118+
v-html="sanitizeHtml(item.content)"
119119
/>
120120

121121
<template v-if="item.attachments && item.attachments.length > 0">
@@ -174,6 +174,7 @@ import BaseAppLink from "../../components/basecomponents/BaseAppLink.vue"
174174
import { useNotification } from "../../composables/notification"
175175
import { useMessageReceiverFormatter } from "../../composables/message/messageFormatter"
176176
import { MESSAGE_TYPE_INBOX } from "../../constants/entity/message"
177+
import { sanitizeHtml } from "../../utils/sanitizeHtml"
177178
178179
const { requireConfirmation } = useConfirmation()
179180
const { t } = useI18n()
Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1 @@
1-
{% extends '@ChamiloCore/Layout/layout_one_col.html.twig' %}
2-
{% block content %}
3-
<div id="message_{{ message.id }}" data-status="{{ message.status }}" class="mail-email">
4-
<div class="email-head">
5-
<div class="email-head-subject">
6-
<div class="title">
7-
<a class="active" href="#">
8-
<span class="icon">
9-
<i class="fas fa-star"></i>
10-
</span>
11-
</a>
12-
<span>
13-
{{ message.title }}
14-
</span>
15-
<div class="icons">
16-
<div class="btn-group" role="group">
17-
<a href="{{ message.url.back }}" class="btn btn--secondary-outline icon"><i class="fas fa-arrow-circle-left"></i> {{ 'Back'|trans }}</a>
18-
<a href="#" onclick="window.print();" class="btn btn--secondary-outline icon"><i class="fas fa-print"></i> {{ 'Print'|trans }}</a>
19-
<a href="{{ message.url.new_message }}" class="btn btn--secondary-outline icon"><i class="fas fa-reply"></i> {{ 'Reply'|trans }}</a>
20-
<a href="{{ message.url.delete }}" class="btn btn--secondary-outline icon"><i class="fas fa-trash"></i> {{ 'Delete'|trans }}</a>
21-
</div>
22-
</div>
23-
</div>
24-
</div>
25-
<div class="email-head-sender">
26-
<div class="date">{{ message.date }}</div>
27-
<div class="avatar">
28-
<img src="{{ message.form_user.avatar }}" alt="Avatar" class="rounded-circle user-avatar-md">
29-
</div>
30-
<div class="sender">
31-
<a href="{{ url('index') }}main/social/profile.php?u={{ message.form_user.id }}">{{ message.form_user.name }}</a>
32-
<div class="email">{{ message.form_user.email }}</div>
33-
</div>
34-
</div>
35-
</div>
36-
<div class="email-body">
37-
{{ message.content|raw }}
38-
</div>
39-
40-
{% if message.attachments.quantity > 0 %}
41-
<div class="email-attachments">
42-
<div class="title">{{ 'Attachments'|trans }} <span>({{ message.attachments.quantity }} {{ 'Files'|trans }}, {{ message.attachments.total_size }})</span></div>
43-
<ul>
44-
{% for item in message.attachments.files %}
45-
<li>
46-
<a href="{{ item.url }}">
47-
<i class="fas fa-paperclip"></i> {{ item.filename }}
48-
<span>({{ item.size }})</span>
49-
</a>
50-
</li>
51-
{% endfor %}
52-
</ul>
53-
</div>
54-
{% endif %}
55-
</div>
56-
{% endblock %}
1+
{# Intentionally left blank because this file is not used #}

0 commit comments

Comments
 (0)