# SDR Page Iframe Embedding Configuration

**Last Updated:** 2025-01-05

## Overview

The `/sdr` page is configured to allow iframe embedding from any domain for partner CRM integration. This document explains the implementation and troubleshooting.

## Implementation

### 1. Apache `.htaccess` Configuration

The `.htaccess` file uses `SetEnvIf` and conditional `Header` directives to allow iframe embedding specifically for the `/sdr` page:

```apache
# Allow iframe embedding for SDR page (partner CRM integration)
# SetEnvIf must be evaluated BEFORE Header directives that use the environment variable
<IfModule mod_setenvif.c>
  # Match /sdr with optional trailing slash and query parameters
  SetEnvIf Request_URI "^/sdr(/.*)?(\?.*)?$" ALLOW_IFRAME=1
  SetEnvIf Request_URI "^/sdr$" ALLOW_IFRAME=1
</IfModule>

# Inside mod_headers.c block:
# X-Frame-Options: Set to SAMEORIGIN for all pages EXCEPT /sdr (which allows iframe embedding)
Header always set X-Frame-Options "SAMEORIGIN" env=!ALLOW_IFRAME

# Allow iframe embedding for SDR page (partner CRM integration)
Header always unset X-Frame-Options env=ALLOW_IFRAME
Header always set Content-Security-Policy "frame-ancestors *;" env=ALLOW_IFRAME
```

### 2. PHP-Level Backup (Defense in Depth)

As a backup measure, `v2/pages/sdr.php` also removes and sets headers at the PHP level:

```php
// Allow iframe embedding for SDR page (partner CRM integration)
// Remove X-Frame-Options header if set by server/WordPress
header_remove('X-Frame-Options');
// Set Content-Security-Policy to allow iframe embedding from any domain
header("Content-Security-Policy: frame-ancestors *;");
```

## How It Works

1. **SetEnvIf** evaluates the request URI and sets `ALLOW_IFRAME=1` environment variable when the URL matches `/sdr`
2. **Conditional Headers**:
   - For `/sdr`: Unsets `X-Frame-Options` and sets `Content-Security-Policy: frame-ancestors *`
   - For all other pages: Sets `X-Frame-Options: SAMEORIGIN`
3. **PHP Backup**: PHP code ensures headers are correct even if Apache configuration is overridden

## Testing

### Manual Testing

1. **Test HTTP Headers:**

   ```bash
   curl -I "https://www.ordio.com/sdr" | grep -i "x-frame-options\|content-security-policy"
   ```

   Expected output for `/sdr`:

   - `X-Frame-Options` should be absent or unset
   - `Content-Security-Policy: frame-ancestors *;` should be present

2. **Test Iframe Embedding:**

   - Use [iframetester.com](https://iframetester.com/?url=https://www.ordio.com/sdr)
   - The page should load successfully in the iframe

3. **Test Form Functionality:**
   - Embed the page in an iframe
   - Verify the HubSpot form loads and submits correctly
   - Check that form tracking (GTM) works

### Automated Testing

Run the Python test script:

```bash
python3 tests/test_iframe_headers.py
```

## Troubleshooting

### Issue: Headers Still Show DENY or SAMEORIGIN

**Possible Causes:**

1. Changes not deployed to live server
2. Apache modules not enabled (`mod_setenvif`, `mod_headers`)
3. Server-level configuration overriding `.htaccess`
4. WordPress or plugin setting headers globally

**Solutions:**

1. Verify `.htaccess` changes are deployed
2. Check Apache modules: `apachectl -M | grep -E 'setenvif|headers'`
3. Verify PHP-level headers are working (check `v2/pages/sdr.php`)
4. Check for WordPress plugins or themes setting headers globally

### Issue: Iframe Still Blocked

**Check:**

1. Browser console for CSP violations
2. Network tab for actual headers sent
3. Server error logs for Apache configuration errors

**Verify:**

- `SetEnvIf` pattern matches correctly
- `Header` directives are in correct order
- No conflicting headers from other sources

## Security Considerations

- **Current:** Only `/sdr` page allows embedding; all other pages remain protected with `SAMEORIGIN`
- **Future Restriction:** If needed, we can restrict `frame-ancestors` to specific partner domains:
  ```apache
  Header always set Content-Security-Policy "frame-ancestors https://partner-domain.com https://another-domain.com;" env=ALLOW_IFRAME
  ```

## Partner Instructions

See partner documentation for iframe embed code and integration instructions.

## References

- [Apache mod_headers documentation](https://httpd.apache.org/docs/current/mod/mod_headers.html)
- [Apache mod_setenvif documentation](https://httpd.apache.org/docs/current/mod/mod_setenvif.html)
- [Content-Security-Policy frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
