2009-03-14 7 views
18

Yêu cầu ajax trả về cho tôi một mảng JSON chuẩn chứa đầy các thông tin nhập của người dùng của tôi. Đầu vào đã được khử trùng và sử dụng hàm eval(), tôi có thể dễ dàng tạo đối tượng javascript và cập nhật trang của mình ...Đánh giá là điều xấu ... Vậy tôi nên sử dụng cái gì?

Vì vậy, đây là vấn đề. Không có vấn đề làm thế nào cứng tôi cố gắng để khử trùng đầu vào, tôi không muốn sử dụng hàm eval(). Tôi đã kiểm tra google để biết cách sử dụng "JSON trong AJAX mà không có eval" và đã chạy trên nhiều phương thức khác nhau ...

Tôi nên sử dụng cái nào? Có cách nào tiêu chuẩn, an toàn đã được chứng minh để thực hiện việc này không?

+0

Có một cái nhìn tại địa chỉ: http://stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad -idea –

+0

Tôi nghĩ rằng eval trong trường hợp này không phải là điều ác ... Có lẽ bạn nên xem xét câu hỏi đó: [Khi nào JavaScript của eval() không phải là ác?] (http://stackoverflow.com/questions/197769/ khi-là-javascripts-eval-không-ác) –

Trả lời

20

json.org có một tốt đẹp javascript library

sử dụng đơn giản:

JSON.parse('[{"some":"json"}]'); 
JSON.stringify([{some:'json'}]); 

Sửa: Như đã chỉ ra trong ý kiến, điều này sử dụng eval nếu bạn xem xét thông qua nguồn của nó (mặc dù nó có vẻ là khử trùng trước)

để tránh hoàn toàn, hãy xem json_parse hoặc json-sans-eval

json2.js là không an toàn, json_parse.js là chậm, json-sans-eval.js là không xác nhận

+7

Nó sử dụng eval quá. –

+2

Nó chỉ sử dụng eval làm dự phòng cho các trình duyệt không hỗ trợ đối tượng JSON, và nếu điều này không có chức năng "phân tích cú pháp". –

+0

_json2.js không an toàn_ ** từ đâu? nó có 1mb của regex mà syntisize chuỗi trước khi sử dụng eval ** –

8

Tôi sẽ nói, khi đầu vào được vệ sinh, eval là cách tốt nhất để thực hiện. Nếu máy chủ của bạn bị xâm nhập, mọi người sẽ có thể gửi bất kỳ tập lệnh nào họ muốn cho khách hàng. Vì vậy, đặt một eval không phải là một nguy cơ bảo mật lớn. Nếu bạn lo lắng về việc mọi người thao túng các gói dữ liệu trước khi họ tiếp cận khách hàng thì một lần nữa, bản thân các tập lệnh có thể được sửa đổi.

Đừng lo lắng về eval. Nhưng hãy chắc chắn để bọc nó trong một thử ... bắt khối để người dùng của bạn không nhận được JS lỗi nếu JSON của bạn bị xáo trộn.

:)

0

So sánh với mẫu thiết kế lệnh: http://en.wikipedia.org/wiki/Command_pattern. Với điều này, bạn có thể xác định chính xác các hoạt động mà một khách hàng có thể thực thi và ứng dụng của bạn sẽ an toàn như cách diễn giải cơ bản.

0

Phụ thuộc vào những gì bạn đang cố gắng hoàn thành với vệ sinh. Tôi đã thành công rực rỡ với sự hỗ trợ của khung công tác prototype cho JSON và đánh giá an toàn.

10

Có một tiêu chuẩn, cách chứng minh-an toàn để làm điều này?

Có một cách tiêu chuẩn được đề xuất để thực hiện việc này, trong phiên bản ECMAScript 3.1 sắp tới của JavaScript: JSON.parse.

Nó sẽ được hỗ trợ trong IE8, Firefox 3.1/3.5 và rất có thể là các trình duyệt phổ biến khác trong tương lai. Trong thời gian chờ đợi, bạn có thể quay lại hoặc sử dụng riêng, eval(). Cái ác nó có thể hoặc có thể không; chắc chắn nó sẽ chậm hơn JSON.parse. Nhưng đó là cách thông thường để phân tích cú pháp JSON hôm nay.

Nếu kẻ tấn công có thể tiêm JavaScript độc hại vào nội dung bạn đang phun ra thông qua JSON, bạn có vấn đề lớn hơn phải lo lắng hơn là xấu xa.

2

Để chuyển đổi JSON thành đối tượng JS một cách an toàn, bạn nên sử dụng trình phân tích cú pháp JSON như hàm JSON.parse() được cung cấp bởi this library.

0

Nếu bạn chắc chắn không có nguy cơ tiêm, và bạn không phải là eval()ing trong một vòng lặp, hãy sử dụng eval(). Nó sẽ so sánh thuận lợi với các tùy chọn khác mà chắc chắn sẽ chậm hơn, có thể phá vỡ và sẽ yêu cầu khách hàng tải xuống mã bổ sung.

0

"đánh cắp" từ jQuery

// Try to use the native JSON parser first 
return window.JSON && window.JSON.parse ? 
    window.JSON.parse(data) : 
    (new Function("return " + data))(); 
0

Vấn đề: Vấn đề eval đặt ra là nó thực hiện trong phạm vi toàn cầu

eval.call(document, "console.log(this)") 
eval.call(navigator, "console.log(this)") 
eval.call(window, "console.log(this)") 
(function(){eval.call(document, "console.log(this)")})() 
>Window 

Kịch bản:

Giả sử bạn đang sử dụng các thuộc tính riêng lẻ trong mã đánh dấu của nhiều tài liệu khác nhau ent-yếu tố như một thuộc tính onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';"> 

Bạn muốn có được tất cả các yếu tố có thuộc tính này, xoay onvisible-content-chuỗi thành một đóng cửa và đặt nó vào một hàng đợi EventHandler. Đây là nơi hàm tạo Hàm JS đi vào hoạt động.

Function === 0..constructor.constructor 
>true 

Function('return [this, arguments]').call(window, 1,2,3) 
>Window, Arguments[3]] 
Function('return [this, arguments]').call(document, 1,2,3) 
>Document, Arguments[3]] 
Function('return [this, arguments]').call(navigator, 1,2,3) 
>Navigator, Arguments[3]]  

Đưa nó tất cả cùng nhau:

var eventQueue = []; 
var els = document.querySelectorAll('[onvisible]'); 

for (var el in els) { 
    var jscode = els[el].getAttribute('onvisible'); 
    eventQueue.push({el:els[el], cb:Function(jscode)}) 
} 

//eventQueue[0].cb.call(scope, args);