客户端的JavaScript代码替换

JavaScript code substitution on client side

本文关键字:替换 代码 JavaScript 客户端      更新时间:2023-09-26

我现在正在学习一些新技术(如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…"行中的用户名并以不同的名称连接聊天?

第页。这种特殊的情况只是一个例子,很明显,聊天中更改昵称不仅仅是一个简单的笑话,但类似的情况也可能出现在其他项目中。。。

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

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

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

看看我是如何在我的聊天服务器上做到这一点的:

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模块将会话从标准http请求(使用passport进行身份验证)传播到socket.io连接。所有不应该由用户提供的东西都是从会话/db/服务器中获取的。