Skip to content

Commit 6aad3d3

Browse files
Merge pull request #46 from DHTMLX/GS-3246
xss protection for wrappers
2 parents 7701b39 + 35b2009 commit 6aad3d3

6 files changed

Lines changed: 117 additions & 0 deletions

File tree

docs/guides/app-security.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,4 +383,41 @@ It helps preventing various code injection attacks and improve the safety of app
383383

384384
[Read more about applying the CSP standard to a dhtmlxGantt application](api/config/csp.md).
385385

386+
## Framework Wrapper XSS Protection
387+
388+
Starting from v9.2, the [React](integrations/react.md), [Vue](integrations/vue.md), and [Angular](integrations/angular.md) wrappers automatically HTML-escape string values returned by user-provided template functions. This covers:
389+
390+
- Functions passed via the `templates` prop
391+
- `config.columns[].template` functions
392+
- `config.scales[].format` functions
393+
394+
This means that if a template returns a string containing HTML tags, those tags will be rendered as text rather than as markup, preventing XSS through unsanitized data.
395+
396+
### Per-template opt-out
397+
398+
If a specific template needs to return raw HTML, wrap it with the `allowRawHTML` helper exported from the wrapper package:
399+
400+
~~~js
401+
import { allowRawHTML, escapeHTML } from "@dhx/react-gantt";
402+
403+
const templates = {
404+
task_text: allowRawHTML((start, end, task) => {
405+
return `<b>${escapeHTML(task.text)}</b>`;
406+
})
407+
};
408+
~~~
409+
410+
:::note
411+
When using `allowRawHTML`, you are responsible for sanitizing any user-provided data inside that template. Use the exported `escapeHTML` utility for values that come from user input.
412+
:::
413+
414+
### Global opt-out
415+
416+
Set the `allowRawHTML` component prop to `true` to disable escaping for all templates:
417+
418+
~~~jsx
419+
<ReactGantt allowRawHTML={true} />
420+
~~~
421+
422+
See [Migration notes](migration.md#91---92) for more details.
386423

docs/integrations/angular/configuration-props.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ This page documents the public wrapper surface of `@dhtmlx/trial-angular-gantt`
104104
<td>ResourceFilter</td>
105105
<td>Predicate for filtering rows in the configured resource datastore.</td>
106106
</tr>
107+
<tr>
108+
<td>allowRawHTML</td>
109+
<td>boolean</td>
110+
<td>When <code>false</code> (default), string values returned from template functions are HTML-escaped to prevent XSS. Set to <code>true</code> to allow raw HTML in all templates. For per-template control, wrap individual template functions with the exported <code>allowRawHTML()</code> helper. See <a href="/migration#91---92">Migration notes</a>.</td>
111+
</tr>
107112
</tbody>
108113
</table>
109114

docs/integrations/react/configuration-props.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ This page describes the props accepted by React Gantt and how they map to DHTMLX
110110
<td>Allows replacing <code>onBeforeTaskDelete</code> and <code>onBeforeLinkDelete</code> modals with custom components.</td>
111111
</tr>
112112
<tr>
113+
<td>allowRawHTML</td>
114+
<td>boolean</td>
115+
<td>When <code>false</code> (default), string values returned from template functions are HTML-escaped to prevent XSS. Set to <code>true</code> to allow raw HTML in all templates. For per-template control, wrap individual template functions with the exported <code>allowRawHTML()</code> helper. See <a href="/migration#91---92">Migration notes</a>.</td>
116+
</tr>
117+
<tr>
113118
<td>(Event Props)</td>
114119
<td>Function</td>
115120
<td>The wrapper also supports passing event handler props that correspond to DHTMLX Gantt events. For example, onTaskClick, onAfterTaskAdd, etc. If the prop name matches the event name, it's attached automatically.</td>

docs/integrations/vue/configuration-props.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ Use it as a reference after [Overview](integrations/vue/overview.md) or [Quick S
121121
<td>VueGanttEvents</td>
122122
<td>Event-name to handler map.</td>
123123
</tr>
124+
<tr>
125+
<td>allowRawHTML</td>
126+
<td>boolean</td>
127+
<td>When <code>false</code> (default), string values returned from template functions are HTML-escaped to prevent XSS. Set to <code>true</code> to allow raw HTML in all templates. For per-template control, wrap individual template functions with the exported <code>allowRawHTML()</code> helper. See <a href="/migration#91---92">Migration notes</a>.</td>
128+
</tr>
124129
</tbody>
125130
</table>
126131

docs/migration.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,58 @@ sidebar_label: "Migration from Older Versions"
55

66
# Migration from Older Versions
77

8+
## 9.1 -> 9.2 {#91---92}
9+
10+
### XSS protection in framework wrappers
11+
12+
Starting from v9.2, [React Gantt](integrations/react.md), [Vue Gantt](integrations/vue.md), and [Angular Gantt](integrations/angular.md) wrappers automatically HTML-escape string values returned from user-provided template functions. This prevents XSS vulnerabilities caused by unsanitized user data rendered through templates.
13+
14+
The escaping applies to:
15+
16+
- Functions passed via the `templates` prop
17+
- `config.columns[].template` functions
18+
- `config.scales[].format` functions
19+
20+
If your templates intentionally return HTML markup (e.g. `<b>`, `<span>`, `<div>`), the markup will now be escaped and rendered as plain text by default.
21+
22+
#### Per-template opt-out (recommended)
23+
24+
Wrap specific templates that need to output raw HTML with the `allowRawHTML` helper:
25+
26+
~~~jsx
27+
import { allowRawHTML } from "@dhx/react-gantt";
28+
// or "@dhx/vue-gantt" / "@dhx/angular-gantt"
29+
30+
<ReactGantt
31+
templates={{
32+
task_text: allowRawHTML((start, end, task) => {
33+
return `<b>${escapeHTML(task.text)}</b>`;
34+
}),
35+
task_class: (start, end, task) => task.priority // still escaped
36+
}}
37+
/>
38+
~~~
39+
40+
:::note
41+
When using `allowRawHTML`, you are responsible for sanitizing any user-provided data inside that template. Use the exported `escapeHTML` utility for values that come from user input.
42+
:::
43+
44+
#### Full opt-out
45+
46+
Set the `allowRawHTML` component prop to `true` to restore pre-9.2 behavior and disable escaping for all templates:
47+
48+
~~~jsx
49+
<ReactGantt allowRawHTML={true} /* ... */ />
50+
~~~
51+
52+
~~~vue
53+
<VueGantt :allowRawHTML="true" /* ... */ />
54+
~~~
55+
56+
~~~html
57+
<dhx-gantt [allowRawHTML]="true" /* ... */></dhx-gantt>
58+
~~~
59+
860
## 9.0 -> 9.1
961

1062
The v9.1 does not introduce breaking changes but several configuration options have been **deprecated** and

docs/whats-new.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ sidebar_label: "What's New"
99
Updating from an earlier version? Check the [migration guide](migration.md) for required changes and update steps.
1010
:::
1111

12+
## 9.2
13+
14+
<span class='release_date'>Minor update</span>
15+
16+
### Breaking Changes
17+
18+
This update brings some changes in the behavior of framework wrappers. Make sure to check the
19+
[Migration notes](migration.md#91---92) to be on the safe side.
20+
21+
### New Functionality
22+
23+
- [React Gantt](integrations/react.md), [Vue Gantt](integrations/vue.md), and [Angular Gantt](integrations/angular.md) wrappers now **HTML-escape string values returned from template functions** by default to prevent XSS attacks. This applies to `templates`, `config.columns[].template`, and `config.scales[].format` functions
24+
1225
## 9.1.3
1326

1427
<span class='release_date'>March 16, 2026. Bugfix release</span>

0 commit comments

Comments
 (0)