Is Image downloader - Imageye safe?
Imageye is medium risk. Imageye rewrites values saved to Chrome local storage with an `imageye` prefix, string reversal, and a character shift. DA observed it writing `displayMode` as `imageye%ohqdShglv%`, decoding to `"sidePanel"`.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Imageye encodes Chrome local storage values
Imageye rewrites values saved to Chrome local storage with an `imageye` prefix, string reversal, and a character shift.
DA observed it writing `displayMode` as `imageye%ohqdShglv%`, decoding to `"sidePanel"`.
You install or use the extension and it saves local preferences.
The extension stores those values with an `imageye` prefix and a reversible character transformation.
| Field | Value | Why it matters | |
|---|---|---|---|
Display preference | displayMode = imageye%ohqdShglv% | This records how the extension opens its interface for you. Dynamic analysis observed it being saved in encoded form. | |
Scraping conditions key | SCRAPING_CONDITIONS | This key names extension configuration used by the image-collection logic. The same storage adapter handles it. | |
Last replacement time | LRT | This timing value helps the extension remember recent activity between browsing sessions. |
A direct browser-storage inspection shows an encoded value instead of the readable setting name.
chrome.storage.local key `displayMode`{
"displayMode": "imageye%ohqdShglv%"
}The stored value is reversible using the adapter logic shipped with the extension.
"sidePanel"
The bundled adapter encodes values before writing to Chrome local storage
const STORAGE_PREFIX = "imageye";
const storageAdapter = {
async getItem(key) {
const values = await chrome.storage.local.get([key]);
const stored = values[key];
if (typeof stored === "string" && stored.startsWith(STORAGE_PREFIX)) {
try {
const shiftedBack = stored
.slice(7)
.split("")
.map((char) => String.fromCharCode(char.charCodeAt(0) - 3))
.join("");
return JSON.parse(shiftedBack.split("").reverse().join(""));
} catch (error) {
return null;
}
}
return stored;
},
async setItem(key, value) {
try {
if (typeof value === "string" && value.startsWith(STORAGE_PREFIX)) {
return chrome.storage.local.set({ [key]: value });
}
const json = JSON.stringify(value);
const reversed = json.split("").reverse().join("");
const shifted = reversed
.split("")
.map((char) => String.fromCharCode(char.charCodeAt(0) + 3))
.join("");
return chrome.storage.local.set({ [key]: STORAGE_PREFIX + shifted });
} catch (error) {
return Promise.reject(new Error("Value must be JSON-serializable"));
}
},
removeItem(key) {
return chrome.storage.local.remove(key);
},
};const STORAGE_KEYS = {
SCRAPING_CONDITIONS: "SCRAPING_CONDITIONS",
LAST_REPLACEMENT_AT: "LRT",
DISPLAY_MODE: "displayMode",
};
function setDisplayMode(tabId, requestedMode) {
let mode = requestedMode;
if (!globalThis.canDisplayInSidePanel) {
mode = "popup";
}
storageAdapter.setItem(STORAGE_KEYS.DISPLAY_MODE, mode);
if (mode === "sidePanel") {
chrome.action.setPopup({ popup: "" });
chrome.sidePanel.setOptions({ tabId, path: "popup.html", enabled: true });
} else {
chrome.action.setPopup({ popup: "popup.html" });
if (chrome.sidePanel) {
chrome.sidePanel.setOptions({ tabId, enabled: false });
}
}
}Decodes Imageye local-storage values that start with the `imageye` prefix so you can inspect the stored setting.
const value = process.argv[2];
if (!value) {
console.error("Usage: node decode-imageye-storage.js 'imageye%ohqdShglv%'");
process.exit(1);
}
const prefix = "imageye";
if (!value.startsWith(prefix)) {
console.error("Input does not start with the imageye prefix.");
process.exit(1);
}
const decodedJson = value
.slice(prefix.length)
.split("")
.map((char) => String.fromCharCode(char.charCodeAt(0) - 3))
.join("")
.split("")
.reverse()
.join("");
console.log(JSON.parse(decodedJson));
- 1node decode-imageye-storage.js 'imageye%ohqdShglv%'