Is Hagro safe?

Medium risk

Hagro reads your full LinkedIn cookie jar, including the session-auth cookie, and exposes it to its own site.

When you click the extension's "get LinkedIn cookies" button, Hagro calls the Chrome cookies API to read every cookie for linkedin.com, including the httpOnly li_at session cookie that a web page can never read on its own. It writes the raw cookie data into a form field on the vendor's own hagro.cn page, making your LinkedIn session available to Hagro's backend, which could use it to access LinkedIn as you.

eoseocnv1.0.4Chrome Web Store
45Risk
Who publishes it

eoseocn - 1 other listing from the same operator, 1 of them carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
eoseocn

Same store account

1 other listing published from this account, 164 users between them. 1 of them carries a finding.

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-522
SourceAI FOUND

Hagro copies your entire LinkedIn cookie jar into a page form field

Code analysis shows Hagro reads every LinkedIn cookie, including the httpOnly li_at session token, and writes it into a form field on Hagro's own site, where the page's script can read and submit it.

01EvidenceCAUSE EFFECT
What actually happens
You did this

Signed into linkedin.com, you click the Get LinkedIn Cookies button on admin.hagro.cn/linkedinAccount.

The extension did this

Hagro's background worker fetches every LinkedIn cookie, including the httpOnly li_at token, and hands it to the page.

02EvidenceFIELD TABLE
What chrome.cookies.getAll returns for linkedin.com
FieldValueWhy it matters
Full LinkedIn login session
li_at=AQEDAVX7k92DABcAAAGSbQx1234xyzABCDefGhijKLMnopLets whoever holds it act as you on LinkedIn without a password, until you sign out everywhere.
LinkedIn browser identity
bcookie="v=2&8f3a1c02-44e1-4b9d-9a2f-1d7c6e0b5a3f"A long-lived id LinkedIn uses to recognize your browser across visits.
Session routing marker
lidc="b=VB01:s=V:r=V:a=V:p=V:g=2761:u=1:x=1:i=1758901234"Routes your requests to the right LinkedIn server; low value on its own if intercepted.
Ad-matching identifiers
UserMatchHistory=AQKp8Fz...; AnalyticsSyncHistory=AQGH2p...Cookies LinkedIn uses to match your account to ad audiences and analytics.
03EvidenceCODE COMPARE
The code that does this

The cookie read and the DOM write, verbatim

What it actually does
background.js: fetching every LinkedIn cookiebackground.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
	new Promise(async (resolve, reject) => {
		console.log('收到来自content-script的消息:');
		let linkedin_url = 'https://www.linkedin.com/';
		chrome.cookies.getAll({ url:linkedin_url }, function (cookies) {
			let login = 0;
			const resList = cookies.map(item => {
				if(item.name == 'li_at'){
					login = 1;
				}
				//console.log(item);
				// return `${item.name}=${item.value}`;
				return item;
			});
			const cookieJsonStr = JSON.stringify( resList );
			//console.log("linkedin_cookies-----", cookieJsonStr);
			if(login == 1){
				chrome.notifications.create({
					type: 'basic',
					iconUrl: 'img/icon.png',
					title: 'Hagro提示',
					message: '获取领英Cookies成功!',
					priority: 0
				});
			}else{
				chrome.notifications.create({
					type: 'basic',
					iconUrl: 'img/icon.png',
					title: 'Hagro提示',
					message: '请先自行登录领英平台后重试!',
					// buttons: [
					// 	{ title: 'Keep it Flowing.' }
					// ],
					priority: 0
				});
			}
			sendResponse({is_login: login, cookie: cookieJsonStr});
			// if(login==1){
			// 	//saveCookies(resolve, reject, uuid_val, cookieJsonStr);
			// }else{
			// 	console.log("三方站点未登录");
			// }
		});
content-script.js: writing the cookie JSON into the pagecontent-script.js
connect_to_linkedIn.onclick = async function(){
    chrome.runtime.sendMessage
    (
        {
            cookies: 'update',
            data:"hagro_linkedIn",
        },
        function(response)
        {
            tip(JSON.stringify("content-script向background 发送消息"));
            //console.log(response.is_login);
            if(response.is_login == 1){
                $('input[name="cookies"]').val(response.cookie);
                //console.log(response.cookie);

                $("#connect_to_linkedIn").text('已获取Cookies');
                $("#connect_to_linkedIn").prop("disabled",true);
                //tip('领英平台端的回复:' + JSON.stringify( response ));
            }else{
                $("#connect_to_linkedIn").text('请先登录领英');
                tip('收到来自background的回复:未登录领英');
                let url = "https://www.linkedin.com/";
                window.open(url);
            }
        }
    );
    // const [tab] = await chrome.tabs.query({active: true,lastFocusedwindow: true});//然后向这个tab页里面发送消息
    // const response = await chrome.tabs.sendMessage(tab.id,{ greeting: "hello" });
    // // do something with response here, not outside the function
    // console.log(response);
};
04EvidenceTHIRD PARTY LIST
Where the cookie value can end up
  • hagro.cn

    Serves the linkedinAccount page whose form field receives your LinkedIn cookie JSON from the content script.

  • admin.hagro.cn

    The vendor's own backend; a commented-out function in the same file posts the identical cookie payload directly here.

05EvidenceARTIFACT
Check if you're affected

Watches the page's cookies form field and flags if your LinkedIn li_at session token gets written into it.

RequiresChrome with the Hagro extension installedAn active linkedin.com session
detect-cookie-exfil.js · js
// Paste into the DevTools console while viewing
// https://admin.hagro.cn/linkedinAccount with the Hagro extension installed.
const target = document.querySelector('input[name="cookies"]');
if (!target) {
  console.log('No input[name="cookies"] found on this page.');
} else {
  const checkValue = () => {
    if (target.value && target.value.includes('"li_at"')) {
      console.warn('[cookie-exfil-check] input[name="cookies"] now contains your LinkedIn li_at session cookie:', target.value);
    }
  };
  ['input', 'change'].forEach(evt => target.addEventListener(evt, checkValue));
  new MutationObserver(checkValue).observe(target, { attributes: true, attributeFilter: ['value'] });
  checkValue();
  console.log('Watching input[name="cookies"] for your li_at session cookie...');
}
How to run it
  1. 1
    Sign into linkedin.com.
  2. 2
    Open admin.hagro.cn/linkedinAccount with Hagro installed.
  3. 3
    Paste this in DevTools.
  4. 4
    Click the connect button.
06EvidencePLAIN NOTE
Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

What it can do

Permissions this extension asks for, as declared in version 1.0.4. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on hagro.cn

    *://*.hagro.cn/*

  • Read and change your data on linkedin.com

    *://*.linkedin.com/*

  • Show you desktop notifications

    notifications

  • Read and change cookies, including the ones that keep you signed in

    cookies

  • See the address and title of every tab you have open

    tabs

Where it sends data

Destinations our analysis observed Hagro 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.

  • admin.hagro.cn

    Hagro sends data to admin.hagro.cn. No other extension we have analysed sends data here.

  • hagro.cn

    Hagro sends data to hagro.cn. No other extension we have analysed sends data here.

Updated 30 September 2026ioidlpnjclohlmjkkgedffcokmdcngdd