1

Quite simply, I'd like to "re-hydrate" functions which are passed from AJAX, as follows:

//AJAX response:
{"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"}

And obviously, baz should be a function and not a string. How would I do this?

2

2 Answers 2

2

As Jozef already suggested you can use eval().

But, if you go through Google you will see that the use of that function is NOT recommended:

  1. https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
  2. When is JavaScript's eval() not evil?
  3. https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
  4. Why is using the JavaScript eval function a bad idea?

As this blog suggests (http://2ality.com/2014/01/eval.html) I would recommend you, to use this:

let json = {"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"};

let func = new Function("console.log('I am back working as a function!');");
func();

If you don't have the possibility to change your json you can simply use str.replace().


Please keep in mind that arbitrary code could be executed! I would strongly recommend that you do e.g. sth. like this instead of just responding with a function. By doing the following you would do some sort of whitelisting. So, no matter if the http-response has been manipulated, the attacker can only execute the pre-defined javascript functions.

function func1() {
  console.log('I am back working as a function!');
}

function func2() {
  console.log('another code block');
}

let json = {"foo":"bar","baz":"1"};

switch(json.baz) {
  case "1": func1();break;
  case "2": func2();break;
  default: console.error("Invalid response");
}

I hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

1

It's possible, but of course we must use the evil eval .. use at your own risk!!

var ajaxResponse = {"foo":"bar","baz":"function(){console.log('I am back working as a function!')}", "lambda": "() => console.log('Hello i\\'m a lambda')"};

function isAFunction(v) {
    try {
        eval("var f = " + v);
        return typeof f === "function";
    } catch (e) {
        return false;
    }
}

var result = Object.entries(ajaxResponse).reduce((obj, [key,value]) => {
      if (isAFunction(value)) {
          eval("obj[key] = " + value);
      } else {
            obj[key] = value;
      }
      return obj;
      
}, {});

result.baz();
result.lambda();

2 Comments

that does work, and I presume it will also hydrate any Objects that are declared inside the function itself. I am only doing this in an environment with trusted interaction between the client and server
You might need to play about with the syntax, but yes, it should do that!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.