cloudfront: unique_string() uses non-cryptographic random, risking CallerReference collision
- Dominant language
- Python
- Stars
- 17.3k
- Forks
- 4.6k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 13
Description
## Describe the bug
`unique_string()` in `awscli/customizations/cloudfront.py` generates the `CallerReference` for `create-invalidation` and `create-distribution` using `random.randint(1, 1000000)` combined with a Unix timestamp (1-second precision):
```python
def unique_string(prefix='cli'):
return '%s-%s-%s' % (prefix, int(time.time()), random.randint(1, 1000000))
```
Because the timestamp component has only 1-second granularity, two invocations within the same second share the same timestamp and have a 1-in-1,000,000 chance of generating an identical `CallerReference`. When this collision occurs, CloudFront treats the second request as a duplicate and silently ignores it.
Additionally, Python's `random` module uses the Mersenne Twister algorithm and is not cryptographically secure, which is inappropriate for generating values that are expected to be unique and unpredictable.
## Regression Issue
- [ ] Select this option if this issue appears to be a regression.
## Expected Behavior
Every CLI invocation generates a unique `CallerReference`, regardless of how quickly consecutive commands are executed.
## Current Behavior
When `create-invalidation` or `create-distribution` is called more than once within the same second, there is a 1/1,000,000 probability of a `CallerReference` collision. In that case, CloudFront treats the second request as a duplicate and does not create a new invalidation or distribution.
## Reproduction Steps
```bash
# Run two invalidations within the same second
for i in 1 2; do
aws cloudfront create-invalidation --distribution-id YOUR_DIST_ID --paths "/*" &
done
wait
```
If the two calls land in the same second and happen to generate the same random number, only one invalidation will be created.
## Possible Solution
Replace `random.randint` with `uuid.uuid4()`, which provides 122 bits of cryptographically random entropy and eliminates both the timestamp dependency and collision risk:
```python
import uuid
def unique_string(prefix='cli'):
return '%s-%s' % (prefix, uuid.uuid4())
```
`uuid` is already part of the Python standard library and requires no additional dependencies.
## Additional Information/Context
Affected code locations:
- `awscli/customizations/cloudfront.py:66` — `unique_string()` definition
- `awscli/customizations/cloudfront.py:86` — used in `PathsArgument.add_to_params()` for `create-invalidation --paths`
- `awscli/customizations/cloudfront.py:102` — used in `ExclusiveArgument.distribution_config_template()` for `create-distribution`
## CLI version used
1.45.4
## Environment details (OS name and version, etc.)
macOS 15.4 (Darwin 25.4.0, arm64) / Python 3.14.4
Contributor guide
Assessment
This issue has not been assessed yet.