XSS (Cross-Site Scripting) là kiểu tấn công xảy ra khi kẻ tấn công chèn mã độc (thường là JavaScript) vào website. Mã độc này sẽ được trình duyệt của người dùng thực thi, cho phép kẻ tấn công truy cập dữ liệu nhạy cảm, đánh cắp phiên đăng nhập hoặc thực hiện các hành động trái phép.
Các loại tấn công XSS:
- Stored XSS (XSS lưu trữ): Mã độc được lưu trên máy chủ và thực thi khi người dùng xem trang bị ảnh hưởng.
- Reflected XSS (XSS phản chiếu): Mã độc được phản hồi từ máy chủ và thực thi trên trình duyệt người dùng.
- DOM-based XSS: Mã độc được thực thi ngay trong DOM của trình duyệt mà không qua xử lý phía máy chủ.
Cách hoạt động của tấn công XSS:
Hãy tưởng tượng một website cho phép người dùng đăng bình luận. Nếu website không lọc hoặc mã hóa dữ liệu người dùng gửi trước khi hiển thị, kẻ tấn công có thể đăng một bình luận như sau:
<script>alert('You have been hacked!');</script>
Khi người dùng khác xem bình luận này, trình duyệt của họ sẽ thực thi đoạn JavaScript chèn vào. Điều này có thể dẫn đến nhiều hoạt động độc hại, ví dụ:
- Đánh cắp cookie: Script có thể truy cập cookie của người dùng và chiếm quyền phiên đăng nhập.
- Làm biến dạng website: Script có thể thay đổi nội dung trang web.
- Chuyển hướng người dùng: Script có thể chuyển hướng người dùng đến trang đăng nhập giả mạo hoặc website lừa đảo.
- Keylogging: Script có thể ghi lại thao tác bàn phím của người dùng.
Bảo vệ ứng dụng Angular khỏi tấn công XSS
1. Sử dụng tính năng bảo mật tích hợp sẵn của Angular
Angular mặc định coi tất cả giá trị là không đáng tin cậy. Khi bạn dùng interpolation ({{ ... }}
) hoặc property binding ([property]="value"
) để hiển thị giá trị trong DOM, Angular sẽ tự động sanitize (làm sạch) giá trị đó. Tức là Angular sẽ kiểm tra và loại bỏ mã độc tiềm ẩn như thẻ <script>
.
Cách hoạt động: Angular sử dụng dịch vụ DomSanitizer để đánh dấu giá trị là an toàn theo từng ngữ cảnh (HTML, style, URL, resource URL).
2. Xác thực dữ liệu người dùng
Thực hiện kiểm tra dữ liệu đầu vào phía server để ngăn mã độc bị lưu trữ hoặc phản chiếu.
Sử dụng các tính năng xác thực của Angular như Validators
và FormControl
.
3. Sử dụng Content Security Policy (CSP)
Triển khai CSP để chỉ định các nguồn nội dung được phép và ngăn chặn script độc hại thực thi.
Ví dụ header CSP:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none';
Header trên chỉ cho phép script từ chính domain của bạn ('self'
) và https://trusted.cdn.com
, đồng thời chặn script inline và các nguồn không đáng tin.
4. Hạn chế sử dụng [innerHTML]
[innerHTML]
cho phép chèn HTML tùy ý vào DOM và tiềm ẩn nguy cơ XSS nếu dữ liệu không được kiểm soát.
5. Sử dụng bypassSecurityTrustHtml
một cách thận trọng
Chỉ dùng bypassSecurityTrustHtml
khi thật sự cần thiết và cực kỳ cẩn trọng, vì nó có thể mở ra lỗ hổng XSS.
Trong trường hợp hiếm hoi bạn cần hiển thị nội dung HTML không an toàn (ví dụ: văn bản giàu định dạng do người dùng tạo), Angular cung cấp DomSanitizer
với các phương thức:
bypassSecurityTrustHtml()
bypassSecurityTrustStyle()
bypassSecurityTrustScript()
bypassSecurityTrustUrl()
bypassSecurityTrustResourceUrl()
QUAN TRỌNG:
- Tuyệt đối không dùng các phương thức này với dữ liệu có nguồn gốc từ người dùng hoặc nguồn ngoài nếu chưa tự tay sanitize kỹ càng ở phía server.
6. Luôn cập nhật Angular và các thư viện phụ thuộc
Việc cập nhật thường xuyên giúp bạn tránh các lỗ hổng bảo mật đã được công bố.
Kết luận
Best practices:
✅ Sử dụng template-driven forms hoặc reactive forms để xử lý dữ liệu người dùng.
✅ Dùng pipes của Angular để định dạng dữ liệu thay vì innerHTML.
✅ Tránh dùng eval()
hoặc Function()
để thực thi code từ dữ liệu người dùng.
✅ Sử dụng Content Security Policy (CSP) để xác định nguồn nội dung được phép.
Bằng cách áp dụng những nguyên tắc trên và khai thác các tính năng bảo mật sẵn có của Angular, bạn có thể giảm thiểu đáng kể nguy cơ bị tấn công XSS trong ứng dụng của mình.