Is Content Ninja Suggest safe?
Generates AI comment suggestions for LinkedIn posts based on the user’s profile, tone, and settings.
This extension provides one-click comment suggestions for LinkedIn posts in styles such as professional, supportive, curious, and insightful. It can learn from the user’s profile, writing patterns, and comment history, and includes engagement lists, guided engagement sessions, and settings for tone, emoji frequency, dialect, and custom instructions.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
LinkedIn Session Token Read from Page Cookies for Voyager API Access
On LinkedIn, Content Ninja Suggest reads the JSESSIONID cookie via document.cookie.
LinkedIn uses it as a CSRF token for Voyager; the extension sends it as a csrf-token header for profile, feed, and search requests, scoped to linkedin.com.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You visit any page on linkedin.com while the extension is installed.
The extension reads your LinkedIn JSESSIONID cookie from the page and uses it as an authentication header to call LinkedIn's internal Voyager API on your behalf.
The JSESSIONID value is never sent outside linkedin.com; it authenticates requests the extension makes directly to LinkedIn's own endpoints.
Cookie-reading and API-calling code: shipped source vs. deobfuscated readable form.
Deobfuscated: getCSRFToken() — reads JSESSIONID cookie
VoyagerClient.prototype.getCSRFToken = function() { try { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var parts = cookies[i].trim().split('='); var name = parts[0]; var value = parts.slice(1).join('='); if (name === 'JSESSIONID') { // LinkedIn wraps the value in quotes; strip them return value.replace(/^"(.+)"$/, '$1'); } } return null; } catch (e) { return null; }};Deobfuscated: request() — attaches token as csrf-token header
VoyagerClient.prototype.request = function(path, options) { var csrfToken = this.getCSRFToken(); if (!csrfToken) { throw new VoyagerError('Not logged into LinkedIn - CSRF token not available', 'NOT_LOGGED_IN'); } var url = 'https://www.linkedin.com' + path; var headers = Object.assign({ accept: 'application/vnd.linkedin.normalized+json+2.1', 'csrf-token': csrfToken, 'x-li-lang': 'en_US', 'x-li-page-instance': 'urn:li:page:feed_index;' + this.generatePageInstance(), 'x-restli-protocol-version': '2.0.0' }, (options && options.headers) || {}); return fetch(url, Object.assign({ method: 'GET' }, options, { headers: headers, credentials: 'include', cache: 'no-store' }));};- Your LinkedIn profile/voyager/api/me
The extension retrieves your own profile data when you first use it.
- Any LinkedIn member's full profile/voyager/api/identity/dash/profiles/ACoAABcABcABcABcABcA?decorationId=com.linkedin.voyager.dash.deco.identity.profile.FullProfile-76
The extension fetches the full profile of members it processes, including work history, education, and contact data.
- LinkedIn feed content/voyager/api/feed/updates/urn%3Ali%3Aactivity%3A7123456789012345678
Post and activity data from your feed or a member's activity feed.
- LinkedIn search results/voyager/api/graphql?includeWebMetadata=true&variables=(start:0,origin:SWITCH_SEARCH_VERTICAL,query:(keywords:AI+tools,...))&queryId=voyagerSearchDashClusters.ef3d0937fb65bd7812e32e5a85028e79
Content search via the Voyager GraphQL endpoint, using your session to query LinkedIn's internal index.
- www.linkedin.com
LinkedIn's own Voyager API. All requests stay on linkedin.com; the JSESSIONID token is not forwarded to any third-party server.
Run this in DevTools on any LinkedIn page to confirm whether the JSESSIONID cookie is accessible to page-level JavaScript and whether the extension would be able to read it.
- Chrome with an active LinkedIn session
- DevTools Console access
// content-ninja-csrf-check.js// Reproduces the logic of Content Ninja Suggest's getCSRFToken().// Run in Chrome DevTools Console while on any linkedin.com page.(function checkCSRFToken() { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var parts = cookies[i].trim().split('='); var name = parts[0]; var value = parts.slice(1).join('='); if (name === 'JSESSIONID') { var token = value.replace(/^"(.+)"$/, '$1'); console.log('[CNS-CSRF] JSESSIONID accessible to page JS:', token); console.log('[CNS-CSRF] Would be sent as csrf-token header to /voyager/api/*'); return token; } } console.log('[CNS-CSRF] JSESSIONID not found in document.cookie (not logged in, or HttpOnly)'); return null;})();- 1Open linkedin.com/feed, logged in.
- 2Console: paste, run.
- 3JSESSIONID prints.
- 4fetch('/voyager/api/me',{headers:{'csrf-token':<t>,'x-restli-protocol-version':'2.0.0'},credentials:'include'}).then(r=>r.text()).then(console.log)
Where it sends data
Destinations our analysis observed Content Ninja Suggest contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- LinkedIn
Content Ninja Suggest sends data to LinkedIn. Named as a recipient by 4 other extensions we have analysed.