# Displayed vs stored value divergence

Value validated or rendered differs from the value later stored, billed, or granted

_Area: Web business logic and race conditions. Seen in 4 disclosed reports; latest 2024-07-09. Updated 2026-10-23._

## How it works
A value is checked, priced, or rendered in one place, then normalized, recomputed, or interpreted differently somewhere else. The assumption that breaks: that the value you validated is the value you store, bill, or display. When two code paths or two renderers derive the same fact independently, they can disagree, and the attacker picks the cheaper or more permissive interpretation.

## Where it shows up
- A quantity used both for a resource grant and for a price, computed with different rounding (ceil vs floor) [E2](https://bugbountylibrary.com/r/h1%3A1446090.md)
- Input validated before normalization (trim, case-fold, unicode) but stored after it [E3](https://bugbountylibrary.com/r/h1%3A963774.md)
- Formats with redundant representations where viewers pick different precedence (form field value vs annotation appearance) [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-fickle-pdfs-exploiting-browser-rendering-discrepancies.md)
- Any field rendered for approval by one component but persisted by another
- Fractional, negative, or overflow numeric inputs reaching billing or allocation

## How to review
Find every place the same value is derived and confirm they agree. The invariant: the value validated, the value stored, the value billed, and the value displayed must be the same value after all normalization. Check ordering: normalize before validate, never after. For quantities, confirm allocation and pricing use identical rounding and bounds. For rendered documents, confirm the approving viewer and the authoritative store read the same representation. Trace the value end to end and diff each transformation.

## Variants seen
- Rounding mismatch between grant and price paths on fractional input [E2](https://bugbountylibrary.com/r/h1%3A1446090.md)
- Validation on raw string, normalization (space stripping) applied later, flipping a price tier [E3](https://bugbountylibrary.com/r/h1%3A963774.md)
- Renderer precedence disagreement between default value and annotation stream across viewers [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-fickle-pdfs-exploiting-browser-rendering-discrepancies.md)

## Impact and severity
Led to paying less for more seats [E2](https://bugbountylibrary.com/r/h1%3A1446090.md), premium tier obtained at non-premium price [E3](https://bugbountylibrary.com/r/h1%3A963774.md), and invoice totals that differ by viewer, undermining approval workflows [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-fickle-pdfs-exploiting-browser-rendering-discrepancies.md). Severity rises when the divergence crosses a trust boundary: money, entitlements, or documents used for approval. Worse when the discrepancy is silent and only visible to one party.

## Why fixes fail
Fixing one path (e.g. rounding in billing) without aligning the other leaves the divergence; the root cause is duplicated derivation, so partial fixes regress.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-fickle-pdfs-exploiting-browser-rendering-discrepancies.md
- E2: https://bugbountylibrary.com/r/h1%3A1446090.md
- E3: https://bugbountylibrary.com/r/h1%3A963774.md
