The Checkout Works. Would You Let This Store Go Live?
“Checkout works. The tests are green. We launch tomorrow.” You are reviewing a fictional store called LoomMart. The product manager has one question: can we ship? There are three observations in your review notes. Non
“Checkout works. The tests are green. We launch tomorrow.”
You are reviewing a fictional store called LoomMart. The product manager has one question: can we ship?
There are three observations in your review notes. None causes a crash. Every screen looks normal.
This is a tabletop exercise, not a report about a real company or an announcement of a playable store.
Observation one: the order number
Alice signs in and opens her order. The browser requests /api/orders/order-100.
In the exercise, changing the identifier to order-101 returns an order whose owner is Bob. The API verifies the session but retrieves orders by ID alone.
The frontend never links Alice to Bob's order. Does that help?
Only with navigation. It does not enforce permission at the server. The API needs to apply the relevant ownership or membership policy before returning the object.
Observation two: the coupon
The coupon is intended for one redemption per account. The implementation does this:
Read whether the coupon was used.
If unused, apply the discount.
Mark the coupon as used.
One request at a time looks fine. Two overlapping requests can both read “unused” before either records the redemption.
That is a concurrency hypothesis to test in a controlled environment. The snippet alone does not prove how the real database behaves.
You would want the redemption rule enforced atomically, using appropriate database constraints or transactional logic, and a test showing that overlapping requests cannot both succeed.
Observation three: the profile preview
The store displays a customer's profile name as HTML. Plain names render correctly. Input intended to be text is being treated as markup.
If the product only needs a plain-text name, use a text-rendering operation. If it intentionally supports rich HTML, the requirements and sanitization strategy become more complicated.
“It looks fine with my name” is a happy-path test, not an answer to the trust question.
Your launch decision
For each observation, write three sentences:
- The rule the application should enforce.
- The evidence you have, and what still needs verification.
- The test that would demonstrate a successful repair.
Avoid reducing this to three vulnerability names. A team needs reproducible evidence and a repair it can verify.
For the order issue, I would test both directions: Alice cannot read Bob's order, and Bob can still read it. For the coupon, I would check concurrent requests and subsequent retries. For the profile name, I would confirm that ordinary names and markup-looking text both behave as intended.
Why I like this format
A working demo can conceal assumptions about ownership, timing and interpretation. A launch review makes those assumptions visible in a familiar product.
I am building Breachloom, where learners practice web security through browser simulations and code-repair tasks. The free IDOR case lets you explore the first kind of mistake. LoomMart itself is a proposed scenario, not an available Breachloom feature.
Which observation would you investigate first, and what would you ask the team before making the launch decision?
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.