You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pentesting-web/xss-cross-site-scripting/integer-overflow.md
+72-6Lines changed: 72 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,9 +29,9 @@ Typical attack surface:
29
29
30
30
| Year | Component | Root cause | Impact |
31
31
|------|-----------|-----------|--------|
32
-
| 2023 |**libwebp – CVE-2023-4863**|32-bit multiplication overflow when computing decoded pixel size|Triggered a Chrome 0-day (`BLASTPASS` on iOS), allowed *remote code execution* inside the renderer sandbox. |
33
-
| 2024 |**V8 – CVE-2024-0519**|Truncation to 32-bit when growing a `JSArray` leads to OOB write on the backing store | Remote code execution after a single visit. |
34
-
|2025|**Apollo GraphQL Server**(unreleased patch) | 32-bit signed integer used for `first/last` pagination args; negative values wrap to huge positives | Logic bypass & memory exhaustion (DoS). |
32
+
| 2023 |**libwebp – CVE-2023-4863**|Malformed WebP lossless Huffman tables caused a heap overflow while building decoder lookup tables|A single malicious image was enough to get **heap corruption / renderer RCE** in Chromium-based browsers.|
33
+
| 2024 |**Chrome Layout – CVE-2024-7025**|Integer overflow in the rendering/layout pipeline reachable from a crafted HTML page | Demonstrates that integer bugs are not limited to JS engines: **HTML/CSS alone** can be enough to reach heap corruption.|
34
+
|2024|**Chrome Skia – CVE-2024-9123**| Integer overflow in the graphics stack while processing crafted HTML content | A page visit could trigger an **out-of-bounds memory write** in the renderer. |
35
35
36
36
---
37
37
@@ -69,6 +69,43 @@ Pad to length: 10, Enable hex prefix 0x
69
69
***Fuzzilli** – grammar-aware fuzzing of JavaScript engines to hit V8/JSC integer truncations.
70
70
***boofuzz** – network-protocol fuzzing (WebSocket, HTTP/2) focusing on length fields.
71
71
72
+
### 3.4 JavaScript and browser coercion cases worth forcing
73
+
74
+
Not every web integer bug is a native-style `size_t` wraparound. A lot of exploitable web logic starts with a **representation mismatch**:
75
+
76
+
* JavaScript numbers are IEEE-754 doubles, so integers above `Number.MAX_SAFE_INTEGER` (`2^53 - 1`) lose precision.
77
+
* Legacy code frequently uses bitwise operators such as `|0`, `~~x`, `x<<0`, or `x>>>0`, which **coerce values to 32-bit signed/unsigned integers**.
78
+
* Browser-facing code often parses a value once in JS and a second time in the backend, producing different range checks and different final values.
79
+
80
+
Useful probes:
81
+
82
+
```javascript
83
+
// Precision loss above 2^53-1
84
+
JSON.parse('{"n":9007199254740993}').n
85
+
86
+
// Signed wrap to negative
87
+
(2147483648|0) // -2147483648
88
+
89
+
// Unsigned wrap to a huge positive
90
+
(-1>>>0) // 4294967295
91
+
92
+
// Common "fast truncation" gadget in legacy code
93
+
(4294967297|0) // 1
94
+
```
95
+
96
+
When a target mixes client-side validation with API-side validation, replay the same field as:
97
+
98
+
* JSON number vs JSON string
99
+
* decimal vs hex-like string (`4294967295` vs `0xffffffff`)
100
+
* plain integer vs scientific notation (`10000000000` vs `1e10`)
101
+
* positive vs negative boundary (`2147483647`, `2147483648`, `-1`, `4294967295`)
102
+
103
+
Interesting symptoms:
104
+
105
+
* Pagination or `limit` checks pass, but the query executes with `0`, `-1`, or a huge unsigned value.
106
+
* Frontend blocks a value while the backend accepts it after a second parse.
107
+
* A value displayed in the UI is not the value finally used by the API / renderer / WASM module.
108
+
72
109
---
73
110
74
111
## 4. Exploitation patterns
@@ -84,13 +121,42 @@ if($total > 1000000){
84
121
```
85
122
86
123
### 4.2 Heap overflow via image decoder (libwebp 0-day)
87
-
The WebP lossless decoder multiplied image width × height × 4 (RGBA) inside a 32-bit `int`. A crafted file with dimensions `16384 × 16384` overflows the multiplication, allocates a short buffer and subsequently writes **~1GB** of decompressed data past the heap – leading to RCE in every Chromium-based browser before 116.0.5845.187.
124
+
The WebP lossless decoder bug behind `CVE-2023-4863` was a good reminder that browser bugs still start with simple arithmetic mistakes around attacker-controlled metadata. In practice, a crafted image can make the decoder build invalid Huffman lookup tables and write past the heap before consistency checks finish. For web testing this means that **image dimensions, chunk sizes, color-table counts and compression metadata** are still first-class attack surface when the browser or the backend parses user-supplied files.
88
125
89
126
### 4.3 Browser-based XSS/RCE chain
90
127
1.**Integer overflow** in V8 gives arbitrary read/write.
91
128
2. Escape the sandbox with a second bug or call native APIs to drop a payload.
92
129
3. The payload then injects a malicious script into the origin context → stored XSS.
93
130
131
+
### 4.4 Web logic bug → DOM XSS via integer truncation
132
+
133
+
This pattern is much more common in pentests than full renderer RCE:
134
+
135
+
```javascript
136
+
constraw=JSON.parse(location.hash.slice(1)).len;
137
+
constlen= raw |0; // "fast" int cast to signed 32-bit
138
+
139
+
if (len <=64) {
140
+
preview.innerHTML=userInput.slice(0, len);
141
+
}
142
+
```
143
+
144
+
If `raw=4294967295`, then `len` becomes `-1`. Depending on the surrounding code, this may:
145
+
146
+
* bypass a max-length check,
147
+
* make `slice(0, -1)` drop the last character and preserve the rest of the payload,
148
+
* or desynchronize validation and the eventual sink (`innerHTML`, template renderer, markdown preview, etc.).
149
+
150
+
The offensive lesson is simple: whenever you see **bitwise truncation in client-side code**, test whether the sanitized/validated length is the same value that later reaches the DOM sink.
151
+
152
+
### 4.5 WASM note
153
+
154
+
If the target uses Emscripten/WASM, a single integer bug in linear-memory management can often be upgraded into DOM XSS by corrupting writable HTML templates instead of the sanitized source string:
155
+
156
+
{{#ref}}
157
+
wasm-linear-memory-template-overwrite-xss.md
158
+
{{#endref}}
159
+
94
160
---
95
161
96
162
## 5. Defensive guidelines
@@ -107,6 +173,6 @@ The WebP lossless decoder multiplied image width × height × 4 (RGBA) inside a
0 commit comments