Песочница для обеспечения безопасности? [Дубликат]

Эти linemarkers упомянуты в man gcc для опции -P.

Опция -P предназначена специально для того, чтобы избавиться от этих строк для ясности:

gcc -E -P source.c

См. подробную документацию (ранее).

22
задан cammil 26 January 2012 в 17:27
поделиться

9 ответов

Запустите код в iframe, размещенном на другом Origin. Это единственный способ гарантировать, что ненадежный код изолирован и не доступен для доступа к глобальным или DOM страницы.

17
ответ дан josh3736 17 August 2018 в 20:50
поделиться

Насколько мне известно, в Javascript любая переменная, объявленная вне функции, принадлежит глобальной области видимости и поэтому доступна из любого места вашего кода.

Каждая функция имеет свою собственную область действия, и любая переменная, объявленная внутри этой функции, доступна только из этой функции и любых вложенных функций. Локальная область в JavaScript создается только функциями, которая также называется функцией scope.

Помещение функции внутри другой функции может быть одной из возможностей, когда вы можете достичь уменьшенной области видимости (т.е. вложенной области)

0
ответ дан Amandeep Midha 17 August 2018 в 20:50
поделиться

Вы не можете ограничить область действия с помощью методов «вызов» или «применить», но вы можете использовать простой трюк, используя «eval» и scoping, чтобы скрыть какие-либо конкретные глобальные переменные от вызываемой функции .

Причина этого в том, что функция имеет доступ к «глобальным» переменным, которые объявлены в области, которую сама функция объявляет. Таким образом, скопировав код метода и введя его в eval, вы можете существенно изменить глобальную область функции, которую вы хотите вызвать. Конечный результат по существу заключается в том, что он может несколько изолировать фрагмент кода javascript.

Вот пример полного кода:

<html>
<head>
<title>This is the page title.</title>
<script>
    function displayTitle()
    {
        alert(document.title);
    }

    function callMethod(method)
    {
        var code = "" +
            // replace global "window" in the scope of the eval
            "var window = {};" +
            // replace global "document" in the scope of the eval
            "var document = {}; " +
            "(" +

            // inject the Function you want to call into the eval
                method.toString() +

            // call the injected method
            ")();" +
            "";
        eval(code);
    }

    callMethod(displayTitle);
</script>
</head>
<body></body>
</html>

Код, который получает eval'd, выглядит следующим образом:

var window = {};
var document = {};
(function displayTitle()
{
    alert(document.title);
})();
3
ответ дан Chris Pietschmann 17 August 2018 в 20:50
поделиться

EDIT: этот ответ не скрывает переменные window.something. Но у него есть чистый способ запуска пользовательского кода. Я пытаюсь найти способ маскировать переменные окна

Вы можете использовать функцию javascript Function.prototype.bind () , чтобы привязать функцию, представленную пользователем к настраиваемой переменной области видимости по вашему выбору, в этой настраиваемой области вы можете выбрать, какие переменные должны делиться с пользовательской функцией и скрывать. Для пользовательских функций код сможет получить доступ к переменным, которые вы использовали, используя this.variableName. Вот пример, чтобы подробно остановиться на идее:

// A couple of global variable that we will use to test the idea
var sharedGlobal = "I am shared";
var notSharedGlobal = "But I will not be shared";

function submit() {
  // Another two function scoped variables that we will also use to test
  var sharedFuncScope = "I am in function scope and shared";
  var notSharedFuncScope = "I am in function scope but I am not shared";

  // The custom scope object, in here you can choose which variables to share with the custom function
  var funcScope = {
    sharedGlobal: sharedGlobal,
    sharedFuncScope: sharedFuncScope
  };

  // Read the custom function body
  var customFnText = document.getElementById("customfn").value;
  // create a new function object using the Function constructor, and bind it to our custom-made scope object
  var func = new Function(customFnText).bind(funcScope);

  // execute the function, and print the output to the page. 
  document.getElementById("output").innerHTML = JSON.stringify(func());

}

// sample test function body, this will test which of the shared variables   does the custom function has access to. 
/* 
return {
        sharedGlobal : this.sharedGlobal || null,
         sharedFuncScope : this.sharedFuncScope || null,
       notSharedGlobal : this.notSharedGlobal || null,
         notSharedFuncScope : this.notSharedFuncScope || null
 }; 
*/
<script type="text/javascript" src="app.js"></script>
<h1>Add your custom body here</h1>
<textarea id="customfn"></textarea>
<br>
<button onclick="submit()">Submit</button>
<br>
<div id="output"></div>

В следующем примере:

  1. Принять тело функции от пользователя
  2. Когда пользователь нажимает кнопку отправки, пример создает новый объект функции из настраиваемого тела с помощью конструктора функций . В примере мы создаем настраиваемую функцию без параметров, но параметры могут быть легко добавлены в качестве первого входа конструктора Function
  3. . Функция выполняется, и ее выход печатается на экране.
  4. В комментарии добавлен образец тела функции, который проверяет, к какой из переменных имеет доступ пользовательская функция.
3
ответ дан Hisham 17 August 2018 в 20:50
поделиться

Использование встроенных веб-рабочих может позволить запускать безопасные функции. Что-то вроде этого позволяет пользователю вводить javascript, запускать его и получать результат без доступа к вашему глобальному контексту.

globalVariable = "I'm global";

document.getElementById('submit').onclick = function() {
  createWorker();
}


function createWorker() {
  // The text in the textarea is the function you want to run
  var fnText = document.getElementById('fnText').value;

  // You wrap the function to add a postMessage 
  // with the function result
  var workerTemplate = "\
function userDefined(){" + fnText +
    "}\
postMessage(userDefined());\
onmessage = function(e){console.log(e);\
}"

  // web workers are normally js files, but using blobs
  // you can create them with strings.
  var blob = new Blob([workerTemplate], {
    type: "text/javascript"
  });

  var wk = new Worker(window.URL.createObjectURL(blob));
  wk.onmessage = function(e) {
    // you listen for the return. 
    console.log('Function result:', e.data);
  }

}
<div>Enter a javascript function and click submit</div>
<textarea id="fnText"></textarea>
<button id="submit">
  Run the function
</button>

Вы можете попробовать их, например, вставив их в текстовое поле:

return "I'm a safe function";

Вы можете видеть, что это безопасно:

return globalVariable;

У вас даже могут быть более сложные скрипты, например:

var a = 4, b = 5;
function insideFn(){
    // here c is global, but only in the worker context
    c = a + b;
}
insideFn();
return c;

См. Информацию о веб-мастерах здесь, особенно встроенных веб-работников: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Embedded_workers

10
ответ дан Julien Grégoire 17 August 2018 в 20:50
поделиться
  • 1
    Можно ли передать параметр в пользовательскую функцию? – Dulguun Otgon 13 September 2016 в 10:52
  • 2
    @DulguunOtgon Вы можете передавать параметры строк, добавляя их к функции user Defined (parameters) {... – Julien Grégoire 13 September 2016 в 22:18

Вы можете использовать WebWorkers для выделения вашего кода:

Создать полностью отдельную и параллельную среду исполнения (то есть отдельный поток или процесс или эквивалентную конструкцию) и выполните остальные эти шаги асинхронно в этом контексте.

Вот простой пример:

someGlobal = 5;

//As a worker normally take another JavaScript file to execute we convert the function in an URL: http://stackoverflow.com/a/16799132/2576706
function getScriptPath(foo) {
  return window.URL.createObjectURL(new Blob([foo], {
    type: 'text/javascript'
  }));
}

function protectCode(code) {
  var worker = new Worker(getScriptPath(code));
}

protectCode('console.log(someGlobal)'); // prints 10
protectCode('console.log(this.someGlobal)');
protectCode('console.log(eval("someGlobal"))');
protectCode('console.log(window.someGlobal)');

Этот код вернет:

Uncaught ReferenceError: someGlobal is not defined

undefined

Uncaught ReferenceError: someGlobal is not defined и

Uncaught ReferenceError: window is not defined

, поэтому код теперь безопасен.

3
ответ дан Ludovic Feltz 17 August 2018 в 20:50
поделиться

Я дам технический ответ на ваш вопрос, по крайней мере, с одной возможностью. Используйте имя глобального в качестве аргумента для этой функции:

someGlobal = 5;

function cantSeeThatGlobal(someGlobal) {
  console.log(someGlobal);
}

cantSeeThatGlobal();   // prints undefined
cantSeeThatGlobal(10); // prints 10

Лучше, конечно, просто не использовать глобальные переменные когда-либо.

3
ответ дан Simon Sarris 17 August 2018 в 20:50
поделиться

Создайте локальную переменную с тем же именем. Если у вас есть глобальная переменная:

var globalvar;

В вашей функции:

function noGlobal(); {
    var globalvar;
}

Если функция ссылается на globalvar, она будет ссылаться на локальную.

3
ответ дан Snivy 17 August 2018 в 20:50
поделиться
  • 1
    Это не работает, потому что код все равно может получить доступ к глобальной переменной, вызвав window.globalvar. – Jamie 3 April 2016 в 07:32
  • 2
    Хм, ты прав, извини. – Snivy 3 April 2016 в 07:52

Немного поздно, но, возможно, это поможет вам немного

function RestrictFunction(params) {

    params = ( params == undefined ? {} : params );
    var scope = ( params.scope == undefined ? window : params.scope );
    var data = ( params.data == undefined ? {} : params.data );
    var script = ( params.script == undefined ? '' : params.script );
    if (typeof params.script == 'function') {
        script = params.script.toString();
        script = script.substring(script.indexOf("{") + 1, script.lastIndexOf("}"));
        }

    // example: override native functions that on the white list

    var setTimeout = function(_function,_interval) {

        // this is important to prevent the user using `this` in the function and access the DOM
        var interval = scope.setTimeout( function() { 
            RestrictFunction({
                scope:scope,
                data:data,
                script:_function
                });
            } , _interval );

        // Auto clear long user intervals
        scope.setTimeout( function() {
            scope.clearTimeout(interval);
            } , 60*1000 );

        return interval;
        }       

    // example: create custom functions

    var trace = function(str) {
        scope.console.log(str);
        }   

    return (function() {

        // remove functions, objects and variables from scope

        var queue = [];
        var WhiteList = [
            "Blob","Boolean","Date","String","Number","Object","Array","Text","Function",
            "unescape","escape","encodeURI","encodeURIComponent","parseFloat","parseInt",
            "isNaN","isFinite","undefined","NaN",
            "JSON","Math","RegExp",
            "clearTimeout","setTimeout"
            ];

        var properties = Object.getOwnPropertyNames(scope);
        for (var k = 0; k<properties.length; k++ ) {
            if (WhiteList.indexOf(properties[k])!=-1) continue;
            queue.push("var "+properties[k]+" = undefined;");
            }   

        for (var k in scope) {
            if (WhiteList.indexOf(k)!=-1) continue;
            queue.push("var "+k+" = undefined;");
            }

        queue.push("var WhiteList = undefined;");   
        queue.push("var params = undefined;")   ;
        queue.push("var scope = undefined;")    ;
        queue.push("var data = undefined;") ;
        queue.push("var k = undefined;");   
        queue.push("var properties = undefined;");  
        queue.push("var queue = undefined;");   
        queue.push("var script = undefined;");  
        queue.push(script); 

        try {
        return eval( '(function(){'+ queue.join("\n") +'}).apply(data);' ); 
        } catch(err) { }

        }).apply(data);

    }   

Пример использования

// dummy to test if we can access the DOM
var dummy = function() {

    this.notify = function(msg) {
        console.log( msg );
        };

    }

var result = RestrictFunction({

    // Custom data to pass to the user script , Accessible via `this`
    data:{
        prop1: 'hello world',
        prop2: ["hello","world"],
        prop3: new dummy()
        },

    // User custom script as string or function
    script:function() {

        trace( this );

        this.msg = "hello world";
        this.prop3.notify(this.msg);

        setTimeout( function() {
            trace(this); 
            } , 10 );

        trace( data );
        trace( params );
        trace( scope );
        trace( window );
        trace( XMLHttpRequest );
        trace( eval );

        return "done!"; // not required to return value...

        },

    }); 

console.log( "result:" , result );
6
ответ дан user1732451 17 August 2018 в 20:50
поделиться
  • 1
    Это не дурацкое доказательство. & quot; trace ((function () {return this} ())); & quot; все равно будет показывать доступ к глобальной сфере (и есть другие способы). – James Wilkins 12 August 2014 в 23:49
Другие вопросы по тегам:

Похожие вопросы: