2013-07-07 32 views
34

Tôi muốn có khả năng cho phép người dùng gửi mã JavaScript tùy ý, sau đó được gửi đến máy chủ Node.JS và được thực thi an toàn trước khi đầu ra được gửi lại cho nhiều khách hàng (dưới dạng JSON). Chức năng eval xuất hiện trong đầu, nhưng tôi biết điều này có nhiều mối quan tâm về bảo mật (mã người dùng đã gửi sẽ có thể truy cập File API của Node, v.v.). Tôi đã thấy một số dự án như Microsoft Web Sandbox và Google Caja cho phép thực thi đánh dấu và kịch bản đã khử trùng (để nhúng quảng cáo của bên thứ ba trên trang web), nhưng có vẻ như đây là những công cụ phía máy khách và tôi không chắc liệu chúng có thể được sử dụng an toàn trong Node.Hộp cát an toàn và thực thi JavaScript do người dùng gửi?

Có cách nào tiêu chuẩn để sandbox và thực thi JavaScript không đáng tin cậy trong Nút, nhận đầu ra. Có sai lầm khi thử và làm điều này phía máy chủ không?

EDIT: Điều quan trọng là người dùng có thể tận dụng toàn bộ khả năng của JavaScript, trên thực tế sẽ tốt hơn nếu có thể chọn và chọn API nào sẽ được cung cấp cho mã người dùng.

EDIT: Tôi sẽ tiếp tục và cập nhật những gì tôi đã tìm thấy. Mô-đun Sandcastle này (bcoe/sandcastle) dường như nhằm mục đích làm những gì tôi có trong tâm trí. Bạn không chắc chắn nó an toàn đến mức nào, nhưng vì tôi không phải vì bất cứ điều gì quá quan trọng, tôi nghĩ tôi sẽ thử nó. Tôi sẽ thêm câu trả lời của riêng mình nếu tôi có thể thực hiện thành công việc này.

+0

Tại sao phải thực thi trên máy chủ của bạn, thay vì trên máy khách? – delnan

+2

Tôi nghĩ rằng đây là một sai lầm, nhưng bạn có thể thử nút 'vm' công cụ - http: //nodejs.org/api/vm.html – JoshRagem

+1

Đây là một khái niệm trò chơi lập trình cho vui, tôi không thể tin tưởng khách hàng thực thi mã. Tôi muốn làm điều đó phía máy chủ vì lý do đó và bởi vì đầu ra sẽ được serialized và gửi đến 1 hoặc nhiều khách hàng khác. Nó trông giống như mô-đun vm hoặc một cái gì đó gói nó là những gì tôi muốn. –

Trả lời

3

Câu trả lời này là lỗi thời như GF3 không cung cấp bảo vệ chống lại sandbox phá vỡ

http://gf3.github.io/sandbox/ - nó sử dụng require('child_process') thay vì require('vm').

+0

Tôi sẽ tiếp tục và chấp nhận, tôi sẽ xem xét cả sandbox và mô-đun sandcastle mà tôi đã liên kết ở trên trong vài ngày tới. Cảm ơn. –

+1

Đừng lừa dối, gf3/sandbox sử dụng cả hai mô-đun con và mô-đun vm, kiểm tra mã. Và tất cả các giải pháp hộp cát đều giống nhau. –

+5

Đối với người xem trong tương lai, hiện tại vì nó là viết tắt của gf3 là có thể khai thác và có thể bị hỏng. –

4

Dưới Node.js bạn có thể tạo một quy trình con hộp cát, nhưng bạn cũng cần phải nối mã với "use strict";, nếu không, bạn có thể phá vỡ hộp cát bằng arguments.callee.caller.

Không chắc chắn lý do tại sao bạn cần phải gửi nó đến máy chủ, bởi vì mã cũng có thể được thực hiện trong một công nhân web sandboxed.

Ngoài ra hãy xem thư viện Jailed của mình để đơn giản hóa mọi thứ vừa được đề cập cho cả Node.js và trình duyệt web, đồng thời cung cấp cơ hội xuất một tập hợp các hàm vào hộp cát.

+2

Vào thời điểm này, Bị bỏ tù bị hỏng : https://github.com/asvd/jailed/issues/33 – arve0

+0

@ arve0 bạn đúng, bị bỏ tù đã bị xâm phạm dưới nút, bản sửa lỗi đang được chuẩn bị – asvd

+2

Thay thế: https://github.com/patriksimek/vm2 Có vẻ như được an toàn, nhưng nắm bắt được sự phá vỡ tiềm năng đăng nhập, tôi sẽ cẩn thận. – arve0

9

Bạn có thể sử dụng hỗ trợ sandbox trong nodejs với vm.runInContext ('js mã', bối cảnh), mẫu trong tài liệu hướng dẫn api:

https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options

const util = require('util'); 
const vm = require('vm'); 

const sandbox = { globalVar: 1 }; 
vm.createContext(sandbox); 

for (var i = 0; i < 10; ++i) { 
    vm.runInContext('globalVar *= 2;', sandbox); 
} 
console.log(util.inspect(sandbox)); 

// { globalVar: 1024 } 

WARN: Như đã chỉ bởi "s4y" nó dường như bị thiếu sót. Hãy nhìn vào các bình luận.

+1

Điều này dường như không an toàn, ví dụ: 'vm.runInNewContext ('this.constructor.constructor (" return process ")(). Exit()');' (từ vm2 README: https: // github .com/patriksimek/vm2). – s4y

2

Một thay thế sẽ được sử dụng http://github.com/patriksimek/vm2:

$ npm install vm2 

thì:

const {VM} = require('vm2'); 
const vm = new VM(); 

vm.run(`1 + 1`); // => 2 

như đã đề cập trong ý kiến ​​của câu trả lời khác.

Tôi không biết nó an toàn như thế nào, nhưng ít nhất nó tuyên bố rằng nó chạy mã không tin cậy một cách an toàn (trong README).Và tôi không thể tìm thấy bất kỳ vấn đề an ninh rõ ràng cho đến nay như các giải pháp được đề xuất trong các câu trả lời khác ở đây.

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