Validate storage region to prevent hostname injection#15
Conversation
StorageClient::new() now rejects unknown --region values against a whitelist of known Bunny CDN regions. Previously, an attacker-controlled region like "evil.com" would produce https://evil.com.bunnycdn.com and send the AccessKey header to an attacker-controlled host. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR hardens the Edge Storage client construction path by rejecting unexpected/unsafe region values, preventing caller-controlled input from influencing the request hostname in a way that could leak the AccessKey header.
Changes:
- Add a
VALID_REGIONSallowlist and validateregioninbunny-api-storage::StorageClient::new. - Make
StorageClient::newfallible (Result<Self>) and update CLI call sites to propagate errors. - Add unit tests for valid, unknown, and empty region inputs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/commands/storage.rs |
Propagates the now-fallible StorageClient::new(..)? and keeps debug/record configuration behavior intact. |
crates/bunny-api-storage/src/client.rs |
Introduces region allowlist validation in the storage client constructor and adds targeted unit tests. |
| pub fn new(region: &str, access_key: impl Into<String>) -> Result<Self> { | ||
| if !VALID_REGIONS.contains(®ion) { |
There was a problem hiding this comment.
StorageClient::new now returns Result<Self> instead of Self, which is a breaking public API change for bunny-api-storage consumers. If this crate is published/semver-tracked, consider either (a) bumping the crate version accordingly, or (b) keeping the old new signature (e.g., delegating to a fallible try_new) to preserve source compatibility while still preventing hostname injection.
There was a problem hiding this comment.
This crate is 0.1.0, unpublished, and only consumed within the workspace — the breaking change is intentional and all call sites are updated in this PR. No version bump needed.
Summary
StorageClient::new()now validates--regionagainst a whitelist of known Bunny CDN storage regions (storage,uk,ny,la,sg,syd,br,jh,se)--region evil.comvalue would constructhttps://evil.com.bunnycdn.comand send theAccessKeyheader to an attacker-controlled hostTest plan
cargo fmt— cleancargo clippy -- -D warnings— cleancargo test— all tests passhoppy storage ls --zone test --region evil.comnow returns an errorhoppy storage ls --zone test --region lastill works🤖 Generated with Claude Code