GameFoundry · In-house product · London

A games marketplace that lets strangers run their code on our servers — safely

GameFoundry is ICE WIND’s own product: a marketplace where independent developers upload playable games and players rate them for real money prizes. Anyone can publish. That single decision turned the project into a security engineering problem before it was ever a design problem.

Client
ICE WIND (in-house product)
Sector
Games, marketplaces & user-generated content
Location
London, England
Live website
www.gamefoundry.co.uk

Services

Product design Full-stack development Platform security Payments & prize operations Telegram Mini App Multilingual SEO Deployment & support
GameFoundry games marketplace homepage showing the USDT prize pool.
The marketplace opens with the prize pool, not a sign-up wall.
The challenge

Anyone can upload. Everything else follows from that.

Most marketplaces sell things. GameFoundry hands visitors a file that a stranger wrote and runs it — in the browser, on the same infrastructure that holds every account on the platform. A single careless assumption anywhere in that chain turns the product into a distribution channel for malware.

That reframed the whole build. Before we could think about catalogue design or the prize mechanic, we had to answer three questions honestly. How do we accept an arbitrary binary from an unverified account without trusting a single byte of it? How do we let an untrusted web build execute in the browser without it ever touching a logged-in session? And how do we run a real cash prize round — money leaving a wallet every week — with rules a stranger can audit and no manual guesswork in between?

On top of that sat the ordinary marketplace problem: a catalogue that stays useful as it grows, a rating system that cannot be gamed by the people it rewards, and a reason for anyone to come back next week. That part is ordinary web application development; the upload pipeline was not.

The approach

Treat every upload as hostile, then design around it

We built the platform on a simple rule: nothing a user uploads is ever trusted, and nothing about that distrust is hidden from players.

File format is decided by reading the actual bytes, never the extension. Archives are inspected before extraction for traversal paths and decompression bombs. Every build is scanned by ClamAV, and when scanning is unavailable the game page says so instead of quietly implying the file is clean. Uploaded web games run from a separate registrable domain, so the session cookie for the main site is never sent to them — a game literally cannot reach an authenticated endpoint, no matter what its code tries.

With that foundation in place the product side became straightforward. Browsing, downloading and playing need no account at all. Registration is required only to upload a game or leave a rating, which is where identity actually matters. The prize round runs on published rules with a live countdown, and every payout is recorded on the site with its transaction hash.

GameFoundry prize rules page showing the 100 USDT weekly split.
Published rules: 100 USDT a week, split 50 / 30 / 20, decided by player ratings.
What we delivered

Everything included in the live platform

  • A public catalogue with format filters and search, sorting by rating, recency and downloads
  • Browser-playable games running in a sandboxed frame, plus downloadable builds (Windows .exe, Android .apk and .zip archives)
  • Registration with email verification, bcrypt password hashing and __Host- prefixed httpOnly session cookies holding only a hashed token
  • An upload flow covering game builds, screenshots, trailers and store metadata
  • Layered upload validation: magic-byte format detection, size ceilings, and zip-slip and zip-bomb inspection on every archive the server extracts
  • ClamAV antivirus scanning on a fail-closed pipeline, with an honest, player-visible scan status on every game page
  • Ratings and written reviews, one per player per game, with self-rating blocked
  • A dynamic leaderboard across weekly, monthly and all-time periods
  • A 100 USDT weekly prize round with published rules including champion rotation, a live countdown and a public payout record carrying transaction hashes
  • Developer profiles, tip links and a founding-developer programme
  • An admin console for approval, blocking, rescanning and abuse reports, backed by a server-side audit log of sensitive actions
  • A Telegram Mini App and bot sharing the same catalogue and rating data
  • Interface localisation into 10 languages
  • A 10-language SEO blog with canonical, hreflang and x-default handling
  • Production deployment on Railway with a persistent volume and a scripted git-push release
GameFoundry leaderboard with weekly, monthly and all-time standings.
Weekly, monthly and all-time standings with a live countdown to the draw.
Key engineering decisions

The four decisions that shaped the platform

Untrusted code gets its own domain

Uploaded web games are served from a separate registrable domain rather than a path on the main site. Because the session cookie is __Host- prefixed and host-only to the main domain, a game never receives it and cannot make an authenticated API call — regardless of what its JavaScript attempts. The user-content origin serves only games plus a small set of anonymous, cookieless score and play-count endpoints. There is no login there to attack.

The bytes decide, not the filename

Upload validation reads the actual file header and matches it against known signatures. A JPEG renamed to .zip is rejected. A web build that is not really a ZIP archive is rejected before anything is extracted. Web builds — the only archives the server ever unpacks — are then walked entry by entry before a byte is written to disk, enforcing a 20,000-entry ceiling and a 2 GB uncompressed limit so a small file cannot expand into a full disk. Download-only builds are never extracted server-side at all.

Fail closed, then tell the truth

Every build is scanned by ClamAV, and nothing reaches the catalogue until the scan comes back clean. If the scanner is unavailable the upload is held for manual review rather than auto-published — and when a held build is approved, the game page tells players the file was not checked instead of showing a reassuring badge. The same principle governs the prize round: the rules, the countdown and the standings are public, and each payout is published with its transaction hash as rounds complete.

An account only where it earns its place

Browsing, downloading and playing require no registration — friction there costs players for no security benefit. An account is required exactly where identity matters: uploading a game and rating one. Email verification gates uploads, one rating per player per game is enforced at the database level, and developers cannot rate their own work.
Technical delivery

How the platform is built

The backend is Node.js and Express on SQLite via better-sqlite3, with fourteen tables covering accounts, sessions, games, media, reviews, scores, prizes, reports and an audit log. Authentication uses bcrypt hashing with server-side sessions: the cookie is __Host- prefixed and httpOnly, and the database stores only a SHA-256 hash of the session token. Uploads are handled by multer and archives inspected with adm-zip. ClamAV is an optional dependency, so the server still boots without it — but the upload pipeline fails closed: an unscanned or unscannable build is held for manual review, never auto-published.

The frontend is deliberately framework-free: semantic HTML, hand-written CSS and vanilla JavaScript, with a custom internationalisation layer covering ten languages and around 3,000 translated strings. Every response carries a Content-Security-Policy with no inline scripts anywhere — strict on the main site, sandboxed for uploaded game HTML — plus nosniff, frame protection, referrer policy, permissions policy and HSTS. Rate limiting is applied per route family: 300 requests a minute globally, tightening to 40 per fifteen minutes on authentication and 30 an hour on uploads.

The Telegram Mini App runs inside the same Express application but authorises writes through Telegram’s HMAC-signed initData instead of the session cookie, because a SameSite cookie is never delivered inside a cross-site Telegram frame. The bot is a webhook mounted into the same app and calls the Bot API through native fetch — no additional dependency.

The platform runs on Railway behind a TLS proxy with a persistent volume for the database and game files, and ships through a scripted git-push release.

The outcome

Live, multilingual and open for submissions

GameFoundry is live at www.gamefoundry.co.uk in ten languages, with the weekly prize round open, a public payout record that fills in as rounds complete, and a Telegram Mini App running alongside the web platform.

For ICE WIND it is the reference project for a category of work most agencies quietly avoid: products where the users supply the code. The security model, the moderation tooling and the prize operations behind it are all reusable — and everything we learned building our own platform is available to clients building theirs. For clients who need the games themselves rather than the platform around them, that work sits under game development.

Visit live website (opens in a new tab) Next case: Barsion

Start a project

Building a platform where users supply the content?

Marketplaces, upload flows, user-generated content and the security model underneath them. We have built it for ourselves — and we build it for clients.

Start a project
[email protected]
+44 7345 058863