- Security
- A
How the anti-bot works in the Wildberries mobile app
Hello tekkix! My name is Denis Ulyanov, I have been in IT for 12 years, and for the past year and a half I lead the Antibot team at Wildberries.
Before I started working at WB, I spent three years on the dark side, building products that collect data from open sources. Neutral hint that these are parsers :) I have to admit, this experience helps me shoot down bots on WB resources.
Today I'll share how my team built not just an anti-bot system, but also our own parser to launch attacks on ourselves. I hope there's no mass bot attack after this is published!
Why Wildberries invests in anti-bot systems
According to our data, up to 60% of WB's traffic is generated by bots and parsers. This creates extra parasitic load on our infrastructure, and we suffer direct financial losses. When parsers and bots automate business processes and gain an unfair competitive advantage, we suffer reputational losses.
What bad bots do we spot on our radars?
1. Market parsers. They scrape prices, stock levels, product cards, search and catalog results, and recommendation feeds en masse.
Why? To gather as much information as possible about WB as a competitor, find out sales volumes, niche and category growth dynamics, and the size of discounts for regular customers. Back when I worked on the dark side, I did exactly this type of scraping, so I know this area very well.
2. DDoS activity. Bots disrupt company resource operations so that legitimate users can't access the marketplace.
3. Business logic attacks. Bots try to harm us by brute-forcing and making mass attempts in sensitive scenarios. For example, they brute-force phone numbers in the authentication feature: we send an SMS with a code, but a bot receives it instead of the user. The company wastes money sending these messages for nothing. Not fun!
4. Automation for unfair advantage. For example, sellers use automation to book delivery slots faster than others by unfair means.
How the mobile API is attacked
Working with industrial-scale parsers inevitably leads to interaction with our resources via the backend.
I can hear your unspoken question: "Why the mobile API specifically?" I'll share the two most significant reasons, and then we'll move on to the attacks.
First, mobile endpoints in REST APIs are usually well-structured: it is clear what parameters need to be passed and what response is returned. The JSON format is more compact, easier to read, and significantly more convenient for machine processing than HTML and parsing via regular expressions. My condolences to everyone who has ever worked with that. I know how painful it is.
Second, mobile APIs have a long tail of updates. When a segment of users remains on older versions of the app, we must maintain backward compatibility to avoid losing that audience.
Mobile API attack chain
Let's imagine that you and I want to scrape data via a mobile API. What should we do?
First, we intercept and analyze traffic. We install an Android emulator or use a real phone, spin up MITMproxy alongside it, and route the device's traffic through the proxy server.
Next, we break down the protocol. How does the mobile app interact with the server? What requests are sent? With what parameters? Which parameters are mandatory? What is the semantics of the requests?
We write a script. A very simple script that automatically sends requests to the backend is sufficient.
And finally — we scale. We add request parallelism and bot infrastructure so our scraper can operate stably for at least a few weeks without manual intervention, bypass the site's protection mechanisms, and obtain an anti-bot token — a verification key confirming that the client is a human.
Now we know how to build a scraper that can obtain and retain an anti-bot token. But what does this mean for our protection?
The client is always right lying. We just confirmed that we cannot trust the client. It can be emulated, hacked, and run in an unnatural environment. This means all critical checks must be performed on the server.
Anti-bot tokens must be bound to the device and session to increase the cost of an attack for hackers. After all, if the client can be hacked, the anti-bot token can be stolen as well.
Server-side risk assessment and traffic segmentation are required. We need to distinguish between unremarkable (normal) clients and suspicious ones running in an unknown environment, which may be hacked or compromised.
Copying behavioral features and enabling token revocation is possible, but it is costly. A team of skilled engineers can indeed build a parser that impersonates a human at the moment of token acquisition, but maintaining that impersonation continuously is expensive.
How our anti-bot system evolved
The anti-bot architecture consists of two major components:
Client-side SDK library (in our case, Mobile Software Development Kit) for obtaining and renewing anti-bot tokens.
Server for token validation and session risk assessment.
To assess risks, we collect a large volume of data: challenge results; the user's source network; user behavior and ML features. I will return to the last point later. Ultimately, the server issues an access decision:
allow access;
enhanced verification;
blocking;
token revocation.
The Wildberries mobile app sends a request to the protected resource wildberries.ru and receives an access denial due to the absence of an anti-bot token. Then the mobile app initiates the anti-bot token acquisition flow via the Antibot SDK. The SDK returns the token to the app, and the request to the protected resource is retried — this time successfully. We pass the check and gain access to wildberries.ru.
Building a Web SDK inside WebView in one iteration
When our team was tasked with building a Mobile SDK for the WB app, we already had a mature, production-tested Web SDK for browsers. So we cut corners and, for a quick start, reused it in WebView, the component for viewing web pages inside the app.
We built the first version in a single iteration and promptly handed it over to the product team for integration. After some time, the team came back with feedback. The undeniable upsides were fast deployment to production and data collection for the next iteration.
The downside was that WebView-related issues arose when serving a large audience in production (a subpar browser that is difficult to diagnose).
I have to admit, if I went back in time and faced the exact same task, I would choose WebView again. The pros outweigh the sole downside!
I’ll tell you what exactly we run inside WebView.
JS Challenge: Device Fingerprint
This is our core mechanism for identifying devices to assess if they are emulated, hacked, or legitimate. The challenge performs scoring: it collects environment parameters, normalizes features, and builds a device profile.
Why is the normalization step necessary? If you don’t segregate the data, you’ll end up with a noisy fingerprint that will barely differ from a randomly generated string. This is our core mechanism, but it has downsides too. For one, it can be faked. That’s why we have other mechanisms in place as well.
Proof of Work (PoW)
Anyone familiar with blockchains knows this mechanism. The essence of PoW (Proof of Work) is that to receive a token, the client must solve a computational task that confirms resource expenditure and boosts trust in the request. We ask the client to find a certain number of hashes that meet the specified conditions.
The difficulty can be adjusted for different scenarios. A trusted client can be given the task of finding 1 hash, while a device with an IP address from Singapore will be asked to find 50 hashes, to determine if it is an ordinary user on a VPN or a bot.
Solving the task is computationally costly for the client, but verification on the server is very fast. PoW slows down bots and scrapers, and makes large-scale optimization more expensive. If a device is limited to 1 generation per second, that is its cap for mining tokens.
When we were developing this mechanism, it seemed like a magic bullet that could solve all our problems. But unfortunately, PoW has its own downsides as well.
The main operational limitation is the diverse device fleet. Some users use the latest high-performance flagship devices, while others use budget smartphones that are a decade old. On low-end devices, this mechanism causes app lag, device overheating, and battery drain.
What’s more, PoW is not all-powerful: its effect is limited against an attacker with powerful infrastructure that is orders of magnitude larger than the consumer device fleet. That’s why we segment users and use this mechanism selectively.
Moving on to adaptive policies
At launch, we treated all users with a one-size-fits-all approach and assigned the same tasks, ignoring session suspiciousness, device newness, and other parameters. Of course, this backfired quickly, so we ultimately made the anti-bot flow more dynamic to ensure protection measures are targeted.
Now:
The decision model is built based on session trust level. Before full scoring, we conduct pre-scoring and determine the primary trust level for the device.
Fewer checks for legitimate sessions. If the device raises no suspicions, we simplify or skip some checks.
More challenges and additional checks for suspicious sessions. We make it harder to obtain a token for devices with a questionable reputation.
Native platform checks
As the saying goes: if the OS provides you with security tools, use them.
At a high level, if you understand how one of these tools works, you can grasp all three. I’ll use Play Integrity API as an example.
The app requests a verification token from the Play Integrity API → the platform returns a signed token → the server checks its validity and links the result to the request or session → a path is selected: 1) trust without additional checks; 2) issue extra tasks.
Extending tokens for good behavior
Everything I described above is a secure but not very user-friendly path. We ruin the user experience if we force users to go through the entire token issuance flow every single time.
Here’s what we added to fix this:
Token extension for legitimate sessions. After issuing a token, we analyze the user’s session for anomalies. If everything is "clean", the flow is simplified or the token is issued immediately without checks next time.
We do not extend tokens and enable enhanced checks for "gray" clients. If we suspect the token has been compromised and passed to a parser, we deny the extension request and ask the user to obtain a new token.
This way, we reduce the number of repeated checks and speed up core user flows in the app.
How we integrated ML into our anti-bot solution
Machine learning is used in two stages.
First, resolving challenges. When a device requests a token, information about it is very limited. Initially, we determined request legitimacy using "if" logic and heuristics, until we eventually decided we’d had enough of this! We rolled out an ML model, which now uses data to decide whether to trust the user.
Second, post-token behavior assessment. This is a far more interesting and complex stage. The model analyzes the client session, and can flag anomalous behavior and trigger token revocation at any point. Even if the token was acquired via challenge-solving services, it will be detected and will no longer be accepted.
Deploying ML allowed us to multiply bot detection accuracy, reduce false positives (when a regular user cannot access a resource), and further increase the cost of an attack.
How we label our dataset
For ML to work well, it needs to be trained properly. We used two approaches to label our dataset.
Manual tagging (don't neglect this at the start!). The Data Science team manually analyzed and clustered logs, looked for anomalies. Afterwards, we assessed whether this looked like real user behavior or showed signs of compromise.
Integration with product teams, use of retrospective data. Let's recall the example with phone number brute-forcing. At the moment of an authorization request, it is impossible to determine legitimacy, but after the fact we can check: whether a login was made using that phone number, how many repeated verification attempts there were, etc. This is how we tag retrospective data and use it to fine-tune the ML model for specific use cases. Logs are collected regularly, and the model is continuously retrained on new attack vectors. If (and when) a new type of bot appears, we will definitely learn how to counter it.
Red Team approach: we attack our own infrastructure
The term Red Team came to IT from the military sphere. A Red Team refers to engineers who simulate hacker attacks on their own infrastructure to test its resilience. I had valuable experience working with parsers, and I wanted my team of engineers to also be able to put themselves in the attackers' shoes.
We developed a parser and now we detect and block bypasses before they become incidents. Most importantly, we are forming the habit of «thinking like an attacker». Engineers need to understand that the people attacking them are the same ones who attend daily standups in the morning.
What do we plan to implement in the future?
Overall, all defensive mechanisms boil down to one goal: increasing the cost of an attack for threat actors:
SSL Pinning: complicating traffic interception and reverse engineering. To parse the application, traffic needs to be routed to a proxy server and the root certificate needs to be replaced. Pinning the public certificates of our domains prevents this. If the certificate is replaced (for example, during a Man-in-the-Middle, «man-in-the-middle» attack), the application detects the untrusted network and terminates the connection.
Integration with products: more context for accurate protection. We improved the ML model thanks to retrospective data from the product team and plan to expand this practice, as security should not develop in a vacuum.
Secured client runtime: makes application modification more difficult. We do not want threat actors to have the ability to modify our application to bypass protection and mine tokens. We will implement mechanisms that prevent this.
What to Keep in Mind
First, the mobile anti-bot system is multi-level, but the key decision is still made by the server.
Second, platform certification increases trust in the device and session. Use the security tools provided by the platform itself.
Third, ML models and token revocation help detect dynamic automation. Track the full user lifecycle, not just token issuance.
Ask your questions in the comments! Parsing specialists, try not to reveal your shady interests too much :)
Write comment