Server-Side Reward Validation: How Perkox Prevents Offerwall Fraud

⬢ Perkox · Developer-First Offerwall SDK

Server-Side Reward Validation: How Perkox Prevents Offerwall Fraud

By Perkox Engineering · · 12 min read
server-side reward validation
offerwall fraud prevention
postback validation
offerwall security

Offerwalls are one of the most effective monetization surfaces in modern apps and games: users complete surveys, installs, or trial subscriptions and earn in-app currency, while developers earn real revenue from advertisers. But the same economic model that makes offerwalls attractive also makes them a prime target for fraud. Bad actors will spoof completions, replay callbacks, hide behind proxies, and tamper with the client to mint virtual currency they never earned. The only reliable defense is server-side reward validation — the principle that every reward decision is made on infrastructure the attacker cannot touch.

This guide explains exactly how Perkox implements offerwall fraud prevention through secure postback validation and broader offerwall security controls. If you are integrating an offerwall for the first time, start with our primer on what an offerwall is, then come back here for the deep technical dive.

1. Why Client-Side Validation Is Dangerous

The most common — and most dangerous — mistake in offerwall integration is trusting the client. In a client-side reward model, the SDK or game client decides whether a user has completed an offer and then grants currency locally. This sounds simple, but the client is an inherently untrusted environment. The binary runs on hardware the attacker owns, in a runtime they can inspect and modify.

Concretely, client-side validation fails in the following ways:

  • Memory patching: Attackers use tools like Frida, GameGuardian, or memory scanners to flip a “completed = false” flag to “true” and trigger the reward path without ever opening the offer.
  • Replay injection: A captured reward event is replayed into the client’s event bus, granting currency repeatedly from a single legitimate completion.
  • Binary tampering: The client is patched to skip the offer and jump straight to the reward screen. Integrity checks, if present, are often themselves patched out.
  • API spoofing: The client calls a reward endpoint directly with a forged payload, bypassing the advertiser entirely.
  • Emulator automation: Offer completion is scripted on an emulator farm, with the client happily awarding currency for offers no human ever saw.

The fundamental issue is asymmetry: the attacker has unlimited time and full control of the endpoint, while the client has no trusted root of secrecy. No amount of obfuscation, packing, or anti-debug hardening changes that. Any secret embedded in the client will be extracted. Server-side reward validation removes the target: the reward decision never happens on the device, so there is nothing on the client to patch.

Rule of thumb: If the client can grant a reward, an attacker can grant a reward. Move every reward decision to a server you control.

2. How Server-Side Postback Validation Works

Perkox replaces the untrusted client loop with a trusted server-to-server (S2S) loop. The flow has four actors: the user, the partner app, the advertiser/offer provider, and the Perkox validation service. The client is reduced to a display surface; it never authorizes rewards.

  1. Offer start: The user opens the Perkox offerwall inside the partner app. Perkox records the user ID, device fingerprint, originating IP, and offer ID. A session token is issued and linked to this context.
  2. Completion: The user completes the offer on the advertiser’s surface. The advertiser’s server, not the user’s device, is the one that knows completion happened.
  3. Postback: The advertiser sends an HTTP POST (the postback) to the Perkox validation endpoint. This is a direct server-to-server call; the user’s device is not in the path.
  4. Validation: Perkox verifies the signature, checks the transaction ID for duplicates, validates the device fingerprint, inspects the IP for proxy/VPN use, and enforces geo-consistency.
  5. Reward: Only after every check passes does Perkox credit the user’s balance and notify the partner backend through a second signed callback. The client is told to refresh its balance — it is informed of the reward, not the source of it.

This architecture means an attacker who fully controls the client gains nothing: there is no client-side reward API to call, no flag to flip. The only way to earn currency is to produce a valid, signed, non-duplicate postback from a real advertiser for a real completion — which requires actually completing the offer.

For the complete integration walkthrough, see our complete offerwall postback guide.

3. Postback URL Parameters

Every Perkox postback is a signed HTTP request to a validation endpoint. The canonical parameter set is designed to carry everything needed to authorize a reward and everything needed to detect fraud, without relying on any client-supplied claim.

Parameter Purpose Trusted?
transaction_id Globally unique ID for this completion; used for idempotency and replay protection Advertiser
user_id The Perkox-assigned user identifier the offer was credited to Perkox (issued at offer start)
offer_id The specific offer completed Advertiser
payout The real-currency payout to the publisher, in cents Advertiser
currency Virtual currency code to credit Perkox config
signature HMAC-SHA256 of the canonical parameter string Computed
timestamp Unix timestamp of the postback; used for skew/replay windows Advertiser
device_id Stable device fingerprint captured at offer start Perkox
ip IP the offer was started from Perkox
country Geo country of completion Advertiser / Perkox
sub1 / sub2 Optional custom tracking parameters Publisher

Crucially, the user_id, device_id, and ip are not taken from the postback at face value — they were captured and bound to the session when the offer started, so an attacker cannot inject a different identity at completion time. The postback only carries a reference; Perkox reconciles it against the trusted session record.

4. Hashed Callback Signatures

The signature is the cryptographic guarantee that a postback genuinely came from the expected advertiser and was not tampered with in transit. Perkox uses HMAC-SHA256 with a per-integration shared secret provisioned out-of-band. The secret never appears in the client, in the URL, or in any log.

The signature is computed over a deterministic canonical string: parameters are sorted alphabetically, the shared secret is appended, and the whole thing is hashed. This prevents parameter reordering attacks and prevents an attacker from swapping the payout or user_id in a captured postback.

# Canonical string construction
params = {
  "transaction_id": "tx_9f3a2c",
  "user_id":        "u_1024",
  "offer_id":       "off_5512",
  "payout":         "1250",          # cents
  "timestamp":      "1724576400",
}
canonical = "&".join(f"{k}={params[k]}" for k in sorted(params))
signature = hmac.new(SHARED_SECRET.encode(), canonical.encode(), hashlib.sha256).hexdigest()

On receipt, Perkox rebuilds the canonical string from the incoming parameters, recomputes the HMAC, and compares it in constant time to the supplied signature. A mismatch is a hard reject — no partial credit, no retry, no logging of the secret. The shared secret can be rotated per integration and is never reused across advertisers, so a compromise of one integration does not weaken others.

Defense in depth: TLS protects the postback on the wire, but the HMAC protects against a compromised or rogue advertiser endpoint, a tampered payload, and insider misuse. They are complementary, not redundant.

5. Device Fingerprinting

A signed, non-duplicate postback still does not prove the completion came from the same device that started the offer. That is the job of device fingerprinting. At offer start, Perkox computes a stable, privacy-respecting device fingerprint from attributes available on the server side and the SDK’s limited, consented telemetry: hardware class, OS family and version, screen density bucket, language, and a Perkox-issued install ID. We deliberately avoid collecting raw identifiers like IMEI or IDFA to respect privacy and platform policy.

The fingerprint serves three fraud-control purposes:

  • Identity binding: The session that started the offer is bound to a fingerprint. The postback must reference a session whose fingerprint matches the one recorded. A completion attributed to a session the device never started is rejected.
  • Multi-account detection: Perkox correlates fingerprints across user IDs. One device churning through dozens of accounts to farm an offer is a strong fraud signal, even before a single postback arrives.
  • Emulator detection: Emulator and farm devices produce distinctive fingerprint clusters. Perkox flags clusters with implausibly high completion velocity for manual review or automatic denial.

Fingerprints are hashed before storage and never leave the Perkox validation service. Because the reward decision is server-side, the fingerprint is compared on trusted infrastructure — an attacker cannot tamper with the comparison the way they could a client-side check.

6. Duplicate Transaction Prevention

Duplicate and replayed postbacks are the single most common offerwall fraud vector. Advertiser systems retry postbacks on network failure, and attackers capture and replay valid postbacks hoping the reward will be granted twice. Perkox treats every reward as an idempotent operation keyed by transaction_id.

The mechanism is an idempotency store backed by a fast, durable key-value layer. Before any validation logic runs, Perkox attempts to claim the transaction_id with a conditional write:

  • Claim succeeds: This is a new transaction. Proceed with signature, fingerprint, and geo validation. On success, credit the reward and persist the transaction as fulfilled.
  • Claim fails (key exists): The transaction was already seen. Respond 409 Conflict without crediting. This covers both legitimate advertiser retries and malicious replays.
def handle_postback(payload):
    tx_id = payload["transaction_id"]
    if not idempotency.claim(tx_id, ttl=30 * 86400):
        return 409, "duplicate transaction"
    if not verify_signature(payload):
        return 401, "bad signature"
    if not verify_session(payload):
        return 403, "session mismatch"
    credit_reward(payload)
    idempotency.mark_fulfilled(tx_id)
    return 200, "ok"

Entries carry a TTL of at least 30 days, after which they expire. This window is deliberately long relative to any legitimate advertiser retry cadence, so a real retry that arrives hours or days later is still recognized as a duplicate and safely ignored. A timestamp skew check (typically ±5 minutes) rejects postbacks that are too stale or too far in the future, closing the window for captured-postback replay even after the TTL expires.

7. Proxy and VPN Mitigation

Fraudsters route offer completions through proxies and VPNs to manufacture geo-targeted impressions, hide emulator farms behind residential IPs, and evade per-IP rate limits. Perkox applies layered network-intelligence checks at both offer start and postback validation.

  • IP reputation feeds: Every IP is checked against commercial and open proxy/VPN/datacenter feeds, Tor exit lists, and a Perkox-maintained list of known-fraud ranges. Residential IPs behind known VPN providers are scored, not blanket-blocked, to avoid false positives.
  • Geo-consistency: The country declared at offer start must match the country of the completion IP. A user who starts an offer in Brazil and “completes” it from a German datacenter VPN is denied.
  • ASN correlation: Perkox flags completions from hosting ASNs (cloud providers, datacenters) that have no residential equivalent. A burst of completions from a single ASN is a farm signal.
  • Velocity limits: Per-IP and per-ASN completion rates are capped. Exceeding the cap throttles or rejects further postbacks from that source until a cooldown expires.
  • Device-IP binding: The IP at offer start is bound to the session. A completion from a wildly different network (a proxy rotation mid-offer) is treated as suspicious and can require step-up validation.

The goal is not to ban all VPN users — many legitimate users run VPNs for privacy. The goal is to deny rewards where the network evidence is inconsistent with a real human completing a real offer on the device that started it. Because these checks run server-side, they cannot be bypassed by patching the client.

8. Offerwall Security Best Practices

Beyond the core validation pipeline, Perkox follows and recommends a set of offerwall security best practices. For the SDK-specific checklist, see our offerwall SDK security best practices.

  • Never trust the client for rewards. The client’s only job is to display offers and show the user their balance. All reward logic lives server-side.
  • Use a shared secret per integration, rotated regularly. Never embed the secret in the client or ship it in plaintext config. Rotate on offboarding of any team member with access.
  • Enforce idempotency on every reward path. Every credit operation must be keyed by a unique, server-controlled identifier. No idempotency, no reward.
  • Validate timestamps. Reject postbacks outside a tight skew window to neutralize replay of captured-but-expired callbacks.
  • Bind sessions at offer start. Capture user ID, device fingerprint, and IP when the offer begins. Reconcile against these on the postback — do not trust advertiser-supplied identity for the credit.
  • Layer network intelligence. Combine proxy/VPN feeds, ASN analysis, and velocity limits. No single signal is enough; correlation is what catches farms.
  • Log for audit, not for replay. Log enough to reconstruct a decision (transaction ID, verdict, signal scores) but never log secrets, full IPs in the clear, or raw fingerprints.
  • Monitor and alert on anomalies. Sudden spikes in completion rate, payout, or a single offer’s popularity are fraud signals. Alert humans, don’t just silently deny.
  • Keep the validation service hardened. Rate-limit the endpoint, enforce mTLS where the advertiser supports it, and isolate the service from your public-facing app APIs.
  • Plan for advertiser misconfig. A legitimate advertiser can still send a malformed postback. Respond with clear, documented status codes so retries converge instead of looping.

9. Conclusion

Offerwall fraud prevention is not a single feature; it is a property of the architecture. The moment reward decisions move server-side, the entire class of client-tampering attacks collapses. From that foundation, postback validation through signed callbacks, idempotent transaction handling, device fingerprinting, and proxy/VPN mitigation form a layered defense that scales from a single integration to a global offer network. Perkox was built developer-first around exactly this model: the SDK is thin, the validation service is authoritative, and the client is never the arbiter of value.

If you are building or scaling an offerwall, the highest-leverage decision you can make today is to remove reward authority from the client entirely. Everything else in this guide is reinforcement of that one principle.

10. Frequently Asked Questions

What is server-side reward validation and why does it matter for offerwall fraud prevention?

Server-side reward validation is the process of verifying that an offerwall completion is legitimate by processing a secure server-to-server postback from the offer provider before granting virtual currency or rewards. It matters because client-side validation can be bypassed, spoofed, or replayed by attackers, leading to fraudulent rewards. Perkox performs every reward decision on trusted infrastructure so attackers cannot mint currency by tampering with the client.

How does postback validation work in the Perkox offerwall?

When a user completes an offer, the advertiser sends a server-to-server postback to Perkox containing the transaction ID, user ID, offer ID, payout, and a hashed signature. Perkox validates the signature against a shared secret, checks for duplicate transaction IDs, verifies the device fingerprint, inspects IP reputation for proxy or VPN use, and only then credits the reward. The developer’s backend is notified through a signed callback.

What postback URL parameters does Perkox expect?

Perkox postbacks include transaction_id, user_id, offer_id, payout, currency, signature, timestamp, device_id, ip, and country. The signature is an HMAC-SHA256 hash of the canonical parameter string using a shared secret. Developers can add custom sub1/sub2 parameters for campaign tracking and segmentation.

How does Perkox prevent duplicate transactions and replay attacks?

Perkox stores every transaction_id in an idempotency store with a TTL of at least 30 days. Incoming postbacks are checked against this store before any reward is credited, so a replayed or duplicated callback is rejected with a 409 Conflict. Timestamp validation rejects callbacks outside a configurable skew window, blocking stale replay attacks.

Can Perkox detect users who hide behind proxies or VPNs to commit offerwall fraud?

Yes. Perkox cross-references the postback IP against proxy, VPN, datacenter, and known-fraud IP feeds, combines this with device fingerprint consistency checks, and flags suspicious sessions for review or rejection. Publishers can enforce geo-consistency rules so a reward is denied when the completion IP does not match the country declared at offer start.

Start Building a Fraud-Resistant Offerwall

Integrate Perkox in minutes with a thin SDK and authoritative server-side reward validation. Read the docs, then ship.

Get Started Free
Read the Docs