Is Cheap Flight Finder safe?
This extension notifies you when cheaper flight prices are available during your flight search.
It compares prices across hundreds of flight booking websites and highlights cheaper deals for the flight you are searching for. The extension is free to use and is available in multiple languages.
Who publishes itTrip.com Travel Singapore Pte. Ltd. - no other listings under this identity
Trip.com Travel Singapore Pte. Ltd. - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Extension reports visited travel sites and a persistent ID to fly.trip.com
Visiting a travel site, incl.
Booking.com, Skyscanner, Expedia, and a dozen competitors, makes the extension POST the URL to fly.trip.com/logUserInfo with a UUID made at install.
Tracked sites load from a remote config, expandable anytime.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You visit any travel booking website.
The extension monitors all tab navigations and checks each completed URL against a remotely-updated list of airline and hotel booking sites.
The extension sends the full URL you visited and a permanent identifier to fly.trip.com.
A throttled POST request carries the visited URL, the fly_uid UUID, the referral source, and extension version to fly.trip.com/logUserInfo, automatically, with no prompt.
HTTP 200; request confirmed observed in dynamic analysis (2 POST requests captured to /logUserInfo from background service worker).
- uid
- e85d34d7-c895-4b7f-a7d9-e144e0e10cf8
- source
- direct
- version
- 1.7.16
- Content-Type
- application/json
- authorization
- ade5f8beb741
{ "url": "https://www.booking.com/flights/", "extends": { "version": "1.7.16", "source": "direct", "uid": "e85d34d7-c895-4b7f-a7d9-e144e0e10cf8" }}- Visited URLhttps://www.skyscanner.com/transport/flights/lon/jfk/250815/
The full address of the travel site visited, including search parameters that may reveal destination, dates, and travel preferences.
- Persistent device ID (fly_uid)e85d34d7-c895-4b7f-a7d9-e144e0e10cf8
A UUID generated once when you installed the extension and never rotated. It links every travel-site visit to the same device across time.
- Referral sourcedirect
Tracks which channel referred you to install the extension (e.g. 'direct', an affiliate code).
- Extension version1.7.16
The installed version of the extension, used by the server to segment reports.
Every 5 minutes
URL reporting is throttled to at most once every 5 minutes per qualifying navigation event. The throttle window is set by logInterval in the remote config (default 300,000 ms) and can be changed server-side without an extension update.
Navigation listener: URL matching and throttled POST dispatch (background.js lines 592-636)
p() — the throttled logUserInfo sender (background.js lines 470–527)
background.jsfunction p(e) { // e = { url: <visited URL> } // Reads fly_uid from chrome.storage.sync, appends to POST body const uid = yield chrome.storage.sync.get('fly_uid'); const source = yield chrome.storage.sync.get('fly_source'); return fetch('https://fly.trip.com/logUserInfo', { method: 'POST', headers: { 'Content-Type': 'application/json', authorization: 'ade5f8beb741', version: '1.7.16', source, uid }, body: JSON.stringify({ ...e, // { url: <visited URL> } extends: { version: '1.7.16', source, uid } }) }).then(r => r.json());}- fly.trip.com
Trip.com Group (NASDAQ: TCOM), receives visited URL and persistent UUID at /logUserInfo; also serves remote config at /client/config that controls which sites are tracked.
Remote config from fly.trip.com sets which sites are tracked and how often
A GET to fly.trip.com/client/config returns config for the extension's own tracking: otaReg/travelReg gate /logUserInfo, logInterval sets the gap.
Fallbacks apply only on fetch failure; on success, server values persist locally.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
The background service worker runs on install, and again roughly every 24 hours as the user browses.
It fetches configuration from fly.trip.com/client/config and stores the returned tracking-site patterns and send interval for use on future page navigations.
200 OK. Observed during dynamic analysis. Response body contains otaReg, travelReg, and logInterval fields that set which visited-page URLs get sent to fly.trip.com/logUserInfo and how often, matching the fallback shape hardcoded in background.js.
- authorization
- ade5f8beb741
- Tracked booking-site list (otaReg)(booking|kiwi|skyscanner|expedia|agoda|priceline|ctrip|...)\.(com|co|sg|uk|es|jp|ko) (default fallback value shipped in the extension)
A regular expression naming which travel-booking domains (e.g. booking.com, expedia.com, priceline.com) trigger a URL send when visited.
- Tracked keyword pattern (travelReg)(search|fly|flight|flights|travel|from|hotel|train) (default fallback value shipped in the extension)
A regular expression matching travel-related keywords (search, fly, flight, hotel, train) anywhere in a visited URL.
- Send interval (logInterval)300000 (5 minutes; default fallback value shipped in the extension)
The minimum time between URL sends to fly.trip.com/logUserInfo, in milliseconds.
- Authorization headerade5f8beb741
A fixed API key hardcoded in the extension's code, sent with every config and tracking request.
Config-fetch function with hardcoded fallback values
function h() { return l(this, void 0, void 0, function*() { const e = yield fetch(`${t}/client/config`, { headers: { authorization: "ade5f8beb741" } }), r = yield e.json(); 0 === r.errorCode ? u.set(c.CONFIG, r.data) : u.set(c.CONFIG, { isShowLoading: !1, loadingTimeout: 3e3, higherDiscountRate: .05, otaReg: "(booking|kiwi|skyscanner|expedia|agoda|priceline|ctrip|makemytrip|traveloka|edreams|onthebeach|jtb|tuniu|hotelscombined|elong|qunar|hrs|alitrip|weg|docholiday|cleartrip|rakuten)\\.(com|co|sg|uk|es|jp|ko)", travelReg: "(search|fly|flight|flights|travel|from|hotel|train)", logInterval: 3e5 }) }) }Every 1 day
The config fetch runs on extension install and is re-triggered on the first completed page navigation more than 24 hours after the last refresh, so a server-side change to otaReg/travelReg/logInterval can take effect fleet-wide within about a day without an extension update.
Extension posts visited travel-site URLs with a persistent ID to trip.com
The background script POSTs a visited URL, install ID, and source to fly.trip.com/logUserInfo, gated by 2 remote regexes (travel sites, keywords).
Matches go to trip.com, debounced 5 min; capture fired on the onboarding page at install.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
User navigates to a page matching the extension's travel/OTA site patterns, such as booking.com, expedia.com, or skyscanner.com.
The background script sends the visited page's full URL, along with a persistent installation ID, to fly.trip.com/logUserInfo.
Captured during dynamic analysis. The URL field carries the page navigated to; because the extension's own onboarding page was the first completed navigation after install, it is the URL captured here, but the same code path fires for any subsequent page matching the travel/OTA regex.
- uid
- b3985d23-9220-4185-abea-47e0e13a81c6
- source
- direct
- version
- 1.7.16
- Content-Type
- application/json
- authorization
- ade5f8beb741
{ "url": "https://us.trip.com/pages/flights/pages/save-fly-crx-welcome.html?locale=en-US&utm_source=direct", "extends": { "version": "1.7.16", "source": "direct", "uid": "b3985d23-9220-4185-abea-47e0e13a81c6" }}- Visited page URLhttps://www.booking.com/searchresults.html?ss=Paris (illustrative)
The full URL of the page you navigated to, including query string, is sent when it matches a travel/OTA pattern.
- Persistent installation IDb3985d23-9220-4185-abea-47e0e13a81c6
A UUID generated once on install, stored in sync storage, sent with every request to link visits to this installation over time.
- Install sourcedirect
Records where the extension install originated from (e.g. a referral or campaign tag).
- Extension version1.7.16
The installed extension version, sent with every request.
Navigation listener that matches visited URLs and posts them to fly.trip.com
let d = !1, f = 0; function h() { return l(this, void 0, void 0, function*() { const e = yield fetch(`${t}/client/config`, { headers: { authorization: "ade5f8beb741" } }), r = yield e.json(); 0 === r.errorCode ? u.set(c.CONFIG, r.data) : u.set(c.CONFIG, { isShowLoading: !1, loadingTimeout: 3e3, higherDiscountRate: .05, otaReg: "(booking|kiwi|skyscanner|expedia|agoda|priceline|ctrip|makemytrip|traveloka|edreams|onthebeach|jtb|tuniu|hotelscombined|elong|qunar|hrs|alitrip|weg|docholiday|cleartrip|rakuten)\\.(com|co|sg|uk|es|jp|ko)", travelReg: "(search|fly|flight|flights|travel|from|hotel|train)", logInterval: 3e5 }) }) } function p(e) { return function(e) { return r = this, n = arguments, u = function*({ url: e, data: r, options: n, method: i = "POST" }) { const u = yield o.get(a.FLY_UID), c = yield o.get(a.SOURCE); return fetch(`${t}${e}`, Object.assign({ method: i, headers: { "Content-Type": "application/json", authorization: "ade5f8beb741", version: s, source: c, uid: u }, body: "POST" === i ? JSON.stringify(Object.assign(Object.assign({}, r || {}), { extends: { version: s, source: c, uid: u } })) : void 0 }, n || {})).then(t => t.json()) }, new((i = void 0) || (i = Promise))(function(t, e) { function o(t) { try { s(u.next(t)) } catch (t) { e(t) } } function a(t) { try { s(u.throw(t)) } catch (t) { e(t) } } function s(e) { var r; e.done ? t(e.value) : (r = e.value, r instanceof i ? r : new i(function(t) { t(r) })).then(o, a) } s((u = u.apply(r, n || [])).next()) }); var r, n, i, u }({ url: "/logUserInfo", method: "POST", data: e }) } var v = r(7350), y = r.n(v), g = function(t, e, r, n) { return new(r || (r = Promise))(function(i, o) { function a(t) { try { u(n.next(t)) } catch (t) { o(t) } } function s(t) { try { u(n.throw(t)) } catch (t) { o(t) } } function u(t) { var e; t.done ? i(t.value) : (e = t.value, e instanceof r ? e : new r(function(t) { t(e) })).then(a, s) } u((n = n.apply(t, e || [])).next()) }) }; const m = { da: "da-DK", de: "de-DE", el: "el-GR", "en-US": "en-US", es: "es-ES", fi: "fi-FI", fr: "fr-FR", id: "id-ID", it: "it-IT", ja: "ja-JP", ko: "ko-KR", ms: "ms-MY", nl: "nl-NL", pl: "pl-PL", "pt-BR": "pt-BR", "pt-PT": "pt-PT", ru: "ru-RU", sv: "sv-SE", th: "th-TH", tr: "tr-TR", uk: "uk-UA", vi: "vi-VN", "zh-CN": "zh-HK", "zh-TW": "zh-HK" }, x = ["https://fly.trip.com/checkPriceV3"]; chrome.webRequest.onBeforeRequest.addListener(t => { t.url, t.tabId }, { urls: ["https://fly.trip.com/*"] }, ["requestBody"]); let w = null; try { let r, i; chrome.tabs.onUpdated.addListener((e, n, v) => g(void 0, void 0, void 0, function*() { yield function() { return l(this, void 0, void 0, function*() { if (d) return; d = !0; const e = f || (yield o.get(a.LAST_UPDATE_DATE)) || 0, r = yield o.get(a.FLY_UID), n = yield o.get(a.SOURCE), i = yield chrome.cookies.get({ url: "https://fly.trip.com", name: "cticket" }), u = Date.now(); if (u - e > 864e5 && r && n) { f = u, yield o.set(a.LAST_UPDATE_DATE, u), h(); try { yield fetch(`${t}/trackerV2`, { credentials: "include", method: "POST", headers: { "Content-Type": "application/json", authorization: "ade5f8beb741" }, body: JSON.stringify({ cticket: null == i ? void 0 : i.value, extends: { version: s, source: n, uid: r } }) }) } catch (t) {} } d = !1 }) }(); const e = yield u.get(c.CONFIG); if (e && !r && !i) { const { otaReg: t, travelReg: n } = e; r = new RegExp(t), i = new RegExp(n) } e && e.logInterval && !w && (w = y()(p, e.logInterval)), v.url && "complete" === n.status && (r.test(v.url) || i.test(v.url)) && (null == w || w({ url: v.url }))Every 5 minutes
The extension can send at most one matching URL per debounce window; the window length is set by the logInterval value returned from the extension's remote config (5 minutes/300000ms by default) and can be changed by the server at any time without an extension update.
Where it sends data
Destinations our analysis observed Cheap Flight Finder contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- trip.com
Cheap Flight Finder sends data to trip.com. No other extension we have analysed sends data here.