Light hero background

Things About Nonce & CSRF Token: Differences, Use Cases, and How They Work

December 21, 2024

To prevent web attacks, Nonce (Number Used Once) and CSRF Token (Cross-Site Request Forgery Token) are two common and important security mechanisms for modern websites. Although both are related to web security, their design goals, problems addressed, and application scenarios are distinct. This article introduces the workings of these two mechanisms, their differences, and their appropriate use cases.

What is a Nonce? Why do we need it?

A nonce is a randomly generated string used only once to ensure the uniqueness of each request or operation. It is typically generated by the server and included with each request. By storing and validating the nonce on the server, it can effectively prevent attackers from intercepting and re-executing requests, ensuring each request is executed only once.

For instance, when users accidentally click the submit button multiple times in a web form, it could result in multiple orders being created. The nonce mechanism prevents the server from processing duplicate requests. It also safeguards against replay attacks, which attempt to exploit intercepted legitimate requests to perform multiple actions, leading to unauthorized operations.

A good analogy for a nonce is an event ticket. Each ticket has a unique number and can only be used once to gain entry to the event. Once scanned at the entrance, the system marks it as used, ensuring the same ticket cannot be reused to enter again. Similarly, a nonce ensures that each request is unique and cannot be duplicated or reused maliciously.

Reduce the game from idea to excution

Use Cases for Nonce

Scenario 1: Prevent Duplicate Form Submissions

In scenarios requiring order submissions, users might accidentally click the submit button multiple times, resulting in multiple requests. Without a verification mechanism, the server could process these duplicate requests, causing multiple orders or tasks to be executed repeatedly.

To solve this issue, a nonce can be used to ensure the uniqueness of each form submission. The server generates a random nonce and embeds it in the form. When the user submits the form, the server verifies whether the nonce has already been used. If it has, the request is rejected.

Consider a shopping website, a user may unintentionally click the "Submit" button multiple times after submitting an order. The server uses a nonce to validate each request's uniqueness, ensuring the order is not submitted multiple times.

Secnario 1 Implementation

Form:

<form method="POST" action="/submit-order">
  <input type="hidden" name="nonce" value="123456789abcdef">
  <input type="text" name="orderDetails">
  <button type="submit">Submit Order</button>
</form>

Server Validation:

if (isNonceValid(request.body.nonce)) {
    processOrder();
    invalidateNonce(request.body.nonce);
} else {
    throw new Error("Invalid nonce!");
}

Scenario 2: Prevent Replay Attacks

Attackers may intercept legitimate API requests and send identical requests multiple times for malicious purposes. To prevent such replay attacks, a nonce can ensure each request is unique. The server checks whether the nonce has already been used to determine the request's validity.

A RESTful API for executing deductions could be maliciously exploited by repeatedly sending the same deduction request. A nonce ensures that the request is executed at most once.

Secnario 2 Implementation

Request:

POST /transactions HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer <access_token>

{
    "nonce": "abcdef123456",
    "amount": 100.00,
    "account_id": "1234567890",
    "transaction_type": "deduction"
}

Server Validation:

if (isNonceValid(request.body.nonce)) {
    executeTransaction(request.body.amount, request.body.account_id, request.body.transaction_type);
    invalidateNonce(request.body.nonce);
} else {
    throw new Error("Invalid or reused nonce!");
}

Special Scenario: Content Security Policy (CSP)

There is a specific use of nonces under Content Security Policy (CSP) that provides robust protection for web applications. A CSP nonce is a randomly generated string, used only once, to control the execution of inline scripts or styles. It is generated by the server and included in both the CSP header and authorized <script> or <style> tags. The process is similar to the previously introduced nonce mechanism, but here, validation happens in the browser. The browser enforces CSP rules, ensuring only scripts or styles with the correct nonce are executed, blocking unauthorized ones.

For example, a webpage displaying user-specific data may require dynamically generated inline JavaScript. By embedding a nonce in the server-generated CSP header and the authorized scripts, only the intended scripts are executed, while unauthorized ones are blocked. This ensures critical inline scripts can run safely without exposing the page to malicious script injections.

Special Scenario Implementation

Server-Set CSP Header:

Content-Security-Policy: script-src 'self' 'nonce-abcdef123456';

HTML Page:

<script nonce="abcdef123456">
  console.log('This is a secure script.');
</script>

<script>
  console.log('This script will be blocked by CSP.');
</script>

Result:

  • Only embedded scripts with the correct nonce will execute.

  • Other embedded or injected external scripts will be blocked by CSP.

  • The console of this page will show This is a secure script.

What is a CSRF Token? Why do we need it?

A CSRF Token (Cross-Site Request Forgery Token) is a security measure designed to prevent cross-site request forgery (CSRF) attacks. Its purpose is to verify that each request comes from the user's legitimate operation rather than a malicious site's induced request.

A typical CSRF attack exploits the victim's logged-in state to send malicious requests to a trusted website without the victim's authorization or knowledge. For example, an attacker might forge a request to transfer funds, change passwords, or delete user accounts.

The CSRF Token is usually generated by the server and bound to the session. The server sends the token to the user's browser and requires the user to include this token in every request. Upon receiving the request, the server verifies whether the token matches the value stored in the user's session. If the token is invalid or missing, the request is rejected.

This mechanism verifies the legitimacy of requests, preventing attackers from impersonating users through cross-site methods to perform sensitive operations, thus enhancing application security.

Reduce the game from idea to excution

Use Cases for CSRF Tokens

Scenario: Enhance Security for Sensitive Actions

Attackers may exploit a user's logged-in state to initiate high-risk actions like transferring funds. To prevent such situations, a CSRF Token serves as an effective validation method.

Users must include a CSRF Token to protect fund transfer requests.

Implementation

Form:

<form method="POST" action="/transfer-funds">
  <input type="hidden" name="csrf_token" value="abcd1234efgh">
  <input type="number" name="amount" placeholder="Transfer Amount">
  <input type="text" name="to_account" placeholder="Recipient Account">
  <button type="submit">Submit Transfer</button>
</form>

Server Validation:

if (request.body.csrf_token === session.csrf_token) {
    processTransfer(request.body.amount, request.body.to_account);
} else {
    throw new Error("Invalid CSRF token!");
}

Summary

Differences Between Nonce and CSRF Token

FeatureNonceCSRF Token
Main PurposePrevent replay attacks, duplicate submissionsPrevent cross-site request forgery
UsageEnsure request uniquenessValidate request legitimacy
Implementation LevelCommonly used in APIs or form submissionsCommonly used in APIs or form submissions
ReuseSingle-use (non-reusable)May be reused (e.g., within a session)
  • Nonce ensures request uniqueness to avoid duplicates and works with CSP to allow only authorized scripts to execute.

  • CSRF Token prevents Cross-Site Request Forgery by verifying the random string included in each request matches the server-generated token, ensuring the request originates from a legitimate user.

Can Nonce and CSRF Tokens Be Used Together?

Yes, these mechanisms address different issues and can be used together without conflict. Implementation depends on the specific problem you aim to solve.

References: