Building a Telegram Mini App taught me something about authentication

by•

I've been building a Telegram Mini App recently, and one thing I've spent time on is making sure the backend doesn't blindly trust requests coming from the frontend. It's tempting to assume that because someone opened your app through Telegram, the request is legitimate. But the frontend is still just a client, and requests can be modified. For my project, I started testing what happens when authentication data is missing or modified, and whether protected endpoints reject those requests properly. It reminded me that a working login flow and a secure login flow aren't necessarily the same thing. For developers who've built Telegram Mini Apps or similar embedded apps, what authentication mistakes have you encountered, and how did you catch them during testing?

32 views

Add a comment

Replies

Best

The worst one I've seen wasn't even in the login. An older version of my app wrote its own purchase counters straight into the database after a purchase, so anyone who looked at the requests could give themselves more. In the rebuild the client can't write anything it gets paid for: credits only change from the store's webhook on the backend, and the database rules reject the field from the app. I have a similar embedded case too, a web view inside the app that signs the user in on the site. The page never trusts that it's running inside our app, it gets a one time sign in link from the backend instead. For testing, the useful habit was calling every protected endpoint with the token removed, then with someone else's id in the body, and expecting both to fail.

I haven't built a Telegram Mini App, but I've dealt with the same thing on web apps. Rate limiting on login is now a fixed rule across all my products.

Here's how I set it up: failed attempts are counted per account and per IP, and either one gets locked after 5 failed attempts. Each new lock waits longer: 1 minute, then 5, 15, 60. While locked, it returns 429 with Retry-After. And the error never says whether the account doesn't exist or the password was wrong, because that leaks who's registered.