Is AuthoredUp – No. 1 LinkedIn ™ Content Tool safe?
AuthoredUp is medium risk. AuthoredUp's Coauthor assistant sends the text before/after your cursor, any selection, and your typed instruction to backend.authoredup.com. No triggered request body was captured in testing; evidence below is code-derived.
Who publishes itTalentKit Limited - no other listings under this identity
TalentKit Limited - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Coauthor Sends LinkedIn Draft Text to AuthoredUp
AuthoredUp's Coauthor assistant sends the text before/after your cursor, any selection, and your typed instruction to backend.authoredup.com.
No triggered request body was captured in testing; evidence below is code-derived.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You ask Coauthor to create or rewrite text from a LinkedIn draft.
The same task builder is used for creation, hook, insertion, ending, and modification operations.
The extension packages nearby draft text and your instruction into a Coauthor task.
That task is passed to the backend client for a JSON POST to backend.authoredup.com.
- Writing actionmodification (illustrative)
Tells the server which Coauthor mode you used, such as creating a post or modifying selected text.
- Your AI instructionMake this paragraph shorter and more direct (illustrative)
Sends the wording you typed into the Coauthor prompt box.
- Text before the cursorExcited to share three lessons from our Q2 launch (illustrative)
Shares unpublished draft text that appears before the cursor or selected range.
- Selected draft textour pilot customers reduced review time by 42% (illustrative)
Shares the selected part of the LinkedIn draft when you ask Coauthor to modify it.
- Text after the cursorWe will publish the full case study next week. (illustrative)
Shares draft text that follows the cursor or selected range so the server has surrounding context.
- Draft identifierdrf_9f4c2a8b6e1d (illustrative)
Links the Coauthor task back to the draft being edited in the extension.
- Saved prompt identifierprm_7c52e48a31b0 (illustrative)
Identifies a saved prompt template when the request came from the prompt deck.
- content-type
- application/json
Shipped code that slices the draft and posts the Coauthor task
Draft text is split into before, selected, and after slices
js/host_script.jsfunction eB(o, t, n) { const r = o.state.doc.slice(t, n, !0), i = A(o.state.doc.slice(0, t, !0), r), c = A(r, o.state.doc.slice(n, o.state.doc.content.size, !0)), u = av(o.state.doc, o.schema, { from: 0, to: t - (i ? 1 : 0) }), d = av(o.state.doc, o.schema, { from: t, to: n - (c ? 1 : 0) }), s = av(o.state.doc, o.schema, { from: n, to: o.state.doc.content.size }); return [u, d, s]; function A(p, g) { var E, f, C, w, y; const D = (f = (E = p.content.lastChild) == null ? void 0 : E.type) == null ? void 0 : f.name; return !(D !== UO.Rg.name && D !== jO._J.name || D !== ((w = (C = g.content.firstChild) == null ? void 0 : C.type) == null ? void 0 : w.name) || !((y = p.content.lastChild) != null && y.lastChild) || !iv(p.content.lastChild.lastChild) || iv(g.content.firstChild)) }}The task object receives the prompt and three draft slices
js/host_script.jsconst T = Ae((ce, Me) => f3(null, null, function*() { if (A || C || !(t != null && t.state) || !f) return !1; const [re, ye] = L0(t, f); if (typeof re != "number" || typeof ye != "number") return !1; const [ge, Fe, $e] = eB(t, re, ye), Re = { operation: f, user_prompt: ce, text_before: ge, text_selected: Fe, text_after: $e, prompt_deck_prompt_id: Me || null }; return !s && !(yield w(Vl())) ? !1 : (b && D({ filter: "" }), w(N0(Re, [re, ye])))}), () => {}, d.errorGuard("Failed to generate content"))The task dispatcher adds the open draft identifier
js/host_script.jsconst N0 = (o, t) => (n, r, i) => Qr(null, [n, r, i], function*(c, u, { appBackend: d, time: s, log: A, toaster: p }) { var g, E, f, C, w, y; const D = (E = (g = u().auth) == null ? void 0 : g.user) == null ? void 0 : E.membership, b = u().openedDraftId; if (!b) return A.warn("Cannot start a new coauthor task without an open draft"), !1; const S = (f = u().coauthorActiveTask) == null ? void 0 : f.id, O = Va(Nr({}, o), { draft_id: b }); u().coauthorDevSimulation && (O.devSimulation = u().coauthorDevSimulation); let T; try { T = yield d.postCoauthorTask(O) } catch (_) { return _.name === "Remote.LicenseCreditManager_InsufficientCreditsError" ? ((D == null ? void 0 : D.role) === "member" ? p.error("Insufficient coauthor credits", { name: "Insufficient coauthor credits", message: "You don't have enough coauthor credits to perform this action. Please contact your administrator." }) : p.error("Insufficient coauthor credits", { name: "Insufficient coauthor credits", message: "You don't have enough coauthor credits to perform this action. Please purchase more credits or contact support." }), !1) : (p.error("Coauthor unavailable", _), !1) } if (((C = u().coauthorActiveTask) == null ? void 0 : C.id) !== S) return A.warn(`Race condition: started task ${T.id} while task ${u().coauthorActiveTask.id} is active`), !1; const N = u().coauthorPromptDeckPrompts, K = T.prompt_deck_prompt_id && N && (w = N.find(_ => _.id === T.prompt_deck_prompt_id)) != null ? w : null; let U; c(Ze(`Start streaming ${T.operation} task ${T.id}`, { coauthorActiveTask: (0, F.val)(Va(Nr({}, T), { refreshedAt: s.now(), diffMethod: gE(T), accepted_variant_index: 0, streamingPhases: T.streamingPhases || null, streamingPhaseIndex: (y = T.streamingPhaseIndex) != null ? y : null, selectedRange: t, promptDeckPrompt: K })) })), U = () => { var _; return ((_ = u().coauthorActiveTask) == null ? void 0 : _.id) === T.id ? u().coauthorActiveTask : null }; function G() { return Qr(this, null, function*() { var _; const J = U(); if (!J || J.completed_at) { U = null; return } const q = s.now().getTime() - J.refreshedAt.getTime(); if (q >= 8 * ee.Z2 && (A.warn(`Coauthor task ${T.id} has not been updated for ${Math.round(q/1e3)}s, refreshing from server...`), yield c(P0(T.id)), (_ = U()) != null && _.completed_at)) { U = null; return } setTimeout(G, 10 * ee.Z2) }) } return G(), !0 })postCoauthorTask uses the POST request descriptor
js/host_script.jspostCoauthorTask: (Q, B) => X(null, null, function*() { const L = _4(Q); return yield a(B ? h(h({}, L), B) : L)})The request descriptor sets POST, path, JSON body, and content type
js/host_script.jsfunction _4(a) { return { method: "POST", url: "/app/api/v9/coauthor/tasks", data: a, headers: { "content-type": "application/json" }, normalizeResponse: eC }}The backend base URL is AuthoredUp's backend host
js/vendor.jsbackendBaseURL: f.string("https://backend.authoredup.com").required().default("https://backend.authoredup.com"),- backend.authoredup.com
Receives Coauthor task requests containing the draft slices, typed instruction, operation, saved prompt id, and draft id.