@libs-ui/pipes-security-trust
v0.2.357-12
Published
> Pipe đánh dấu giá trị là an toàn (trusted) để bypass cơ chế bảo mật mặc định của Angular, tích hợp sẵn XSS Filter cho nội dung HTML động.
Readme
@libs-ui/pipes-security-trust
Pipe đánh dấu giá trị là an toàn (trusted) để bypass cơ chế bảo mật mặc định của Angular, tích hợp sẵn XSS Filter cho nội dung HTML động.
Giới thiệu
LibsUiPipesSecurityTrustPipe bọc DomSanitizer của Angular, cho phép đánh dấu một chuỗi là an toàn theo từng loại (html, style, script, url, resourceUrl) mà không cần gọi DomSanitizer thủ công trong TypeScript. Đối với loại html, pipe tự động áp dụng xssFilter từ @libs-ui/utils trước khi bypass để loại bỏ mã độc hại. Vì xssFilter là hàm bất đồng bộ, pipe trả về Promise — luôn kết hợp với pipe async trong template.
Tính năng
- ✅ Hỗ trợ đầy đủ 5 loại trust:
html,style,script,url,resourceUrl - ✅ Tích hợp
xssFiltertự động cho loạihtml(bật mặc định, có thể tắt) - ✅ Trả về
Promise— an toàn với Change Detection Strategy OnPush khi dùng cùngasyncpipe - ✅ Standalone pipe — import trực tiếp vào component, không cần module
- ✅ Dùng
inject(DomSanitizer)theo chuẩn Angular modern
Khi nào sử dụng
- Hiển thị nội dung HTML động lấy từ server hoặc người dùng nhập vào (WYSIWYG editor, rich text)
- Áp dụng inline style động khi component con yêu cầu kiểu
SafeStylehoặc cần suppress Angular dev-mode warning - Nhúng URL động vào thẻ
<iframe>,<embed>,<object>(ResourceUrl) - Sử dụng
javascript:URL hoặc URL scheme không chuẩn trong thuộc tínhhref,src
Cài đặt
npm install @libs-ui/pipes-security-trustImport
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';Import vào component:
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
@Component({
standalone: true,
imports: [CommonModule, LibsUiPipesSecurityTrustPipe],
templateUrl: './my.component.html',
})
export class MyComponent {}Ví dụ sử dụng
1. Trusted HTML — hiển thị HTML động có XSS Filter
// my.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
@Component({
standalone: true,
imports: [CommonModule, LibsUiPipesSecurityTrustPipe],
templateUrl: './my.component.html',
})
export class MyComponent {
htmlContent = '<b style="color: red">Nội dung đậm có style</b>. Được lấy từ API.';
}<!-- my.component.html -->
<!-- Mặc định: Angular xóa thuộc tính style để bảo mật -->
<div [innerHTML]="htmlContent"></div>
<!-- Dùng pipe + XSS Filter (mặc định): giữ style, lọc mã độc -->
<div [innerHTML]="htmlContent | LibsUiPipesSecurityTrustPipe:'html' | async"></div>
<!-- Dùng pipe nhưng tắt XSS Filter (nguy hiểm — chỉ khi nguồn hoàn toàn tin tưởng) -->
<div [innerHTML]="htmlContent | LibsUiPipesSecurityTrustPipe:'html':false | async"></div>2. Resource URL — nhúng iframe
// my.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
@Component({
standalone: true,
imports: [CommonModule, LibsUiPipesSecurityTrustPipe],
templateUrl: './my.component.html',
})
export class MyComponent {
videoUrl = 'https://www.youtube.com/embed/dQw4w9WgXcQ';
}<!-- my.component.html -->
<!-- Không dùng pipe: Angular ném lỗi "unsafe value used in a resource URL context" -->
<!-- <iframe [src]="videoUrl"></iframe> ← LỖI -->
<!-- Dùng pipe: iframe load bình thường -->
<iframe
[src]="videoUrl | LibsUiPipesSecurityTrustPipe:'resourceUrl' | async"
class="w-full h-full border-0"
allowfullscreen>
</iframe>3. Trusted URL — link với scheme không chuẩn
// my.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
@Component({
standalone: true,
imports: [CommonModule, LibsUiPipesSecurityTrustPipe],
templateUrl: './my.component.html',
})
export class MyComponent {
// Dùng trong deep link app mobile hoặc custom protocol
appDeepLink = 'myapp://open?screen=profile&userId=123';
}<!-- my.component.html -->
<!-- Không dùng pipe: Angular thêm prefix "unsafe:" vào href -->
<a [href]="appDeepLink">Mở ứng dụng (Bị chặn)</a>
<!-- Dùng pipe: href được gán nguyên vẹn -->
<a [href]="appDeepLink | LibsUiPipesSecurityTrustPipe:'url' | async">Mở ứng dụng</a>4. Trusted Style — component yêu cầu kiểu SafeStyle
// my.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
@Component({
standalone: true,
imports: [CommonModule, LibsUiPipesSecurityTrustPipe],
templateUrl: './my.component.html',
})
export class MyComponent {
gradientStyle = 'background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 16px; border-radius: 8px;';
}<!-- my.component.html -->
<!-- Dùng khi component con yêu cầu kiểu SafeStyle hoặc suppress Angular dev-mode warning -->
<div [attr.style]="gradientStyle | LibsUiPipesSecurityTrustPipe:'style' | async">
Nội dung với gradient động
</div>Transform
Cú pháp pipe:
value | LibsUiPipesSecurityTrustPipe : type : useXssFilter | async| Tham số | Type | Bắt buộc | Mô tả | Ví dụ |
|---|---|---|---|---|
| value | string | Có | Chuỗi cần đánh dấu an toàn | '<b>text</b>' |
| type | 'html' \| 'style' \| 'script' \| 'url' \| 'resourceUrl' | Có | Loại nội dung cần trust | 'html' |
| useXssFilter | boolean | Không | Bật/tắt XSS Filter — chỉ áp dụng với type: 'html'. Mặc định true | false |
Giá trị trả về (Return type):
| type | Return type |
|---|---|
| 'html' | Promise<SafeHtml> |
| 'style' | Promise<SafeStyle> |
| 'script' | Promise<SafeScript> |
| 'url' | Promise<SafeUrl> |
| 'resourceUrl' | Promise<SafeResourceUrl> |
Ví dụ standalone (gọi trực tiếp trong TypeScript):
import { inject } from '@angular/core';
import { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';
// Trong constructor hoặc method
const pipe = inject(LibsUiPipesSecurityTrustPipe);
// HTML với XSS Filter
const safeHtml = await pipe.transform('<b style="color:red">text</b>', 'html');
// HTML không dùng XSS Filter
const rawHtml = await pipe.transform('<b>text</b>', 'html', false);
// Resource URL
const safeUrl = await pipe.transform('https://www.youtube.com/embed/abc123', 'resourceUrl');Lưu ý quan trọng
⚠️ Luôn dùng pipe async trong template: Vì transform() trả về Promise, bắt buộc phải pipe qua async (từ CommonModule) để Angular unwrap giá trị. Thiếu async sẽ khiến template nhận được object Promise thay vì giá trị thực.
⚠️ Bypass cơ chế bảo mật của Angular: Pipe này vô hiệu hóa DomSanitizer cho giá trị được truyền vào. Chỉ sử dụng với nội dung từ nguồn mà bạn hoàn toàn kiểm soát hoặc đã xử lý phía server.
⚠️ XSS Filter chỉ áp dụng cho type 'html': Các loại style, script, url, resourceUrl không qua XSS Filter — developer chịu trách nhiệm đảm bảo an toàn cho nội dung đầu vào.
⚠️ type: 'style' ít cần thiết với Angular 14+: Angular 14+ đã relaxed bộ style sanitizer, CSS property thông thường (color, background, font-size...) không bị chặn ngay cả khi không dùng pipe. Chỉ cần loại style khi component con yêu cầu kiểu TypeScript SafeStyle hoặc cần suppress dev-mode warning.
⚠️ type: 'script' rất hiếm dùng: Angular không có binding nào yêu cầu SafeScript trong template thông thường. Chỉ sử dụng khi tích hợp với thư viện bên thứ ba có yêu cầu đặc biệt.
⚠️ Truyền false cho useXssFilter là nguy hiểm: Chỉ tắt XSS Filter khi nội dung HTML đã được sanitize hoàn toàn ở phía server và bạn cần giữ nguyên toàn bộ markup.
⚠️ type không hợp lệ sẽ throw lỗi: Nếu truyền giá trị type khác 5 loại trên ('html' | 'style' | 'script' | 'url' | 'resourceUrl'), pipe throw Error('Invalid safe type specified: ...'). Vì transform() là hàm async, lỗi này reject Promise — cần đảm bảo type luôn hợp lệ (tốt nhất dùng literal string, không dùng biến động không kiểm soát).
