Implementation of proper input validation and sanitization
import express from 'express';
import { exec } from 'child_process';
const app = express();
const port = 3000;
app.get('/execute', (req, res) => {
const command = req.query.command;
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error}`);
return res.status(500).send('Error executing command');
}
console.log(`Command executed successfully: ${stdout}`);
res.send(stdout);
});
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
The vulnerability in this code is a lack of data validation, specifically the lack of sanitization of the
command
variable obtained from the
req.query
object.
In the code, the
command
variable is directly passed to the
exec()
function from the
child_process
module without any validation or sanitization. This means that any value provided as the
command
parameter can be executed as a system command on the server.
This can be exploited by an attacker to execute unauthorized scripts or commands on the server. For example, an attacker could pass a malicious command that deletes files or compromises the server's security.
To fix this vulnerability, it is recommended to implement proper data validation and sanitization. One approach is to use whitelists or identifiers that are transformed into static inputs to the
exec()
function. This ensures that only allowed commands can be executed and prevents any unauthorized or malicious commands from being executed.
import express from 'express';
import { exec } from 'child_process';
const app = express();
const port = 3000;
app.get('/execute', (req, res) => {
const allowedCommands = ['command1', 'command2', 'command3'];
const command = req.query.command;
if (!allowedCommands.includes(command)) {
console.error(`Invalid command: ${command}`);
return res.status(400).send('Invalid command');
}
const sanitizedCommand = transformToStaticValue(command);
exec(sanitizedCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error}`);
return res.status(500).send('Error executing command');
}
console.log(`Command executed successfully: ${stdout}`);
res.send(stdout);
});
});
function transformToStaticValue(input: string): string {
// Perform any necessary transformations on the input
// to ensure it becomes a static value
return input;
}
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
The fixed code addresses the vulnerability by implementing data validation and sanitization techniques. Here's an explanation of the changes made:
1. The code imports the necessary modules, including the
exec
function from the
child_process
module, which is used to execute system commands.
2. The code creates an instance of the Express application and sets the port to 3000.
3. The code defines a route handler for the
/execute
endpoint using the
app.get
method. This endpoint expects a query parameter called
command
.
4. The code defines an array called
allowedCommands
that contains the list of commands that are allowed to be executed.
5. The code retrieves the value of the
command
query parameter from the request.
6. The code checks if the
command
value is included in the
allowedCommands
array using the
includes
method. If the command is not allowed, an error message is logged, and a response with a status code of 400 and an error message is sent back to the client.
7. The code calls the
transformToStaticValue
function, passing the
command
value as an argument, to sanitize and transform the input into a static value.
8. The code uses the
exec
function to execute the sanitized command. It provides a callback function that handles the result of the command execution.
9. Inside the callback function, if an error occurs during command execution, an error message is logged, and a response with a status code of 500 and an error message is sent back to the client.
10. If the command execution is successful, the standard output of the command is logged, and the response with the command output is sent back to the client.
11. The code defines the
transformToStaticValue
function, which takes an input string and performs any necessary transformations to ensure it becomes a static value. In this example, the function is left empty, but you can add any necessary logic to sanitize and transform the input.
12. The code starts the Express application and listens on the specified port. A message is logged to indicate that the server is running.
By implementing data validation, using a whitelist approach, and sanitizing the input before executing the command, the fixed code mitigates the vulnerability and ensures that only allowed commands can be executed.