AWS policy variable resolution can loop forever (`resolve_single_pass`), hanging a worker thread
概要
Summary
resolve_aws_variables has an outer max_iterations = 10 guard, but the loop that diverges is one level down in resolve_single_pass, which the guard never gets to run. On crafted resolver values a substituted variable re-forms a ${...} that the pass rescans, so resolution never te...
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 直った版 |
|---|---|---|---|
| other | rustfs-policy |
= 1.0.1 |
1.0.2 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Summary
resolve_aws_variables has an outer max_iterations = 10 guard, but the loop that diverges is one level down in resolve_single_pass, which the guard never gets to run. On crafted resolver values a substituted variable re-forms a ${...} that the pass rescans, so resolution never terminates and the task spins without yielding, pinning a worker thread. If the crafted values are reachable through an attacker-influenced username, account id, or JWT claim, this is a denial of service.
Details
Policy variables are resolved in crates/policy/src/policy/variables.rs:
resolve_aws_variables(:254) loopswhile changed && iteration < max_iterationswithmax_iterations = 10(:258) and callsresolve_single_pass(:267).resolve_single_pass(:296) walks a string withwhile i < results.len()and advancesionly when a pass makes no change (if !modified { i += 1 },:392). On a successful substitution it doesresults.splice(...); modified = true; break(:366,:377), leavingifixed, and the next round rescans the same string fromstart = 0viaresults[i][start..].find("${")(:307). A${produced by a substitution is therefore found and expanded again.
Because the divergence is inside resolve_single_pass, control never returns to the max_iterations = 10 check, so that guard does not bound it.
Crafted values that trigger the cycle (neither value itself contains ${):
aws:AccountId=$$aws:username= `{aws:A…
出典: GitHub Repository Security Advisories (Game のスタック) GitHub Advisory OSV
参照URL
- GITHUB_REPO_ADVISORY rustfs/rustfs