Is Illust Downloader for pixiv.net safe?
Illust Downloader is low risk. When a licensed user downloads Pixiv content with PC sync and history on, the extension builds a history record and queues it for sync to orca-soft.net: item ID, content type, timestamp, title, compacted thumbnail URL, and author name.
Who publishes itOrcaSoft - 4 other listings from the same operator, none carrying a finding
OrcaSoft - 4 other listings from the same operator, none 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, 91k+ users between them, none of them carrying a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Pixiv download history synced to orca-soft.net
When a licensed user downloads Pixiv content with PC sync and history on, the extension builds a history record and queues it for sync to orca-soft.net: item ID, content type, timestamp, title, compacted thumbnail URL, and author name.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You download Pixiv content with PC sync and download history enabled.
The sync path is also gated on the extension's license check succeeding.
The extension records that download and queues it to be sent to orca-soft.net.
The content script sends a sync_history_wr message, and the background script posts queued records for synchronization.
- Pixiv item identifierp_a_12345678 (illustrative)
Links the synced history entry to the specific Pixiv item you downloaded.
- Content typei (illustrative)
Shows whether the saved item was an illustration, manga, ugoira, novel, or another Pixiv item type.
- Download time1720839117245 (illustrative)
Adds a time marker to your saved Pixiv history entry.
- Pixiv page titleSummer seaside illustration (illustrative)
Names the downloaded work in the synced history entry.
- Compacted thumbnail URL|C2024/07/12/12/34/56/12345678_p0|F (illustrative)
Carries a thumbnail reference for the downloaded Pixiv item.
- Author namepixiv_user_123 (illustrative)
Associates the synced download-history entry with the Pixiv creator shown on the page.
- Sync operationadd
Marks the record as a new history item to add during synchronization.
Your Pixiv download-history record can wait in the extension's local queue before the next synchronization upload.
- Location
- chrome.storage.local key syncDataList
{ "syncDataList": [ { "a": "i", "c": "|C2024/07/12/12/34/56/12345678_p0|F", "d": 1720839117245, "n": "pixiv_user_123", "t": "Summer seaside illustration", "u": "p_a_12345678", "sync": "add" } ]}The code treats a text response of done as successful synchronization and removes matching queued records.
- Content-Type
- application/x-www-form-urlencoded
The content script creates the history record and the background script uploads the queue
sh.js: successful downloads become sync_history_wr records
sh.js1 == e ? $("a.pxvdwn_l[data-num=" + y + "]").bind("click", function() { var G = location.href; yb(y); ({ dlmat: na, novel: ta, unlisted: va } = Fa(location.href)); Oa(G)}) : $("a.pxvdwn_l[data-num=" + y + "]").bind("click", function() { yb(y); Oa(g)});if (option.iine_dl) { var c = $("section section").find("button > svg[viewBox='0 0 12 12']").parent().parent(); c.click(function() { "disabled" != c.find("button").attr("disabled") && $("a.pxvdwn_l[data-num=" + y + "]").click() }); $("html").keydown(function(G) { 76 == G.keyCode && "disabled" != c.find("button").attr("disabled") && $("a.pxvdwn_l[data-num=" + y + "]").click() })}function yb(a) { $("a.pxvdwn_l[data-num=" + a + "]").css({ "pointer-events": "none", opacity: .5 })}function Oa(a) { var g = cb(); if (($a || ab) && Ca) alert(chrome.i18n.getMessage("download_in_progress")); else { Ca = !0; var e = na, f = ta, I = va, y = Za(na, ta, va); try { chrome.runtime.sendMessage({ mode: "permissions_check" }, function(D) { 1 == D.result ? chrome.runtime.sendMessage({ mode: "op" }, function(M) { try { option = JSON.parse(M.option), version = M.version, update = M.update, l = M.l, lspop = M.lspop, ni = M.n, syncTime = M.syncTime, memozed = JSON.parse(M.memozed), memozedDef = M.memozedDef, ex_md = M.md, after_flag = M.after, eb = 0, Eb(g), Pa({ url: y, cache: !1, success: function(U) { Fb(U, a, e, g, f, I) }, error: function(U, W, T) { Ja ? fb ? ka.push("[" + W + "] " + a) : (ka.push("[" + W + "] " + a), retryMsg = chrome.i18n.getMessage("alldl_append_msg"), "error" === W ? alert(chrome.i18n.getMessage("dl_sippai") + retryMsg) : "timeout" === W ? alert(chrome.i18n.getMessage("dl_timeout") + retryMsg) : alert(chrome.i18n.getMessage("dl_sippai") + retryMsg)) : "error" === W ? alert(chrome.i18n.getMessage("dl_sippai")) : "timeout" === W ? alert(chrome.i18n.getMessage("dl_timeout")) : alert(chrome.i18n.getMessage("dl_sippai")); wa(g); la(!1) } }) } catch (U) { alert(chrome.i18n.getMessage("unknown_error")) } }) : wa(g) }) } catch (D) { Ma() } }}function Eb(a) { zb = setTimeout(function() { qa(chrome.i18n.getMessage("outou_machi"), !0, a) }, 2E3)}function wa(a) { clearTimeout(zb); qa("", !1, a); $("a.pxvdwn_l").attr("style", "")}function la(a, g, e) { Ca = !1; a && Gb(g, e); option.illust_downloaded && $("body").find("a[data-gtm-value],span[data-gtm-value],a[href*='/artworks/'],a[href*='/novel/show.php']").each(function() { Qa($(this), !1) })}function Hb(a) { a = a.replace("https://i.pximg.net/", "|A"); a = a.replace("c/600x600/novel-cover-master/img/", "|B"); a = a.replace("c/250x250_80_a2/img-master/img/", "|C"); a = a.replace("c/250x250_80_a2/custom-thumb/img/", "|D"); a = a.replace("_master1200.jpg", "|E"); a = a.replace("_square1200.jpg", "|F"); return a = a.replace("_custom1200.jpg", "|G")}function Gb(a, g) { if (!va) { var e = "illust" === g[0].type || "manga" === g[0].type || "ugoira" === g[0].type ? "p_a_" : "novel" === g[0].type ? "p_n_" : "p_u_", f = Date.now(); a = { u: e + a[1], a: g[0].type[0], d: f, t: g[0].historyDataArray.title, c: Hb(g[0].historyDataArray.thumb), n: g[0].historyDataArray.userName }; g[0].historyDataArray.r && (a.r = 1); try { chrome.runtime.sendMessage({ mode: "dl_w", jsonData: a }) } catch (I) { Ma(); return } vb(); if (option.syncPC && option.dl_history && l.result) try { chrome.runtime.sendMessage({ mode: "sync_history_wr", userId: option.syncId, syncData: { ...a, sync: "add" } }, function(I) { "error" === I.result && alert(chrome.i18n.getMessage("sync_id_error")) }) } catch (I) { Ma() } }}bg.js: sync_history_wr is queued and sent to sync_api.php
bg.js"sync_history_wr" === a.mode && da(a.mode, a.userId, a.syncData, 1).then(f => { c({ result: f })});"sync_history_rm" === a.mode && da(a.mode, a.userId, a.syncData, 2).then(f => { c({ result: f })});"sync_history_get" === a.mode && V(a.userId, function(f) { c(f) });"sync_pointer_refresh" === a.mode && ia(a.userId, function(f) { c(f)});"sync_check" === a.mode && (S(), c({}))let Z = Promise.resolve();const da = (() => { async function a(g) { await Y(async () => { let l = await h.getItem("syncDataList"); Array.isArray(l) || (l = []); g && g.u && (l.push(g), await h.setItem("syncDataList", l)) }) } async function b(g) { function l(m, r = {}) { const u = new AbortController, x = setTimeout(() => u.abort(), 5E3); return fetch(m, { ...r, signal: u.signal }).finally(() => clearTimeout(x)) } let q = await h.getItem("syncDataList"); if (!Array.isArray(q) || 0 === q.length) return "done"; const t = new URLSearchParams; t.append("i", JSON.stringify(q)); t.append("u", g); t.append("m", "1"); g = 0; let f = ""; for (; 3 > g;) try { f = await (await l("https://orca-soft.net/chrome/pd/sync_api.php", { method: "POST", cache: "no-store", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: t.toString() })).text(); if ("done" === f) { let m = await h.getItem("syncDataList"); Array.isArray(m) || (m = []); const r = q.map(u => u.u); m = m.filter(u => !r.includes(u.u)); await h.setItem("syncDataList", m); return "done" } if ("error" === f) return "error"; g++; if (3 < g) return f; await new Promise(m => setTimeout(m, 5E3)) } catch (m) { g++; if (3 < g) return "fetch_error"; await new Promise(r => setTimeout(r, 5E3)) } return f } let c = null; return async function(g, l, q) { await a(q); c && clearTimeout(c); c = setTimeout(() => { Y(() => b(l)) }, 2E3) } })()- orca-soft.net
Receives the extension's PC synchronization requests for Pixiv download-history records.
What it can do
Permissions this extension asks for, as declared in version 1.9.2.0. 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 1.10.0.0, which we have not unpacked yet.
Read and change your data on pixiv.net
http://*.pixiv.net/ and 1 more
Read and change your data on pximg.net
http://*.pximg.net/ and 1 more
Read and change your data on orca-soft.net
http://orca-soft.net/ and 1 more
Store data in your browser
storage
Store an unlimited amount of data in your browser
unlimitedStorage
Start, monitor and manage your downloads
downloads
Block and redirect the requests your browser makes
declarativeNetRequest
Show you desktop notifications
notifications
Run hidden pages in the background
offscreen