Skip to content

Commit

Permalink
fix: sanitize potentially malicious values in order template and wish…
Browse files Browse the repository at this point in the history
…list titles (#1551)

The execution of potentially malicious scripts in Order Template/Wishlist display names (title) is prevented in the PWA UI layer. Entering such values via the PWA UI layer was already prevented.
  • Loading branch information
SGrueber authored Dec 12, 2023
1 parent cf7541c commit 4602463
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { Injectable, SecurityContext, inject } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

import { AttributeHelper } from 'ish-core/models/attribute/attribute.helper';
import { Attribute } from 'ish-core/models/attribute/attribute.model';
Expand All @@ -8,6 +9,8 @@ import { OrderTemplate, OrderTemplateItem } from './order-template.model';

@Injectable({ providedIn: 'root' })
export class OrderTemplateMapper {
private sanitizer = inject(DomSanitizer);

private static parseIdFromURI(uri: string): string {
const match = /wishlists[^\/]*\/([^\?]*)/.exec(uri);
if (match) {
Expand Down Expand Up @@ -40,7 +43,7 @@ export class OrderTemplateMapper {

return {
id: orderTemplateId,
title: orderTemplateData.title,
title: this.sanitizer.sanitize(SecurityContext.HTML, orderTemplateData.title),
itemsCount: orderTemplateData.itemsCount || 0,
creationDate: orderTemplateData.creationDate,
items,
Expand All @@ -54,7 +57,7 @@ export class OrderTemplateMapper {
if (orderTemplate && id) {
return {
id,
title: orderTemplate.title,
title: this.sanitizer.sanitize(SecurityContext.HTML, orderTemplate.title),
creationDate: orderTemplate.creationDate,
};
}
Expand All @@ -63,12 +66,7 @@ export class OrderTemplateMapper {
/**
* extract ID from URI
*/
fromDataToIds(orderTemplateData: OrderTemplateData): OrderTemplate {
if (orderTemplateData) {
return {
id: OrderTemplateMapper.parseIdFromURI(orderTemplateData.uri),
title: orderTemplateData.title,
};
}
fromDataToId(orderTemplateData: OrderTemplateData): string {
return orderTemplateData ? OrderTemplateMapper.parseIdFromURI(orderTemplateData.uri) : undefined;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Order Template Service', () => {
"id": "1234",
"items": [],
"itemsCount": 0,
"title": undefined,
"title": null,
},
]
`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ export class OrderTemplateService {
*/
getOrderTemplates(): Observable<OrderTemplate[]> {
return this.apiService.get(`customers/-/users/-/wishlists`).pipe(
unpackEnvelope(),
map(orderTemplateData => orderTemplateData.map(this.orderTemplateMapper.fromDataToIds)),
map(orderTemplateData => orderTemplateData.map(orderTemplate => this.getOrderTemplate(orderTemplate.id))),
unpackEnvelope<OrderTemplateData>(),
map(orderTemplateData =>
orderTemplateData.map(data => this.getOrderTemplate(this.orderTemplateMapper.fromDataToId(data)))
),
switchMap(obsArray => (obsArray.length ? forkJoin(obsArray) : of([])))
);
}
Expand Down
22 changes: 10 additions & 12 deletions src/app/extensions/wishlists/models/wishlist/wishlist.mapper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { Injectable, SecurityContext, inject } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

import { AttributeHelper } from 'ish-core/models/attribute/attribute.helper';
import { Attribute } from 'ish-core/models/attribute/attribute.model';
Expand All @@ -8,7 +9,9 @@ import { Wishlist, WishlistItem } from './wishlist.model';

@Injectable({ providedIn: 'root' })
export class WishlistMapper {
private static parseIDfromURI(uri: string): string {
private sanitizer = inject(DomSanitizer);

private static parseIdFromURI(uri: string): string {
const match = /wishlists[^\/]*\/([^\?]*)/.exec(uri);
if (match) {
return match[1];
Expand All @@ -17,6 +20,7 @@ export class WishlistMapper {
return;
}
}

fromData(wishlistData: WishlistData, wishlistId: string): Wishlist {
if (wishlistData) {
let items: WishlistItem[];
Expand All @@ -39,7 +43,7 @@ export class WishlistMapper {
}
return {
id: wishlistId,
title: wishlistData.title,
title: this.sanitizer.sanitize(SecurityContext.HTML, wishlistData.title),
itemsCount: wishlistData.itemsCount || 0,
preferred: wishlistData.preferred,
public: wishlistData.public,
Expand All @@ -54,7 +58,7 @@ export class WishlistMapper {
if (wishlist && id) {
return {
id,
title: wishlist.title,
title: this.sanitizer.sanitize(SecurityContext.HTML, wishlist.title),
preferred: wishlist.preferred,
public: wishlist.public,
};
Expand All @@ -64,13 +68,7 @@ export class WishlistMapper {
/**
* extract ID from URI
*/
fromDataToIds(wishlistData: WishlistData): Wishlist {
if (wishlistData) {
return {
id: WishlistMapper.parseIDfromURI(wishlistData.uri),
title: wishlistData.title,
preferred: wishlistData.preferred,
};
}
fromDataToId(wishlistData: WishlistData): string {
return wishlistData ? WishlistMapper.parseIdFromURI(wishlistData.uri) : undefined;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('Wishlist Service', () => {
"itemsCount": 0,
"preferred": true,
"public": undefined,
"title": undefined,
"title": null,
},
]
`);
Expand All @@ -75,7 +75,7 @@ describe('Wishlist Service', () => {
"itemsCount": 0,
"preferred": true,
"public": undefined,
"title": undefined,
"title": null,
},
]
`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ export class WishlistService {
first(),
concatMap(restResource =>
this.apiService.get(`${restResource}/-/wishlists`).pipe(
unpackEnvelope(),
map(wishlistData => wishlistData.map(this.wishlistMapper.fromDataToIds)),
map(wishlistData => wishlistData.map(wishlist => this.getWishlist(wishlist.id))),
unpackEnvelope<WishlistData>(),
map(wishlistData => wishlistData.map(data => this.getWishlist(this.wishlistMapper.fromDataToId(data)))),
switchMap(obsArray => (obsArray.length ? forkJoin(obsArray) : of([])))
)
)
Expand Down

0 comments on commit 4602463

Please sign in to comment.