Harden ProgressBar against local DoS from unbounded width/maxval and widget output#86
Merged
NiltonVolpato merged 3 commits intomasterfrom Feb 24, 2026
Merged
Conversation
Co-authored-by: NiltonVolpato <761595+NiltonVolpato@users.noreply.github.com>
Co-authored-by: NiltonVolpato <761595+NiltonVolpato@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix DoS vulnerabilities via resource exhaustion in progressbar
Harden ProgressBar against local DoS from unbounded width/maxval and widget output
Feb 24, 2026
NiltonVolpato
approved these changes
Feb 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
progressbaraccepted unboundedterm_width,maxval, and widget output, allowing local resource exhaustion (large allocations and expensive arithmetic) through constructor args, environment (COLUMNS), and resize handling. This change introduces strict bounds and normalization on those high-amplification paths while preserving existing API behavior.Input bounds in
ProgressBarProgressBar._MAX_TERMSIZE = 4096andProgressBar._MAX_MAXVAL = 10**12._sanitize_term_width()and_sanitize_maxval()and applied them to:term_width,maxval)__call___env_size()_handle_resize()maxvalnow raisesValueErrorwith specific messages; terminal width is clamped.Widget output size guard
widgets._MAX_UPDATABLE_LENGTH = 4096.format_updatable()now normalizes output (None/non-string) and truncates oversized strings before formatting/joining.Focused regression coverage
term_widthclampingCOLUMNSclampingmaxvalOriginal prompt
This section details on the original issue you should resolve
<issue_title>Multiple Local Denial of Service (DoS) vulnerabilities via resource exhaustion</issue_title>
<issue_description>Description:
The progressbar library contains multiple input validation flaws that allow local Denial of Service (DoS) attacks. An attacker can cause memory exhaustion or CPU overload by passing extreme values to constructor parameters.
Tested Environment:
OS: Arch Linux (virtual machine)
Memory: 3.7GB RAM
Vulnerability Details:
FLAW #1: term_width Parameter Without Validation
....
Why it happens:
term_width is used directly in ljust()/rjust() without size validation
If term_width = 1,000,000, each update creates a 1MB string
After 100 updates → 100MB allocated → MemoryError and crash
FLAW #2: maxval Parameter Without Validation
Why it happens:
maxval can be 10**100 (googol) without validation
Each update calculates currval * 100.0 / maxval
Divisions with astronomical numbers consume excessive CPU
Result: 100% CPU usage, slow system, timeouts
FLAW #3: Iterator Without Iteration Limit
Why it happens:
__iterable can be an infinite generator (while True: yield)
update() is called on each iteration → cumulative resource consumption
Result: Infinite loop + continuous allocation → memory/CPU crash
FLAW #4: Interval Calculation Without Protection
Why it happens:
num_intervals = max(100, term_width) → if term_width=10^6, num_intervals=10^6
update_interval = maxval / num_intervals → if maxval=10^100, division with huge numbers
Result: Heavy calculations on each update
FLAW #5: Widgets Can Return Huge Strings
Why it happens:
Widgets can implement update() without limits
Return value is concatenated into the final string
Result: Exponential memory allocation
FLAW #6: Environment Can Be Manipulated
Why it happens:
Attacker can set COLUMNS=1000000 in the environment
term_width will be set to 999999
Result: DoS via environment without passing direct parameters
FLAW #7: Signal Handler Without Protection
Why it happens:
ioctl() with '\0'*8 buffer may not be safe
If w is huge (e.g., 65535), term_width becomes gigantic
Result: Next update creates massive string
FLA...
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.