0

I am using the following function to make an XHR request and execute javascript from the response if possible:

function ajaxRequest(resultDiv, processing, action, paramName, param, paramName2, param2, parseJs) {
  if (processing) {
    document.getElementById(resultDiv).innerHTML = processing;
  }
  var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
  xmlhttp.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
      var resp = this.responseText;
      document.getElementById(resultDiv).innerHTML = resp;
      if (parseJs) {
        parseScript(resp);
      }
    }
  }
  if (paramName2) {
    xmlhttp.open("GET", "/query?" + paramName + "=" + param + "&" + paramName2 + "=" + param2 + "&action=" + action, true);
  } else {
    xmlhttp.open("GET", "/query?" + paramName + "=" + param + "&action=" + action, true);
  }
  xmlhttp.send();
}

function parseScript(strcode) {
  var scripts = new Array();
  while (strcode.indexOf("<script") > -1 || strcode.indexOf("</script") > -1) {
    var s = strcode.indexOf("<script");
    var s_e = strcode.indexOf(">", s);
    var e = strcode.indexOf("</script", s);
    var e_e = strcode.indexOf(">", e);
    scripts.push(strcode.substring(s_e + 1, e));
    strcode = strcode.substring(0, s) + strcode.substring(e_e + 1);
  }
  for (var i = 0; i < scripts.length; i++) {
    try {
      eval(scripts[i]);
    } catch (ex) {
      alert("Error while executing");
    }
  }
}

But I got to know that eval function is somehow dangerous and very slow. So can you help me to find something alternative of eval and rewrite the code snippet to work same way it meant to be but with alternative of eval? Thanks in advance, and sorry for my bad English.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 1
    there really is not an alternative – epascarello Sep 02 '20 at 16:01
  • @epascarello so do you know how other sites achieve this functionality? do they use eval too? – Meraj-Ul Islam Sep 02 '20 at 16:03
  • 1
    You're evaluating arbitrary JavaScript. That's the exact usecase for `eval`. I'd question though whether you should be doing this in the first place. You want to evaluate all JavaScript in a response? Why do you need this functionality? – Carcigenicate Sep 02 '20 at 16:03
  • 1
    Most sites do not return scripts that need to be evaluated. – epascarello Sep 02 '20 at 16:04
  • @Carcigenicate yes, for example, to showing toasts or modal. (note: I use materializecss framework). – Meraj-Ul Islam Sep 02 '20 at 16:06
  • Just load the script as text, create a new ` – Mr. Polywhirl Sep 02 '20 at 16:08
  • In the case where you're trying to show toasts or modals, I think most people would generally return the *content* of the modal and handle the showing/hiding in the front end – Jon Warren Sep 02 '20 at 16:08
  • I think I found a solution. using @GirkovArpa's code I altered the function. Now the function doesn't executes with eval function. also the code comes from response is only gets executed. so I think there is no way to inject any code in ajax response. – Meraj-Ul Islam Sep 02 '20 at 16:53

2 Answers2

0

An alternative to eval() might be to inject the code into a <script> tag on your page, upon which it is then immediately executed.

In the example below, the code is provided to script.text. For a URL as in your question, use script.src instead.

const script = document.createElement('script');
script.text = 'console.log("foo");';
document.body.append(script);
// logs "foo"
GirkovArpa
  • 4,427
  • 4
  • 14
  • 43
-1

Eval can be slow but is as dangerous as any other solution if you are running code that is not trusted or verified by yourself. If you do need another way to run this you can try dynamic script text insertion as described in the answer here

DoubleJG
  • 85
  • 4
  • so is it possible to meddle in the eval function and do something bad (attack) b users or hackers? – Meraj-Ul Islam Sep 02 '20 at 16:09
  • @Meraj-UlIslam That depends on where the imported JS comes from. If it's at all user supplied, the JS may contain code that steals session cookies or something, and eval'ing that would be bad. – Carcigenicate Sep 02 '20 at 16:10
  • _"That depends on where the imported JS comes from"_ - Why imported JS? You just have to call `parseScript()` with your "evil" payload. And this can be quite easy (depending on other problems of the site). – Andreas Sep 02 '20 at 16:17
  • it's like: a user typed a comment on post. then the comment posted via ajax. in ajax hosted file (php) tries to save the comment. and then the result shown immediately via some js execution (modal for example). and reloads the comments dynamically. nothing that executes comes from user. but I wonder if user can take advantage of eval function in any way. – Meraj-Ul Islam Sep 02 '20 at 16:18