logo

Excessive privileges - Access Mode - Typescript


Need

Restriction of access privileges to system files and directories


Context

  1. Usage of TypeScript for statically typed JavaScript development
  2. Usage of Express for building web applications and APIs
  3. Usage of fs for file system operations

Description

Insecure Code Example

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

const app = express();

app.get('/readFile', (req, res) => {
  fs.readFile('/path/to/file', 'utf8', (err, data) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Internal Server Error');
    }
    res.send(data);
  });
});

app.post('/writeFile', (req, res) => {
  const content = req.body.content;
  fs.writeFile('/path/to/file', content, 'utf8', (err) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Internal Server Error');
    }
    res.send('File written successfully');
  });
});

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

The vulnerability in the given code is excessive privileges in accessing files. This vulnerability arises from the fact that the code does not properly restrict the access mode of the files being read or written. In the `app.get('/readFile')` route handler, the code uses the `fs.readFile()` function to read a file from the specified path. However, it does not specify any custom permission mask to restrict the access mode of the file. This means that the file being read may have a permissive access mode, allowing anyone to read, write, or execute it. Similarly, in the `app.post('/writeFile')` route handler, the code uses the `fs.writeFile()` function to write content to a file. Again, there is no custom permission mask specified, which means that the file being written to may have a permissive access mode, allowing anyone to modify or execute it. These excessive privileges can have serious security implications. An attacker could potentially read sensitive information from system files or modify important files, leading to unauthorized access or data breaches. It can also allow an attacker to create potentially harmful files on the system. To mitigate this vulnerability, it is recommended to restrict the access mode of system files and directories by using a custom permission mask, such as an access mode of 0600. This will ensure that only the owner of the file has read and write permissions, while others have no access.

Steps

  1. Identify the system files or directories that need to be restricted by a custom permission mask.
  2. Set the appropriate permission mask for the files or directories. For example, an access mode of 0600 can be used to restrict read, write, and execute permissions to the owner only.
  3. Update the file paths in the code to point to the correct system files or directories.
  4. Modify the code to use the fs.access() function to check the access mode of the files or directories before performing any read or write operations.
  5. Handle the case where the access mode check fails by returning an appropriate error response.
  6. Test the updated code to ensure that the access mode restrictions are enforced correctly.

Secure Code Example

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

const app = express();

const filePath = '/path/to/file';

app.get('/readFile', (req, res) => {
  fs.access(filePath, fs.constants.R_OK, (err) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Internal Server Error');
    }

    fs.readFile(filePath, 'utf8', (err, data) => {
      if (err) {
        console.error(err);
        return res.status(500).send('Internal Server Error');
      }
      res.send(data);
    });
  });
});

app.post('/writeFile', (req, res) => {
  const content = req.body.content;

  fs.access(filePath, fs.constants.W_OK, (err) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Internal Server Error');
    }

    fs.writeFile(filePath, content, 'utf8', (err) => {
      if (err) {
        console.error(err);
        return res.status(500).send('Internal Server Error');
      }
      res.send('File written successfully');
    });
  });
});

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

The fixed code addresses the vulnerability by implementing proper access control for system files and directories. In the code, the `fs.access` function is used to check the access mode of the file specified by the `filePath` variable. The `fs.constants.R_OK` flag is passed to check if the file is readable, and the `fs.constants.W_OK` flag is passed to check if the file is writable. For the `/readFile` route, the code first checks if the file is readable using `fs.access`. If the file is not readable, it logs an error and sends a 500 Internal Server Error response. If the file is readable, it then uses `fs.readFile` to read the file content and sends it as a response. For the `/writeFile` route, the code first checks if the file is writable using `fs.access`. If the file is not writable, it logs an error and sends a 500 Internal Server Error response. If the file is writable, it uses `fs.writeFile` to write the content received from the request body to the file and sends a success response. By performing access checks before reading or writing files, the code ensures that only files with appropriate access modes can be accessed or modified. This helps to prevent unauthorized access or modification of system files, reducing the risk of potential security vulnerabilities.


References

  • 405 - Excessive privileges - Access Mode

  • Last updated

    2023/09/18