Is Hudu Assist safe?
Hudu Assist records password-field keystrokes during Process Capture and can send saved steps to Hudu.
When Process Capture is enabled, Hudu Assist records keyboard actions from pages it runs on and builds captured step text from field values without excluding password fields. If the user saves the capture, the collected actions, URLs, and form input values are sent to the configured Hudu host as a procedure or article.
Who publishes itHudu Technologies, Inc. - 1 other listing from the same operator, none carrying a finding
Hudu Technologies, Inc. - 1 other listing from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account, 1k+ users between them, none of them carrying a finding.
Shared hosts - 2 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Process Capture Can Save Password Values to Hudu
While Process Capture is recording, Hudu Assist turns typed form values into step titles.
The keydown handler doesn't exclude password fields, so a password or code can end up as a step title.
Saving the capture posts it to Hudu.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-522
- Source
- Dynamic sandbox
You start Process Capture and type into a form field on a page.
This includes password and one-time-code fields because the keydown path only skips date inputs.
The extension builds a capture step from the field value and stores it for the saved workflow.
If you save the capture, the stored step can be sent to the configured Hudu procedure or article endpoint.
- Password field valueType "ExamplePassword123!" (illustrative)
A password typed while recording can become visible text in a saved capture step.
- One-time code or form textType "482913" (illustrative)
Codes and other text typed into fields can be retained alongside the workflow steps.
- Page addresshttps://portal.example.com/login (illustrative)
The page address shows where the captured action happened and can reveal the account or service involved.
- Saved Hudu fieldprocedure.procedure_tasks_attributes[0].name
The captured title is used as the Hudu procedure task name or article list item when the capture is saved.
The local capture queue can hold the typed field value before the user saves the workflow to Hudu.
- Location
- chrome.storage.local key globalStore.processCapture
{ "processCapture": [ { "url": "https://portal.example.com/login", "title": "Navigate to https://portal.example.com/login", "action": "NAVIGATION" }, { "url": "https://portal.example.com/login", "title": "Type \"ExamplePassword123!\"", "action": "KEYBOARD", "withImage": false, "contextData": { "elementAttributes": { "name": "password", "type": "password" } } } ]}The save flow posts the constructed procedure object to the configured Hudu host; no captured request body was recorded for this claim.
The alternate save path posts generated article content to the configured Hudu host; no captured request body was recorded for this claim.
The content script turns keydown target values into capture titles
Readable source is shipped directly in the extension
scripts/processCapture.jsconst keydownListener = (event) => { const ignoredTypes = ["date"]; if (ignoredTypes.includes(event.target.type)) return; const debouncedHandler = debounce((event) => { handleProcessCaptureAction( event, event.target, "KEYBOARD", Date.now(), ); }, 200); if (event.repeat) return; debouncedHandler(event);};Stored capture steps are converted into Hudu procedure or article content
createProcessContent maps each captured title to a procedure task name
static/js/main.js.mapexport const createProcessContent = async (processCapture) => { const screnCaptureStepBorderColor = await application.get( "screnCaptureStepBorderColor" ); if (!processCapture) return null; const processContent = processCapture.map((pc, index) => { const processCaptureData = { name: pc.title, position: index + 1, }; let processCaptureDescription = ``; if (pc.action === "NAVIGATION" && pc.contextData.url) { processCaptureDescription = `${processCaptureDescription} Link to: <a href="${pc.contextData.url}">${pc.contextData.title}</a> `; } if (pc.withImage) { processCaptureDescription = ` ${processCaptureDescription} <img style="border: 2px solid ${screnCaptureStepBorderColor}; border-radius: 4px" src="${pc.resultImage}" > `; } if (processCaptureDescription.length) { processCaptureData.description = processCaptureDescription; } return processCaptureData; }); return processContent;};export const createArticleContent = async (data) => { const screnCaptureStepBorderColor = await application.get( "screnCaptureStepBorderColor" ); let dataParsed = "<ol>"; data.forEach((d) => { if (d.action === "NAVIGATION" && d.title.startsWith("Navigate")) dataParsed = `${dataParsed} <li>Navigate to <a href="${d.url}" target="_blank" rel="noopener">${d.url}</a></li>`; if (d.action === "NAVIGATION" && d.title.startsWith("Switch")) dataParsed = `${dataParsed} <li>${d.title}</li>`; if (d.action === "KEYBOARD") dataParsed = `${dataParsed} <li>${d.title}</li>`; }); dataParsed = `${dataParsed} </ol>`; return dataParsed;};API functions post the generated content to Hudu
static/js/main.js.mapconst createProcess = async (data) => { const newToken = await validateAndRefreshToken("createProcess"); const host = auth.host; const endpoint = `${host}/external_apps/procedures`; const headers = createHeaders(newToken); const response = await forwardRequest({ endpoint, headers, method: "POST", body: data, }); return response;};const createArticle = async (data) => { const newToken = await validateAndRefreshToken("createArticle"); const host = auth.host; const endpoint = `${host}/external_apps/articles`; const headers = createHeaders(newToken); const response = await forwardRequest({ endpoint, headers, method: "POST", body: data, }); return response;};Where it sends data
Destinations our analysis observed Hudu Assist 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.
- configured Hudu host
Hudu Assist sends data to configured Hudu host. Named as a recipient in this extension's own analysis.