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

Open
#111 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

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

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.

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:

 template<class Res, class Iter>
 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<Res>::max() - 9) / 10) { n = (1<<20); break; }
+        n = n*10 + (*start - '0');
+    }
     return n;
 }

Dominant language
C++
Stars
31
Forks
53
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from boostorg/format

All issues in boostorg/format

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.