Layoutify: Improved Layout for Instagram

ID: nekeeojpcbiehcignddhindbgacbghmi

Could be malicious

Supported Languages

🇺🇸English
🇩🇪German
🇮🇹Italian

Extension Info & Metadata

Status
Removed
Version
3.10.1
Size
0.17 MB
Rating
3.7/5
Reviews
218
Users
11,277
Type
Extension
Updated
Jul 26, 2022
Category
Lifestyle Social
Price
Free
Featured
No
Visibility
Listed
Mature
No
By Google
No
Trusted
Yes

Publisher Contextual Analysis

Trusted
Author
Jacob "kurtextrem" GroßView Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
Yes
Mailbox exists
Yes
Total Extensions
15
Active
6
Obsolete
9
Listed
15
Unlisted
0
Total Users
45,099

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.

Item
Type
Severity
Description
declarativeNetRequest
Permission
Critical
This permission allows the extension to define rules to block, redirect, or modify network requests. Rated Critical because it can control all network traffic, potentially blocking security updates or redirecting to malicious sites.
cookies
Permission
High
This permission provides full access to read and modify browser cookies. Rated High because it can steal session tokens, modify authentication cookies, and compromise accounts across websites.
Contextual Risk Factors
Risk Factor
High
The following context increases the overall risk:• 20% increase: Access to sensitive domains increases potential impact• 10% increase: Early script execution enables pre-emptive content manipulation
storage
Permission
Medium
This permission allows storing data locally in the browser. Rated Medium because it can persist sensitive user data, track user activities over time, and potentially store malicious payloads.
unlimitedStorage
Permission
Medium
This permission removes storage quota restrictions. Rated Medium because it can store large amounts of user data without limits, potentially impacting browser performance and storing extensive tracking data.
*://*.instagram.com/*
Host
Medium
Host permission — access limited to this URL pattern.
*://*.fbcdn.net/*
Host
Medium
Host permission — access limited to this URL pattern.
*://*.cdninstagram.com/*
Host
Medium
Host permission — access limited to this URL pattern.
Access to Sensitive Domains
Risk Factor
Medium
This extension requests access to sensitive domains: *://*.instagram.com/*, *://*.cdninstagram.com/*
Early Content Script Execution
Risk Factor
Medium
This extension runs content scripts at document_start.
notifications
Permission
Low
This permission displays system notifications. Rated Low because it can only show user-visible notifications without accessing system data.
alarms
Permission
Low
This permission schedules periodic tasks. Rated Low because it can only trigger events at specified times without access to sensitive data.

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.

content/background.js (Line 161)
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.

content/background.js (Line 411)
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.

content/igdata.js (Line 61)
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.

content/main.js (Line 798)
// 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.

content/background.js (Line 91)
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.

content/background.js (Line 411)
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.

content/background.js (Line 969)
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.

content/start.js (Line 5)
;(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

Critical0
High5
Medium3
Low0

Versions scanned

Showing 1 of 39 scanned versions with more than one unique finding. Counts are unique findings that include each version.

Extension VersionCode Review Findings
3.10.18

Files with findings

4 distinct paths — top paths by unique finding count:

  • content/background.js5
  • content/igdata.js1
  • content/main.js1
  • content/start.js1
S.No.
Category
Severity
File
Summary
Found in Version
1Credential Theft
high
content/igdata.js (line 61)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…
2Credential Theft
high
content/main.js (line 798)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.se…
3Credential Theft
high
content/background.js (line 91)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 …
4Network Interception
high
content/background.js (line 411)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…
5Privilege Escalation
high
content/background.js (line 161)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 whe…
6Code Injection
medium
content/start.js (line 5)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 a…
7Network Interception
medium
content/background.js (line 411)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 spoo…
8Tracking
medium
content/background.js (line 969)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 ea…
URLs
33
IPv4
1
IPv6
0

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.

getbootstrap.com-https://getbootstrap.com/
github.com/twbs/bootstrap/blob/main/LICENSEhttps://github.com/twbs/bootstrap/blob/main/LICENSE
www.w3.org/2000/svghttp://www.w3.org/2000/svg
github.com/kurtextrem/Layoutify-for-Instagram/blob/master/CHANGELOG.mdhttps://github.com/kurtextrem/Layoutify-for-Instagram/blob/master/CHANGELOG.md#changelog
github.com/kurtextrem/Layoutify-for-Instagramhttps://github.com/kurtextrem/Layoutify-for-Instagram
github.com/kurtextrem/Layoutify-for-Instagram/issueshttps://github.com/kurtextrem/Layoutify-for-Instagram/issues
www.paypal.com/cgi-bin/webscrhttps://www.paypal.com/cgi-bin/webscr
www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gifhttps://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif
www.paypal.com/en_DE/i/scr/pixel.gifhttps://www.paypal.com/en_DE/i/scr/pixel.gif
chrome.google.com/webstore/detail/layoutify-improved-layout/nekeeojpcbiehcignddhindbgacbghmi/reviewshttps://chrome.google.com/webstore/detail/layoutify-improved-layout/nekeeojpcbiehcignddhindbgacbghmi/reviews
Showing 1 to 10 of 40 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

121.0.0.29
IPv4
-
Showing 1 to 10 of 40 rows
Rows per page:

Code Diff

Compare extension code between any two versions.

0 changed files (scanned top 25 shared text files)

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.