【问题标题】:JavaScript code substitution on client side客户端的 JavaScript 代码替换
【发布时间】:2014-04-14 12:40:30
【问题描述】:

我现在正在学习一些新技术(例如node.js、socket.io、redis等)并制作一些简单的测试应用程序,看看它是如何工作的。

我的问题是关于客户端 javascript 代码的安全性:例如,我在 node.js+express 上有一个聊天服务器,当用户连接到这个聊天时,服务器应该分配他的注册用户名(通过 oldschool 授权php+mysql 用于)到他的套接字。问题是,用户可以修改他的客户端脚本并以不同的用户名连接聊天吗?

部分代码如下:

(分配用户名的服务器端部分,只是从客户端调用中获取用户名)

// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
    // store the username in the socket session for this client
    socket.username = username;
    // store the room name in the socket session for this client
    socket.room = 'General';
    // add the client's username to the global list
    usernames[username] = username;
    // send client to room 1
    socket.join('General');
    // echo to client they've connected
    socket.emit('updatechat', 'SERVER', 'you have connected to General');
    // echo to room 1 that a person has connected to their room
    socket.broadcast.to('General').emit('updatechat', 'SERVER', username + ' has connected to this room');
    socket.emit('updaterooms', rooms, 'General');
});

(将用户名发送到服务器的客户端部分,对于特定用户,它看起来像 'var username = "User";')

Yii::$app->view->registerJs('var username = "'.$user->identity->username.'";', yii\web\View::POS_HEAD);

(连接函数)

chat.on('connect', function(){
        // call the server-side function 'adduser' and send one parameter (value of prompt)
        chat.emit('adduser', username);
});

所以问题是:用户可以更改(例如,通过 chrome 开发工具)他在“var username ...”行中的用户名并以不同的名称连接到聊天吗?

附:这种特殊情况只是一个例子,很明显,在聊天中改昵称不仅仅是一个简单的玩笑,但在其他项目中可能会出现类似的情况......

【问题讨论】:

  • "用户可以修改他的客户端脚本" - 是的。永远不要相信客户和他寄给你的东西。 “并以不同的用户名连接聊天?” - 你的服务器应该阻止这种情况。
  • @Bergi,我也这么认为...但我希望我错了:)谢谢)

标签: javascript node.js authentication express socket.io


【解决方案1】:

假设您的变量在闭包中受到保护,并且通过在控制台中输入 username='root' 来更改它们并非易事,用户可以简单地替换整个代码。

客户端发生的一切都完全超出您的控制。

好消息是它们是不涉及重复身份验证的解决方案。假设您已经在 express 应用程序中对用户进行了身份验证,您可以从中获取会话和用户。

在我的chat server 中查看我是如何做到的:

var sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
    function die(err){
        console.log('ERR', err);
        socket.emit('error', err.toString());
        socket.disconnect();
    }
    if (! (session && session.passport && session.passport.user && session.room)) return die ('invalid session');
    var userId = session.passport.user;
    if (!userId) return die('no authenticated user in session');
    ... handling socket for authenticated user
});

基本上,它使用session.socket.io module 将会话从标准http 请求(使用护照进行身份验证)传播到socket.io 连接。并且所有不应该由用户提供的东西都取自 session/db/server。

【讨论】:

  • 所以,为了避免这个问题,我应该传递一些编码的哈希,然后在服务器脚本中,将用户名与传递的哈希匹配?
  • @Fortis 你可以通过 (session) hash->(temporary) map->username,但要知道如果他们能找到另一个用户 hash,那么他们可以“劫持”另一个用户名
  • @Fortis 我在我的(开源)聊天服务器中添加了我如何做到这一点的链接。我正在查看此处包含的最相关的代码。
  • @dystroy,好的,我看看这个例子,谢谢! “db.on(userId).then(db.getUserById)” - 似乎正是我的想法,获取 sessId 然后将其与用户匹配
  • @PaulS.,是的,显然,如果他们可以破解像“var username = 'User'”这样的代码,那么我意识到,知道另一个用户的散列,他们可以对散列做同样的事情。但我希望哈希能安全地存储在 mysql 中 :)
猜你喜欢
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 2010-09-25
  • 1970-01-01
  • 2011-09-14
相关资源
最近更新 更多