logo

Insecure session management - CSRF Fixation - Typescript


Need

Secure session management and protection against CSRF Fixation


Context

  1. Usage of TypeScript for statically typed JavaScript development
  2. Usage of Express for building web applications and APIs

Description

Insecure Code Example

import express from 'express';

const app = express();

app.get('/transaction', (req, res) => {
  const authorizationHeader = req.headers.authorization;
  // Perform transaction logic
  res.send('Transaction completed successfully');
});

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

The vulnerability in this code is an insecure session management issue known as CSRF (Cross-Site Request Forgery) Fixation. In the code, the `/transaction` route is defined as a GET request handler. Inside the handler function, the code retrieves the `authorization` header from the request using `req.headers.authorization`. The problem is that the `authorization` header is being used as a public key for authentication, and it is always the same for payment links. This means that an attacker can create a button or link that includes the content of a request and trick a user into clicking it. When the user clicks the button or link, the app will send a push notification to complete the transaction using the fixed `authorization` header. This vulnerability allows an attacker to spoof an authenticated user in the application by modifying the link and executing critical transactions such as transfers or payments on behalf of the victim. To fix this vulnerability, it is recommended to implement CSRF protection by using tokens in the forms for verification of requests made by legitimate users. This will ensure that only requests originating from the application itself are considered valid, preventing CSRF attacks.

Steps

  1. Implement CSRF protection in the application
  2. Generate and include a CSRF token in the forms used for transactions
  3. Validate the CSRF token on the server-side before processing the transaction
  4. Ensure that the CSRF token is unique for each session and request
  5. Use a secure method to generate and store the CSRF token, such as using a cryptographic library or a secure random number generator
  6. Include the CSRF token in the request headers or body when making a transaction request
  7. Verify the CSRF token on the server-side by comparing it with the token stored in the session or database
  8. Reject the transaction request if the CSRF token is invalid or missing
  9. Regularly review and update the CSRF protection mechanism to address any new vulnerabilities or attack techniques

Secure Code Example

import express from 'express';
import csrf from 'csurf';

const app = express();
const csrfProtection = csrf({ cookie: true });

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

app.get('/transaction', (req, res) => {
  const authorizationHeader = req.headers.authorization;
  // Perform transaction logic
  res.send('Transaction completed successfully');
});

app.post('/transaction', (req, res) => {
  const authorizationHeader = req.headers.authorization;
  const csrfToken = req.csrfToken();
  // Validate CSRF token
  // Perform transaction logic
  res.send('Transaction completed successfully');
});

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

The fixed code addresses the vulnerability by implementing CSRF protection using tokens. Here's an explanation of the changes made: 1. The `csrf` middleware is imported from the `csurf` library. This middleware generates and validates CSRF tokens. 2. The `csrfProtection` middleware is created using `csrf({ cookie: true })`. This configures the middleware to store the CSRF token in a cookie. 3. The `express.urlencoded` and `express.json` middlewares are used to parse incoming request bodies. 4. The `csrfProtection` middleware is added to the middleware stack using `app.use(csrfProtection)`. This ensures that all routes below this middleware are protected against CSRF attacks. 5. The `GET /transaction` route is modified to include the `authorizationHeader` in the request. This is just for demonstration purposes and should be replaced with the actual logic for handling transactions. 6. The `POST /transaction` route is modified to include the `authorizationHeader` and `csrfToken` in the request. The `csrfToken` is obtained from `req.csrfToken()`, which generates a new CSRF token for each request. 7. The `POST /transaction` route also includes a step to validate the CSRF token. This step ensures that the request is coming from a legitimate user and not from an attacker trying to perform a CSRF attack. 8. After the necessary validations, the transaction logic is performed, and a response is sent back to the client. 9. The server is set to listen on port 3000 using `app.listen(3000)`.


References

  • 337 - Insecure session management - CSRF Fixation

  • Last updated

    2023/09/18