aws / aws/aws-cli

cloudfront: unique_string() uses non-cryptographic random, risking CallerReference collision

Open
#10,281 2 comments 0 reactions 1 assignee Claimed by @RyanFitzSimmonsAK View on GitHub
bug cloudfront p3
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.