Is Devolutions Password Manager safe?
Devolutions Workspace reads form fields on every page to autofill saved logins, and ships hardcoded credentials for its telemetry server.
As a password manager, Devolutions Workspace injects a content script into every http/https/file page and frame that enumerates forms and reads input field values (including hidden fields, truncated at 254 chars) to power autofill. A second script runs in the page's main world and intercepts navigator.credentials.create/get calls to relay WebAuthn challenges to the extension. The background script also embeds a fixed username and password used to POST analytics to Devolutions' OpenSearch telemetry server; because extension source is readable after install, those credentials are effectively public.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
OpenSearch Basic-auth credentials in the extension package
Devolutions Password Manager includes an OpenSearch Basic-auth username and password in its background script, used to build a daily analytics POST to telemetry2.devolutions.net:9200, so anyone inspecting the package can read both values.
You keep the extension installed while its background script is running.
The analytics sender runs on startup and then uses a 24-hour interval before sending again.
The extension builds an OpenSearch analytics request with Basic-auth credentials stored in its own code.
The packaged source includes the account name and password value used for the request.
The analytics sender runs once when the background script initializes, then suppresses another send until a full day has elapsed.
| Content-Type | application/json |
| Authorization | Basic <redacted> |
| Field | Value | Why it matters | |
|---|---|---|---|
Analytics host | telemetry2.devolutions.net:9200 | This is the remote service that receives the analytics request from the extension. | |
Basic-auth account | WBEX_2025.3 | This account name is packaged with the extension and is used to authenticate the OpenSearch write request. | |
Basic-auth password | password value redacted | The corresponding password is also packaged with the extension, making the credential readable from the installed code. | |
OpenSearch index | wbex_configuration_events | This names the destination collection where the extension writes the settings event. | |
Installation identifier | 4f45d8a3-2c6d-4d3b-9f25-1f0c7f7a8b61 | This value lets the analytics event be tied back to the same extension installation over time. | |
Application and browser details | WBEX 2026.2.0.6 on Chrome/Linux, en-US | These fields describe the extension version, browser, operating system, architecture, and language included in the analytics event. | |
Never-list counters | neverAutofillCount: 2 | These counters summarize how many sites were added to local lists that prevent saving, autofill, or icons. |
The shipped constants and request builder
const FA = {
url: "https://telemetry2.devolutions.net:9200",
username: "WBEX_2025.3",
password: "<redacted>",
datasourceFeatureEventIndex: "wbex_configuration_events",
featureEventIndex: "feature_events"
};static async send() {
try {
const e = await x.getLocalStorageModelKey(["settings", "analyticsInfos", "NeverAddSite", "NeverAutofill", "NeverDoAnything", "NeverShowIconsInFields"]);
if (!e.settings || e.settings.disableAnalytics) return;
const i = e.analyticsInfos?.lastSentAt ?? 0;
if (Date.now() - i < this.TWENTY_FOUR_HOURS_MS) return;
const n = {
neverAddSiteCount: (e.NeverAddSite ?? []).length,
neverAutofillCount: (e.NeverAutofill ?? []).length,
neverDoAnythingCount: (e.NeverDoAnything ?? []).length,
neverShowIconsInFieldsCount: (e.NeverShowIconsInFields ?? []).length
},
r = !!(await M.getManagedStorageItem())?.Settings,
a = await this.getInstallID();
await x.setLocalStorageModel({
analyticsInfos: {
...e.analyticsInfos,
applicationInstallUniqueId: a,
lastSentAt: Date.now()
}
}), await this.sendToOpenSearch(e.settings, n, r, a);
} catch (e) {
le.debug(e);
}
}static async sendToOpenSearch(e, i, n, s) {
const {
url: r,
username: a,
password: l,
datasourceFeatureEventIndex: u
} = FA, d = u, h = await this.getApplicationInfos(), c = {
eventDate: new Date().toISOString(),
eventId: As(),
installId: s,
application: h,
settings: this.sanitizeSettings(e),
neverList: i,
hasManagedSettings: n
};
await fetch(`${r}/${d}/_doc`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Basic ${btoa(`${a}:${l}`)}`
},
body: JSON.stringify(c)
});
}- telemetry2.devolutions.net
Devolutions telemetry host that receives OpenSearch analytics POST requests on port 9200.