Is Onelog safe?
Onelog is high risk. We observed Onelog posting to its localhost relay during browsing. Source shows navigation can build a BeforeNavigateRequest with the page URL, window/browser context, a resolved username; our test's agent stalled at the language probe.…
Who publishes itInfo Technology Supply Limited - no other listings under this identity, 1 shared hostname
Info Technology Supply Limited - no other listings under this identity, 1 shared hostname
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 1 hostname
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
Navigation URLs Posted to Onelog Localhost Relay
We observed Onelog posting to its localhost relay during browsing.
Source shows navigation can build a BeforeNavigateRequest with the page URL, window/browser context, a resolved username; our test's agent stalled at the language probe.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You open or navigate to a web page.
Onelog prepares a navigation record and sends JSON to its local relay service.
Repeated localhost relay POSTs were observed; the URL-bearing BeforeNavigateRequest body was not captured because the desktop-agent handshake did not complete.
- Content-Type
- application/json
{ "LanguageItems": {}}- Page URLhttps://example.com/
Shows the exact page you were opening, including path and query text when present.
- Resolved usernamejane.doe@example.com (illustrative)
Can connect the browsing event to a specific signed-in person when Onelog has resolved a username.
- Window and tab contextWindowId 2, WindowHandle 1 (illustrative)
Adds browser context that ties the page visit to a specific tab and window.
- Browser typechrome
Identifies the browser family used for the page visit.
Navigation event and request construction
Navigation listener calls the request sender
deobfuscated/extensionEvents.jsolExtension.Listeners._internal.Events = { _beforeNavigateEvent: function (event) { try { var alertContent_ = new olFunctions.AlertContent('EVT Before navigate event', 'Caught by extension Url: ' + event.target.getUrl()); if (event.target.url == olExtension.Data.LogoutUrl) { olExtension._internal.HandleLogoutWindow(event); } else { //Check logout array if (olData.LogoutTabs.indexOf(event.target.getId()) == -1) { // not a logout tab var tabId_ = event.target.getId(); chrome.webNavigation.getAllFrames({ tabId: tabId_ }, function (result) { try { var framesArray_ = []; for (var i = 0; i < result.length; i++) { var currentFrame_ = result[i]; var currentFrameId_ = currentFrame_.frameId; framesArray_.push(currentFrameId_) } } catch (e) { framesArray_ = []; var alertErrorContent_ = new olFunctions.AlertContent('_beforeNavigateEvent chrome.webNavigation.getAllFrames', e.message + ' ' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } finally { var tabMember_ = olExtension._internal.TabMember.Create(event.target.getId(), event.target.getUrl(), framesArray_); var urlDomain_ = olFunctions.GetDomainFromUrl(event.target.getUrl()); if (urlDomain_ && (ol$Functions.inArray(urlDomain_, tabMember_.Domains) == -1)) { tabMember_.Domains.push(urlDomain_); } var requestContent_ = new olExtension.DataConstructors.RequestContent(tabMember_); olExtension.Service.BeforeNavigateRequestSend(requestContent_); } }) } else { // logout tab return; } } olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('_beforeNavigateEvent', e.message + ' ' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } }, BeforeNavigate: function () { olWrap.browser.addEventListener(olWrap.browser.event.BeforeNavigate, function (event) { try { var waitingForSw_Init = setInterval(function () { if (olExtension.Data.SW_Initialised) { clearInterval(waitingForSw_Init); if (event.url != null && !olWrap.urlExcluded(event.url)) { olExtension.Listeners._internal.Events._beforeNavigateEvent(event); } } }, 50) } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('BeforeNavigate', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } }); },BeforeNavigateRequest fields
deobfuscated/extensionApiService.jsBeforeNavigateRequestSend: function (requestContent, processRequestSuccess) { try { requestContent.TabMember._internal.ExtensionFlags.BeforeNavigateRequestSent = true; var alertContent_ = new olFunctions.AlertContent('API Before navigate request sent', 'Url: ' + requestContent.TabMember._internal.GetUrl()); var successFunction_ = olExtension.Service._internal.SetSuccessFunction(processRequestSuccess, olExtension.Service._internal.SuccessBeforeNavigateRequest); var browserName_ = olData.BrowserName; var ajaxData_ = { BeforeNavigateRequest: { URL: requestContent.TabMember.PageInfo.RequestUrl, // URL: requestContent.TabMember._internal.GetUrl(), WindowId: requestContent.TabMember.WindowId, SessionSetId: 1, WindowHandle: requestContent.TabMember.WindowHandle, BrowserType: (browserName_ == olWrap.browser.name.edg ? 'chrome' : browserName_), NewEdgeCompatibility: (browserName_ == olWrap.browser.name.edg) } }; if (olExtension._internal.UsernameResolved) { ajaxData_.BeforeNavigateRequest.Username = olExtension._internal.Username } var sendRequestParams_ = new olExtension.DataConstructors.SendRequestParameters('BeforeNavigateRequest', ajaxData_, requestContent, successFunction_); olExtension.Service._internal.SendRequest(sendRequestParams_); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('BeforeNavigateRequestSend', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },Shared JSON POST transport
deobfuscated/extensionApiService.js_SendRequestFetch: async function (sendRequestParameters) { const response = await fetch(olOptions.General.Extension.ServerUrl(), { method: sendRequestParameters.AjaxParam.Type, cache: 'no-cache', timeout: sendRequestParameters.AjaxParam.Timeout, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(sendRequestParameters.AjaxParam.Data) // body data type must match "Content-Type" header }); return response.json(); },Localhost relay setting
deobfuscated/modOptions.js{ Name: 'ServerUrl', Visible: false, Label: 'Server URL', Value: 'http://localhost:12345/index/', DefaultValue: 'http://localhost:12345/index/', ElementOptions: null, ObjectId: 'olServerURL', Type: 'internal', ParentId: 'olAdministratorSettings' },- localhost
Onelog local relay service on port 12345 receives JSON request types including LanguageItems and, when the handshake permits, BeforeNavigateRequest.
Page Titles Sent After Onelog Navigation Completion
Onelog source records the document title for a tab and builds a DocumentCompleteRequest with that title and session ID.
We observed posts to the same relay during testing, but this request needs a successful desktop-agent chain, uncaptured.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You load a page whose title is visible to the extension.
Onelog stores the title and can include it in a completion request to its local relay.
Localhost relay POSTs were observed after page load; the DocumentCompleteRequest body was not captured without a valid navigate-complete response.
- Content-Type
- application/json
{ "LanguageItems": {}}- Page titleExample Domain
Can reveal which page or account view you opened even when the URL is not shown.
- Application session IDApplicationSessionId 42 (illustrative)
Links the completed page load to the application session tracked by Onelog.
- Response flagsIgnore=false, TurnAway=false (illustrative)
Carries control flags from the earlier navigation response into the completion record.
Document title capture and completion request
The page title is stored on the tab record
deobfuscated/extensionMessaging.jsif (!tabMember_._internal.ExtensionFlags.BeforeNavigateRequestSent) { var requestContent_ = new olExtension.DataConstructors.RequestContent(tabMember_); olExtension.Service.BeforeNavigateRequestSend(requestContent_); } tabMember_._internal.ExtensionFlags.DocumentReady = true; tabMember_.DocumentTitle = documentTitle; var messageContent_ = new olExtension.DataConstructors.MessageContent(tabMember_);Navigate-complete success invokes DocumentCompleteRequestSend
deobfuscated/extensionApiService.jsSuccessNavigateCompleteRequest: function (requestResult, requestContent) { try { var alertContent_ = new olFunctions.AlertContent('API Success Navigate complete request succeeded', 'Url: ' + requestContent.TabMember.PageInfo.Url); if (olFunctions.IsFilledArray(requestResult.NavigateCompleteResponses)) { if (requestResult.NavigateCompleteResponses.length > 1) { var navigateResponse_ = requestResult.NavigateCompleteResponses[1]; var filterMembers_ = olExtension._internal.TabMember.Filter(null, null, null, navigateResponse_.ApplicationsSessionId); if (navigateResponse_.ApplicationsSessionId && olFunctions.IsFilledArray(filterMembers_)) { var tabMember_ = filterMembers_[0]; tabMember_.PageInfo.ClosingResponse = navigateResponse_; olExtension._internal.TabMember.HandleResourceEnd(tabMember_); } } var ncr0_ = requestResult.NavigateCompleteResponses[0]; //and send pause duration if (!(ncr0_.PauseDuration && ncr0_.PauseDuration > 0)) { ncr0_.PauseDuration = 0; } requestContent.TabMember.PageInfo.Response.BeforeNavigateResponses[0].PauseDuration = ncr0_.PauseDuration; // send pause duration back to tab var pauseDuration_ = { ApplicationName: ncr0_.ApplicationName, PauseDuration: ncr0_.PauseDuration }; var messageContent_ = new olExtension.DataConstructors.MessageContent(requestContent.TabMember, pauseDuration_); olExtension.Messages.PauseDuration(messageContent_); } olExtension.Service.DocumentCompleteRequestSend(requestContent); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('SuccessNavigateCompleteRequest', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },DocumentCompleteRequest fields
deobfuscated/extensionApiService.jsDocumentCompleteRequestSend: function (requestContent, processRequestSuccess) { try { if (!requestContent.TabMember._internal.ExtensionFlags.DocumentCompleteRequestSent) { requestContent.TabMember._internal.ExtensionFlags.DocumentCompleteRequestSent = true; var alertContent_ = new olFunctions.AlertContent('API Document complete request sent', 'Url: ' + requestContent.TabMember.PageInfo.Url); var successFunction_ = olExtension.Service._internal.SetSuccessFunction(processRequestSuccess, olExtension.Service._internal.SuccessDocumentCompleteRequest); var ajaxData_ = { DocumentCompleteRequest: { WindowTitle: requestContent.TabMember.DocumentTitle, ApplicationSessionId: requestContent.TabMember.ApplicationsSessionId, Ignore: requestContent.TabMember.PageInfo.Response.BeforeNavigateResponses[0].Ignore, TurnAway: requestContent.TabMember.PageInfo.Response.BeforeNavigateResponses[0].TurnAway, TurnAwaySpecified: requestContent.TabMember.PageInfo.Response.BeforeNavigateResponses[0].TurnAwaySpecified } }; var sendRequestParams_ = new olExtension.DataConstructors.SendRequestParameters('DocumentCompleteRequest', ajaxData_, requestContent, successFunction_); olExtension.Service._internal.SendRequest(sendRequestParams_); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('DocumentCompleteRequestSend', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },Shared JSON POST transport
deobfuscated/extensionApiService.js_SendRequestFetch: async function (sendRequestParameters) { const response = await fetch(olOptions.General.Extension.ServerUrl(), { method: sendRequestParameters.AjaxParam.Type, cache: 'no-cache', timeout: sendRequestParameters.AjaxParam.Timeout, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(sendRequestParameters.AjaxParam.Data) // body data type must match "Content-Type" header }); return response.json(); },- localhost
Onelog local relay service on port 12345 receives JSON request types including LanguageItems and, when the response chain permits, DocumentCompleteRequest.
Shared Password Flow Relays Credentials via Localhost
Onelog's shared-password overlay can send a selected user name and password-details user ID to its localhost relay, then process a SharedPasswordsResponse and dispatch data to page content.
Confirmed from code, not a captured request.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-522
- Source
- Dynamic sandbox
You select a shared-password user inside the Onelog page overlay.
Onelog requests shared password data from the local relay and sends the response back to the page.
The GetSharedPasswordsRequest is posted to this URL by the shared fetch transport; no password-request body was captured in traffic because the overlay and desktop-agent conditions were not present.
- Content-Type
- application/json
- Selected user nameshared.user@example.com (illustrative)
Identifies the shared-password account entry selected in the overlay.
- Password details user IDPasswordDetailsUserId 18472 (illustrative)
Links the request to the stored shared-password record for that selected user.
- Application session IDApplicationSessionId 42 (illustrative)
Associates the shared-password request with the application session Onelog is tracking.
- Returned shared password dataSharedPasswordsResponse.SharedPasswordsUser.VariableReplacement.PersonalDetail (source field)
Password replacement data can be sent back into page content for form filling.
Shared-password request and response dispatch
Overlay click collects selected shared user details
deobfuscated/page.jsSelectedSharedUser_onClick: function (event) { try { olInjection.Parameters.ForcedInjected = false; var parameters_ = { UserName: event.data.UserName, UserId: event.data.UserId, Title: event.data.Title, }; olPage.Content.Divs.Close.PromptChooseSharedUserToUsePasswordsFrom(false); olPage.Messages.GetSharedPasswordsRequest(parameters_); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('SelectedSharedUser_onClick', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },Extension receives the page message
deobfuscated/extensionMessaging.jsGetSharedPasswordsRequest: function () { olWrap.addMessageListener('olGetSharedPasswordsRequest', function (event) { try { var alertContent_ = new olFunctions.AlertContent('MSG Get shared password message', 'Received by extension Url: ' + event.target.getUrl()); var waitingForSw_Init = setInterval(function () { if (olExtension.Data.SW_Initialised) { clearInterval(waitingForSw_Init); var tabUrl_ = event.url; var tabId_ = event.target.getId(); var filterTabMembers_ = olExtension._internal.TabMember.Filter(olExtension.Data.WindowHandle, tabId_, tabUrl_, null); var tabMember_ = filterTabMembers_[0]; var requestContent_ = new olExtension.DataConstructors.RequestContent(tabMember_, event.data); olExtension.Service.GetSharedPasswordsRequestSend(requestContent_); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } }, 50) } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('GetSharedPasswordsRequest', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } }); },GetSharedPasswordsRequest fields
deobfuscated/extensionApiService.jsGetSharedPasswordsRequestSend: function (requestContent, processRequestSuccess) { try { var alertContent_ = new olFunctions.AlertContent('API Get shared passwords request sent', 'Url: ' + requestContent.TabMember.PageInfo.Url); var successFunction_ = olExtension.Service._internal.SetSuccessFunction(processRequestSuccess, olExtension.Service._internal.SuccessGetSharedPasswordsRequest); var ajaxData_ = { GetSharedPasswordsRequest: { ApplicationSessionId: requestContent.TabMember.ApplicationsSessionId, UserName: requestContent.Parameters.UserName, PasswordDetailsUserId: requestContent.Parameters.UserId } }; var sendRequestParams_ = new olExtension.DataConstructors.SendRequestParameters('GetSharedPasswordsRequest', ajaxData_, requestContent, successFunction_); olExtension.Service._internal.SendRequest(sendRequestParams_); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('GetSharedPasswordsRequestSend', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },Returned shared-password data is processed
deobfuscated/extensionApiService.jsSuccessGetSharedPasswordsRequest: function (requestResult, requestContent) { try { var alertContent_ = new olFunctions.AlertContent('API Success Get shared users passwords succeeded', 'Url: ' + requestContent.TabMember.PageInfo.Url); if (requestResult.SharedPasswordsResponse && olFunctions.IsFilledArray(requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement.PersonalDetail)) { if (!requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement) { requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement = {}; } if (!requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement.Variables) { requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement.Variables = []; } var usernameArray_ = requestContent.TabMember.PageInfo.DefinedNames.UsernameArray; var passwordArray_ = requestContent.TabMember.PageInfo.DefinedNames.PasswordArray; var matterArray_ = requestContent.TabMember.PageInfo.DefinedNames.MatterArray; var timeKeeperArray_ = requestContent.TabMember.PageInfo.DefinedNames.TimeKeeperArray; var commentArray_ = requestContent.TabMember.PageInfo.DefinedNames.CommentArray; var shareVariableRepacement_ = requestResult.SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement; olExtension.Service._internal._populateVariableReplacements(usernameArray_, shareVariableRepacement_); olExtension.Service._internal._populateVariableReplacements(passwordArray_, shareVariableRepacement_); olExtension.Service._internal._populateVariableReplacements(matterArray_, shareVariableRepacement_); olExtension.Service._internal._populateVariableReplacements(timeKeeperArray_, shareVariableRepacement_); olExtension.Service._internal._populateVariableReplacements(commentArray_, shareVariableRepacement_); requestContent.TabMember.PageInfo.Response.SharedPasswordsResponse = requestResult.SharedPasswordsResponse; } else { requestContent.TabMember.PageInfo.Response.SharedPasswordsResponse = { SharedPasswordsUser: { VariableReplacement: { PersonalDetail: [] } } }; } var messageContent_ = new olExtension.DataConstructors.MessageContent(requestContent.TabMember, requestResult.SharedPasswordsResponse); messageContent_.TabMessageContent.Parameters = requestContent.Parameters; olExtension.Messages.GetSharedPasswordsDispatchResponse(messageContent_); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('SuccessRequestGetSharedUsersRequest', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },Response is dispatched back to page content
deobfuscated/extensionMessaging.jsGetSharedPasswordsDispatchResponse: function (messageContent) { try { var alertContent_ = new olFunctions.AlertContent('MSG Get shared passwords request response message', 'Sent by extension'); olExtension.Messages._internal.DispatchMessageToTab('olResponseToGetSharedPasswordsRequest', messageContent); olFunctions.Alert(olOptions.DebugApiMess(), alertContent_, 'apimessevent'); } catch (e) { var alertErrorContent_ = new olFunctions.AlertContent('GetSharedPasswordsDispatchResponse', e.message + '\n' + e.stack); olFunctions.Alert(olOptions.Errors(), alertErrorContent_, 'error'); } },- localhost
Onelog local relay service on port 12345 receives the shared-password request and returns SharedPasswordsResponse data to the extension.
+1 more finding not shown
What it can do
Permissions this extension asks for, as declared in version 2.10.2511.5. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 2.10.2607.21, which we have not unpacked yet.
Read and change your data on every site you visit
http://*/*
Read and change your data on every secure site you visit
https://*/*
See the address and title of every tab you have open
tabs
Run its own code inside the pages you visit
scripting
See every page you navigate to, as you navigate to it
webNavigation
Read and change cookies, including the ones that keep you signed in
cookies
Keep running in the background while your browser is open
background
Store data in your browser
storage
Store an unlimited amount of data in your browser
unlimitedStorage
Read information about your displays
system.display