---
hide:
  - toc
---

<div class="camp-banner">
  <div class="camp-banner-content">
    <div class="camp-banner-text">
      <div class="camp-banner-label">Camp 1 · Cloud Exploits</div>
      <h1>Exploit Cloud Vulnerabilities</h1>
      <p>See how static tokens become even more dangerous once exposed in the Azure portal — and where the same patterns from Base Camp slip past basic cloud defaults.</p>
    </div>
    <div class="camp-banner-image">
      <span class="banner-icon"><span class="material-icons">gpp_bad</span></span>
    </div>
  </div>
</div>

## Waypoint 2: Exploit Cloud Vulnerabilities

The same vulnerabilities from Base Camp are more critical in Azure because:

- **Tokens are visible in Azure Portal** (not just in code)
- **Audit logs expose tokens** (compliance violation)
- **Wider attack surface** (anyone with read access can steal tokens)
- **Persistent deployment** (vulnerable server runs 24/7, not just during development)

---

### Exploit 2.1: Steal Token from Portal & Use It Forever

**The vulnerability:** Static tokens stored in environment variables are visible in the Azure Portal to anyone with read access, and they never expire.

**Steps to exploit:**

1. Open [Azure Portal](https://portal.azure.com)
2. Navigate to your resource group (e.g., `rg-camp1-dev`)
3. Click on the **vulnerable server** Container App (named `ca-vulnerable-xxxxx`)
4. In the left menu, go to **Application** → **Containers**
5. Click the **Environment variables** tab
6. Find `REQUIRED_TOKEN` with value `camp1_demo_token_INSECURE` - it's right there in plain text!

**Try it yourself:** Copy the stolen token and use it to authenticate:

=== "Bash"
    ```bash
    # Get your vulnerable server URL
    VULNERABLE_URL=$(azd env get-values | grep VULNERABLE_SERVER_URL | cut -d= -f2 | tr -d '"')

    # Test with the stolen token - server accepts it!
    curl -X POST ${VULNERABLE_URL}/mcp \
      -H "Authorization: Bearer camp1_demo_token_INSECURE" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"exploit-test","version":"1.0"}},"id":1}'
    ```

=== "PowerShell"
    ```powershell
    # Get your vulnerable server URL
    $VULNERABLE_URL = azd env get-value VULNERABLE_SERVER_URL

    # Test with the stolen token - server accepts it!
    curl.exe -X POST "$VULNERABLE_URL/mcp" `
      -H "Authorization: Bearer camp1_demo_token_INSECURE" `
      -H "Content-Type: application/json" `
      -H "Accept: application/json, text/event-stream" `
      -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"exploit-test","version":"1.0"}},"id":1}'
    ```

**What you'll see:** The server returns a successful response. The MCP server can't tell the difference between a legitimate request and your stolen token - **it just works!**

**Now wait an hour... or a day... or even a month...** Run the same command again - **it STILL works!** The token never expires.

??? danger "Security Impact: Double Threat"
    **Easy to Steal:**

    - Anyone with **Reader** access to the Container App can steal the token
    - Developers, operations teams, security auditors all have this access
    - Token appears in audit logs (compliance violation)
    - Compromised Azure accounts gain immediate access
    - No way to detect if token was stolen

    **Impossible to Revoke:**

    - Stolen token can be used **indefinitely** - no expiration
    - No token rotation mechanism
    - No way to revoke access without redeploying the entire application
    - Even if you discover the breach, you can't disable the token
    - A single breach = permanent compromise

This demonstrates both **OWASP MCP01 (Token Mismanagement & Secret Exposure)** and **MCP07 (Insufficient Authentication & Authorization)** - static tokens are visible to too many people AND they never expire!

---

### Exploit 2.2: No Audience Validation (Conceptual)

Even if we were using JWTs (we're not yet), the `StaticTokenVerifier` doesn't validate the `aud` (audience) claim.

**What this means:**

- A token intended for **Service A** could be used with **Service B**
- This is called a **confused deputy attack**
- The server can't distinguish "is this token meant for me?"

**Example scenario:**

- Alice gets a JWT for accessing the payment service
- She uses that same JWT to access the user data service
- Both services accept it because neither checks audience

We'll fix this in Waypoint 5 with proper JWT validation including audience checking.

---

### Summary of Exploits

| Exploit | Impact | OWASP Risk |
|---------|--------|------------|
| Steal token from Portal & use forever | Anyone with Portal access gets permanent access | MCP01, MCP07 |
| No audience check | Confused deputy attacks | MCP07 |
