What is a Prototype in JavaScript?

Mỗi đối tượng trong JavaScript được liên kết với một đối tượng khác, được gọi là prototype của nó. Theo mặc định, JavaScript tự động gán cho các đối tượng mới một trong các prototype tích hợp sẵn của nó.

let myObject = {}
Object.getPrototypeOf(myObject) // Object.prototype
 
let myString = ""
Object.getPrototypeOf(myString) // String.prototype
 
let myArray = []
Object.getPrototypeOf(myArray) // Array.prototype
 
let myNumber = 1
Object.getPrototypeOf(myNumber) // Number.prototype

What is Prototype Pollution?

Prototype pollution là một lỗ hổng JavaScript cho phép kẻ tấn công thêm các thuộc tính tùy ý vào các prototype của đối tượng toàn cục, các thuộc tính này có thể được kế thừa bởi các đối tượng do người dùng định nghĩa. Mặc dù thường không nguy hiểm một mình, nó có thể cho phép kẻ tấn công thao túng các thuộc tính đối tượng mà nếu không sẽ không thể truy cập được. Điều này có thể dẫn đến các cuộc tấn công khác, chẳng hạn như DOM XSS ở phía client hoặc thực thi mã từ xa ở phía server.

Preventing Prototype Pollution Vulnerabilities

Sanitizing Property Keys

Một trong những cách rõ ràng hơn để ngăn chặn các lỗ hổng prototype pollution là làm sạch các khóa thuộc tính trước khi hợp nhất chúng vào các đối tượng hiện có.

Chúng tôi chỉ đề xuất đây là một giải pháp tạm thời chứ không phải là một giải pháp dài hạn.

Preventing Changes to Prototype Objects

Việc gọi phương thức Object.freeze() trên một đối tượng đảm bảo rằng các thuộc tính và giá trị của nó không thể bị sửa đổi nữa, và không có thuộc tính mới nào có thể được thêm vào:

Object.freeze(Object.prototype)

Phương thức Object.seal() tương tự, nhưng vẫn cho phép thay đổi giá trị của các thuộc tính hiện có.

Using Safer Alternatives Where Possible

Một biện pháp phòng thủ mạnh mẽ khác chống lại prototype pollution là sử dụng các đối tượng cung cấp sự bảo vệ tích hợp.

Ví dụ, khi định nghĩa một đối tượng tùy chọn, chúng ta có thể sử dụng Map thay thế vì nó có một phương thức get() tích hợp chỉ trả về các thuộc tính được định nghĩa trực tiếp trên bản đồ đó:

Object.prototype.evil = "polluted"
let options = new Map()
options.set("transport_url", "https://normal-website.com")
 
options.evil // 'polluted'
options.get("evil") // undefined
options.get("transport_url") // 'https://normal-website.com'

Set là một lựa chọn thay thế khác nếu chúng ta chỉ lưu trữ các giá trị thay vì các cặp key:value.

Resources