2012-07-17 25 views
6

Câu hỏi này có liên quan đến What are the best practices to follow when declaring an array in Javascript?Bạn có thể thêm chức năng vào một Array bị tấn công không?


Hãy nói rằng một khách hàng, hãy gọi cho họ "D. B. Cooper", có một yêu cầu đầu tiên mà các mã sau đây phải chạy trước bất kỳ mã JavaScript khác:

Array = function(){ 
    alert('Mwahahahaha'); 
}; 

Bên cạnh đó, Cooper yêu cầu phải thêm các hàm tùy chỉnh vào đối tượng Array được xây dựng (không phải là đối tượng bị tấn công). Ví dụ, nếu Array được unhijacked, điều này sẽ được thực hiện với:

Array.prototype.coolCustomFunction = function(){ 
    alert('I have ' + this.length + ' elements! Cool!'); 
}; 

Trong đó sẽ đủ khả năng:

var myArray = []; 
myArray.coolCustomFunction(); 

Tuy nhiên, điều này không phù hợp với yêu cầu đầu tiên. Vì vậy, làm thế nào bạn có thể đáp ứng tốt nhất cả hai yêu cầu của D. B. Cooper?

Lưu ý: D.B. thậm chí đã viết a test fiddle để giúp đảm bảo các giải pháp đáp ứng yêu cầu của mình ... một chàng trai!


Cập nhật: Đối với những người thích một thách thức: hãy cố gắng tìm một giải pháp qua trình duyệt unhijackable cho vấn đề này. Ví dụ: here's trường hợp kiểm tra bị tấn công thậm chí còn nhiều hơn (nhờ định dạng lại Bergi này) tấn công Array, Object, Array.prototype.constructor và Object.prototype.constructor. Cho đến nay, có vẻ như có một giải pháp cụ thể cho trình duyệt này (xem Bergi's comment on his answer và cho chúng tôi biết nếu bạn tìm cách xâm nhập nó trong FF), nhưng hiện chưa rõ liệu có trình duyệt chéo hay không giải pháp này.

+2

Định dạng của câu hỏi này cần được yêu cầu tài liệu nghiên cứu cho các áp phích mới trên SO – rjz

+2

Gửi yêu cầu về tài liệu cho DB Cooper và nhấn mạnh vào các trường hợp sử dụng cho mọi nhu cầu. :) – Quentin

+0

@Quentin: Nếu bạn có thể tìm thấy anh ấy, đó sẽ là một lựa chọn tốt :) – Briguy37

Trả lời

2

Dù bạn Array chức năng/constructor là, cú pháp theo nghĩa đen cho mảng sẽ luôn luôn tạo ra các mảng "thật" với họ [[Prototype]] thiết lập để các đối tượng nguyên mẫu mảng mẹ đẻ (một lần, điều này was a security vulnerability). Vì vậy, bạn luôn có thể truy cập bằng cách sử dụng

Object.getPrototypeOf([]) 

ngay cả khi Array hoặc [].constructor đang bị tấn công.(Will tất nhiên không hoạt động khi Object đang bị tấn công, sau đó nó được thực sự phức tạp)

(Brought D.B. down!)


Nếu bạn muốn sử dụng một workaround, in FF dòng sau sẽ luôn luôn làm việc (và không phải là hijackable):

[].__proto__.coolCustomFunction = coolCustomFunction; 
+0

Thú vị! Tôi quyết định thử chiếm đoạt hàm tạo của đối tượng mảng: '[] .constructor.prototype.constructor = ..', và điều đó khiến cho giải pháp của Torsten thất bại. Sau đó, tôi đã tấn công Object và điều đó làm cho giải pháp của bạn thất bại, nhưng nó hoạt động với '({}). Constructor'. Sau đó, tôi đã chiếm đoạt hàm tạo của đối tượng Object: '({}). Constructor.prototype.constructor = ..' khiến mọi thứ thất bại. Tại thời điểm đó, tôi đang mắc kẹt, vì vậy tôi đã không tìm thấy một giải pháp un-hijackable này chưa :) Đây là một fiddle cập nhật: http://jsfiddle.net/briguy37/yXPJ8/8/ – Briguy37

+1

Đó là chính xác dòng của tôi của tư tưởng :-) Tuy nhiên, tôi đã [cấu trúc lại fiddle nặng nề của bạn] (http://jsfiddle.net/yXPJ8/9/) để dễ đọc hơn. Bây giờ, bạn chỉ có thể sử dụng phi tiêu chuẩn '__proto__' trong FF (không thể tin được, tôi nghĩ) – Bergi

+0

Rất đẹp, tôi không thấy cách nào để chiếm quyền điều khiển đó trong FF! Tôi vẫn quan tâm để xem gợi ý của @ Torsten để có được hàm tạo từ một đối tượng cửa sổ mới hay một phương thức khác có thể dẫn đến một giải pháp không thể tấn công qua trình duyệt cho điều này. – Briguy37

1

Có ... bạn chỉ cần làm ... nhưng bạn đã tạo mảng bằng [] .. nếu bạn sử dụng new Array() nó hoạt động tốt ...

See example here

+2

Rất tiếc, điều đó không hoàn thành trường hợp kiểm tra. Bạn không được phép chỉnh sửa nó. – Briguy37

+0

@ Briguy37 sau đó nó không thể - bạn không thể ghi đè lên '[]' chức năng - điều này trỏ đến một nhà xây dựng nội bộ – ManseUK

+0

Điều đó rất có thể là trường hợp. Tuy nhiên, nếu bạn sửa đổi nguyên mẫu 'Array' để thêm một hàm trước khi bạn chiếm đoạt nó, bạn có thể sử dụng hàm đó trên một đối tượng được tạo bằng' [] '. Vì vậy, tôi đã tự hỏi nếu có một cách để làm điều này sau khi Array bị tấn công. – Briguy37

3

Kể từ Array là không nhất thiết phải bằng [].constructor , bạn có thể sử dụng [].constructor để tham chiếu đến hàm Array gốc vì đây là tính năng cứng và Array = function(){} sẽ không thay đổi.

Array = function() { alert("foo")}; 

// this will always point to the original Array 
[].constructor.prototype.foo = "bar"; 

var myArray = [0, 1]; 
alert(myArray.foo) // alerts "bar" 

http://jsfiddle.net/yXPJ8/5/

+0

Giải pháp đầu tiên của bạn là D.B. hạnh phúc :) (thứ hai sẽ vi phạm yêu cầu đầu tiên của mình) – Briguy37

+0

Được rồi, bỏ qua "trước khi bất kỳ bit nào khác". ;) –

+0

Điều gì sẽ xảy ra nếu 'arrayProto.constructor = wrongArray'? – Bergi

Các vấn đề liên quan