Proxy Credential Encoding Validation: Prevent 407 Errors and Secret Leaks

Proxy credentials often work in one tool and fail in another because the same logical username and password cross different parsing boundaries. A dedicated username field may expect the original value, while URL user information may require percent-encoding. A shell can transform characters before the client sees them, and a client may decode them again. The result is frequently reported as a proxy authentication failure even when the account is valid.

Colorful internet traffic passes through transparent encoding prisms into a clean proxy gateway with separated credential capsules

This guide provides a controlled acceptance test for proxy credential handling. It is designed for authorized data collection, browser testing, ad verification and market research. The goal is not to discover a universal encoding rule; it is to prove what each configuration surface actually sends while keeping secrets out of source code, logs and evidence.

The three boundaries that cause most failures

Configuration boundary. A client can expose separate server, username and password fields, a combined username-and-password field, or one proxy URL. These interfaces do not necessarily apply the same decoding rules.

Serialization boundary. Characters such as :, @, %, spaces, backslashes and non-ASCII text can have structural meaning when serialized into a URL. Encoding a value twice is just as damaging as not encoding it where required.

Execution boundary. Interactive shells, CI variable expansion, YAML, JSON and command wrappers may transform quoting or escape sequences before the network client receives them.

Treat each boundary as a separate testable layer. A 407 status alone does not identify which layer changed the credential.

Prefer structured credential fields

When a supported client exposes separate fields, use them. Playwright, for example, accepts proxy server, username and password as separate options. This avoids placing the secret inside a URL and reduces ambiguity about which component should perform URL parsing.

const browser = await chromium.launch({
  proxy: {
    server: process.env.PROXY_SERVER!,
    username: process.env.PROXY_USERNAME!,
    password: process.env.PROXY_PASSWORD!,
  },
});

The environment variables should be supplied by an approved secret store. Do not print the configuration object. Separate fields do not remove the need to verify behavior, but they create a cleaner ownership boundary: the application provides logical values and the client performs protocol serialization.

Know when URL decoding is documented

curl documents a specific behavior for proxy credentials: the username and password supplied in its proxy credential string are URL-decoded before use. That permits encoded delimiters such as %40 for @ and requires a colon inside the username to be represented so it is not mistaken for the username/password separator. This is a client-specific contract, not a rule to copy blindly into every SDK.

curl --proxy "$PROXY_SERVER" \
  --proxy-user "$PROXY_USERPASS" \
  --fail-with-body "$AUTHORIZED_TEST_URL"

Build PROXY_USERPASS in a protected configuration layer, not in a public command history. Never paste a real password into tickets or examples. If the API accepts separate fields, do not pre-encode the password unless that API explicitly requires it.

Build a disposable character matrix

Ask the provider or credential administrator for a short-lived test credential on an isolated account. Create one case per character class instead of combining every difficult character at once.

CaseCharacter classWhat it detects
baselineletters and digitsaccount and route validity
delimitercolon and at signURL component confusion
escape markerpercent signaccidental decoding or double encoding
whitespacespacetrimming and quoting defects
path-likeslash and backslashURL and runner escaping
Unicodeapproved non-ASCII sampleinconsistent character encoding

Use synthetic values and store only a case ID plus a one-way fingerprint in evidence. The matrix should never reveal the test secret itself.

A seven-step acceptance test

1. Prove the clean baseline

Use a simple disposable credential through the provider-supported client. Record the proxy route, expected region, destination status and a sanitized exit fingerprint. If this baseline fails, stop; encoding experiments will not isolate the problem.

2. Freeze every other variable

Keep the endpoint, protocol, authentication scheme, destination, region and request unchanged. Change only one credential character class at a time.

3. Test structured configuration first

Pass the original logical values through separate fields. If this succeeds, it becomes the reference result for that client. If it fails, inspect configuration loading and secret injection before adding encoding.

4. Test serialized forms only where required

For a proxy URL or a documented combined field, encode only the relevant URL component. Do not encode the complete URL, and do not reuse an encoded value in a raw password field.

5. Compare execution environments

Run the same case from a local argument array and the CI runner. If local succeeds but CI fails, inspect YAML quoting, variable interpolation, newline handling and secret masking. Avoid interactive shell commands for production workflows.

6. Classify the observed failure

  • configuration parse error: the client rejected the value before connecting;
  • name resolution or connection error: the proxy endpoint was not reached;
  • tunnel or TLS error: authentication may have succeeded but the next hop failed;
  • HTTP 407: the proxy rejected or did not receive acceptable credentials;
  • destination response: the proxy path completed and the target answered.

Confirm the provider actually observed the attempt before attributing a 407 to account permissions. The proxy authentication 407 troubleshooting guide provides a broader layer-by-layer workflow.

7. Pin the proven contract

Document the accepted configuration surface, whether values are logical or serialized, the responsible encoder, tested runtime versions and the redaction policy. Add the character matrix to continuous integration using disposable credentials.

Detect double encoding without exposing secrets

Do not log authorization headers or full proxy URLs. Instead, calculate a one-way fingerprint of the logical test value and a separate fingerprint after the application’s intended serialization step. Record lengths, character-class case IDs and the responsible code path.

If a percent marker becomes its encoded representation and is then encoded again, the receiving side may decode only once and authenticate with the wrong value. The safe fix is to establish one serialization owner, not to add another decode step at random.

Operational evidence schema

test_case_id
client_name
client_version
configuration_surface
runner_type
logical_value_fingerprint
serialized_value_fingerprint
expected_proxy_route
provider_attempt_observed
result_class
http_status
exit_fingerprint
redaction_check
timestamp

Keep proxy passwords, full usernames, authorization headers, cookies and full proxy URLs out of the record. Apply the controls in the proxy HAR credential redaction guide, and rotate any credential that appears in a log using the proxy credential rotation playbook.

Release checklist

  • [ ] The credential is disposable, scoped and short-lived.
  • [ ] A simple baseline succeeds before special-character testing.
  • [ ] Endpoint, route, protocol and destination remain fixed.
  • [ ] Structured username and password fields are preferred.
  • [ ] Encoding is applied only to the documented component.
  • [ ] Exactly one layer owns serialization.
  • [ ] Local and CI execution paths are tested separately.
  • [ ] Shell history and process output contain no secret.
  • [ ] Logs redact proxy URLs and authorization material.
  • [ ] Failures are classified before credentials are rotated.
  • [ ] Mandatory proxy traffic fails closed rather than bypassing directly.
  • [ ] The provider and destination permit the test traffic.

FAQ

Should every special character be percent-encoded?

No. It depends on the configuration surface. A URL component may require encoding, while a dedicated password field may expect the original logical value. Follow the exact client contract and test it.

Does HTTP 407 always mean the password is wrong?

No. The proxy did not accept the presented authentication, but parsing, encoding, scheme selection, account policy or secret injection may have changed what was presented.

Can I inspect the outgoing authorization header?

Avoid capturing real authorization material. Use disposable credentials, client diagnostics that redact secrets and provider-side confirmation of the attempt. Treat any accidental capture as a credential exposure.

Why does a command work locally but fail in CI?

The shell, YAML parser, variable store or wrapper may handle special characters or trailing newlines differently. Compare fingerprints and configuration boundaries rather than printing the secret.

Compliance note

Use proxies only for lawful, authorized testing and collection. Respect destination terms, robots directives, privacy and data-protection requirements, rate limits and provider policies. Credential validation must use approved accounts and disposable secrets. Do not use it to guess credentials, bypass access controls, conceal prohibited activity or obtain data without permission.