HTTP

Header

Proxy-Authorization Header

Learn how Proxy-Authorization provides credentials to access resources through a proxy server. Understand proxy authentication schemes and security.

6 min read advanced Try in Playground

What is Proxy-Authorization?

TL;DR: Provides authentication credentials to access resources through a proxy server. Sent in response to 407 Proxy Authentication Required challenges.

The Proxy-Authorization header is used to authenticate with a proxy server that requires credentials before forwarding requests to the destination server. It’s like showing your ID to a security guard (the proxy) before they let you through to enter a building (the destination server).

This header is similar to the Authorization header, but it’s specifically for authenticating with proxy servers, not the destination server.

How Proxy-Authorization Works

Request without credentials (first attempt):

GET https://api.example.com/data HTTP/1.1
Host: api.example.com
```text

**Proxy responds with authentication challenge:**

```http
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Corporate Proxy"
Content-Length: 0

Request with credentials:

GET https://api.example.com/data HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
```text

**Proxy forwards request to destination:**

```http
GET /data HTTP/1.1
Host: api.example.com

HTTP/1.1 200 OK
Content-Type: application/json

{"data": "value"}

Syntax

Proxy-Authorization: <type> <credentials>
```text

The format varies by authentication scheme.

### Basic Authentication

```http
Proxy-Authorization: Basic <base64-encoded-credentials>

Credentials format: username:password encoded in Base64

# username: user, password: pass
# "user:pass" → base64 → "dXNlcjpwYXNz"
Proxy-Authorization: Basic dXNlcjpwYXNz
```text

### Bearer Token

```http
Proxy-Authorization: Bearer <token>
Proxy-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```text

### Digest Authentication

```http
Proxy-Authorization: Digest username="user", realm="proxy", nonce="...", uri="/", response="..."

Common Examples

Basic Proxy Authentication

Request:

GET https://api.example.com/users HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==
```text

### Corporate Proxy with Token

```http
GET https://api.example.com/data HTTP/1.1
Host: api.example.com
Proxy-Authorization: Bearer proxy-token-abc123xyz

Multiple Authentications (Proxy and Server)

GET https://api.example.com/protected HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```javascript

The proxy uses `Proxy-Authorization`, the destination server uses `Authorization`.

## Real-World Scenarios

### Corporate Network Access

**JavaScript fetch through corporate proxy:**

```javascript
// Browser automatically handles proxy authentication if configured
// Or manually for Node.js
const https = require('https')
const HttpsProxyAgent = require('https-proxy-agent')

const proxyUrl = 'http://username:password@proxy.company.com:8080'
const agent = new HttpsProxyAgent(proxyUrl)

fetch('https://api.example.com/data', {
  agent: agent
})
  .then((response) => response.json())
  .then((data) => console.log(data))

Node.js with Proxy Authentication

const axios = require('axios')
const HttpsProxyAgent = require('https-proxy-agent')

const proxyAgent = new HttpsProxyAgent({
  host: 'proxy.company.com',
  port: 8080,
  auth: 'username:password'
})

axios
  .get('https://api.example.com/data', {
    httpsAgent: proxyAgent,
    proxy: false // Don't use axios proxy, use agent instead
  })
  .then((response) => console.log(response.data))
```javascript

### Environment-Based Proxy Configuration

```javascript
// Read proxy config from environment
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY

if (proxyUrl) {
  const agent = new HttpsProxyAgent(proxyUrl)

  // Use with fetch
  fetch('https://api.example.com/data', { agent })
}

// Example environment variables:
// HTTPS_PROXY=http://user:pass@proxy.company.com:8080
// HTTP_PROXY=http://user:pass@proxy.company.com:8080
// NO_PROXY=localhost,127.0.0.1,.local

Authenticated Proxy with Certificate Validation

const https = require('https')
const HttpsProxyAgent = require('https-proxy-agent')
const fs = require('fs')

const agent = new HttpsProxyAgent({
  host: 'proxy.company.com',
  port: 8080,
  auth: 'username:password',
  ca: fs.readFileSync('proxy-ca-cert.pem'), // Corporate CA
  rejectUnauthorized: true
})

https.get('https://api.example.com/data', { agent }, (res) => {
  console.log('Status:', res.statusCode)
})
```javascript

## Encoding Credentials

### Basic Authentication Encoding

```javascript
// Encode username:password to Base64
function encodeBasicAuth(username, password) {
  const credentials = `${username}:${password}`
  return Buffer.from(credentials).toString('base64')
}

const encoded = encodeBasicAuth('proxyuser', 'proxypass')
console.log(`Proxy-Authorization: Basic ${encoded}`)
// Output: Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==

Command Line

# Encode credentials
echo -n "username:password" | base64
# Output: dXNlcm5hbWU6cGFzc3dvcmQ=

# Use with curl
curl -x http://proxy.company.com:8080 \
  -H "Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
  https://api.example.com/data

# Or let curl encode it
curl -x http://username:password@proxy.company.com:8080 \
  https://api.example.com/data
```javascript

## Security Considerations

### 1. Use HTTPS for Proxy Connection

```javascript
// Credentials sent in clear text over HTTP proxy
const agent = new HttpsProxyAgent('http://user:pass@proxy.com:8080')

// Use HTTPS proxy or tunnel
const agent = new HttpsProxyAgent('https://user:pass@proxy.com:8443')

2. Don’t Log Credentials

// ❌ Logs contain credentials
console.log('Making request with headers:', {
  'Proxy-Authorization': 'Basic dXNlcjpwYXNz'
})

// ✅ Redact sensitive headers
function sanitizeHeaders(headers) {
  const sanitized = { ...headers }
  if (sanitized['Proxy-Authorization']) {
    sanitized['Proxy-Authorization'] = '[REDACTED]'
  }
  return sanitized
}

console.log('Making request with headers:', sanitizeHeaders(headers))
```javascript

### 3. Store Credentials Securely

```javascript
// ❌ Hardcoded credentials
const proxyAuth = 'Basic dXNlcjpwYXNz'

// ✅ Use environment variables
const proxyAuth = process.env.PROXY_AUTH

// ✅ Or use secrets management
const proxyAuth = await getSecretFromVault('proxy-credentials')

4. Rotate Credentials Regularly

// ✅ Support credential rotation
async function getProxyAuth() {
  // Fetch fresh credentials from secrets manager
  const credentials = await secretsManager.getSecret('proxy-creds')
  return `Basic ${Buffer.from(credentials).toString('base64')}`
}

// Use in request
const proxyAuth = await getProxyAuth()
```javascript

## Best Practices

### 1. Handle 407 Responses

```javascript
async function fetchWithProxyAuth(url, credentials) {
  let response = await fetch(url)

  if (response.status === 407) {
    // Proxy authentication required
    const auth = Buffer.from(credentials).toString('base64')

    response = await fetch(url, {
      headers: {
        'Proxy-Authorization': `Basic ${auth}`
      }
    })
  }

  return response
}

2. Support Multiple Authentication Schemes

function createProxyAuthHeader(scheme, credentials) {
  switch (scheme) {
    case 'Basic':
      return `Basic ${Buffer.from(credentials).toString('base64')}`

    case 'Bearer':
      return `Bearer ${credentials}`

    case 'Digest':
      // Implement digest auth
      return calculateDigestAuth(credentials)

    default:
      throw new Error(`Unsupported scheme: ${scheme}`)
  }
}
```javascript

### 3. Configure Proxy Bypass

```javascript
const NO_PROXY = process.env.NO_PROXY || ''
const noProxyList = NO_PROXY.split(',').map((h) => h.trim())

function shouldUseProxy(url) {
  const hostname = new URL(url).hostname

  // Check if hostname is in no-proxy list
  return !noProxyList.some((pattern) => {
    if (pattern.startsWith('.')) {
      return hostname.endsWith(pattern)
    }
    return hostname === pattern
  })
}

// Use proxy only if needed
if (shouldUseProxy(targetUrl)) {
  options.agent = proxyAgent
}

4. Handle Proxy Errors

async function fetchThroughProxy(url, proxyConfig) {
  const agent = new HttpsProxyAgent(proxyConfig)

  try {
    const response = await fetch(url, { agent })

    if (response.status === 407) {
      throw new Error('Proxy authentication failed')
    }

    if (response.status === 502) {
      throw new Error('Proxy cannot reach destination')
    }

    if (response.status === 504) {
      throw new Error('Proxy timeout')
    }

    return response
  } catch (error) {
    if (error.code === 'ECONNREFUSED') {
      throw new Error('Cannot connect to proxy')
    }
    throw error
  }
}
```javascript

## Common Patterns

### Automatic Proxy Detection

```javascript
function getProxyConfig() {
  // Check environment variables
  const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy
  const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy

  if (httpsProxy) {
    const url = new URL(httpsProxy)
    return {
      host: url.hostname,
      port: url.port,
      auth: url.username && url.password ? `${url.username}:${url.password}` : null
    }
  }

  return null
}

// Use it
const proxyConfig = getProxyConfig()
if (proxyConfig) {
  const agent = new HttpsProxyAgent(proxyConfig)
  // Use agent in requests
}

Proxy Middleware (Express)

const { createProxyMiddleware } = require('http-proxy-middleware')

app.use(
  '/api',
  createProxyMiddleware({
    target: 'https://api.example.com',
    changeOrigin: true,
    onProxyReq: (proxyReq, req, res) => {
      // Add proxy authentication
      const proxyAuth = process.env.PROXY_AUTH
      if (proxyAuth) {
        proxyReq.setHeader('Proxy-Authorization', `Basic ${proxyAuth}`)
      }
    }
  })
)
```text

## Testing

### Test with curl

```bash
# Test proxy authentication
curl -x http://proxy.company.com:8080 \
  --proxy-user username:password \
  https://api.example.com/data

# Or with explicit header
curl -x http://proxy.company.com:8080 \
  -H "Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
  https://api.example.com/data

# Verbose output to see proxy negotiation
curl -x http://proxy.company.com:8080 \
  --proxy-user username:password \
  -v https://api.example.com/data

Test Proxy Connection

async function testProxyConnection(proxyUrl) {
  const agent = new HttpsProxyAgent(proxyUrl)

  try {
    const response = await fetch('https://api.ipify.org?format=json', {
      agent: agent
    })

    if (response.ok) {
      const data = await response.json()
      console.log('Proxy working! External IP:', data.ip)
      return true
    }
  } catch (error) {
    console.error('Proxy test failed:', error.message)
    return false
  }
}

// Test
testProxyConnection('http://user:pass@proxy.company.com:8080')

Difference from Authorization Header

FeatureProxy-AuthorizationAuthorization
PurposeAuthenticate with proxyAuthenticate with server
Used byProxy serverDestination server
Stripped byProxy (not forwarded)Kept through chain
Status code407 (Proxy Auth Required)401 (Unauthorized)
Challenge headerProxy-AuthenticateWWW-Authenticate

Frequently Asked Questions

What is Proxy-Authorization?

Proxy-Authorization sends credentials to authenticate with a proxy server. It is the response to a 407 Proxy Authentication Required challenge.

How is Proxy-Authorization different from Authorization?

Authorization authenticates with the origin server. Proxy-Authorization authenticates with an intermediate proxy. Both can be present in the same request.

What format does Proxy-Authorization use?

Same format as Authorization: scheme followed by credentials. For Basic: "Proxy-Authorization: Basic base64(user:pass)". For other schemes, follow their specification.

Is Proxy-Authorization secure?

Basic scheme sends credentials in base64 (easily decoded). Always use HTTPS between client and proxy, or use more secure schemes like Digest or negotiate.

Keep Learning