Bài viết được sự cho phép của tác giả Lưu Bình An

Dùng data binding mặc định để có XSS protection

Khi render một nội dung dạng text bằng kiểu data binding mặc định (đặt trong dấu {}), React sẽ mặc định xử lý để tránh các vấn đề về XSS. Lưu ý một điều là nếu truyền vào cho attribute của element thì sẽ không có được tính năng này.

Mặc định có XSS protection

<div>{textContent}</div>

Không có XSS protection, nhớ validate thủ công trước

<form action={data} />

Tìm việc làm lập trình React lương cao các công ty HOT

Validate URLs trước khi sử dụng

URLs có thể bị inject một code js bằng javascript:. Để validate một URL chỉ được phép là một trong 2 dạng http: https::

function validateURL(url) {
  const parsed = new URL(url)
  return ['https:', 'http:'].includes(parsed.protocol)
}

<a href={validateURL(url) ? url : ''}>Click here!</a>

Render HTML

Việc render HTML như trên trang chính thức của React cũng đã đề cập, hết sức nguy hiểm, nên luôn phải sanitized trước khi render, dùng thư viện https://www.npmjs.com/package/dompurify

import purify from "dompurify";

<div dangerouslySetInnerHTML={{ __html:purify.sanitize(data) }} />

Truy cập trực tiếp đến DOM

Không được truy cập trực tiếp đến DOM rồi inject thêm vào element nào đó, luôn sử dụng cặp đôi dangerouslySetInnerHTML và dompurify như ở trên nếu cần chèn nội dung

import purify from "dompurify";

<div dangerouslySetInnerHTML={{__html:purify.sanitize(data) }} />

Đừng có làm vậy nghe, dùng findDomNode(), rồi innerHTML như thời đi học

this.myRef.current.innerHTML = attackerControlledValue;

Kiểm tra thư viện dependency

Các thư viện dependency đôi khi cũng rất nguy hiểm, một cách vô tình hay cố ý, dùng những công cụ như là snyk tích hợp với công cụ quản lý code (Github, Gitlab, Bitbucket) để kiểm tra một cách tự động.

JSON

Việc gửi đi một JSON lên phía server cũng không phải là ít gặp, luôn escape ký tự < để tránh bị inject

window.__PRELOADED_STATE__ =   ${JSON.stringify(preloadedState).replace( /</g, '\\u003c')}