boostorg / boostorg/format

boost::format %Nt tabulation: unchecked str2int -> unbounded std::string allocation

Open
#111 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
31
Forks
53
PR merge metrics
No merged PRs in 30d

Description

We are filing this as hardening and not as a security advisory. This is one of two issues the Netskope Threat Labs team discovered and is reporting. They share no root cause with this report and can be triaged independently.

## Technical details

| | |
|---|---|
| **Component** | `boost/format/parsing.hpp:70-83,178-180,233-234,314-318; format_implementation.hpp:228,233-238,257-263` |
| **Upstream tested** | boostorg/format @ 3fb39d7d (develop HEAD) |
| **Class** | CWE-190 -> CWE-789 uncontrolled allocation (DoS, not OOB - std::string throws first) |
| **Severity** | LOW — CVSS ~3.7 |
| **Reachability** | `boost::format(attacker_format_string)` |
---

## Root cause

str2int multiplies/adds digit-by-digit into signed Res, no overflow/magnitude check. %Nt tabulation -> width_ -> str() reserves/appends width_ chars.

## Trigger

boost::str(boost::format("%2147483647t")); // 13-byte format string -> ~2GiB alloc attempt

## Upstream status

Present in vendored 1.65; needs check vs boost develop HEAD

## Suggested fix

Clamp `str2int()` result to a sane bound (e.g. `1<<20`) so `%Nt` width and `%N$` position cannot reach overflow/huge-alloc territory:

```diff
template
Res str2int (Iter& start, Iter last, ...) {
Res n = 0;
- for (; start != last && isdigit(*start); ++start)
- n = n*10 + (*start - '0');
+ for (; start != last && isdigit(*start); ++start) {
+ if (n > (std::numeric_limits::max() - 9) / 10) { n = (1<<20); break; }
+ n = n*10 + (*start - '0');
+ }
return n;
}
```

---

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in boost/format/parsing.hpp, especially str2int at the listed ranges, then trace how %Nt reaches width_ and allocation in format_implementation.hpp. Verify the overflow path is bounded for the supplied large-width trigger and that normal format parsing remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.