Sensitive information sent via URL parameters - TypeScript

Sensitive information sent via URL parameters - TypeScript

Need

Secure transmission of sensitive information

Context

  • Usage of TypeScript for type-checking and compiling JavaScript code
  • Usage of Express for building web applications and APIs

Description

Non compliant code

        import express from 'express';

const app = express();

app.get('/login', (req, res) => {
  const username = req.query.username;
  const password = req.query.password;

  // Perform login logic here

  res.send('Login successful');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});
        
        

The vulnerability in this code is that sensitive information, such as the username and password, is being sent via URL parameters using the GET method.

In the code, the app.get('/login', ...) route is defined to handle the login functionality. The req.query object is used to retrieve the values of the username and password parameters from the URL.

However, sending sensitive information in the URL parameters is considered insecure for several reasons:

1. The parameters are stored in clear text in the browser history, which means that anyone with access to the browser history can see the sensitive information. 2. The parameters are sent to external sites via the referrer HTTP header. If a user clicks on a link from the application to an external site, the sensitive information will be included in the referrer header, potentially exposing it to the external site. 3. If the browser interprets the URL as a query, the parameters may be visible in the search bar, exposing them to anyone who can see the user's screen. 4. The parameters are also visible to any scripts running on the browser, including third-party scripts, which could potentially capture the sensitive information.

To mitigate this vulnerability, it is recommended to send sensitive information using secure methods such as the POST method, or by obtaining and using session cookies instead of sending them as URL parameters.

Steps

  • Change the HTTP method from GET to POST for the login route
  • Update the form in the frontend to use the POST method when submitting the login credentials
  • In the backend, update the route handler to retrieve the username and password from the request body instead of the query parameters
  • Ensure that the login credentials are encrypted or hashed before storing them or comparing them with the stored values
  • Implement session management using secure methods such as cookies or tokens to handle user authentication and authorization

Compliant code

        import express from 'express';

const app = express();

app.use(express.urlencoded({ extended: true }));

app.post('/login', (req, res) => {
  const username = req.body.username;
  const password = req.body.password;

  // Perform login logic here

  res.send('Login successful');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});
        
        

The fixed code addresses the vulnerability by ensuring that sensitive information, such as the username and password, is not sent via URL parameters using the GET method. Instead, it uses the POST method to send this information securely.

The code imports the Express framework and creates an instance of the Express application. It then configures the application to parse URL-encoded data using the express.urlencoded() middleware with the extended option set to true. This allows the application to parse data sent in the body of a POST request.

The code defines a route handler for the /login endpoint using the app.post() method. Inside the route handler, it retrieves the username and password from the request body using req.body.username and req.body.password respectively. This ensures that the sensitive information is sent securely in the request body rather than being exposed in the URL.

After performing the necessary login logic, the code sends a response to the client with the message "Login successful" using the res.send() method.

Finally, the code starts the Express application and listens on port 3000 for incoming requests.

By using the POST method and sending sensitive information in the request body, the fixed code ensures that the information is not exposed in URLs, browser history, referrer headers, or visible to third-party scripts.

References