Skip to main content

Technical information leak - Console functions

Need

Secure logging and debugging practices

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('/users/:id', (req, res) => {
const userId = req.params.id;

// Vulnerable code using console functions
console.log(`Retrieving user with ID: ${userId}`);

// Process the request and send the response
// ...
});

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

The vulnerability in this code is the usage of console functions, specifically the console.log() function. In this case, the code is using console.log() to log the user ID when retrieving a user.

The problem with using console functions like console.log() in a production environment is that it can lead to information leakage. When an attacker gains access to the application, they can potentially see the logged information, including sensitive data such as user IDs, which can be used to craft more complex attack vectors.

In this specific case, the code is logging the user ID when retrieving a user. This information could be valuable to an attacker as it reveals the user ID structure and potentially exposes the application's logic for handling user data.

To mitigate this vulnerability, it is recommended to avoid using console functions in production environments. Instead, it is advised to use logging mechanisms that are specifically designed for error and exception handling, such as logging libraries or frameworks. These logging mechanisms can be configured to log errors and exceptional events while ensuring that sensitive information is not leaked.

Steps

  • Replace the usage of console.log with a logging library like Winston or Bunyan.
  • Configure the logging library to write logs to a file or a centralized logging system.
  • Remove any sensitive information from the log messages, such as user IDs or passwords.
  • Ensure that the logging library is properly configured for production environments.
  • Test the application to verify that the logging functionality is working correctly.

Compliant code

import express from 'express';
import winston from 'winston';

const app = express();
const logger = winston.createLogger({
transports: [
new winston.transports.File({ filename: 'logs.log' })
]
});

app.get('/users/:id', (req, res) => {
const userId = req.params.id;

logger.info(`Retrieving user with ID: ${userId}`);

// Process the request and send the response
// ...
});

app.listen(3000, () => {
logger.info('Server is running on port 3000');
});

The fixed code addresses the vulnerability by avoiding the use of console functions in a production environment and instead using a logging library called Winston to log errors and exceptional events.

First, the code imports the necessary modules, including Express for creating the server and Winston for logging.

Then, an instance of the Express application is created using the express() function and stored in the app variable.

Next, a logger is created using the winston.createLogger() function. The logger is configured to use a file transport, which means that log messages will be written to a file named "logs.log".

After that, an endpoint is defined for handling GET requests to "/users/:id". Inside the endpoint handler function, the user ID is extracted from the request parameters using req.params.id.

To log the retrieval of a user with a specific ID, the logger's info() method is called with a template string that includes the user ID. This logs a message like "Retrieving user with ID: {userId}".

Finally, the server is started by calling the app.listen() function, which listens on port 3000. When the server starts, the logger's info() method is called to log a message indicating that the server is running on port 3000.

By using the Winston logger instead of console functions, the code ensures that sensitive technical information is not leaked in a production environment. The log messages are written to a file, which can be accessed for debugging or monitoring purposes without exposing potentially vulnerable methods, technologies, or logic.

References