Angular Security Album No. 5 - Preventing Sensitive Information in URLs from Leaking

Sensitive data in URL refers to confidential or personal information on the website, including UserId, usernames, passwords, session, token, etc. Other certification information.

Because URLs may be intercepted and viewed by third parties (such as Internet service providers, proxies, or other attackers monitoring network traffic), sensitive data in URLs poses a security risk, and attackers may capture and use it to carry out attacks.

For example:

  1. Information leakage: Sensitive data leakage in the URL will be intercepted by attackers and lead to the leakage of personally identifiable information or system confidential information.
  2. Account Hijacking: Attackers can use sensitive data in URLs to gain unauthorized access to user accounts and perform various malicious activities.
  3. Phishing attack: An attacker can create a fake web page that mimics a legitimate website and includes sensitive data in the URL to trick users into revealing their login credentials or other sensitive information.
  4. Cross-site scripting (XSS) attack: An attacker can inject malicious code into a URL that, when executed by the user's browser, can steal sensitive data such as cookies or session IDs .

How to prevent sensitive data leakage in URLs

1. It is prohibited to store sensitive data in code

for example:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title></title>
</head>
<body>
  <form  method="post">
  <div class="imgcontainer">
    <img src="img_avatar2.png" alt="Avatar" class="avatar">
  </div>

  <div class="container">
    <label for="uname"><b>Username</b></label>
    <input type="text" placeholder="Enter Username" name="uname" required>

    <label for="psw"><b>Password</b></label>
    <input type="password" placeholder="Enter Password" name="psw" required>

    <button type="submit">Login</button>
    <label>
      <input type="checkbox" checked="checked" name="remember"> Remember me
    </label>
  </div>

  <div class="container" style="background-color:#f1f1f1">
    <button type="button" class="cancelbtn">Cancel</button>
    <span class="psw">Forgot <a href="#">password?</a></span>
  </div>
</form>

</body>
</html>
<!-- test user: user1/12345-->

The test account and password information are saved in the code. In order not to leak sensitive data, the test account and password need to be deleted.

2. Don’t add sensitive data to the URL

For example: when we successfully logged in, we obtained our own auth token = eydGbGciOiJSUzI3VidIsInR5cCI6IkpXVCIsImtpZCI6IlJfRmJ0MllaTW142310dencYVpxWCJ9

Now connect to the socket:

Client:

  const ioSocket = io.connect(
                        'localhost: 4200', {
                            query:  'utcoffset=' + (new Date()).getTimezoneOffset(),
                            transports: ['websocket', 'polling'],
                        });

Server:

At this point we actually added the auth token to the URL. As shown below

How to modify: Do not put the auth token in the URL.

Client:

const ioSocket = io.connect(
                        'localhost: 4200', {
                            forceNew: false,
                            query:  'utcoffset=' + (new Date()).getTimezoneOffset(),
                            transports: ['websocket', 'polling'],
                            upgrade: false
                        });
ioSocket.on('connect', () => {
                        ioSocket.emit('authenticate', { token: 'eydGbGciOiJSUzI3VidIsInR5cCI6IkpXVCIsImtpZCI6IlJfRmJ0MllaTW142310dencYVpxWCJ9' });
                    });

Server:

const cookie = require('cookie');
const _ = require('lodash');

module.exports = function(app, server) {
    io.on('connection', async function(socket) {
        socket.authenticated = false;
        socket.on('authenticate', async function(data) {
            // 验证token
            socket.authenticated = checkToken(data.token);
        });
        let authId = _.get(socket, ['request', 'decoded_token', 'sub']);       
        const cookieStr  = _.get(socket, ['request', 'headers', 'cookie']);
        const cookies = cookie.parse(cookieStr);
        const consid = cookies['connect.sid' ];
        if (authId) {
            let userSockets = _.get(app, ['ioUserSockets', authId], []);

            if (!_.find(userSockets, socket)) {
                userSockets.forEach(socket => {
                    if (_.get(socket, 'consid') === consid) {
                        delete socket.consid;
                    }
                });
                _.set(socket, 'consid', consid);

                userSockets.push(socket);
                _.set(app, ['ioUserSockets', authId], userSockets);
            }

            socket.on('disconnect', () => {
                let userSockets = _.get(app, ['ioUserSockets', authId], []);
                logger.debug('Removing socket for user %s', authId);
                _.pull(userSockets, socket);
                _.set(app, ['ioUserSockets', authId], userSockets);
            });
        }    

        setTimeout(function() {
            if (!socket.authenticated) {
                socket.disconnect('unauthorized');
            }
        }, 3000);
    }
};

This will prevent the auth token from appearing in the URL.

Guess you like

Origin blog.csdn.net/KenkoTech/article/details/133853618