Is Content Ninja Suggest safe?

Medium risk

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.

content-ninja-dev-teamv5.0.4Chrome Web Store
45Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You visit any page on linkedin.com while the extension is installed.

The extension did this

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.

02EvidenceCODE COMPARE
The code that does this

Cookie-reading and API-calling code: shipped source vs. deobfuscated readable form.

What it actually does
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'
  }));
};
03EvidenceFIELD TABLE
Voyager API endpoints the extension calls using the extracted session token:
FieldValueWhy it matters
Your LinkedIn profile
/voyager/api/meThe 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-76The 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%3A7123456789012345678Post 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.ef3d0937fb65bd7812e32e5a85028e79Content search via the Voyager GraphQL endpoint, using your session to query LinkedIn's internal index.
04EvidenceTHIRD PARTY LIST
Hosts that receive authenticated Voyager API requests:
  • 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.

05EvidenceARTIFACT
Reproduce it yourself

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.

RequiresChrome with an active LinkedIn sessionDevTools Console access
content-ninja-csrf-check.js · js
// 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;
})();
How to run it
  1. 1
    Open linkedin.com/feed, logged in.
  2. 2
    Console: paste, run.
  3. 3
    JSESSIONID prints.
  4. 4
    fetch('/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.

Updated 30 September 2026fleloaemgeopkjancpbiiflagoiihaak