简体   繁体   中英

Is it possible to return a javascript function via REST API with node/express?

I have a unique use case where I would like to make a GET request to an endpoint and return a javascript function as the response. Im currently using node.js with express, but open to other frameworks.

So on the server side, if the client makes a request to get the function for "addition".

I want the server to send as the response a function that looks like so:

function add(num1, num2){
return num1 + num2
} 

Which the the client can then take the response and utilize the function. eg:

axios(config).then(response=>{
myfunction = response
return myfunction(1,5)
//returns 6
})

Is there a way to 'serialize' the function on server side and convert it to an actual function on client side.

No matter what you do you will end up with a code you'll need to eval on client side, so you will always risk XSS and you need to make sure somehow that they don't contain dangerous code. From REST perspective this is not a big deal, you just need to return the javascript code with application/javascript MIME type and you can add it to the DOM with a SCRIPT tag or just use eval or new Function .

function add(a, b){
    return a+b;
}

From security perspective this can be even more problematic if your users can upload these functions fully or partially. If this is the case, then you need to convert the function code to a data format on the server and process it to make sure that it is safe to use in your clients. For example you can allow only operators like +-*/ and you can allow accessing only local variables. The data format can be something like this:

{
    function: "add",
    params: ["a", "b"],
    code: [
        {
            "return": {"+": ["a", "b"]}
        }
    ]
}

Or you can use an already existing format, like the javascript AST. There are tools you can use for this format: https://github.com/search?l=JavaScript&q=ECMAScript+AST&type=Repositories

{
  "type": "Program",
  "start": 0,
  "end": 32,
  "body": [
    {
      "type": "FunctionDeclaration",
      "start": 0,
      "end": 32,
      "id": {
        "type": "Identifier",
        "start": 9,
        "end": 12,
        "name": "add"
      },
      "expression": false,
      "generator": false,
      "async": false,
      "params": [
        {
          "type": "Identifier",
          "start": 13,
          "end": 14,
          "name": "a"
        },
        {
          "type": "Identifier",
          "start": 15,
          "end": 16,
          "name": "b"
        }
      ],
      "body": {
        "type": "BlockStatement",
        "start": 17,
        "end": 32,
        "body": [
          {
            "type": "ReturnStatement",
            "start": 19,
            "end": 30,
            "argument": {
              "type": "BinaryExpression",
              "start": 26,
              "end": 29,
              "left": {
                "type": "Identifier",
                "start": 26,
                "end": 27,
                "name": "a"
              },
              "operator": "+",
              "right": {
                "type": "Identifier",
                "start": 28,
                "end": 29,
                "name": "b"
              }
            }
          }
        ]
      }
    }
  ],
  "sourceType": "module"
}

If you are afraid that your database contains unsafe functions or that it can be modified by attackers to distribute unsafe functions, then better to verify them again before you send them to the clients.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM