Is Manuals Search safe?
ManualsSearch is medium risk. Manuals Search stores GUID e1d0dc83-340b-60c6-1a09-8d9dc1f59eaf in Chrome sync storage, adds it plus type tag Y243_F1_221843_071226 to searches sent through search.freshysearch-api.net via a redirect rule, and to omnibox manual-search URLs.
Who publishes itTightrope Interactive - 14 other listings from the same operator, 3 of them carrying a finding
Tightrope Interactive - 14 other listings from the same operator, 3 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same operator - 14 listings
Published under a different store account, but sharing the registered address, contact or declared legal entity this one gave the store.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Persistent GUID tags Manuals Search queries
Manuals Search stores GUID e1d0dc83-340b-60c6-1a09-8d9dc1f59eaf in Chrome sync storage, adds it plus type tag Y243_F1_221843_071226 to searches sent through search.freshysearch-api.net via a redirect rule, and to omnibox manual-search URLs.
You install Manuals Search and use its search provider or manual-search keyword.
The extension adds the same install GUID and tracking tag to search URLs sent through Freshy Search.
Dynamic analysis observed the GUID in Chrome sync storage and in a redirect rule for search.freshysearch-api.net.
This stores the install identifier in browser-synced storage, so later searches can be tied back to the same extension install.
chrome.storage.sync key 'guid'{
"guid": "e1d0dc83-340b-60c6-1a09-8d9dc1f59eaf"
}| Field | Value | Why it matters | |
|---|---|---|---|
Install GUID | e1d0dc83-340b-60c6-1a09-8d9dc1f59eaf | This value lets repeated searches be associated with the same extension install. | |
Tracking tag | Y243_F1_221843_071226 | This adds partner and install-attribution context to each tagged search URL. | |
Search term | manual | This reveals the search text that was routed through the extension's search provider. | |
Tagged search URL | https://search.freshysearch-api.net/crx/search.php?k=manual&type=Y243_F1_221843_071226&guid=e1d0dc83-340b-60c6-1a09-8d9dc1f59eaf | This combines the search term with the persistent identifier in one request URL. |
Source paths that request, store, and reuse the GUID
const install = async () => {
const src =
`https://api.${this.config.apiDomain}/api/v2/json/install?` +
`&eType=${this.config.eType}&ext.yid=${
this.config.yID
}&ext.domain=${await getSetting(
"domain"
)}&ext.partner_name=${await getSetting(
"partner_name"
)}&ext.region=${await getSetting(
"region"
)}&ext.id=${await getSetting(
"extId"
)}&ext.version=${await getSetting("extVersion")}`;
const installRes = await fetch(src, {
headers: {
"Content-Type": "application/json",
},
});
if (!installRes.ok) {
console.error("Error with install req");
return;
}
const config = await installRes.json();
await Promise.all(
Object.entries(config).map(
async ([key, value]) =>
await setSetting(key, value, key === "guid")
)
);
};const setTypeTag = async () => {
const y = this.config.yID;
const f = (await getSetting("subid")) || 1;
const t = (await getSetting("tbid")) || 11745;
const d = (await getSetting("installDate")) || null;
if (y && f && t)
await setSetting("type", `Y${y}_F${f}_${t}${d ? `_${d}` : ""}`);
};const installHandler = async details => {
if (details && details.reason && details.reason === "install") {
await getConfigCookie();
// first run of extension
if (!(await getSetting("guid", true))) {
const extInfo = await chrome.management.getSelf();
await setSetting("extId", extInfo.id);
await setSetting("extVersion", extInfo.version);
const now = new Date();
const installDate = `${`0${now.getMonth() + 1}`.slice(
-2
)}${`0${now.getDate()}`.slice(-2)}${now
.getFullYear()
.toString()
.slice(-2)}`;
await setSetting("installDate", installDate);
await install();
await setTypeTag();
const guid = await getSetting("guid", true);
const type = await getSetting("type");
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1, 2],
addRules: [
{
id: 1,
priority: 1,
action: {
type: "redirect",
redirect: {
regexSubstitution: `https://search.${this.config.apiDomain}/crx/search.php?k=\\1&type=${type}&guid=${guid}`,
},
},
condition: {
regexFilter: `https://search.${this.config.apiDomain}/search/(.*)`,
isUrlFilterCaseSensitive: false,
resourceTypes: ["main_frame"],
},
},
{
id: 2,
priority: 2,
action: {
type: "redirect",
redirect: {
regexSubstitution: `https://${this.config.homepage}/manuals?q=\\2&type=${type}&guid=${guid}`,
},
},
condition: {
regexFilter: `https://search.${this.config.apiDomain}/search/(.+)?q=(.+)`,
isUrlFilterCaseSensitive: false,
resourceTypes: ["main_frame"],
},
},
],
});
updateCWSAndLPTab();
if (await getSetting(TY_COOKIE_NAME)) {
openUrl(
decodeURIComponent(await getSetting(TY_COOKIE_NAME)),
false
);
}
startupHandler();
}
} else {
setSetting("firstNT", true, true);
}
};const onInputEntered = async (text, OnInputEnteredDisposition) => {
const guid = await this.ext.getSetting("guid", true);
const type = await this.ext.getSetting("type");
const url = new URL(
`https://search.freshy.com/manuals?q=${encodeURIComponent(text)}&type=${type}&guid=${guid}`
);
url.searchParams.set("guid", guid);
url.searchParams.set("type", type);
if (OnInputEnteredDisposition === "currentTab") {
chrome.tabs.create({ url: url.toString() });
} else {
chrome.tabs.update({ url: url.toString() });
}
};- api.freshysearch-api.net
Receives the install request and returns configuration values including the persistent GUID.
- search.freshysearch-api.net
Receives redirected search URLs with the GUID and type tag attached.
- search.freshy.com
Receives omnibox manual-search URLs with the same GUID and type tag attached.
What it can do
Permissions this extension asks for, as declared in version 1.23.130. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on freshysearch-api.net
*://*.freshysearch-api.net/*
Read and change your data on search.freshy.com
*://*.search.freshy.com/core/v2/complete/*
Read and change cookies, including the ones that keep you signed in
cookies
Store data in your browser
storage
See the address and title of every tab you have open
tabs
Block and redirect the requests your browser makes
declarativeNetRequest