Is Ubuntu free online linux server safe?

High risk

Ubuntu Online is high risk. Every tab switch or load sends the full URL to a remote server at onworks.net, automatically, no click needed. Dynamic analysis captured 23 such requests across five unrelated sites, including a planted marker recovered verbatim.…

ApkOnline android onlinev1.3.5Chrome Web Store
75Risk
Who publishes it

ApkOnline android online - 23 other listings from the same operator, 16 of them carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
ApkOnline android online
Registered address
Avenue Dr Arce 43, Madrid 28002, Spain

Same store account

4 other listings published from this account, 226k+ users between them. 2 of them carry a finding.

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Extension sends every visited URL to onworks.net on each tab change

Every tab switch or load sends the full URL to a remote server at onworks.net, automatically, no click needed.

Dynamic analysis captured 23 such requests across five unrelated sites, including a planted marker recovered verbatim.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open any webpage or switch to a tab with an http/https URL.

The extension checks that the URL is not already an onworks.net URL and has not been reported since the last navigation.

The extension did this

The extension immediately sends the full URL to onworks.net in the background.

A GET request is made to c-ubuntux-2x.php with the URL hex-encoded as the url= parameter and a persistent tracking ID as u=.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://www.onworks.net/media/system/app/runos/c-ubuntux-2x.php?url=68747470733a2f2f656e2e77696b6970656469612e6f72672f77696b692f43414e4152595f424952445f31323334355f50524f4f46&hex=1&u=yide6oj9j7
HTTP 200. Response body inspected, when it contains '302', the extension calls chrome.tabs.update to redirect the active tab to intro-ubuntu-os.php.
03EvidenceOPAQUE REVEAL
Why you can't catch this in DevTools

The URL is converted character-by-character to two-digit ASCII hex codes before being placed in the query string. This is not encryption, any hex decoder recovers the plaintext immediately.

What's actually being sent
https://en.wikipedia.org/wiki/<page-url>
04EvidenceCODE COMPARE
The code that does this

URL exfiltration listener and fetch call (w.js)

What it actually does
function gti(tabId) {
  chrome.tabs.get(tabId, function(tab) {
    if (
      (tab.url.indexOf('onworks') == -1) &&
      (tab.url.indexOf('http') !== -1) &&
      (lastUrl != tab.url)
    ) {
      urlx = tab.url;
      reporturlscannedandrecorded = urlx;
      extractf(reporturlscannedandrecorded);
      lastUrl = tab.url;
    }
  });
}

async function extractf(urlxx) {
  // ... reads/generates persistent tracking ID ...
  let fgvt = await fetch(
    'https://www.onworks.net/media/system/app/runos/c-ubuntux-2x.php?url=' +
    b2x(urlxx) + '&hex=1&u=' + un
  );
}
05EvidenceTHIRD PARTY LIST
Destinations receiving your browsing history
  • www.onworks.net

    Receives every visited URL (hex-encoded) and the persistent tracking ID. onworks.net is the developer's own online-Linux service; the extension operator controls this endpoint.

06EvidenceARTIFACT
Reproduce it yourself

Decodes any onworks.net request URL parameter from the hex-encoded wire format back to the original visited URL, demonstrating the decoding technique used in dynamic analysis.

RequiresNode.js 12+
decode-onworks-url.js · js
#!/usr/bin/env node
// decode-onworks-url.js
// Usage: node decode-onworks-url.js <hex_string>
// Example: node decode-onworks-url.js 68747470733a2f2f676f6f676c652e636f6d

const hex = process.argv[2];
if (!hex) {
  console.error('Usage: node decode-onworks-url.js <hex_string>');
  process.exit(1);
}

const decoded = hex.match(/.{1,2}/g).map(b => String.fromCharCode(parseInt(b, 16))).join('');
console.log('Decoded URL:', decoded);
How to run it
  1. 1
    Copy the 'url' parameter value from any captured onworks.net request.
  2. 2
    Run: node decode-onworks-url.js <hex_value>.
  3. 3
    The original visited URL is printed.
SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Extension assigns a persistent ID on install and links it to every URL sent

On first run the extension generates a 10-character random ID stored in Chrome's synced storage, following you across profiles and devices.

It's appended to every URL report to onworks.net, seen in 22 of 23 captured requests.

01EvidenceCAUSE EFFECT
What actually happens
You did this

The extension starts for the first time and finds no stored ID.

extractf() reads chrome.storage.local key apkon_key and checks for opcA.usercx.

The extension did this

A 10-character random ID is generated and saved to synced storage, then attached to every subsequent URL report.

ranSX(10) builds the ID from a 62-character alphanumeric charset. It is stored in both chrome.storage.local (apkon_key.usercx) and chrome.storage.sync (usercx), enabling cross-device persistence.

02EvidenceSTORAGE DUMP
What's stored on your device

Local storage holds the outbound ID (usercx) and opt-out flag (apkononline). Sync storage replicates the ID across Chrome sign-ins.

Locationchrome.storage.local key 'apkon_key' + chrome.storage.sync key 'usercx'
Contents (JSON)
{
  "usercx": "vz5rdv5set",
  "apkon_key": {
    "usercx": "yide6oj9j7",
    "apkononline": "1"
  }
}
03EvidenceCODE COMPARE
The code that does this

ID generation and storage (w.js:37-84)

What it actually does
// Top-level startup: sync storage check
if (chrome.storage.sync.get('usercx', function(obj) {})) {
  usercx = chrome.storage.sync.get('usercx', function(obj) {});
} else {
  usercx = '' + ranSX(10) + ''.toLowerCase();
  chrome.storage.sync.set({'usercx': usercx.toLowerCase()}, function() {});
}

// Inside extractf(): local storage check + generation
let storres = await chrome.storage.local.get([apkon_key]);
if (apkon_key in storres) { opcA = storres[apkon_key]; }

if (opcA.usercx) {
  usercx = opcA.usercx;
} else {
  usercx = '' + ranSX(10) + ''.toLowerCase();
  opcA.usercx = usercx;
}

// Sent on every request:
await fetch('https://www.onworks.net/media/system/app/runos/c-ubuntux-2x.php?url=' + b2x(urlxx) + '&hex=1&u=' + un);
04EvidenceFIELD TABLE
Data sent to onworks.net on each request
FieldValueWhy it matters
Visited URL
https://en.wikipedia.org/wiki/Privacy_policyThe full URL of the page you are viewing, hex-encoded in the url= parameter.
Persistent tracking ID
yide6oj9j7A 10-character ID generated on install and appended as u=. Stored in Chrome Sync, it follows you across devices on your Google account.
SeverityLOW
ClassUNWANTED
TypeUnexpected
CWECWE-319
SourceAI SANDBOX

Visited URLs obscured by hex encoding that any decoder can reverse

The extension hex-encodes each character of your visited URL before sending it.

This doesn't protect the data; any hex decoder, including the server's &hex=1 flag, recovers the plaintext instantly.

A planted marker returned verbatim.

01EvidenceCAUSE EFFECT
What actually happens
You did this

The extension prepares to send a visited URL to onworks.net.

Before placing the URL in the request, b2x() is called to convert it to hex.

The extension did this

Each character of the URL is replaced with its two-digit ASCII hex code.

The result is a hex string placed in the url= query parameter. The server's hex=1 flag reverses it immediately on receipt.

02EvidenceOPAQUE REVEAL
Why you can't catch this in DevTools

The on-wire form looks like a random hex string, but it is a verbatim character-by-character encoding of the original URL with no undisclosed material involved.

What's actually being sent
https://en.wikipedia.org/wiki/<page-url>
03EvidenceCODE COMPARE
The code that does this

Hex encoding function (w.js:106-115)

What it actually does
function b2x(bin) {
  var i = 0, l = bin.length, chr, hex = '';
  for (i; i < l; ++i) {
    chr = bin.charCodeAt(i).toString(16);
    hex += chr.length < 2 ? '0' + chr : chr;
  }
  return hex;
}
04EvidenceARTIFACT
Reproduce it yourself

Reproduces the encoding and decoding round-trip, demonstrating that b2x() output is trivially reversible with a standard hex decoder.

RequiresNode.js 12+
verify-hex-roundtrip.js · js
#!/usr/bin/env node
// verify-hex-roundtrip.js
// Reproduces the b2x() encode/decode round-trip from the extension.

// Replicate the extension's b2x() function exactly
function b2x(bin) {
  var i = 0, l = bin.length, chr, hex = '';
  for (i; i < l; ++i) {
    chr = bin.charCodeAt(i).toString(16);
    hex += chr.length < 2 ? '0' + chr : chr;
  }
  return hex;
}

// Standard hex decode (inverse of b2x)
function x2b(hex) {
  return hex.match(/.{1,2}/g).map(b => String.fromCharCode(parseInt(b, 16))).join('');
}

const testUrl = 'https://en.wikipedia.org/wiki/<planted-marker>';
const encoded = b2x(testUrl);
const decoded = x2b(encoded);

console.log('Original :', testUrl);
console.log('Encoded  :', encoded);
console.log('Decoded  :', decoded);
console.log('Match    :', testUrl === decoded ? 'YES — round-trip confirmed' : 'NO — mismatch');
How to run it
  1. 1
    Run: node verify-hex-roundtrip.js.
  2. 2
    Confirm 'Match: YES' is printed.
  3. 3
    Substitute any URL as testUrl to verify arbitrary round-trips.

What it can do

Permissions this extension asks for, as declared in version 1.3.5. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Store data in your browser

    storage

  • See the address and title of every tab you have open

    tabs

Updated 30 September 2026pmaonbjcobmgkemldgcedmpbmmncpbgi