eval против конструктора функции - PullRequest
4 голосов
/ 09 марта 2019

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

сторонний код может видеть область, в которой был вызван eval (), что можетпривести к возможным атакам таким образом, что подобная функция не восприимчива.

- MDN

Что именно делает "сторонним кодомможно увидеть область действия eval () «» и как это влияет на безопасность моих приложений JS?

Ответы [ 2 ]

2 голосов
/ 09 марта 2019

со страницы MDN:

Однако, в отличие от eval, конструктор Function создает функции, которые выполняются только в глобальной области действия.

Если вы закроете весь свой код в замыкании, секретные объекты не будут доступны из тела оцененной функции.

(() => {
  let secret = 42;
  eval("console.log(secret)"); // 42
  let fn = new Function("console.log(secret)");
  fn(); // secret is not defined
})();
1 голос
/ 09 марта 2019

Пример того, как использование eval в этом сценарии для анализа входных данных раскрывает и ставит под угрозу все частные области вашего приложения.

app = (function(){
  // my app with all its shiny little secrets
  // stored in private variables
  var secret = 42;
  var apiUrl = "/api/";

  return {
    withEval(input){
      var someObject = eval(input);
      console.log("withEval", someObject);
      if(apiUrl === "/api/"){
        console.log("xhr to", apiUrl);
      }else{
        console.warn("xhr to", apiUrl);    
      }
    },
    withFunction(input){
      var someObject = Function("return(" + input+")")();
      console.log("withFunction", someObject);
      if(apiUrl === "/api/"){
        console.log("xhr to", apiUrl);
      }else{
        console.warn("xhr to", apiUrl);    
      }
    },
  }
})();

var malware = `(${
()=>{
  try { console.warn("found secret", secret); } catch(err){ console.error(err); }
  try { console.warn("found apiUrl", apiUrl); } catch(err){ console.error(err); }
  apiUrl = "http://attacker.example.com/";
}})(),{ foo: 13, bar: 42 }`;

console.log(malware);

app.withFunction(malware);
console.log("-----------------");
app.withEval(malware);

С eval раскрывается ваш «секрет», такой как идентификаторы, токены, ... и даже «apiUrl» был изменен, поэтому все ваши api-вызовы теперьсовершите обходной путь по веб-странице какого-нибудь злоумышленника.

И ваш код даже не выдаст ошибку;Я зарегистрировал эти ошибки в консоли.

...