Hacktricks-skills integer-overflow-web-testing
Test for integer overflow and truncation vulnerabilities in web applications. Use this skill whenever you need to audit numeric parameters, file parsers, length headers, or business logic calculations for wrap-around bugs. Trigger this skill for any security testing involving: numeric request parameters (id, offset, count), Content-Length or WebSocket frame lengths, image/file format metadata, price/coupon calculations, or pagination arguments. Don't skip this skill when reviewing code that performs arithmetic on user input.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xss-cross-site-scripting/integer-overflow/SKILL.MDInteger Overflow Testing for Web Applications
This skill helps you identify and exploit integer overflow/truncation vulnerabilities in web applications. Even in memory-safe languages, underlying runtimes and libraries often use C/C++ where 32-bit or 64-bit wrap-around can transform harmless parameters into out-of-bounds reads/writes, logic bypasses, or DoS conditions.
When to Use This Skill
Use this skill when:
- Testing numeric request parameters (
,id
,offset
,count
)limit - Auditing length/size headers (
, WebSocket frame length, HTTP/2 continuation_len)Content-Length - Reviewing file format parsers (image dimensions, chunk sizes, font tables)
- Checking business logic calculations (prices, coupons, balances, pagination)
- Analyzing code with signed↔unsigned casts or type conversions
- Security testing any application that performs arithmetic on user-controlled input
Attack Surface Overview
- Numeric request parameters - Classic
,id
,offset
fields in GET/POSTcount - Length/size headers -
, WebSocket frame length, HTTP/2 fieldsContent-Length - File-format metadata - Image dimensions, chunk sizes, font tables parsed server-side or client-side
- Language-level conversions - Signed↔unsigned casts in PHP/Go/Rust FFI, JS
→Number
truncations in V8int32 - Authentication & business logic - Coupon values, prices, balance calculations that silently overflow
Testing Strategy
Step 1: Identify Integer Inputs
Look for these patterns in requests and code:
GET /api/items?id=123&offset=0&count=50 HTTP/1.1 Content-Length: 256 X-Custom-Size: 1024
$price = (int)$_POST['price']; $total = $price * 100;
const buffer = new ArrayBuffer(size * 4); // size from user input
Step 2: Send Boundary Values
Use the boundary value cheat-sheet. Send these extreme signed/unsigned values wherever an integer is expected:
Critical boundaries:
-1, 0, 1
(8-bit boundaries)127, 128, 255, 256
(16-bit boundaries)32767, 32768, 65535, 65536
(32-bit boundaries)2147483647, 2147483648, 4294967295
(64-bit boundaries)9223372036854775807, 9223372036854775808
(hex representations)0x7fffffff, 0x80000000, 0xffffffff
Additional formats to try:
- Hex:
,0x1000x7fffffff - Octal:
0377 - Scientific notation:
,1e109.99e18 - JSON big-int:
9999999999999999999 - Very long digit strings (>1kB) to hit custom parsers
Step 3: Use Automated Testing
Burp Intruder template:
§INTEGER§ Payload type: Numbers From: -10 To: 4294967300 Step: 1 Pad to length: 10, Enable hex prefix 0x
Fuzzing tools:
- AFL++/Honggfuzz with
harness around parsers (WebP, PNG, protobuf)libFuzzer - Fuzzilli - Grammar-aware fuzzing of JavaScript engines for V8/JSC integer truncations
- boofuzz - Network-protocol fuzzing (WebSocket, HTTP/2) focusing on length fields
Step 4: Analyze Responses
Watch for these indicators of integer overflow:
| Indicator | What it means |
|---|---|
| Crash / 500 error | Buffer overflow or invalid memory access |
| Unexpected success | Logic bypass (negative value wrapped to positive) |
| Slow response / timeout | Memory exhaustion or DoS |
| Different response size | Truncation changed buffer allocation |
| Data corruption | Out-of-bounds read/write |
Exploitation Patterns
Pattern 1: Logic Bypass in Server-Side Code
Vulnerable PHP example:
$price = (int)$_POST['price']; // expecting cents (0-10000) $total = $price * 100; // ← 32-bit overflow possible if($total > 1000000){ die('Too expensive'); } // Sending price=21474850 → $total wraps to -2147483648 and check is bypassed
Test: Send
price=21474850 and verify the expensive check is bypassed.
Pattern 2: Heap Overflow via Image Decoder
Real-world example (CVE-2023-4863): The WebP lossless decoder multiplied
width × height × 4 (RGBA) inside a 32-bit int. A crafted file with dimensions 16384 × 16384 overflows the multiplication, allocates a short buffer, and writes ~1GB of decompressed data past the heap.
Test: Create images with extreme dimensions and observe allocation behavior.
Pattern 3: Browser-Based XSS/RCE Chain
- Integer overflow in V8 gives arbitrary read/write
- Escape the sandbox with a second bug or call native APIs
- Inject malicious script into origin context → stored XSS
Defensive Guidelines
When reviewing code or recommending fixes:
-
Use wide types or checked math
instead ofsize_t
for sizesint- Rust:
,checked_addchecked_mul - Go:
,math/bits.Add64math/bits.Mul64
-
Validate ranges early
- Reject any value outside business domain before arithmetic
- Example:
if ($price < 0 || $price > 10000) die('Invalid price');
-
Enable compiler sanitizers
(Clang/GCC)-fsanitize=integer- UBSan (UndefinedBehaviorSanitizer)
- Go race detector
-
Adopt fuzzing in CI/CD
- Combine coverage feedback with boundary corpora
- Test parsers with extreme values automatically
-
Stay patched
- Browser integer overflow bugs are frequently weaponized within weeks
- Monitor CVE databases for relevant vulnerabilities
Recent Real-World Vulnerabilities
| Year | Component | Root Cause | Impact |
|---|---|---|---|
| 2023 | libwebp (CVE-2023-4863) | 32-bit multiplication overflow in decoded pixel size | Chrome 0-day RCE (BLASTPASS on iOS) |
| 2024 | V8 (CVE-2024-0519) | Truncation to 32-bit when growing JSArray | Remote code execution after single visit |
| 2025 | Apollo GraphQL Server | 32-bit signed int for pagination args; negative wraps to huge positive | Logic bypass & memory exhaustion (DoS) |
Quick Reference
Most common overflow points:
width * height * bytes_per_pixelcount * element_sizeoffset + lengthprice * quantity
pagination argumentsfirst/last
Quick test command:
# Test with boundary values curl -X POST http://target/api/checkout \ -d "price=2147483648&quantity=1" curl -X GET "http://target/api/items?offset=-1&count=4294967295"