Skip to content

Commit e818477

Browse files
authored
fix: do not bind content as innerHTML by default (#126)
BREAKING CHANGE: Previously, cell values were bound using `innerHTML`. With this change they are now bound using normal data binding. This means that any html markup will no longer be rendered. To restore the previous behavior set `bindAsUnsafeHtml` on columns where needed. We decided to change this behavior, as binding `innerHTML` can lead to HTML injection. Especially in table content which are often untrusted user generated content. BREAKING CHANGE: Header cell names are now bound using data binding instead of `innerHTML`. Use a `headerTemplate` to provide custom html markup.
1 parent ab910c3 commit e818477

File tree

4 files changed

+16
-2
lines changed

4 files changed

+16
-2
lines changed

projects/ngx-datatable/src/lib/components/body/body-cell.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
7676
}
7777
7878
@if (!column.cellTemplate) {
79-
<span [title]="sanitizedValue" [innerHTML]="value"> </span>
79+
@if (column.bindAsUnsafeHtml) {
80+
<span [title]="sanitizedValue" [innerHTML]="value"> </span>
81+
} @else {
82+
<span [title]="sanitizedValue">{{ value }}</span>
83+
}
8084
} @else {
8185
<ng-template
8286
#cellTemplate

projects/ngx-datatable/src/lib/components/columns/column.directive.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class DataTableColumnDirective<TRow> implements TableColumn, OnChanges {
2525
private columnChangesService = inject(ColumnChangesService);
2626
@Input() name: string;
2727
@Input() prop: TableColumnProp;
28+
@Input({ transform: booleanAttribute }) bindAsUnsafeHtml?: boolean;
2829
@Input({ transform: booleanAttribute }) frozenLeft: boolean;
2930
@Input({ transform: booleanAttribute }) frozenRight: boolean;
3031
@Input({ transform: numberAttribute }) flexGrow: number;

projects/ngx-datatable/src/lib/components/header/header-cell.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ import { NgTemplateOutlet } from '@angular/common';
4747
</ng-template>
4848
} @else {
4949
<span class="datatable-header-cell-wrapper">
50-
<span class="datatable-header-cell-label draggable" (click)="onSort()" [innerHTML]="name">
50+
<span class="datatable-header-cell-label draggable" (click)="onSort()">
51+
{{ name }}
5152
</span>
5253
</span>
5354
}

projects/ngx-datatable/src/lib/types/table-column.type.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ export interface TableColumn<TRow = any> {
119119
*/
120120
prop?: TableColumnProp;
121121

122+
/**
123+
* By default, the property is bound using normal data binding `<span>{{content}}</span>`.
124+
* If this property is set to true, the property will be bound as `<span [innerHTML]="content" />`.
125+
*
126+
* **DANGER** If enabling this feature, make sure the source of the data is trusted. This can be a vector for HTML injection attacks.
127+
*/
128+
bindAsUnsafeHtml?: boolean;
129+
122130
/**
123131
* Cell template ref
124132
*/

0 commit comments

Comments
 (0)