Security Alert: Confirmed Malware
Layoutify: Improved Layout for Instagram
ID: nekeeojpcbiehcignddhindbgacbghmi
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- Jacob "kurtextrem" GroßView Profile
- Privacy
- Privacy Policy
- Help
- Help Center
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- Yes
- Mailbox exists
- Yes
The layout of Instagram.com is not optimized for the desktop. This extension improves this.
The default Instagram.com layout is not optimized for the desktop. This extension improves the design. It also lets you view your saved ("Collections") and liked images on the web. To view them, click the 3-dots menu on the top right. Next, as Instagram is optimized for phones, they never load the highest quality and prevent the right click download of images. This extension changes that. My extension does not collect any private data and your images are only stored on your PC. Also, the code is Open-Source for you to check/contribute: https://github.com/kurtextrem/Layoutify-for-Instagram Privacy Policy: https://kurtextrem.de/chrome/PRIVACY.html (Sensitive data is only collected and stored on your own PC, options are synced if Chrome Sync is turned on) Permissions: "*.instagram.com/*" means that it only has access to Instagram APIs and the Instagram web. *://*.fbcdn.net/*, *://*.cdninstagram.com/*: Needed to display images/videos on the 3-dots page. As written above, data is only collected on your own PC and the data stays there. Changelog --------- v3.12.1: Fixes broken feed. Instagram changed how they store posts. v3.12.0: Fixes the broken design - sorry for that, Instagram did update *everything* and it took a while to fix it. v3.11.3: Fixed stories in the sidebar v3.11.1: Fix broken feed in Brave (Please note: I'm not testing any other browser apart from Chrome) v3.11: Fix feed v3.10.1: Fix "navigation from main feed does not work" (since Instagram changed e.g. how stories loaded) v3.10.0: Download are now working again on /p/ and /tv/ links in new tabs v3.9.1: Fixes the "watch" function in Manifest V3 (looking back at the change, I was maybe too fast to switch. Sorry.) v3.9.0: The extension now less resources in the background by switching to Chrome Manifest V3 v3.7.0: "Watch" now notifies on new IGTV posts, new highlight reels, new tagged photos v3.6.1: Adds an option for the bigger modal; Arrows now appear sharper on Retina and 4k displays v3.6.0: DMs now have dark mode support; Modals with images/videos now appear larger (thanks Dominic for the suggestion) v3.4.0: Adds a new permission, as Instagram added a mechanism to prevent images/videos from loading on the 3-dots page v3.3.3.7: Tagged users now show up again. Also, this release fixes the "watch" functionality. Really sorry for that!! v3.3.3.6: Fixes the repeated likes on the 3-dot page (click the "Clear" button on "About" to fix it) !!! This version needs new permissions, as Instagram now prevents other pages from displaying images - which the 3-dots page does (fbcdn.net) !!! v3.3.3: Fixes clicking on stories in the feed and speeds the loading a bit up. v3.3.2: Added "System Night Mode" option. Turned on by default. When turned on, the night mode automatically activates when your Operating System is in Night/Dark Mode. v3.3.0: Now you can finally see all your collection & names on the web. v3.2.1: New logo (IG lawyers), fix stories sidebar. v2.10.0: You will now get a notification if a user changes his/her profile picture, when you watch his/her posts. v2.9.0: New Design for Stories! v2.8.3: Updated Night Mode. Much nicer colors. Fixed a few bugs regarding the 3-dots page. v2.8.0: You can now see Collection folders. However, it is in a beta test at the moment. So you see an ID instead of the collection name. v2.7.0: Exciting new feature: You can now watch users and get notified whenever they post something or add a story! v2.6.0: New Logo/Icon, thanks to Ibrahim Tenekeci! v2.5.4: You can download videos in stories now v2.5: The 3-dots menu now contains options v2.3.21: New feature: On single post pages, the highest quality is loaded. So you can right click to save the picture in the original quality. v2.3.14: Downloading videos is possible again v2.3.10: Support for native Stories on the web (Instagram implemented it and it's rolling out; No need for an 3rd party extension anymore :) ) v2.2.14: Bugfixes (Thank you to the Community for reporting bugs, especially Kelvin!) v2.0.0: Adds the ability to view likes and saved images on the web! Click the three dots on the top right to view them. In addition many bug fixes. v1.0.20: Fixes a community reported problem: When navigating from main page to a profile and then clicking a post resulted in a broken modal. v1.0.15: Slightly improves performance v1.0.14: Fixed layout when Chrome IG Story is missing v1.0.12: New Icon, name and bug fixes This project is in no way affiliated with, authorized, maintained, sponsored or endorsed by Instagram or any of its affiliates or subsidiaries. This is an independent project. Use at your own risk.
Sensitive Domain Access
This extension has access to the following sensitive domains:
- *://*.instagram.com/*
- *://*.cdninstagram.com/*
The background service worker forges Instagram private mobile-app headers (X-FB-HTTP-Engine: Liger, X-IG-App-ID, X-IG-Capabilities, randomized bandwidth values) to impersonate the official Instagram Android client when calling the private i.instagram.com/api/v1 endpoints. The credit comment to mgp25/Instagram-API (a well-known reverse-engineered IG API library) confirms intent. This is unauthorized API access masquerading as a first-party app, violating Instagram's terms of service.
const PRIVATE_API_OPTS = { headers: { Accept: '*/*', 'Accept-Language': 'en-US', 'X-FB-HTTP-Engine': 'Liger', 'X-IG-App-ID': '567067343352427', 'X-IG-Bandwidth-Speed-KBPS': '-1.000', 'X-IG-Bandwidth-TotalBytes-B': '0', 'X-IG-Bandwidth-TotalTime-MS': '0', 'X-IG-Capabilities': '3brTvw==', 'X-IG-Connection-Speed': `${Math.trunc(Math.random() * 5000 + 1000)}kbps`, 'X-IG-Connection-Type': 'WIFI', }, method: 'GET', // credits to https://github.com/mgp25/Instagram-API/blob/master/src/Request.php#L377}Uses declarativeNetRequest to rewrite the User-Agent header on outbound XHRs to private IG mobile API endpoints (feed/liked, feed/saved, feed/collection), spoofing a hardcoded Instagram-for-Android client string. This circumvents server-side checks that gate mobile-only endpoints to mobile clients, enabling the extension to scrape data the web client is not authorized to read.
chrome.declarativeNetRequest.updateDynamicRules({ addRules: [ ...['i.instagram.com/api/v1/feed/liked/*', 'i.instagram.com/api/v1/feed/saved/*', 'i.instagram.com/api/v1/feed/collection/*' ].map( item => ({ id: ++id, priority: 1, action: { type: 'modifyHeaders', requestHeaders: [{ header: 'user-agent', operation: 'set', value: 'Instagram 121.0.0.29.119 Android (24/7.0; 380dpi; 1080x1920; OnePlus; ONEPLUS A3010; OnePlus3T; qcom; en_US; 185203708)', }, ],This page-context script reads the Instagram session-bound credentials www-claim-v2 (an authenticated session claim token) plus rollout-hash and asbd-id from sessionStorage/localStorage of instagram.com and dispatches them via a CustomEvent (__@@ptb_ige) to the content script, which forwards them to the background service worker for persistent storage in chrome.storage. These session-scoped tokens are then re-attached to background fetch() calls (see background.js fetchFromBackground), allowing the extension to make authenticated requests outside of any tab.
function asbdPromiseHandler(asbd) { const obj = { 'asbd-id': asbd, 'rollout-hash': getFromIGData('rollout_hash'), } const igClaim = sessionStorage['www-claim-v2'] || localStorage['www-claim-v2'] if (igClaim) obj['ig-claim'] = igClaim dispatch(obj)}The content script listens on the page-injected CustomEvent bridge and forwards the Instagram session claim (ig-claim), rollout-hash and asbd-id to the background worker, which stores them with chrome.storage.local.set (background.js:369-378). Using a custom-event bridge from page → content → background to siphon authenticated session identifiers is a classic credential-relay pattern.
// pass from injected page to backgroundwindow.addEventListener('__@@ptb_ige', function(event) { for (const key in event.detail) { if (key !== 'ig-claim' && key !== 'rollout-hash' && key !== 'asbd-id') continue chrome.runtime.sendMessage({ action: key, path: event.detail[key] }) }})Uses the cookies permission to read Instagram's csrftoken cookie directly (background.js:246, 273) and inject it as the x-csrftoken header on background-issued POST/GraphQL calls. Combined with the harvested ig-claim token, this lets the service-worker impersonate the logged-in user's Instagram session from any extension context, even when no IG tab is open.
function getCookie(name) { return new Promise((resolve, reject) => { chrome.cookies.get({ name, url: 'https://www.instagram.com/' }, function cookies(cookie) { if (cookie !== null) resolve(cookie.value) reject() }) })}Forces the Referer header to https://www.instagram.com/ on all requests to fbcdn.net, cdninstagram.com, instagram.com, and i.instagram.com private API endpoints, regardless of the actual originating page. Referer spoofing bypasses Instagram CDN/API hot-link and origin checks so the extension can fetch authenticated media and JSON from contexts the server would normally reject.
chrome.declarativeNetRequest.updateDynamicRules({ addRules: [ ...[ 'fbcdn.net', 'cdninstagram.com', // private_web 'i.instagram.com/api/v1/*', 'instagram.com', ].map(item => ({ id: ++id, priority: 1, action: { type: 'modifyHeaders', requestHeaders: [{ header: 'referer', operation: 'set', value: 'https://www.instagram.com/',Background polling job (triggered by chrome.alarms every 57 minutes per createUpdateAlarm at line 391) iterates the user-supplied watchlist and issues authenticated calls to Instagram's private GraphQL/web APIs for each profile, with randomized 5–25s jitter between requests to evade rate-limit/abuse heuristics. This is account-state surveillance of arbitrary IG users (story latest_reel_media, is_live, profile pic, tagged photos, posts) using the victim's session credentials.
function checkForWatchedContent(users, type, watchData) { const length_ = users.length - 1 let timeout = 0 for (let i = 0; i <= length_; ++i) { const user = users[i], userObject = watchData[user] if (userObject === undefined || userObject.id === '') { setTimeout(function() { createUserObject(user, watchData) .then(function() { notify(user, watchData[user], type, watchData, length_, i) }) .catch(logAndReject) }, timeout) } else setTimeout(notify.bind(undefined, user, watchData[user], type, watchData, length_, i), timeout) timeout += getRandom(5000, 25000) }}Injects four extension-bundled scripts (runtime/commons/feed bundles plus igdata.js) directly into the instagram.com page context via DOM script tags. Page-context injection escapes the content-script isolated world and grants the injected code access to window-scoped objects like _sharedData, _cached_shared_Data, sessionStorage['www-claim-v2'] — which igdata.js then reads to harvest session tokens.
;(function inject() { 'use strict' if (location.pathname.indexOf('/embed/') > 0) return // do not do stuff on embeds, > 0, because a user could be called embed. const scripts = ['runtime.bundle.js', 'commons.bundle.js', 'feed.bundle.js', 'content/igdata.js'] for (let i = 0; i < scripts.length; ++i) { const s = document.createElement('script') s.src = chrome.runtime.getURL(scripts[i]) document.body.appendChild(s) }By severity
Versions scanned
Showing 1 of 39 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 3.10.1 | 8 |
Files with findings
4 distinct paths — top paths by unique finding count:
- content/background.js5
- content/igdata.js1
- content/main.js1
- content/start.js1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.