{
  "compartment_id": "section-5",
  "number": "Section 5",
  "title_local": "The vulnerability profile of the pre-2023 API-key architecture",
  "title_english": "The vulnerability profile of the pre-2023 API-key architecture",
  "source_url": "https://phishdestroy.io/steam_dossier/#vulnerability-profile",
  "source_document": "index.html",
  "content": {
    "html": "<section class=\"border-t border-gray-800 pt-6 print-break\" id=\"vulnerability-profile\">\n<div class=\"max-w-7xl mx-auto space-y-8\">\n<div class=\"section-head section-head-balanced\"><div class=\"section-head-primary\">\n<span class=\"kicker\">Part A — Technical record · Section 5</span>\n<h2>One session. More access than the user sees.</h2>\n\n<section class=\"dossier-note chapter-context\"><div class=\"dossier-note-title\">Context &amp; source limits</div><p class=\"chapter-context-text\">Valve's API-key architecture, as it stood before the 2023 changes, departed from baseline industry standards (OWASP ASVS, NIST SP 800-63B) and is the mechanism described in the automated inventory-theft complaints preserved in the evidence archive (Sections 6–8).</p></section>\n</div><div class=\"section-head-intro\"><p class=\"lede\"><b class=\"text-white\">The rule Valve applied:</b> the account holder created the key, accepted the terms, and bears the loss — that is the answer in the archived refusals. <b class=\"text-white\">The record:</b> until December 2023 a stolen session cookie alone could register that key. No password. No Steam Guard. No notification to the person whose account it was. <strong class=\"text-white\">The user did not create the key, could not see it, and was told he did.</strong> Mobile confirmation was added on 2023-12-04 — about seven years after the 2016 statement and roughly six after the scam panels the archive preserves. Those years were not paid by Valve. They were paid by the accounts emptied in the meantime, a share of them children's.</p></div></div>\n<div class=\"grid grid-cols-1 lg:grid-cols-2 gap-6 items-stretch\">\n<div class=\"h-full bg-gray-900/40 border border-gray-800 hover:border-red-500/40 p-6 rounded-xl transition-all duration-300 flex flex-col justify-between\">\n<div class=\"space-y-4\">\n<div class=\"flex justify-between items-start\">\n<span class=\"bg-red-500/10 border border-red-500/20 text-red-400 text-xs font-mono px-2 py-0.5 rounded\">OWASP ASVS 2.8 / NIST SP 800-63B</span>\n<span class=\"text-xs font-mono text-gray-400\">SEVERITY: CRITICAL</span>\n</div>\n<h3 class=\"text-lg font-bold text-white font-mono\">1. Insufficient Step-up Authentication</h3>\n<p class=\"text-xs text-gray-300 leading-relaxed\">\n                                Steam allowed the generation of highly privileged, long-lived API keys using only a session cookie. No 2FA (Steam Guard) or step-up authentication challenge was required when setting up or modifying a developer API key, so the Steam Guard mobile confirmation — the only second factor Steam offers — did not protect this step. (A hardware second factor was requested in Valve's own tracker in 2016 and the issue is still open: Appendix D, GH-01.)\n                            </p>\n</div>\n<div class=\"mt-6 border-t border-gray-800/80 pt-4 text-xs font-mono text-red-400\">\n                            Status: unpatched before 2023. Allowed a script holding a stolen cookie to register a key without any user interaction.\n                        </div>\n</div>\n<div class=\"h-full bg-gray-900/40 border border-gray-800 hover:border-red-500/40 p-6 rounded-xl transition-all duration-300 flex flex-col justify-between\">\n<div class=\"space-y-4\">\n<div class=\"flex justify-between items-start\">\n<span class=\"bg-red-500/10 border border-red-500/20 text-red-400 text-xs font-mono px-2 py-0.5 rounded\">OWASP A01:2021 / Least Privilege</span>\n<span class=\"text-xs font-mono text-gray-400\">SEVERITY: CRITICAL</span>\n</div>\n<h3 class=\"text-lg font-bold text-white font-mono\">2. Lack of Principle of Least Privilege</h3>\n<p class=\"text-xs text-gray-300 leading-relaxed\">\n                                The Steam Web API lacked any role-based authorisation scopes. A developer API key issued for \"read-only\" inventory status possessed complete \"write\" permissions — including the ability to manipulate existing trades, initiate new ones, register webhooks and decline valid pending exchanges.\n                            </p>\n</div>\n<div class=\"mt-6 border-t border-gray-800/80 pt-4 text-xs font-mono text-red-400\">\n                            Status: systemic design defect. One key = full read/write control of the account's inventory and trades.\n                        </div>\n</div>\n<div class=\"h-full bg-gray-900/40 border border-gray-800 hover:border-red-500/40 p-6 rounded-xl transition-all duration-300 flex flex-col justify-between\">\n<div class=\"space-y-4\">\n<div class=\"flex justify-between items-start\">\n<span class=\"bg-red-500/10 border border-red-500/20 text-red-400 text-xs font-mono px-2 py-0.5 rounded\">OWASP A07:2021 / Sessions</span>\n<span class=\"text-xs font-mono text-gray-400\">SEVERITY: HIGH</span>\n</div>\n<h3 class=\"text-lg font-bold text-white font-mono\">3. Broken Session Management</h3>\n<p class=\"text-xs text-gray-300 leading-relaxed\">\n                                Hijacked web sessions originating from server-hosting IP ranges were reported by users to persist. Standard practice is to terminate sessions on geographic anomalies and on password change; user reports collected in the archive describe sessions that remained active after a password change.\n                            </p>\n</div>\n<div class=\"mt-6 border-t border-gray-800/80 pt-4 text-xs font-mono text-red-400\">\n                            Status: reported behaviour (user complaints in the archive). Sessions could generate API keys without re-authentication.\n                        </div>\n</div>\n<div class=\"h-full bg-gray-950 border border-gray-700 p-6 rounded-lg flex flex-col justify-between\">\n<div class=\"grid grid-cols-1 gap-6 items-center\">\n<div class=\"min-w-0 space-y-4\">\n<div class=\"flex justify-between items-start\">\n<span class=\"bg-red-500/20 border border-red-500/40 text-red-300 text-xs font-mono px-2.5 py-0.5 rounded font-bold uppercase tracking-wider\">Domain-level blocking was technically feasible</span>\n<span class=\"text-xs font-mono text-red-400 font-bold\">ENFORCEMENT FEASIBILITY</span>\n</div>\n<h3 class=\"text-xl font-black text-white font-mono uppercase\">4. Domain-Level Blocking of Auth Hosts Was Technically Feasible</h3>\n<p class=\"text-xs text-gray-300 leading-relaxed\">\n                                    Valve already operates a domain list (the Link Filter) and already receives every auth hostname in its own OpenID requests. The two mechanisms are not connected in any way visible from outside: as of 2026-09-22, in 26 pairs the main domain was on the filter while the proxy carrying its login was not.\n                                </p>\n<p class=\"text-xs text-gray-400 leading-relaxed\">\n                                    Connecting them is a small engineering task: read the <code>openid.realm</code> hostname from each incoming request, compare it against a list, and refuse or flag the request. The illustration on the right shows the shape of such a routine. Refusing the auth host — rather than only the public landing page — would interrupt the \"Sign in with Steam\" step that these platforms depend on.\n                                </p>\n<p class=\"text-xs text-gray-400 leading-relaxed\">\n                                    No public evidence shows that Valve runs such a check. The Steam Community Market's combined fee of about 15% applies to sales completed inside the Market; it is not collected on these platforms' external trades.\n                                </p>\n</div>\n<div class=\"min-w-0 bg-black border border-gray-900 rounded-lg p-4 font-mono text-xs text-gray-400 space-y-2\">\n<div class=\"text-emerald-400 font-bold border-b border-gray-950 pb-1.5 flex justify-between\">\n<span>block_auth_hosts.py</span>\n<span class=\"text-gray-400\">ILLUSTRATION</span>\n</div>\n<div class=\"text-gray-400\">// Read the host Steam already receives — no scanning</div>\n<div><span class=\"text-purple-400\">def</span> on_openid_request(request):</div>\n<div class=\"pl-3 text-gray-300\">host = parse_openid_realm(request)</div>\n<div class=\"pl-3\"><span class=\"text-purple-400\">if</span> host <span class=\"text-purple-400\">in</span> blocked_domains:</div>\n<div class=\"pl-6 text-red-400\">refuse(request)</div>\n<div class=\"bg-red-950/20 text-red-300 p-2.5 rounded border border-red-500/20 text-xs mt-2\">\n<strong>Note:</strong> pseudocode for illustration only. Both halves already exist at Valve — the auth hostname arrives in the request, and the domain list is the Link Filter. No public record explains why they are not connected.\n                                </div>\n</div>\n</div>\n</div>\n</div>\n<section aria-labelledby=\"integration-paradox-title\" class=\"integration-paradox\" id=\"integration-paradox\">\n<div class=\"ip-head\">\n<span class=\"kicker\">Section 5.1 — The standards were not unpublished</span>\n<h3 id=\"integration-paradox-title\">Valve builds against these rules every day. It did not build to them here.</h3>\n<p class=\"ip-lede\">Steam ships on the App Store and Google Play, sells through the major card processors, and consumes third-party APIs like any other large platform. Each of those relationships carries a published, dated security requirement that Valve must satisfy to keep operating. Set the dates of those requirements against the dates on which Steam's own Web API acquired the same protections. <b>Nothing below is a private standard, an internal memo or a trade secret: every row is a public document with a publication date.</b></p>\n</div>\n<div class=\"ip-table-wrap\">\n<table class=\"ip-table\">\n<caption class=\"sr-only\">Published external security requirements, with their dates, set against the date the Steam Web API acquired the equivalent control</caption>\n<thead><tr><th scope=\"col\">The published standard, and the date it took effect</th><th scope=\"col\">The Steam Web API on the same question</th></tr></thead>\n<tbody>\n<tr>\n<th scope=\"row\"><b>Scoped authorisation</b><span>OAuth 2.0 — RFC 6749, <time datetime=\"2012-10\">October 2012</time>. Section 3.3 defines <code>scope</code> so a client receives only the access it asks for. It has been the default of every major platform API since.</span></th>\n<td><b>Granular scopes arrived on <time datetime=\"2026-01-16\">16 January 2026</time>.</b><span>Before that a single Steam Web API key carried full read and write over the account's trades regardless of why it was issued. <b class=\"ip-gap\">Thirteen years and three months</b> after the specification that defines the control.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>A key is not an authorisation</b><span>Google's own Cloud documentation: <q>A standard API key doesn't authenticate a principal</q>, and for APIs that create or manage resources, <q>don't use authorization keys in production.</q></span></th>\n<td><b>The Steam Web API key was exactly that.</b><span>A bearer string, issued to an account, sufficient on its own to read the inventory, cancel a pending trade and send a new one. No principal was authenticated at the point of use.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>Multi-factor authentication on privileged access</b><span>PCI DSS 3.2, requirement 8.3 — mandatory from <time datetime=\"2018-02-01\">1 February 2018</time> for all non-console administrative and all remote access to the cardholder data environment. Apple then required two-factor authentication of every Developer Program account holder from <time datetime=\"2019-02-27\">27 February 2019</time>: <q>developers with the Account Holder role in a developer program will need to enable two-factor authentication to sign in.</q></span></th>\n<td><b>A second factor was required to create an API key from <time datetime=\"2023-12-04\">4 December 2023</time>.</b><span>Until then a stolen session cookie was enough, with no prompt on the account holder's phone and no notification afterwards. <b class=\"ip-gap\">Four years and nine months</b> after Apple made Valve itself use a second factor merely to sign in to a developer portal.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>Credential lifecycle and revocation</b><span>Twitch requires of every third-party application: <q>Your app must validate the OAuth token when it starts and on an hourly basis thereafter</q>, and states that it audits for applications that do not. Its legacy v5 API was retired outright on <time datetime=\"2022-02-28\">28 February 2022</time> on a published schedule.</span></th>\n<td><b>No published key-lifecycle record.</b><span>The 2023 change protected the creation endpoint. No Valve statement located with it addresses keys already registered, and no changelog accompanied the change at all. Whether keys created before it were invalidated cannot be established from public data — which is the question a data subject would need answered to know whether a key created on their account years earlier is still live.</span></td>\n</tr>\n</tbody>\n</table>\n</div>\n<div class=\"api-token-comparator ds-b8c11f1dd6d8\" id=\"token-comparator\">\n<div class=\"ds-96c219008143\">\n<div>\n<span class=\"kicker ds-7c59d7cf7795\">Architectural Benchmark // Token Architecture</span>\n<h4 class=\"ds-252f5d8f5e75\">GitHub Fine-Grained Scopes vs Valve Steam Web API</h4>\n<p class=\"ds-db03930d207b\">Valve developers manage open-source software on GitHub daily using granular least-privilege tokens. Compare that with the monolithic key issued to 130M Steam players.</p>\n</div>\n<button class=\"btn ds-9e6d8af4ecf3\" id=\"btn-simulate-mitm\" type=\"button\">\n<span class=\"ds-a70c68aa4a03\"></span>\n<span id=\"mitm-btn-label\">Simulate Phishing Interception (MITM)</span>\n</button>\n</div>\n<div class=\"grid grid-cols-1 md:grid-cols-2 gap-6 items-stretch\">\n\n<div class=\"ds-38a0569b4e06\">\n<div>\n<div class=\"ds-185ca53d2c80\">\n<div class=\"ds-a4e017b7b0ef\">\n<svg viewBox=\"0 0 24 24\" class=\"ds-2449c9280001\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z\"></path></svg>\n<span class=\"ds-6716093f1afa\">GitHub Fine-Grained Token</span>\n</div>\n<span class=\"ds-6b1f6dfe1a52\">Used by Valve on GitHub</span>\n</div>\n<p class=\"ds-d8208f515427\">Fine-grained token with scoped isolation and mandatory lifecycle enforcement.</p>\n<div class=\"ds-7230026cd28b\">\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Repository Access:</span>\n<span class=\"ds-f5aee7fc5fc4\">Selected Repos only (1 repo)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Issue Permissions:</span>\n<span class=\"ds-062563832b98\">Read-only [✓]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Code &amp; Secrets:</span>\n<span class=\"ds-acc22d4dbe8e\">No access [✕]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Expiration:</span>\n<span class=\"ds-062563832b98\">30 Days (Mandatory TTL)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Audit Logging:</span>\n<span class=\"ds-062563832b98\">IP, User-Agent &amp; Timestamp</span>\n</div>\n</div>\n</div>\n<div id=\"github-mitm-result\" class=\"ds-08e070b7c49a\">\n<strong>Security Posture:</strong> Least-privilege token limits damage to a single read-only resource.\n      </div>\n</div>\n\n<div class=\"ds-ce8dade9d8c2\">\n<div>\n<div class=\"ds-185ca53d2c80\">\n<div class=\"ds-a4e017b7b0ef\">\n<span class=\"ds-386ccb939d53\">!</span>\n<span class=\"ds-6716093f1afa\">Valve Steam Web API Key</span>\n</div>\n<span class=\"ds-32370dc253e2\">Issued to 130M Users</span>\n</div>\n<p class=\"ds-d8208f515427\">Single 32-character master string carrying all-or-nothing trade and inventory authority.</p>\n<div class=\"ds-7230026cd28b\">\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Account Access:</span>\n<span class=\"ds-f60fb1042a0e\">FULL ACCOUNT (Monolithic)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Trade Management:</span>\n<span class=\"ds-f60fb1042a0e\">Read, Cancel, Decline [!]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Granular Scopes:</span>\n<span class=\"ds-f60fb1042a0e\">NONE (Arrived 2026, 13y late)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Expiration:</span>\n<span class=\"ds-f60fb1042a0e\">NEVER (Valid indefinitely)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Audit Logging:</span>\n<span class=\"ds-f60fb1042a0e\">NONE (Zero IP history for user)</span>\n</div>\n</div>\n</div>\n<div id=\"valve-mitm-result\" class=\"ds-772039b58e09\">\n<strong>Vulnerability:</strong> Stolen key allows silent interception of all outgoing trade offers.\n      </div>\n</div>\n</div>\n</div>\n<div class=\"ip-question\">\n<span class=\"kicker\">The standard applied in one direction</span>\n<p>Suppose a vendor Valve depends on — a cloud provider, a payment processor, a CDN — left a credential endpoint without a second factor, and months later Valve's own corporate data left through a key minted at that endpoint. Would Valve accept that the fault lay with whoever clicked the link? The archived refusals preserved in this dossier answer the mirror-image question for the user: the position taken is that the account holder created the key and bears the loss. <b>The same architecture is described as the vendor's failure in one direction and the user's responsibility in the other.</b> Which it is, is not a technical question, and it is not one this investigation can settle — it is what a court or a supervisory authority decides.</p>\n</div>\n<div class=\"ip-reversal\">\n<span class=\"kicker\">Illustration, not evidence — the standard read back the other way</span>\n<ul>\n<li>A payment processor that let a third-party script mint a full-privilege transaction credential from a browser cookie alone, with no prompt to the account holder.</li>\n<li>An identity provider that closed the hole its tokens were minted through and published nothing about the tokens already minted.</li>\n<li>A bank that answered a disputed transfer by observing that the credential used was registered on the customer's own account, and closed the ticket.</li>\n</ul>\n<p>None of these is offered as a finding about any named company. They are the same design decisions, moved to a setting where the supervisory response is well documented — which is the comparison a regulator is being asked to make.</p>\n</div>\n<p class=\"ip-verdict\"><b>What the record establishes:</b> the controls absent from the Steam Web API were public, dated and, in several cases, conditions Valve had to satisfy to keep shipping its own products. The interval between each standard and the equivalent Steam change is measurable and is set out above. <b>What it does not establish is why.</b> No Valve statement of reasons for any of these intervals has been located, and none is assumed here; that record exists inside Valve and has not been published.</p>\n<p class=\"ip-source\">Sources, each a public document: OAuth 2.0 — <a href=\"https://datatracker.ietf.org/doc/rfc6749/\" rel=\"noopener noreferrer\" target=\"_blank\">RFC 6749, October 2012 ↗</a> · Google Cloud — <a href=\"https://docs.cloud.google.com/docs/authentication/api-keys\" rel=\"noopener noreferrer\" target=\"_blank\">API keys documentation ↗</a> · PCI DSS 3.2 requirement 8.3 — <a href=\"https://listings.pcisecuritystandards.org/pdfs/PCI_DSS_Resource_Guide_(003).pdf\" rel=\"noopener noreferrer\" target=\"_blank\">PCI SSC resource guide ↗</a> · Apple — <a href=\"https://developer.apple.com/news/?id=02202019a\" rel=\"noopener noreferrer\" target=\"_blank\">Upcoming Two-Factor Authentication Requirement for Account Holders, 20 February 2019 ↗</a> <a class=\"archived-link\" href=\"https://web.archive.org/web/20250506070026/https://developer.apple.com/news/?id=02202019a\" rel=\"noopener noreferrer\" target=\"_blank\">archived 2025-05-06 ↗</a> · Twitch — <a href=\"https://dev.twitch.tv/docs/authentication/validate-tokens/\" rel=\"noopener noreferrer\" target=\"_blank\">token validation requirement ↗</a> and the <a href=\"https://discuss.dev.twitch.com/t/legacy-twitch-api-v5-i-e-kraken-shutdown-reminder-february-28-2022/36589\" rel=\"noopener noreferrer\" target=\"_blank\">v5 shutdown notice ↗</a> <a class=\"archived-link\" href=\"https://web.archive.org/web/20250127085635/https://discuss.dev.twitch.com/t/legacy-twitch-api-v5-i-e-kraken-shutdown-reminder-february-28-2022/36589\" rel=\"noopener noreferrer\" target=\"_blank\">archived 2025-01-27 ↗</a>. Steam's own dates are those in the update record in this section; the 2023 and 2026 entries are the ones Valve shipped without a changelog. Retrieved 2026-09-22.</p>\n</section>\n</div>\n<figure class=\"evidence-figure v3-valve-updates ds-6db98e7efc2b\">\n<div class=\"flex items-center gap-3 mb-3\">\n<span class=\"kicker ds-ab79ea2b8573\">Valve's own update record — dated, from public sources</span>\n</div>\n<div class=\"overflow-x-auto rounded border border-gray-800\">\n<table class=\"w-full text-xs font-mono\">\n<thead><tr class=\"bg-gray-900 border-b border-gray-800\">\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">Date</th>\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">Valve change</th>\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">Announced?</th>\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">What it closed</th>\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">Lag: mechanism public → fix</th>\n<th class=\"text-left px-4 py-2.5 text-gray-400 font-semibold\">Source</th>\n</tr></thead>\n<tbody class=\"divide-y divide-gray-900\">\n<tr><td class=\"px-4 py-2 text-gray-300\">2026-09-01</td><td class=\"px-4 py-2 text-gray-300\">Automated Suspicious Chat Flagging</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Dangerous links / patterns in group chats</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://store.steampowered.com/news/posts/?enddate=1788390000\">news ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2026-01-16</td><td class=\"px-4 py-2 text-gray-300\">Steamworks Web API granular scopes</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Least-privilege scopes for developer keys</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/groups/steamworks/announcements/detail/4123547285514022851\">announcement ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2025-07-15</td><td class=\"px-4 py-2 text-gray-300\">CS2 Trade Protection &amp; reversal window</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\"><strong class=\"text-red-400\">Nothing.</strong> Not a root-cause security fix. Support-side account recovery access remains untouched. Triggering reversal inflicts an automatic 30-day trade lockout (<a class=\"text-gray-400 underline\" href=\"https://skinvault.gg/blog/cs2-trade-protection-explained/\" rel=\"noopener noreferrer\" target=\"_blank\">Skinvault ↗</a>), while cash-trading shock caused a $104M (-25%) 24h market cap plunge (<a class=\"text-gray-400 underline\" href=\"https://csmarketcap.com/blog/market-insights/from-boom-to-bust-cs2s-trade-protection-impact\" rel=\"noopener noreferrer\" target=\"_blank\">CSMarketCap ↗</a>). In 2026, timers became per-item (<a class=\"text-gray-400 underline\" href=\"https://skin.land/blog/steam-changes-cs2-trade-ban-logic-timing/\" rel=\"noopener noreferrer\" target=\"_blank\">Skin.land ↗</a>).</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://help.steampowered.com/faqs/view/3041-A87A-E5F6-B6AC\">FAQ ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2025-05-14</td><td class=\"px-4 py-2 text-gray-300\">Account Security Announcement</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Stealer / session-hijack guidance</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/ogg/593110/announcements/detail/533224478739530146\">announcement ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2024-10-02</td><td class=\"px-4 py-2 text-gray-300\">CS2 'The Armory' 7-day hold</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Hold on trade/market for Armory items</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/games/CSGO/announcements/detail/4447966961421256740\">announcement ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2024-09-18</td><td class=\"px-4 py-2 text-gray-300\">New-device login trade restriction</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">2–7 day trade lock on new devices</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://help.steampowered.com/faqs/view/3041-A87A-E5F6-B6AC\">FAQ ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2024-02-14</td><td class=\"px-4 py-2 text-gray-300\">Profile name &amp; avatar change hold</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">2–4 h cooldown on trades after rename</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/discussions/forum/1/4202490424033360096/\">post ↗</a></td></tr>\n<tr class=\"bg-amber-950/20 ds-12f4c02de512\"><td class=\"px-4 py-2 text-amber-300 font-bold\">2023-12-04</td><td class=\"px-4 py-2 text-gray-300\">Mobile confirmation for API keys</td><td class=\"px-4 py-2 text-red-400\">No changelog</td><td class=\"px-4 py-2 text-gray-400\">Silent cookie-only key registration</td><td class=\"px-4 py-2 text-amber-300 font-bold\">≈6 years after the 2017-era panels</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/dev/apikey\">dev page ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2023-10-24</td><td class=\"px-4 py-2 text-gray-300\">SMS MFA for game build publications</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Steamworks build publishing</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/groups/steamworks/announcements/detail/3734103130194459461\">announcement ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2023-07-12</td><td class=\"px-4 py-2 text-gray-300\">Custom biography content warning</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Phishing links in bios</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://steamcommunity.com/discussions/forum/1/3807266184852932971/\">forum ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2023-01-25</td><td class=\"px-4 py-2 text-gray-300\">Profile {LINK REMOVED} &amp; cooldown</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Links in profile text</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://help.steampowered.com/faqs/view/225C-C51E-B8F0-55B2\">FAQ ↗</a></td></tr>\n<tr class=\"bg-amber-950/20 ds-12f4c02de512\"><td class=\"px-4 py-2 text-amber-300 font-bold\">2022-10-24</td><td class=\"px-4 py-2 text-gray-300\">Login overhaul &amp; cookie truncation</td><td class=\"px-4 py-2 text-red-400\">No changelog</td><td class=\"px-4 py-2 text-gray-400\">Infinite stolen sessions</td><td class=\"px-4 py-2 text-gray-400\">— (IAuthenticationService token migration)</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://store.steampowered.com/news/group/4/view/3314112260640237775\">news ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2022-10-12</td><td class=\"px-4 py-2 text-gray-300\">Mobile App 3.0 QR login</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Session deauthorisation panel</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://store.steampowered.com/news/group/4/view/3314112260640237775\">news ↗</a></td></tr>\n<tr class=\"bg-amber-950/20 ds-12f4c02de512\"><td class=\"px-4 py-2 text-amber-300 font-bold\">2022-05-10</td><td class=\"px-4 py-2 text-gray-300\">Trade-cancellation endpoints removed</td><td class=\"px-4 py-2 text-red-400\">No changelog</td><td class=\"px-4 py-2 text-gray-400\">Offer-swap (cancel &amp; re-send)</td><td class=\"px-4 py-2 text-amber-300 font-bold\">≈5 years after the 2017-era panels</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://github.com/DoctorMcKay/node-steam-tradeoffer-manager/issues/325\">issue #325 ↗</a></td></tr>\n<tr><td class=\"px-4 py-2 text-gray-300\">2020-05-25</td><td class=\"px-4 py-2 text-gray-300\">Dota 2 7-day trade lock</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Fast item flipping</td><td class=\"px-4 py-2 text-gray-400\">—</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://blog.dota2.com/2020/05/trading-cooldown/\">blog ↗</a></td></tr>\n<tr class=\"bg-amber-950/20 ds-12f4c02de512\"><td class=\"px-4 py-2 text-amber-300 font-bold\">2018-03-29</td><td class=\"px-4 py-2 text-gray-300\">CS:GO 7-day trade lock</td><td class=\"px-4 py-2 text-emerald-400\">Yes</td><td class=\"px-4 py-2 text-gray-400\">Instant bot laundering</td><td class=\"px-4 py-2 text-amber-300 font-bold\">≈20 months after the July 2016 statement</td><td class=\"px-4 py-2\"><a class=\"text-gray-400 underline\" href=\"https://blog.counter-strike.net/index.php/2018/03/20308/\">blog ↗</a> <a class=\"archived-link\" href=\"https://web.archive.org/web/20250226114333/https://blog.counter-strike.net/index.php/2018/03/20308/\" rel=\"noopener noreferrer\" target=\"_blank\">archived 2025-02-26 ↗</a></td></tr>\n</tbody>\n</table>\n</div>\n<figcaption class=\"evidence-caption\">Sources: the linked Valve posts, help pages and GitHub issues, as dated. Three decisive fixes shipped with no changelog (2022-05, 2022-10, 2023-12) and were detected by users, not announced by Valve — that asymmetry is part of the enforcement record. Lags are computed only where the dossier's own dating (July 2016 statement; 2017-era scam panels) supplies the start point; \"—\" means no such start point is established here.</figcaption>\n</figure>\n</section>"
  },
  "original_content_sha256": "c94c57c5acfb5ce5d1b9edb1a23abdf39d4e5ded7f6a9bf3b1860ec1d3351cd3",
  "author_pseudonym": "Agent Sofia",
  "schema": "phishdestroy.macro-fact.v1",
  "language": "en",
  "aggregator": "PhishDestroy",
  "exports": {
    "pdf": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_agent_sofia.pdf",
    "json": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_agent_sofia.json",
    "signature": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_agent_sofia.json.asc"
  },
  "integrity": {
    "signed_object": "steam_dossier_section_5_agent_sofia.json",
    "signature_file": "steam_dossier_section_5_agent_sofia.json.asc",
    "signing_key_fingerprint": "129FC7F39C40C69D2EF3C329BFCF9E8DD295EE01",
    "scope": "Exact JSON bytes, including macro-fact author and corresponding PDF SHA-256. PhishDestroy is the integrity signer; original evidence attribution is unchanged."
  },
  "pdf": {
    "filename": "steam_dossier_section_5_agent_sofia.pdf",
    "sha256": "d34793bba0a023c8f8b6069a479c781e553d56478ad51bca4541ee1a1de3fadd",
    "pages": 8
  }
}
