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')}