awslabs / awslabs/aws-sdk-rust
Invalid presigned URL when region is not configured
- Dominant language
- Rust
- Stars
- 3.3k
- Forks
- 290
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 3
Description
### Describe the bug
If you try to create a presigned URL without a region configured, it will succeed, but the URL will be invalid.
### Expected Behavior
If there's no region to sign the URL with, it should fail to generate the presigned URL (`Result::Err`).
### Current Behavior
It returns an invalid (unsigned) URL without an endpoint:
```
PresignedRequest {
method: GET,
uri: /test?x-id=GetObject,
headers: {},
}
```
A valid presigned URL looks more like:
```
PresignedRequest {
method: GET,
uri: https://bucket.s3.us-east-2.amazonaws.com/test?x-id=GetObject&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=redacted&X-Amz-Date=redacted&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=redacted&X-Amz-Security-Token=redacted,
headers: {},
}
```
### Reproduction Steps
This reliably reproduces the issue if there is no region configured in the AWS config:
```rust
use aws_sdk_s3::presigning::PresigningConfig;
use std::time::Duration;
#[tokio::main]
async fn main() {
let config = aws_config::load_from_env().await;
let client = aws_sdk_s3::Client::new(&config);
let presigned = client
.get_object()
.bucket("bucket")
.key("test")
.presigned(
PresigningConfig::builder()
.expires_in(Duration::from_secs(5 * 60))
.build()
.expect("valid expiration time"),
)
.await
.unwrap();
dbg!(presigned);
}
```
It's possible to make the above snippet produce a valid presigned URL by simply changing the config line to:
```rust
let config = aws_config::from_env().region("us-east-2").load().await;
```
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### Version
```text
aws-sdk-s3 0.29.0, aws-config 0.56.0 (August 3, 2023 release)
```
### Environment details (OS name and version, etc.)
MacOS
### Logs
_No response_
Contributor guide
Research direction
Start by running the Rust reproduction with aws_config::load_from_env and the S3 get_object().presigned entry point, then compare it with a region-configured client. Trace the presigning path to determine how missing-region requests produce the shown unsigned URI. Done means the missing-region case returns Result::Err while the configured-region case still produces a valid signed URL.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, rust
- Domain
- cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100