Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

(Fix) Strict numeric validation for announce fields#5530

Open
skavinski-lab wants to merge 3 commits into
HDInnovations:developmentHDInnovations/UNIT3D:developmentfrom
skavinski-lab:fix/announce-numeric-validationskavinski-lab/UNIT3D:fix/announce-numeric-validationCopy head branch name to clipboard
Open

(Fix) Strict numeric validation for announce fields#5530
skavinski-lab wants to merge 3 commits into
HDInnovations:developmentHDInnovations/UNIT3D:developmentfrom
skavinski-lab:fix/announce-numeric-validationskavinski-lab/UNIT3D:fix/announce-numeric-validationCopy head branch name to clipboard

Conversation

@skavinski-lab

@skavinski-lab skavinski-lab commented Jul 18, 2026

Copy link
Copy Markdown

The announce endpoint validated uploaded, downloaded, left, numwant and corrupt with only is_numeric($value) || $value < 0. Two problems:

  • There's no upper bound. uploaded=9000000000000000000 passes (it's under PHP_INT_MAX), and the delta over the stored peer base is credited straight into users.uploaded by ProcessAnnounce. One request with a valid passkey grants a huge amount of upload credit.
  • Scientific notation slips through. is_numeric('1e19') is true and '1e19' < 0 is false, but (int) '1e19' overflows to a negative value on 64-bit. That negative flows into the Redis peer/history batches and gets upserted into unsignedBigInteger columns, which fails the whole AutoUpsertPeers/AutoUpsertHistories transaction.

Fix: require plain non-negative decimal integers with ctype_digit(), capped at a new MAX_ANNOUNCE_VALUE constant of 1 PiB, well above any real per-session client total. Applied to port, uploaded, downloaded, left, numwant and corrupt. The now-redundant ctype_digit() in the port check is dropped since validation runs before it.

Tests: added cases for oversized values, scientific notation, negatives, floats, whitespace padding, hex, MAX_ANNOUNCE_VALUE + 1, and a passing boundary at exactly 1 PiB.

Conforming clients send decimal integers in range, so nothing changes for them. Malformed or out-of-range values now get failure 134 instead of being silently miscast.

is_numeric() and (int) casts accepted floats and scientific notation
(e.g. "1e19"), and no upper bound existed. A client could credit
itself ~9.2 exabytes of upload in a single announce, and out-of-range
floats overflowed the (int) cast into platform-dependent values that
poison the unsigned bigint peer/history upsert batches.

Require plain non-negative decimal integers (ctype_digit) capped at
1 PiB (MAX_ANNOUNCE_VALUE) for port, uploaded, downloaded, left,
numwant and corrupt.
Laravel's test client sends accept-language/referer/accept-charset
headers by default, which trips tracker error 122 (Abnormal access
blocked) before field validation is reached. Mirror the existing
test by nulling those headers, and assert on the specific error 134
message so the rejection tests prove the validation fired rather
than any generic failure.
Laravel's TrimStrings middleware strips the padding before the
controller runs, so the value is valid by validation time.
@skavinski-lab
skavinski-lab changed the base branch from master to development July 18, 2026 04:02
@Roardom

Roardom commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Hi, just a heads up - would really appreciate it if you refrain from using AI prose when communicating with us maintainers. It's just so tiring to read.

@skavinski-lab

Copy link
Copy Markdown
Author

Hi, just a heads up - would really appreciate it if you refrain from using AI prose when communicating with us maintainers. It's just so tiring to read.

Understand. I'll keep such more concise. My English is not the best, so it also helps there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.