简体   繁体   English

将 eval 用于客户端 JavaScript 计算器是否安全

[英]Is it safe to use eval for a client-side JavaScript calculator

I was making a calculator which is served as a static html page to the user's browser.我正在制作一个计算器,用作用户浏览器的 static html 页面。 The page is not designed to submit any information back to the server.该页面并非旨在将任何信息提交回服务器。 Nothing else will be present on the web page except for this calculator.除此计算器外,web 页面上不会出现任何其他内容。

Is it safe to use "eval" in this scenario?在这种情况下使用“eval”是否安全? Or put another way, does the use of eval in this case cause additional security risk?或者换一种说法,在这种情况下使用 eval 是否会导致额外的安全风险?

To me, it doesn't seem like the user can do anything nefarious with this page they can't do by simply opening the browsers development tools.对我来说,用户似乎无法对这个页面做任何他们不能通过简单地打开浏览器开发工具来做的事情。 I have always read "never" use eval, but in this case, it seems like it makes good sense.我一直在阅读“从不”使用 eval,但在这种情况下,它似乎很有意义。

Here is an example calculator:这是一个示例计算器:

 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1;0"> <title>Calculator</title> </head> <body> <input id="input" type="text"> <button onclick="{ let result= ''. try { result = eval(document.getElementById('input');value); } catch (error) { result = error. } console;log(result). document.getElementById('result');innerHTML=result; }">calculate</button> <div id="result">result here</div> </body> </html>

It will potentially open up the page to arbitrary code execution.它可能会打开页面以执行任意代码。 Consider if someone manages to convince one of your users or a few: "Try pasting in this into the input field, you won't believe what happens next!"考虑一下是否有人设法说服您的一个或几个用户:“尝试将其粘贴到输入字段中,您将不会相信接下来会发生什么!” That's a big potential problem if you save any user-related data on the client - such as login credentials in a cookie, or data in Local Storage or IndexedDB, etc.如果您在客户端上保存任何与用户相关的数据(例如 cookie 中的登录凭据,或 Local Storage 或 IndexedDB 中的数据等),这将是一个很大的潜在问题。

Even if you don't store any such data, it'd probably be a good idea to sanitize the input value so that it only contains mathematical expressions, and nothing else.即使您不存储任何此类数据,清理输入值也可能是一个好主意,以便它只包含数学表达式,而不包含其他内容。 For example, it'd be trivial to permit only numbers and operators you want, maybe +-*/ .例如,只允许您想要的数字和运算符是微不足道的,也许是+-*/ It's so easy to do and makes things safe, so you should do it.这很容易做到并且使事情变得安全,所以你应该这样做。

Also, don't put functions into inline handlers (or use inline handlers at all) - they're quite poor practice.此外,不要将函数放入内联处理程序(或根本不使用内联处理程序)——它们是非常糟糕的做法。 Attach event listeners properly using addEventListener .使用addEventListener正确附加事件监听器。

 document.querySelector('button').addEventListener('click', () => { const sanitizedValue = document.getElementById('input').value .replace(/[^-+/*\d]/g, ''); try { document.getElementById('result').textContent = eval(sanitizedValue); } catch(e) { document.getElementById('result').textContent = 'Syntax not correct'; } });
 <input id="input" type="text"> <button>calculate</button> <div id="result">result here</div>

.replace(/[^-+/*\d]/g, ''); does:做:

  • Match any character that is not:匹配任何不是的字符:
    • - , + , / , * - , + , / , *
    • Or \d (any digit)\d (任何数字)
  • Replace all such matched characters with the empty string用空字符串替换所有匹配的字符

Never use eval() !永远不要使用eval()

From MDN , and it also said:来自MDN ,它还说:

Fortunately, there's a very good alternative to eval() : using the Function constructor.幸运的是,有一个非常好的替代eval() :使用Function构造函数。

So, you can replace eval() like this:因此,您可以像这样替换eval()

        let result= '';
        try {
            result = Function(`"use strict";return (${document.getElementById('input').value})`)();
        } catch (error) {
            result = error;
        }

It's almost the same to the eval except that:它与eval几乎相同,除了:

In the function without the eval() , the object is being evaluated in the global scope, so it is safe...在没有eval()的 function 中,object 正在全球 scope 中进行评估,因此它是安全的...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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