Is Onelog safe?

High risk

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.…

Info Technology Supply Ltdv2.10.2607.21Chrome Web Store
80Risk
Who publishes it

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.

Publisher
Info Technology Supply Ltd
Declared legal entity
Info Technology Supply Limited
Registered address
2, Hobbs House, Bessborough Road, Harrow HA1 3EX, GB
Registered contact
James Wright

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.

thedailybeast.com
Also called by 4 other listings, including Unlock (Paywalls)

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
What actually happens
You did this

You open or navigate to a web page.

The extension did this

Onelog prepares a navigation record and sends JSON to its local relay service.

Captured request
POSThttp://localhost:12345/index/

Repeated localhost relay POSTs were observed; the URL-bearing BeforeNavigateRequest body was not captured because the desktop-agent handshake did not complete.

Headers
Content-Type
application/json
Body
{  "LanguageItems": {}}
Fields assembled for BeforeNavigateRequest
  • Page URL
    https://example.com/

    Shows the exact page you were opening, including path and query text when present.

  • Resolved username
    jane.doe@example.com (illustrative)

    Can connect the browsing event to a specific signed-in person when Onelog has resolved a username.

  • Window and tab context
    WindowId 2, WindowHandle 1 (illustrative)

    Adds browser context that ties the page visit to a specific tab and window.

  • Browser type
    chrome

    Identifies the browser family used for the page visit.

The code that does this

Navigation event and request construction

Readable version

Navigation listener calls the request sender

deobfuscated/extensionEvents.js
olExtension.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.js
BeforeNavigateRequestSend: 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'        },
Destination used by this flow
    • 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
What actually happens
You did this

You load a page whose title is visible to the extension.

The extension did this

Onelog stores the title and can include it in a completion request to its local relay.

Captured request
POSThttp://localhost:12345/index/

Localhost relay POSTs were observed after page load; the DocumentCompleteRequest body was not captured without a valid navigate-complete response.

Headers
Content-Type
application/json
Body
{  "LanguageItems": {}}
Fields assembled for DocumentCompleteRequest
  • Page title
    Example Domain

    Can reveal which page or account view you opened even when the URL is not shown.

  • Application session ID
    ApplicationSessionId 42 (illustrative)

    Links the completed page load to the application session tracked by Onelog.

  • Response flags
    Ignore=false, TurnAway=false (illustrative)

    Carries control flags from the earlier navigation response into the completion record.

The code that does this

Document title capture and completion request

Readable version

The page title is stored on the tab record

deobfuscated/extensionMessaging.js
if (!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.js
SuccessNavigateCompleteRequest: 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.js
DocumentCompleteRequestSend: 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();        },
Destination used by this flow
    • 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
What actually happens
You did this

You select a shared-password user inside the Onelog page overlay.

The extension did this

Onelog requests shared password data from the local relay and sends the response back to the page.

Captured request
POSThttp://localhost:12345/index/

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.

Headers
Content-Type
application/json
Fields and credential data in the shared-password flow
  • Selected user name
    shared.user@example.com (illustrative)

    Identifies the shared-password account entry selected in the overlay.

  • Password details user ID
    PasswordDetailsUserId 18472 (illustrative)

    Links the request to the stored shared-password record for that selected user.

  • Application session ID
    ApplicationSessionId 42 (illustrative)

    Associates the shared-password request with the application session Onelog is tracking.

  • Returned shared password data
    SharedPasswordsResponse.SharedPasswordsUser.VariableReplacement.PersonalDetail (source field)

    Password replacement data can be sent back into page content for form filling.

The code that does this

Shared-password request and response dispatch

Readable version

Overlay click collects selected shared user details

deobfuscated/page.js
SelectedSharedUser_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.js
GetSharedPasswordsRequest: 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.js
GetSharedPasswordsRequestSend: 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.js
SuccessGetSharedPasswordsRequest: 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.js
GetSharedPasswordsDispatchResponse: 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');        }    },
Destination used by this flow
    • 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

Updated 30 September 2026onjjmhhddjeopkhboiehpmhihjmoecpi