# Applied Patching

## Overview

The web application was relatively securely coded, except for the `eval` injection vulnerability. We'll provide:

1. Alternative approaches
2. Extra security measures
3. Specific code patches

***

## Recommendations Summary

| Priority | Recommendation                                   |
| -------- | ------------------------------------------------ |
| 1        | Replace `eval` with function callback            |
| 2        | If `eval` required, use safe-eval (with caution) |
| 3        | Always sanitize user input                       |
| 4        | Always validate user input                       |

***

## Alternative 1: Function Callback (Recommended)

### The Problem

```javascript
function validateString(input, onError) {
  if (...) {
    eval(onError);  // ← User input reaches eval
  }
}
```

### The Solution

Use `onError` as a **function** instead of string:

```javascript
function validateString(input, onError) {
  if (...) {
    onError();  // ← Execute function, not string
  }
}
```

### Updated generateQR Call

```javascript
!validateString(text, function () {
  throw {
    message:
      role === "admin"
        ? `The input "${text}" contains the following invalid characters: [${text.match(
            /['"`;]/g
          )}]`
        : "Invalid input",
    statusCode: 403,
  };
});
```

### Why This Works

* User input stays within `message` string
* No code evaluation occurs
* Same functionality maintained

***

## Alternative 2: safe-eval (Use with Caution)

### Installation

```bash
npm install safe-eval -S
```

### Warning: Known Vulnerabilities!

```bash
$ npm audit

safe-eval  *
Severity: critical
- Sandbox Breakout / Arbitrary Code Execution
- Prototype Pollution vulnerabilities
- Sandbox Bypass due to improper input sanitization
No fix available
```

### Recommendation

> ⚠️ **Avoid eval whenever possible!**

Only use `safe-eval` when:

* `eval` is absolutely required
* Combined with other security measures
* Risk is understood and accepted

***

## Extra Security: Sanitization

### Option 1: Third-Party Package

**Add middleware** in `routes/service-routes.js`:

```javascript
router.use(verifyToken);
router.use(require("sanitize").middleware);
router.post("/generate", generateQR);
```

**Use in controller**:

```javascript
const text = req.bodyString("text");
```

### Option 2: Manual Sanitization (Recommended)

```javascript
const sanitizedText = text.replace(/['"`;]/g, "");
```

### Comparison

| Method  | Pros               | Cons                      |
| ------- | ------------------ | ------------------------- |
| Package | More comprehensive | Dependency overhead       |
| Manual  | Simple, no deps    | Limited to specific chars |

**Recommendation**: Use manual for this app (specific, simple requirement).

***

## Extra Security: Validation

### Why Packages Are Better

* Validation requires thorough understanding
* Multiple input types need different rules
* Built-in patterns reduce errors
* Maintained by security experts

### Using Yup

**Install**:

```bash
npm install yup
```

**Basic Schema**:

```javascript
const yup = require('yup');

let schema = yup
  .string()
  .required()
  .matches(/^[^"';`]*$/);

schema.validateSync(text);
```

### With Role-Based Error Messages

```javascript
let schema = yup
  .string()
  .required()
  .matches(/^[^"';`]*$/, role === "admin" ? null : "Invalid input");

schema.validateSync(text);
```

### Replace validateEmail

**Before**:

```javascript
function validateEmail(email) {
  return String(email)
    .toLowerCase()
    .match(/^...regex...$/);
}
```

**After**:

```javascript
const validateEmail = (email) => {
  const schema = yup.string().email().required();
  return schema.isValidSync(email);
};
```

***

## Complete Patch Summary

### 1. Replace eval with function

```javascript
// Before
eval(onError);

// After
onError();
```

### 2. Update validateString calls

```javascript
// Before
validateString(text, `throw({message: '...'})`)

// After
validateString(text, function() {
  throw { message: '...', statusCode: 403 };
})
```

### 3. Add input sanitization

```javascript
const sanitizedText = text.replace(/['"`;]/g, "");
```

### 4. Add input validation

```javascript
const yup = require('yup');

const schema = yup.string().required().matches(/^[^"';`]*$/);
schema.validateSync(sanitizedText);
```

***

## Patched service-controllers.js

```javascript
const yup = require('yup');
const QRCode = require('qrcode');

function validateString(input, onError) {
  // Input validation with Yup
  const schema = yup.string().required().matches(/^[^"';`]*$/);
  
  try {
    schema.validateSync(input);
    return true;
  } catch (e) {
    onError();  // Execute function instead of eval
    return false;
  }
}

async function generateQR(req, res, next) {
  const text = req.body.text;
  const role = req.user?.role;
  
  // Sanitize input
  const sanitizedText = text?.replace(/['"`;]/g, "") || "";

  try {
    if (!validateString(sanitizedText, function() {
      throw {
        message: role === "admin" 
          ? `Invalid characters in input`
          : "Invalid input",
        statusCode: 403,
      };
    })) {
      return;
    }

    const qr = await QRCode.toDataURL(sanitizedText);
    return res.send(`<img src="${qr}" alt="QR Code" />`);
  } catch (e) {
    if (e.statusCode === 403) {
      return next(e);
    }
    return next({
      message: "Could not generate QR code.",
      statusCode: 500,
    });
  }
}

module.exports = { generateQR };
```

***

## Verification Steps

### 1. Re-run PoC Exploit

```bash
python3 poc.py

> ls
[-] Error: Exploit failed
```

### 2. Test Normal Functionality

```bash
# Valid input
curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"text": "hello world"}' \
  http://localhost:5000/api/service/generate

# Should return QR code
```

### 3. Test Validation

```bash
# Invalid input (contains banned char)
curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"text": "test;injection"}' \
  http://localhost:5000/api/service/generate

# Should return error
{"message":"Invalid input","statusCode":403}
```

***

## Secure Coding Tips

### General

| Tip                   | Description            |
| --------------------- | ---------------------- |
| Avoid eval()          | Use safer alternatives |
| Validate all input    | Server-side, always    |
| Sanitize all input    | Remove unwanted chars  |
| Use typed functions   | Functions over strings |
| Use security packages | yup, validator, helmet |

### JavaScript Specific

```javascript
// ❌ Bad
eval(userInput)
new Function(userInput)
setTimeout(userInput, 1000)

// ✅ Good
JSON.parse(userInput)  // For JSON
userInput.callback()   // For functions
```

### npm Security

```bash
# Check for vulnerabilities
npm audit

# Fix automatically (when possible)
npm audit fix

# Update to latest
npm update
```

***

## Checklist

### Patching

* [ ] Replace eval with function callback
* [ ] Update all validateString calls
* [ ] Add input sanitization
* [ ] Add input validation with Yup
* [ ] Remove vulnerable dependencies

### Verification

* [ ] PoC exploit no longer works
* [ ] Normal functionality preserved
* [ ] Invalid input properly rejected
* [ ] npm audit shows no critical issues

### Documentation

* [ ] Patches documented with code samples
* [ ] Verification steps provided
* [ ] Secure coding tips included
