Use of an insecure channel - HTTP - TypeScript

Use of an insecure channel - HTTP - TypeScript

Need

Secure transmission of client 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();
const port = 3000;

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(port, () => {
  console.log(`Server running on port ${port}`);
});
        
        

The vulnerability in this code is the use of an insecure channel, specifically the use of HTTP instead of HTTPS.

In this code, an Express server is created and listens on port 3000. There is a route defined for the "/login" endpoint, which handles a GET request. The username and password are extracted from the query parameters of the request using req.query.username and req.query.password respectively.

The problem is that this code does not use any encryption to transmit the sensitive information (username and password). The data is sent over an insecure channel (HTTP) which means that it can be intercepted and read by attackers. This puts the credentials and any other confidential information at risk of being captured in plain text.

To mitigate this vulnerability, the code should be modified to use HTTPS instead of HTTP. HTTPS provides encryption and ensures that the data transmitted between the client and the server is secure. This can be achieved by obtaining an SSL certificate and configuring the Express server to use HTTPS with TLS.

Steps

  • Install an SSL/TLS certificate for your domain
  • Update the code to use the HTTPS module instead of the HTTP module
  • Redirect all HTTP traffic to HTTPS
  • Update the port to use the default HTTPS port (443)
  • Test the application to ensure it is working correctly over HTTPS

Compliant code

        import express from 'express';
import https from 'https';
import fs from 'fs';

const app = express();
const port = 443;

const options = {
  key: fs.readFileSync('path/to/privateKey.pem'),
  cert: fs.readFileSync('path/to/certificate.pem')
};

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

  // Perform login logic here

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

app.all('*', (req, res, next) => {
  if (req.secure) {
    return next();
  }
  res.redirect(`https://${req.hostname}:${port}${req.url}`);
});

https.createServer(options, app).listen(port, () => {
  console.log(`Server running on port ${port}`);
});
        
        

The fixed code addresses the vulnerability by implementing secure communication over the HTTPS protocol using TLS encryption.

1. The code imports the required modules: express for creating the server, https for creating an HTTPS server, and fs for reading the private key and certificate files.

2. The app variable is initialized as an instance of the Express application.

3. The port variable is set to 443, which is the default port for HTTPS communication.

4. The options object is created to specify the private key and certificate files required for TLS encryption. The key property is set to the contents of the private key file, and the cert property is set to the contents of the certificate file. These files need to be generated and provided in the specified paths.

5. The code defines a route for the '/login' endpoint using the app.get method. Inside the route handler, the code retrieves the username and password from the request query parameters. The actual login logic is not shown in the code snippet.

6. The code adds a middleware function using app.all to redirect all incoming requests to the HTTPS version of the same URL if the request is not already secure. This ensures that all communication is done over the secure channel.

7. The https.createServer method is used to create an HTTPS server. It takes the options object and the app instance as parameters. The server is then set to listen on the specified port.

8. Finally, a console log message is printed to indicate that the server is running on the specified port.

By using the https module, providing the necessary private key and certificate files, and redirecting insecure requests to the HTTPS version, the code ensures that all communication is encrypted and secure, mitigating the vulnerability.

References