T09 · Insecure Skill Coding Practices
- Location
scripts/speed_test.py:72- Finding
Unbounded Test Size Can Cause Memory and Network Resource Exhaustion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/speed_test.py:72-75,scripts/speed_test.py:226, andscripts/speed_test.py:250-253
Vulnerability Type: Uncontrolled resource consumption
Risk Level: MediumVulnerable Code
python def measure_upload(size_bytes=5_000_000, timeout=30): """Measure upload speed using Cloudflare speed test endpoint.""" data = b"0" * size_bytes try:python parser.add_argument("--size", type=float, default=10, help="Test file size in MB (default: 10)")python if do_download: results["download"] = run_download_test(args.size, args.json) if do_upload: results["upload"] = run_upload_test(max(args.size / 2, 1), args.json)The supplied value is subsequently converted into a byte count without any upper-bound or finite-number validation:
python size_bytes = int(size_mb * 1_000_000)Technical Analysis
The
--sizeargument accepts an unrestricted floating-point value. The value controls both the requested download size and the size of the upload body.For an upload,
measure_upload()constructs the entire request body as one in-memory byte string:python data = b"0" * size_bytesA sufficiently large value can therefore cause excessive memory allocation. This allocation occurs before the function's
tryblock, so allocation failures such asMemoryErrorare not handled by its exception handler.The same argument controls how much data is requested from the external download endpoint. An excessive value can consume substantial network bandwidth and execution time. Non-finite values such as
NaNor infinity may also cause an unhandled failure during integer conversion.The issue requires control over the program's command-line arguments. It does not independently grant additional system privileges or permit arbitrary code execution.
Attack Path
- An attacker or untrusted automation mechanism obtains the ability to influence arguments passed to ` ...[truncated 1239 chars]
- Remediation
View remediation
Remediation Suggestions
- Define a conservative maximum permitted test size based on expected operational needs.
- Reject values that are zero, negative, non-finite, or above the configured maximum.
- Implement validation directly in the argument parser so invalid input fails before network or memory operations begin.
- Avoid constructing the complete upload payload in memory. Use a bounded streaming or chunked upload mechanism where supported.
- Move any unavoidable allocation inside explicit exception handling and report resource failures cleanly.
- Consider applying separate limits to download and upload tests because their resource characteristics differ.
Example validation:
python import math MAX_TEST_SIZE_MB = 100.0 def valid_size(value): try: size = float(value) except ValueError as exc: raise argparse.ArgumentTypeError("size must be a number") from exc if not math.isfinite(size): raise argparse.ArgumentTypeError("size must be finite") if size <= 0 or size > MAX_TEST_SIZE_MB: raise argparse.ArgumentTypeError( f"size must be greater than 0 and no more than {MAX_TEST_SIZE_MB} MB" ) return size parser.add_argument( "--size", type=valid_size, default=10.0, help=f"Test file size in MB, up to {MAX_TEST_SIZE_MB} (default: 10)", )The upload implementation should additionally transmit bounded chunks rather than allocating
b"0" * size_bytesas one object.
