Is AnswerAI - Homework AI Tutor & Study Helper safe?
Answer AI is medium risk. A shipped rule targets XHR to `etpweb.answerai.pro/*`: strips `Origin`, sets `Content-Type: application/x-www-form-urlencoded` and `X-Requested-With`, adds `Access-Control-Allow-Origin: *`. Confirmed from the shipped rule file.…
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
AnswerAI rewrites headers for its analytics domain
A shipped rule targets XHR to `etpweb.answerai.pro/*`: strips `Origin`, sets `Content-Type: application/x-www-form-urlencoded` and `X-Requested-With`, adds `Access-Control-Allow-Origin: *`.
Confirmed from the shipped rule file.
The extension is installed with its packaged network request ruleset enabled.
Chrome applies the shipped rule to matching analytics requests and rewrites request and response headers.
| Field | Value | Why it matters | |
|---|---|---|---|
Origin request header | Origin header removed | Removes the browser header that normally describes where a cross-origin request came from. | |
Request content type | Content-Type: application/x-www-form-urlencoded | Changes how the request declares its body format to the server. | |
XHR marker | X-Requested-With: XMLHttpRequest | Marks the request as an XMLHttpRequest-style call. | |
Response CORS header | Access-Control-Allow-Origin: * | Allows browser code to read responses from any origin when the rule modifies the response. |
The manifest enables the ruleset and rule 5 performs the header rewrite
const manifestHeaderRuleConfig = {
manifest_version: 3,
background: {
service_worker: "static/background/index.js"
},
permissions: [
"storage",
"scripting",
"activeTab",
"clipboardWrite",
"tabs",
"declarativeNetRequest",
"declarativeNetRequestWithHostAccess",
"declarativeNetRequestFeedback",
"unlimitedStorage",
"contextMenus"
],
declarative_net_request: {
rule_resources: [
{
id: "ruleset_1",
enabled: true,
path: "header.7c1f959a.json"
}
]
}
};const headerRewriteRule = {
id: 5,
priority: 1,
action: {
type: "modifyHeaders",
responseHeaders: [
{
header: "Access-Control-Allow-Origin",
operation: "set",
value: "*"
}
],
requestHeaders: [
{
header: "Content-Type",
operation: "set",
value: "application/x-www-form-urlencoded"
},
{
header: "Origin",
operation: "remove"
},
{
header: "X-Requested-With",
operation: "set",
value: "XMLHttpRequest"
}
]
},
condition: {
urlFilter: "https://etpweb.answerai.pro/*",
resourceTypes: ["xmlhttprequest"]
}
};- etpweb.answerai.pro
AnswerAI analytics/API host whose XHR traffic matches the packaged header-rewrite rule.
AI assistant clicks send page details to analytics
Asking the AI assistant a question from a webpage makes the content script build a `search_click` event with the page URL, title, domain, and device ID, sent to `etpweb.answerai.pro/event/report/web`.
Not captured in this test session.
You ask the AI assistant a question while viewing a webpage.
The extension prepares a tracker event that includes that page's URL, title, domain, and a stored device ID.
| Field | Value | Why it matters | |
|---|---|---|---|
Current page URL | https://en.wikipedia.org/wiki/Photosynthesis | Links the assistant question to the exact webpage you were viewing. | |
Page title | Photosynthesis - Wikipedia | Adds a readable description of the page where you used the assistant. | |
Page domain | en.wikipedia.org | Shows which site you were on when the assistant interaction happened. | |
Stored device ID | 1897719478737 | Lets separate tracker events be linked back to the same browser profile over time. |
The content script builds the page-context tracker event; the background tracker adds the stored ID
let handleAssistantAction = async (askType, acceptLanguage, isRegenerate = false) => {
let selectedText = activeSelectionString.current;
if (askType === AskAIButtonType.Translate && !isRegenerate && acceptLanguage) {
let cached = store.getTranslationCache(selectedText, acceptLanguage);
if (cached) {
setAskType(askType);
setWindowVisible(true);
if (!windowOpen) {
setPosition({ x: selectMenuPosition.left, y: selectMenuPosition.top - 15 });
}
setReply({
type: "reply",
content: cached,
source: ChatSource.extTranslate,
acceptLanguage
});
return;
}
}
sendToBackground({
name: "tracker",
body: {
name: "tracker",
props: {
class: askType + 1,
message: selectedText,
domain: domain.current
}
}
});
setAskType(askType);
setWindowVisible(true);
if (!windowOpen) {
setPosition({ x: selectMenuPosition.left, y: selectMenuPosition.top - 15 });
}
store?.setActiveTab?.(0);
setReply(null);
if (!sendMessageRef.current || !await sendMessageRef.current({
curString: selectedText,
askType,
acceptLanguage,
isRegenerate
})) {
if (!store.isLogin) {
setAuthOpen(true);
return;
}
if (!store.flash) {
setWindowVisible(true);
}
return;
}
sendToBackground({
name: "tracker",
body: {
name: "search_click",
props: {
class: 1,
url: location.href.slice(0, 200),
title: document.title.slice(0, 200),
domain: domain.current
}
}
});
countPostTimes();
};const localStorage = new Storage({ area: "local" });
const sessionStorage = new Storage();
const trackEvent = async ({ name, props }) => {
const deviceId = await localStorage.get(DEVICE_ID);
globalThis.sensors?.track(name, {
mid: deviceId,
...props
});
};- etpweb.answerai.pro
AnswerAI analytics reporting endpoint receiving extension tracker events.
Persistent device ID joins AnswerAI tracker events
We observed tracker traffic to `etpweb.answerai.pro/event/report/web` carrying a persistent device identifier and domain `en.wikipedia.org`.
The worker creates a local `device_id` if none exists, stores it, adds it as `mid` before posting.
You use AnswerAI in a way that causes the extension to report a tracker event.
The extension sends the event with a reused device identifier and browsing context to its analytics endpoint.
| Field | Value | Why it matters | |
|---|---|---|---|
Persistent device ID | 1897719478737 | Links multiple extension events back to the same browser profile over time. | |
Secondary device token | 19f537a24446c9 | Adds another stable-looking identifier to the same tracker event. | |
Visited domain | en.wikipedia.org | Shows which website was associated with the extension activity. | |
Tracker event name | plugin_mainpage | Describes the type of extension activity being reported. |
The service worker creates, stores, and attaches the device identifier
const localStorage = new Storage({ area: "local" });
const initDeviceId = async () => {
let deviceId = await localStorage.get(DEVICE_ID);
if (!deviceId) {
deviceId = uuid.v4();
localStorage.set(DEVICE_ID, deviceId);
}
return deviceId;
};const trackEvent = async ({ name, props }) => {
const deviceId = await localStorage.get(DEVICE_ID);
globalThis.sensors?.track(name, {
mid: deviceId,
...props
});
};const headers = {
Client: "web",
mid: await initDeviceId(),
"Content-Type": "application/json",
"X-Content-Security": getContentSecurity({
method,
path: options?.onelink ? path : "/api/v1" + path,
query: query || "",
body,
onelink: options?.onelink
}),
cversion,
tzoffset: initTzOffset(),
...(token ? { authorization: `Bearer ${token}` } : {}),
...options.headers
};- etpweb.answerai.pro
AnswerAI analytics reporting endpoint receiving tracker events with device identifiers and event properties.