Makuhari Development Corporation
10 min read, 1886 words, last updated: 2026/1/22
TwitterLinkedInFacebookEmail

Introduction

When an advertising partner asks your platform to embed a unique identifier in landing page URLs, then call their conversion API upon user registration, the request seems straightforward. In practice, it touches a surprisingly deep intersection of security engineering, data privacy law, and architectural responsibility.

This post examines the full picture: what Server-to-Server (S2S) conversion tracking actually involves, where the real risks hide, what "best practice" genuinely looks like, and how HMAC-based hashing translates from a cryptographic concept into a compliance posture — not just a security measure.


Background: What Is S2S Conversion Postback?

The pattern is common across the advertising ecosystem, particularly in affiliate networks and CPA (cost-per-acquisition) platforms. The flow looks like this:

Ad click
→ Landing page: ?click_id=XYZ
→ User completes registration
→ Your server POSTs click_id to the advertiser's API

This is variously called Server-to-Server Conversion Tracking, a Postback URL, a Conversion Callback, or (in Meta's terminology) a Conversion API (CAPI). It is widely used by affiliate networks, DSPs, and smaller ad platforms precisely because it bypasses ad blockers and browser-side tracking restrictions.

The pattern is mature and legitimate. The problem is not the concept — it is how naively it is often implemented.


The Core Misconception: This Is Not a Sandbox

The first and most important reframe: this is nothing like Google Tag Manager or a tracking pixel.

GTM/Pixel characteristics:

  • Runs in the browser
  • The advertiser receives events but cannot affect your backend logic
  • Injection risks are limited to XSS (mitigable via CSP)
  • Your server is never involved in the data handoff

S2S Postback characteristics:

  • Your server actively calls a third-party API
  • The data it sends originates from user-supplied URL parameters
  • You are validating (or failing to validate) the data
  • You are the entity making the outbound request

This distinction matters enormously. In the GTM model, your server never touches the tracking data. In S2S, your server is the data pipeline. You are not a passive conduit — you are an active participant, and the law treats you accordingly.


Core Concepts

1. The Untrusted Input Problem

URL parameters are user-controlled input. Anyone can craft a link like:

https://yourapp.com/signup?click_id=ARBITRARY_VALUE

If your backend reads click_id and forwards it to an advertiser API without validation, you have built a system where external actors can send arbitrary payloads through your server to a third party. The immediate attack surface includes:

  • Parameter injection: Oversized values, special characters, JSON structures, or SQL-like patterns in click_id can corrupt logs, payloads, or downstream parsing depending on how the advertiser's API handles them.
  • Conversion fraud: Anyone can register with a fabricated click_id, causing you to report a conversion that never legitimately occurred. Depending on your advertiser agreement, this can create financial liability.
  • Replay attacks: The same click_id submitted multiple times across multiple registrations generates multiple reported conversions. Without deduplication on your side, CPA costs explode.

None of these require a sophisticated attacker. The barrier to exploitation is as low as opening a browser's address bar.

2. The Forwarding-vs-Confirming Distinction

The single most important architectural principle for S2S postback:

You should be a conversion confirmer, not a parameter forwarder.

The naive implementation treats your server as a relay: receive click_id from URL, pass it to advertiser API. The correct implementation treats your server as a gatekeeper: receive click_id as a candidate, verify it against your own records, then report a confirmed conversion event using your own internal identifier.

This distinction reshapes the entire threat model.

3. HMAC-Based Anti-Traceability

The concept of "hash + salt to prevent traceability" appears frequently in privacy engineering, but its specific role in advertising contexts deserves precise explanation.

A plain SHA-256 hash of click_id is not sufficient:

hashed = SHA256("abc-click-123")

If the advertiser knows the format of their own click_id values (they do — they generated them), they can enumerate or dictionary-attack the hash space. The input domain is small and structured.

HMAC with a server-side secret resolves this:

hashed = HMAC-SHA256(key=SERVER_SECRET, message=click_id)

Without SERVER_SECRET, neither the advertiser nor an attacker who obtained your database can:

  • Verify whether a given click_id corresponds to a stored record
  • Enumerate which click_id values produced which hashes
  • Link a stored hash back to a specific advertising campaign click

This is not just a security measure. It is a compliance engineering posture.


Analysis

Security Risk Matrix

Approach Injection Risk Replay Risk Fraud Risk Your Liability
Raw parameter forwarding High High High High
Hash without salt Medium Medium Medium Medium
HMAC + TTL + deduplication Low Low Low Low
Frontend fire-and-forget Minimal Shifted to advertiser Shifted to advertiser Minimal

The APPI Compliance Layer (Japan Context)

Japan's Act on the Protection of Personal Information (APPI), as amended in 2022, introduced a category called Personally Related Information (個人関連情報). This category specifically targets identifiers that are not personal information in isolation but become personal information when combined with other records held by the recipient.

Click IDs and tracking parameters are the textbook example. The practical implications:

Scenario A: click_id stored with user_id or email This is personal information under APPI. The click_id is now linkable to a specific natural person within your system. Full APPI obligations apply: purpose limitation, security management, third-party provision controls.

Scenario B: click_id in a separate table, joined via application logic Still likely personal information. APPI does not ask whether you performed the join — it asks whether you could reasonably perform the join. Same operator, same system, available data: yes, you could.

Scenario C: HMAC hash with no original stored, TTL applied, no join path to user records This shifts your position meaningfully. You can argue, in an audit context, that the stored token is not personally identifiable by your organization. Combined with explicit Privacy Policy language describing the advertising identifier use, this is "standing on the safer side of the line" in regulatory terms.

The HMAC is not about cryptographic security from attackers. It is about demonstrating, in a legally legible way, that you have taken reasonable steps to prevent re-identification.

The Privacy Policy as Engineering Artifact

Japanese regulators place significant weight on prior disclosure. A Privacy Policy that explicitly states:

  • Advertising identifiers (click parameters) are used for conversion measurement
  • These may be shared with advertising partners
  • They do not include directly identifying information such as name or email

...provides meaningful legal protection that technical measures alone cannot. The combination of HMAC-based storage and transparent disclosure is substantially more defensible than either measure alone.

Frontend Direct-Call: A Different Risk Profile

An alternative architecture worth examining: instead of your server calling the advertiser API, your frontend SPA calls it directly from the browser.

// Fire-and-forget — no await, no retry, no backend involvement
fetch("https://api.advertiser.example/conversion", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ click_id: clickId, event: "signup" })
}).catch(() => {});

This meaningfully changes the compliance picture:

  • The request originates from the user's browser, not your server
  • You do not "receive, store, manage, or re-provide" the data
  • The legal characterization shifts toward "user browser communicating directly with third party"

However, this architecture also shifts the XSS risk surface. URL parameters flowing directly into a fetch body are relatively contained — the risk is low compared to injecting them into DOM elements. The critical rules:

Never do this:

const clickId = new URLSearchParams(location.search).get("click_id");
element.innerHTML = clickId; // XSS vulnerability

Safe pattern:

const raw = new URLSearchParams(location.search).get("click_id") ?? "";
const clickId = raw.replace(/[^A-Za-z0-9_-]/g, "").slice(0, 128);
// Use only in fetch body, never in DOM

The frontend approach also removes your ability to enforce deduplication and TTL constraints. Conversion fraud prevention becomes entirely the advertiser's responsibility. This is a reasonable trade for early-stage products that prioritize simplicity and low legal exposure over precise attribution control.


Implications

Architecture Decision Framework

The right architecture depends on your relationship with conversion accuracy:

Choose frontend direct-call when:

  • You are in MVP/early stage
  • Your advertiser relationship is informal or low-stakes
  • You need minimal legal exposure
  • Conversion accuracy is nice-to-have, not business-critical

Choose backend S2S when:

  • Your revenue model depends on accurate CPA attribution
  • The advertiser will audit your reporting
  • You need deduplication guarantees
  • You are in a regulated industry (finance, healthcare)

Never combine them carelessly. A frontend call with a backend fallback on failure recreates all the S2S liability while adding architectural complexity. Regulators will look at the outcome (data reached the third party) not the mechanism.

The "You're Just a Forwarder" Trap

Many implementations start with a simple proxy: read URL parameter, call advertiser API. This feels clean. It is not.

The moment your server validates the parameter, deduplicates conversions, or retries failed calls, you have moved from "technical intermediary" to "data controller" in legal terms. The legal tests in both APPI and GDPR frameworks ask about capability and intent, not just technical architecture.

The correct mental model: your server is asserting that a conversion happened. That assertion carries responsibility. Treat it accordingly.

Rotating Secrets and Data Minimization

Two operational practices that compound compliance posture:

  1. Rotate HMAC secrets every 30–90 days. Old records become computationally unverifiable even if the algorithm is known. In a regulatory audit, "the system is designed such that historical data becomes opaque over time" is a credible data minimization argument.

  2. Apply TTLs aggressively. Conversion data that is automatically deleted after 30 or 90 days cannot be misused after that window. Minimum retention is not just storage efficiency — it is a legal argument that you do not maintain a persistent behavioral record.


Conclusion

Server-to-Server conversion postback is a mature, widely-used pattern. The security and compliance risks it introduces are real but well-understood and fully manageable with the right architecture.

The key insights from this analysis:

  1. You are not a passive relay. Your server actively participates in the data handoff. Design accordingly.

  2. Validate before you report. A click_id from a URL parameter is a candidate, not a confirmed conversion. Your database is the source of truth.

  3. HMAC is a compliance instrument, not just a security measure. It creates a legally legible argument that stored data is not re-identifiable, which matters in APPI and GDPR contexts.

  4. Frontend direct-call is a legitimate alternative for early-stage products. It shifts responsibility, reduces your legal exposure, and simplifies the implementation — at the cost of conversion accuracy guarantees.

  5. Privacy Policy language and technical architecture must align. Cryptographic measures alone do not satisfy regulators; documented intent and transparency matter equally.

The question "is this approach reliable?" has a clear answer: yes, with the right implementation. The question "is raw parameter forwarding best practice?" has an equally clear answer: no, and it exposes you to risks that are easily avoided with a small amount of additional engineering.

Build the conversion confirmer, not the parameter forwarder. The difference is a few database rows, a server-side secret, and a well-written privacy notice.

Makuhari Development Corporation
法人番号: 6040001134259
ご利用にあたって
個人情報保護方針
個人情報取扱に関する同意事項
お問い合わせ
Copyright© Makuhari Development Corporation. All Rights Reserved.