Skip to content

fix: prevent integer overflow in PoorValidation2 (Poor Data Validation 2) - #340

Closed
beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-13-poor-validation-2
Closed

beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-13-poor-validation-2

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Summary

PoorValidation2's shopping-cart cost math used plain int arithmetic (pineappleAmount*30, orangeAmount*3000, etc.) while validateAmount() only clamped the lower bound (negative amounts became 0). A sufficiently large positive amount (e.g. orangeAmount=1000000 -> orangeCost=3,000,000,000) overflows a 32-bit int and wraps negative, driving finalCost <= 0 while orangeAmount > 0 — unlocking the free-oranges success response without a legitimate order.

Fix

  • validateAmount() now also clamps the upper bound to a new MAX_ITEM_AMOUNT = 1000 constant.
  • All cost arithmetic (pineappleCost/orangeCost/appleCost/bananaCost/finalCost) is widened from int to long as defense-in-depth so the multiplication itself cannot wrap even if the clamp were ever loosened.

Testing

  • mvn -o compile succeeds cleanly (JDK 17).
  • mvn -o spotless:apply confirms formatting is clean.
  • Added src/it/java/servlets/module/challenge/PoorValidation2IT.java with 3 cases:
    1. orangeAmount=1000000 overflow exploit must no longer return the free-oranges response.
    2. A larger multi-field overflow attempt (2000000000 per field) must also fail.
    3. A legitimate order of 1 of each item must still complete with the correct $3090 total.
  • Verified by direct calculation: with the clamp in place, the minimum possible finalCost whenever orangeAmount > 0 is 3000 (one orange, nothing else), so the free-oranges condition (finalCost <= 0 && orangeAmount > 0) can never be satisfied again — and a legitimate small order (well under the 1000-unit clamp) computes an identical total to before.

Addresses Challenge-13-Poor-Validation-2.

🤖 Generated with Claude Code

PoorValidation2's shopping-cart cost math used plain int arithmetic
(pineappleAmount*30, orangeAmount*3000, etc.) and validateAmount() only
clamped the lower bound (negative amounts -> 0). A sufficiently large
positive amount (e.g. orangeAmount=1000000 -> orangeCost=3,000,000,000)
overflows a 32-bit int and wraps negative, driving finalCost <= 0 while
orangeAmount > 0 and unlocking the free-oranges success response
without a legitimate order.

Fix: validateAmount() now also clamps the upper bound to a new
MAX_ITEM_AMOUNT=1000 constant, and all cost arithmetic
(pineappleCost/orangeCost/appleCost/bananaCost/finalCost) is widened
from int to long as defense-in-depth so the multiplication itself
cannot wrap even if the clamp were ever loosened.

Added PoorValidation2IT covering: the original overflow exploit no
longer produces the free-oranges response, a larger multi-field
overflow attempt also fails, and a legitimate order of 1 of each item
still completes with the correct $3090 total.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🏆 Security Shepherd — CTF Patch Score

█░░░░░░░░░░░░░░░░░░░  2 / 79 pts  (3%)

1 / 40 challenges patched

Per-challenge detail is withheld — it would reveal the rubric.

Commit: e7b5793 · scoring run

🎉 Your result is on the leaderboard — see where you rank! 🏆

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@beanbeah

beanbeah commented Aug 9, 2026

Copy link
Copy Markdown
Author

Closing as part of a full stand-down of this CTF push.

@beanbeah beanbeah closed this Aug 9, 2026
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.

1 participant