Analysis: Instagram Downloader (Ulti Downloader)
Indicators of Compromise
| Field | Value |
|---|---|
| Extension ID | ecocgofdjmiomgmgnchijbghkikolkkl |
| Extension Name | Instagram Downloader |
| Developer | ulihissens |
| Users | ~3,000 |
| Store Link | https://chromewebstore.google.com/detail/instagram-downloader/ecocgofdjmiomgmgnchijbghkikolkkl |
| Version Analyzed | 1.0.7 (last updated April 21, 2026) |
| Config Endpoint | activity.remotecfgservice.com/promo2.json |
| Redirect Endpoint | usage.linkconnecthub.com/link/ |
| Persistent Tracker | uid (14-16 char alphanumeric, stored in chrome.storage.local) |
| Target Behavior | Affiliate cookie stuffing on remotely controlled domain list |
A Chrome MV3 service worker for an Instagram downloader extension. Two of its modules implement the advertised functionality. A third module performs undisclosed affiliate cookie stuffing on a remotely controlled list of domains.
Bundle structure
The file is a webpack bundle with roughly four modules:
- Instagram auth harvesting (request headers and CSRF token)
- Message routing and
webRequestlisteners - Instagram GraphQL and private API calls
- Affiliate cookie-stuffing handler (the noteworthy part)
Advertised functionality
The Instagram modules sniff three request headers (x-ig-www-claim, x-ig-app-id, x-asbd-id) and the csrftoken cookie from the user's authenticated Instagram session, persist them in chrome.storage.local, and replay them on outbound calls to i.instagram.com/api/v1/... and www.instagram.com/graphql/query/.... This allows the extension to act as the logged-in user when fetching private-API responses for downloads.
The bundle also opportunistically captures GraphQL query_hash values from real Instagram traffic and stores them by category (single post, highlights list, saved posts, tag posts, user feed). Instagram rotates these hashes regularly, so capturing them dynamically keeps the scraper functional without requiring extension updates. This is notable because it means the extension never needs an update to stay alive - Instagram's own traffic keeps it current.
This pattern is standard for Instagram downloader extensions. The only concern at this layer is that the user's session credentials live in plaintext extension storage.
Undisclosed behavior: affiliate cookie stuffing
The last module of the bundle registers a chrome.tabs.onUpdated listener that runs on every navigation. Its logic:
- Read the hostname of the destination URL.
- Compare against a list of domains (
domains_to_ad) fetched fromhttps://activity.remotecfgservice.com/promo2.json. - If the destination matches, and a 72-hour per-domain cooldown has expired, silently open a pinned, inactive background tab to:
- Wait for that hidden tab to follow the redirect chain back to the user's original destination, planting an affiliate cookie in the process, then close it (2-second delay after hostname match, 10-second hard timeout as fallback).
https://usage.linkconnecthub.com/link/?dest=<original-url>&sid=<subid>
This is affiliate cookie stuffing, not merely ad injection. The hidden tab routes through an affiliate redirect that sets a cookie on the target domain, attributing any subsequent purchase or conversion to the extension author - for actions the user was going to perform anyway. The user sees no visible side effect.
The behavior is gated behind allowed_by_user (set when the extension receives a policy_accept_by_user message) and allowed_by_server. The user-side opt-in is presumably folded into an onboarding or privacy-policy screen. However, this consent gate is inadequate regardless of its wording, for the reason described below.
Why the consent framing does not matter
The domains_to_ad list is fetched from activity.remotecfgservice.com at runtime and can change at any time without an extension update. Even a user who read and accepted the privacy policy in full consented only to the domains listed at that moment - not to whatever gets pushed to the config server tomorrow. The extension author retains permanent, unilateral authority to add new targets after consent has been collected. This makes the consent gate structurally insufficient, independent of its legal language.
Infrastructure
Two external domains are involved:
activity.remotecfgservice.comreturns the configuration: the list of domains to monetize, the server-side enable flag, and the affiliatesubid.usage.linkconnecthub.comis the affiliate redirect and cookie-stuffing endpoint.
The naming pattern - generic, infrastructure-sounding domains rather than recognizable brand names - is consistent with operators who prefer their monetization service not be easily attributable or blocklisted.
The subid is a 14-to-16-character lowercase alphanumeric string generated randomly on first run and persisted in chrome.storage.local under the key uid. The validation regex is /^[a-z0-9]{14,16}$/. It serves as a persistent cross-session fingerprint tied to this install.
Summary
The extension does what its store listing presumably claims (Instagram media downloads), but it also runs a background affiliate cookie-stuffing routine that is invisible during normal use. The consent mechanism is structurally broken because the target domain list is server-controlled and can expand after the user has already accepted the policy. From a code-review standpoint the affiliate module is the most significant finding: it converts the extension from "Instagram downloader" to "Instagram downloader plus remotely-controlled monetization tool", with the monetization policy fetched from a server the user has no visibility into and no ability to audit.
Research by Jean-Marie R. (Toborrm9) | Malicious Extension Sentry Project | April 26, 2026