# CSRF

#### CSRF in JavaScript

**Vulnerability:** Cross-Site Request Forgery (CSRF)

**Vulnerable Code:**

```javascript
javascriptCopy code// No CSRF token validation
fetch('/update-profile', {
    method: 'POST',
    body: JSON.stringify({ email: 'newemail@example.com' })
});
```

**Reason for vulnerability:** The code performs a sensitive action without validating a CSRF token, making it susceptible to CSRF attacks.

**Fixed Code:**

```javascript
javascriptCopy code// Fetch CSRF token from meta tag
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

fetch('/update-profile', {
    method: 'POST',
    headers: {
        'CSRF-Token': token,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email: 'newemail@example.com' })
});
```

**Reason for fix:** Including a CSRF token in the request header ensures that the request is legitimate and not forged by an attacker.

***

#### Vulnerable Code

```java
@Controller
public class TransferController {
    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String to, @RequestParam BigDecimal amount) {
        // Perform money transfer
        return "redirect:/success";
    }
}
```

#### Reason for Vulnerability:

This endpoint doesn't implement any CSRF protection, allowing attackers to trick users into making unintended transfers.

#### Fixed Code:

```java
javaCopy@Controller
public class TransferController {
    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String to, @RequestParam BigDecimal amount, 
                                @RequestParam String _csrf, HttpSession session) {
        if (!_csrf.equals(session.getAttribute("csrfToken"))) {
            return "redirect:/error";
        }
        // Perform money transfer
        return "redirect:/success";
    }

    @ModelAttribute
    public void addCsrfToken(HttpSession session, Model model) {
        String csrfToken = UUID.randomUUID().toString();
        session.setAttribute("csrfToken", csrfToken);
        model.addAttribute("csrfToken", csrfToken);
    }
}
```

#### Reason for Fix:

The fixed code implements a custom CSRF token validation. A more robust solution would be to use Spring Security's built-in CSRF protection.

***

#### Vulnerable Code:

```java
from flask import Flask, request, session

app = Flask(__name__)

@app.route('/change_email', methods=['POST'])
def change_email():
    new_email = request.form['email']
    user_id = session['user_id']
    update_email(user_id, new_email)
    return "Email updated successfully"
```

#### Reason for Vulnerability:

This Flask route doesn't implement any CSRF protection, allowing attackers to trick users into changing their email without their knowledge.

#### Fixed Code:

```python
pythonCopyfrom flask import Flask, request, session
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
csrf = CSRFProtect(app)

@app.route('/change_email', methods=['POST'])
@csrf.exempt
def change_email():
    if request.form['csrf_token'] != session['csrf_token']:
        return "CSRF token mismatch", 403
    new_email = request.form['email']
    user_id = session['user_id']
    update_email(user_id, new_email)
    return "Email updated successfully"

@app.before_request
def csrf_protect():
    if request.method == "POST":
        token = session.pop('csrf_token', None)
        if not token or token != request.form.get('csrf_token'):
            abort(403)
```

#### Reason for Fix:

The fixed code implements CSRF protection using Flask-WTF's CSRFProtect and custom token validation.

### JavaScript Example

#### Vulnerable Code:

```javascript
javascriptCopy// Client-side code
fetch('/api/update-profile', {
    method: 'POST',
    body: JSON.stringify({ name: 'New Name' }),
    headers: {
        'Content-Type': 'application/json'
    }
});

// Server-side code (Express.js)
app.post('/api/update-profile', (req, res) => {
    // Update user profile
    res.send('Profile updated');
});
```

#### Reason for Vulnerability:

The API endpoint doesn't implement any CSRF protection, making it vulnerable to cross-site requests.

#### Fixed Code:

```javascript
javascriptCopy// Client-side code
fetch('/api/update-profile', {
    method: 'POST',
    body: JSON.stringify({ name: 'New Name' }),
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
    },
    credentials: 'include'
});

// Server-side code (Express.js)
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

app.use(csrfProtection);

app.get('/form', (req, res) => {
    res.render('form', { csrfToken: req.csrfToken() });
});

app.post('/api/update-profile', csrfProtection, (req, res) => {
    // Update user profile
    res.send('Profile updated');
});
```

#### Reason for Fix:

The fixed code implements CSRF protection using the csurf middleware for Express.js and includes the CSRF token in API requests.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://playbook.sidthoviti.com/devsecops/secure-coding/code-review-examples/csrf.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
