HTMLIFrameElement: thuộc tính srcdoc
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
Warning: Thuộc tính này phân tích cú pháp đầu vào của nó dưới dạng HTML, ghi kết quả vào DOM của khung. Các API như thế này được gọi là injection sinks, và có khả năng là vectơ tấn công cross-site scripting (XSS), nếu đầu vào ban đầu đến từ kẻ tấn công.
Bạn có thể giảm thiểu rủi ro này bằng cách luôn gán các đối tượng TrustedHTML thay vì chuỗi và enforcing trusted types.
Xem Xem xét bảo mật để biết thêm thông tin.
Thuộc tính srcdoc của giao diện HTMLIFrameElement lấy hoặc đặt markup HTML nội tuyến của tài liệu khung.
Giá trị
Lấy thuộc tính trả về một chuỗi chứa phần nối tiếp HTML của tài liệu khung.
Giá trị là undefined nếu giá trị chưa được đặt.
Đặt thuộc tính chấp nhận một đối tượng TrustedHTML hoặc một chuỗi.
Nó phân tích cú pháp đầu vào này như một tài liệu HTML và thay thế nội dung của khung bằng kết quả.
Ngoại lệ
TypeError-
Ném ra nếu thuộc tính được đặt thành một chuỗi khi Trusted Types được thực thi bởi CSP và không có chính sách mặc định nào được định nghĩa.
Mô tả
Thuộc tính srcdoc phản ánh nội dung của thuộc tính srcdoc của phần tử <iframe>, và có thể được sử dụng để đặt hoặc lấy tài liệu HTML thuộc về <iframe>.
Khi đặt thuộc tính, đầu vào nên định nghĩa một tài liệu HTML hợp lệ, bao gồm directive doctype, <html>, <body>, và các thẻ khác.
Tuy nhiên, lưu ý rằng các trình duyệt thường dung thứ markup không hợp lệ, và hầu hết sẽ cố gắng kết xuất đầu vào chỉ chứa nội dung body.
Bất kỳ markup nào được hỗ trợ bởi trình duyệt sẽ được phân tích cú pháp/nối tiếp, bao gồm Shadow roots.
Lưu ý rằng nếu thuộc tính này được đặt, nó sẽ ghi đè lên bất kỳ giá trị nào được đặt trong thuộc tính src.
Xem xét bảo mật
Thuộc tính srcdoc cho phép absolutely bất kỳ markup HTML nào chạy trong khung theo mặc định.
Nếu khung không được sandbox bằng chỉ thị sandbox của Chính sách bảo mật nội dung (CSP) (hoặc được sandbox nhưng bao gồm giá trị allow-same-origin) thì nó sẽ có cùng nguồn gốc với trang cha.
Điều này có nghĩa là khung sẽ có quyền truy cập hoàn toàn vào DOM và tài nguyên của trang cha, và ngược lại.
Đây là một vectơ đáng kể cho các cuộc tấn công cross-site scripting (XSS) nếu các chuỗi không an toàn tiềm ẩn do người dùng cung cấp được chèn vào khung mà không được làm sạch trước đó. Xem xét đoạn mã sau đây nơi một chuỗi HTML từ người dùng có thể được chuyển vào khung sau đó được thêm vào tài liệu.
const untrustedStringFromUser = `<!doctype html><script src="http://evil.com/naughty.js"></script>`;
const iframe = document.createElement("iframe");
iframe.srcdoc = untrustedStringFromUser;
document.body.appendChild(iframe);
Nếu khung không cần truy cập vào tài liệu cha của bạn, bạn có thể giảm thiểu rủi ro bằng cách sử dụng sandbox CSP mà không có giá trị allow-same-origin.
Khung sau đó sẽ được xem như một tài nguyên khác nguồn gốc, và các cuộc tấn công sẽ bị hạn chế đáng kể.
Bạn cũng có thể sử dụng CSP tổng quát hơn để hạn chế các vị trí mà từ đó script và các tài nguyên khác được phép lấy.
Bạn có thể giảm thiểu thêm rủi ro bằng cách luôn gán các đối tượng TrustedHTML thay vì chuỗi, và enforcing trusted type bằng cách sử dụng chỉ thị CSP require-trusted-types-for.
Điều này đảm bảo rằng đầu vào được chuyển qua một hàm biến đổi, hàm này có cơ hội làm sạch đầu vào để loại bỏ markup nguy hiểm tiềm ẩn trước khi nó được chèn vào.
Ví dụ
>Đọc HTML từ một iframe
Đọc srcdoc khiến user agent tuần tự hóa tài liệu của iframe.
Với HTML sau:
<iframe
id="example"
srcdoc="<!doctype html><body><p>Hello World!</p></body>"></iframe>
Bạn có thể lấy và ghi lại markup như sau:
const frame = document.querySelector("#example");
const frameDoc = frame.srcdoc;
console.log(frameDoc); // "<!doctype html><body><p>Hello World!</p></body>"
Thay thế nguồn nội tuyến của khung
Trong ví dụ này, chúng ta sẽ thay thế tài liệu của khung bằng cách gán HTML cho thuộc tính srcdoc của nó.
Để giảm thiểu rủi ro XSS, trước tiên chúng ta sẽ tạo một đối tượng TrustedHTML từ chuỗi chứa HTML, và sau đó gán đối tượng đó cho srcdoc.
Trusted types chưa được hỗ trợ trên tất cả các trình duyệt, vì vậy trước tiên chúng ta định nghĩa trusted types tinyfill. Điều này hoạt động như một sự thay thế minh bạch cho JavaScript API Trusted Types:
if (typeof trustedTypes === "undefined")
trustedTypes = { createPolicy: (n, rules) => rules };
Tiếp theo, chúng ta tạo một TrustedTypePolicy định nghĩa một createHTML() để biến đổi một chuỗi đầu vào thành các thể hiện TrustedHTML.
Thông thường, các triển khai của createHTML() sử dụng một thư viện như DOMPurify để làm sạch đầu vào, như dưới đây:
const policy = trustedTypes.createPolicy("my-policy", {
createHTML: (input) => DOMPurify.sanitize(input),
});
Sau đó, chúng ta sử dụng đối tượng policy này để tạo một đối tượng TrustedHTML từ chuỗi đầu vào không an toàn tiềm ẩn, và gán kết quả cho phần tử:
// Chuỗi không an toàn tiềm ẩn
const untrustedString =
"<!doctype html><body><p>I might be XSS</p><img src='x' onerror='alert(1)'></body>";
// Tạo một thể hiện TrustedHTML bằng policy
const trustedHTML = policy.createHTML(untrustedString);
// Chèn TrustedHTML (chứa một chuỗi đáng tin cậy)
const frame = document.querySelector("#example");
const frameDoc = frame.srcdoc;
Warning:
Mặc dù bạn có thể trực tiếp gán một chuỗi cho srcdoc, đây là một rủi ro bảo mật nếu chuỗi được chèn có thể chứa nội dung độc hại tiềm ẩn.
Bạn nên sử dụng TrustedHTML để đảm bảo nội dung được làm sạch trước khi chèn, và bạn nên đặt tiêu đề CSP để enforce trusted types.
Đặc tả kỹ thuật
| Thông số kỹ thuật |
|---|
| HTML> # dom-iframe-srcdoc> |