Is 스마트스토어 쿠팡 분석 - SMART DATA 스마트데이터 safe?

Medium risk

SMART DATA sends buyer PII and customs codes to unipass.customs.go.kr via a hardcoded API key, and sends session data over plaintext HTTP.

The extension iterates Naver SmartStore orders and sends each recipient's name, phone number, and Korean customs clearance code (개인통관고유부호) to the Korean Customs Service API with a hardcoded authentication key embedded in the bundle. Authentication checks and usage quota updates are sent to the extension's backend over an unencrypted HTTP connection. The extension also reads all browser cookies and removes session cookies for smartstore.naver.com and brand.naver.com when entering anonymous API mode.

jkumyu01v3.8Chrome Web Store
52Risk
Who publishes it

RUBYDATALAB - 3 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.

Publisher
jkumyu01
Declared legal entity
RUBYDATALAB
Registered address
김포대로 1009-3, 김포시, 경기도 10100, KR
Registered contact
루비데이터랩

Same store account

3 other listings published from this account, 21k+ users between them, none of them carrying a finding.

Shared hosts - 2 hostnames

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

m.smartstore.naver.com
Also called by 3 other listings, including 아이템스카우트
search.pstatic.net
Also called by 3 other listings: 아이템스카우트, UTAKU image downloader - 이미지 다운로더, 데이터랩툴즈 헬퍼

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

Publishers can request a review.

Findings

Buyer customs details sent to Unipass

MediumunwantedCWE-522Dynamic sandbox

The customs-code confirmation workflow builds GET requests to the Korean Customs Unipass endpoint with buyer details in the query string: crkyCn API key, clearance code, recipient name, phone, from popup fields or the SmartStore order page.

What actually happens

You did this

You run the customs-code confirmation workflow.

The extension did this

The extension sends buyer customs details to Unipass using an API key embedded in the bundle.

The automated order-grid flow retries the lookup with recipient and buyer phone/name combinations when needed.

Captured request

GEThttps://unipass.customs.go.kr:38010/ext/rest/persEcmQry/retrievePersEcm?crkyCn=q220h210p071h371l060m020c3

XML response parsed by the extension

Query-string fields sent to the customs endpoint

  • Bundled API key
    q220h210p071h371l060m020c3

    Anyone with the extension package can read the API credential used for the customs lookup.

  • Recipient name
    Kim Minseo

    This identifies the person whose customs clearance record is being checked.

  • Customs clearance code
    P123456789012

    This links the lookup to a Korean personal customs clearance record.

  • Phone number
    01012345678

    This adds another direct identifier to the customs lookup.

The code that does this

Customs lookup functions and the embedded API key

Readable version

Order-grid customs verification

popup.js
async function confirmnaverpcc() {  let [e] = await chrome.tabs.query({    active: !0,    currentWindow: !0  });  if (!e.url.includes("sell.smartstore.naver.com")) return void alert("스마트스토어 발주(주문)확인/발송관리 메뉴에서 실행해 주세요");  let t = await chrome.scripting.executeScript({    target: {      tabId: e.id    },    func: async function() {      var e = document.querySelector("#__delegate").contentDocument.documentElement.querySelector(".tui-grid-rside-area");      if (e) {        let t = function(e) {          let t = [],            r = [],            n = e.querySelectorAll("th");          for (let e = 0; e < n.length; e++) t.push(n[e].textContent.trim());          let a = e.querySelectorAll("tr");          for (let e = 1; e < a.length; e++) {            let n = a[e].querySelectorAll("td"),              o = {};            for (let e = 0; e < t.length; e++) o[t[e]] = n[e].textContent.trim();            r.push(o)          }          return r        }(e);        return t      }      return []    }  });  var r = t[0].result;  if (console.log(r), 0 != r.length)    if (r[0].수취인명 && r[0].개인통관고유부호 && r[0].수취인연락처1 && r[0].구매자명 && r[0].구매자연락처)      for (var n = 0; n < r.length; n++) {        var a = await confirmpccfor(r[n].수취인명, r[n].개인통관고유부호, r[n].수취인연락처1),          o = a.error;        a.res ? c(n, "green", "일치", e) : r[n].수취인연락처2 && r[n].수취인연락처1 !== r[n].수취인연락처2 && (a = await confirmpccfor(r[n].수취인명, r[n].개인통관고유부호, r[n].수취인연락처2)).res ? c(n, "yellow", "수취인-수취인연락처2-개인통관고유부호 일치", e) : (a = await confirmpccfor(r[n].구매자명, r[n].개인통관고유부호, r[n].수취인연락처1)).res ? c(n, "yellow", "구매자명-수취인연락처1-개인통관고유부호 일치", e) : (a = await confirmpccfor(r[n].구매자명, r[n].개인통관고유부호, r[n].구매자연락처)).res ? c(n, "yellow", "구매자명-구매자연락처-개인통관고유부호 일치", e) : r[n].수취인연락처2 && r[n].수취인연락처1 !== r[n].수취인연락처2 && (a = await confirmpccfor(r[n].구매자명, r[n].개인통관고유부호, r[n].수취인연락처2)).res ? c(n, "yellow", "구매자명-수취인연락처2-개인통관고유부호 일치", e) : c(n, "red", o, e)      } else alert("수취인명, 개인통관고유부호, 수취인연락처1, 구매자명, 구매자연락처를 조회항목에 추가한 후 실행해 주세요");    else alert("개인통관 고유부호를 검증할 내역이 없습니다. \n스마트스토어 발주(주문)확인/발송관리 메뉴에서 실행해 주세요");  async function c(e, t, r, n) {    chrome.scripting.executeScript({      target: {        tabId: n.id      },      func: function(e, t, r) {        var n = document.querySelector("#__delegate").contentDocument.documentElement.querySelector(".tui-grid-lside-area");        n.querySelectorAll("th")[1].outerHTML = '\n      <th data-column-name="productOrderNo" class="tui-grid-cell tui-grid-cell-head" height="48" colspan="2" rowspan="1">\n        <div class="_1-P09c3QA5" data-type="PRODUCT_ORDER_ID" data-direction="">\n          <span class="_1-P09c3QA5" style="text-decoration: underline; pointer-events: none;">개인통관고유부호 검증결과</span>\n          <span class="_1-P09c3QA5" style="color: #9299aa; pointer-events: none;"></span>\n        </div>\n      </th>\n      ';        let a = n.querySelectorAll("tr")[e + 1].querySelectorAll("td");        a[1].outerHTML = "red" == t ? '\n        <td align="center" colspan="2" class="" data-edit-type="normal" data-row-key="0" data-column-name="productOrderNo">\n          <div class="tui-grid-cell-content" style="background-color: ' + t + '">\n            <p style="color:yellow">' + r + "</p>\n          </div>\n        </td>\n        " : "yellow" == t ? '\n          <td align="center" colspan="2" class="" data-edit-type="normal" data-row-key="0" data-column-name="productOrderNo">\n            <div class="tui-grid-cell-content" style="background-color: ' + t + '">\n              <p style="color:black">' + r + "</p>\n            </div>\n          </td>\n          " : '\n          <td align="center" colspan="2" class="" data-edit-type="normal" data-row-key="0" data-column-name="productOrderNo">\n            <div class="tui-grid-cell-content" style="background-color: ' + t + '">\n              <p style="color:white">' + r + "</p>\n            </div>\n          </td>\n          "      },      args: [e, t, r]    })  }}

Lookup helper with hardcoded API key

popup.js
async function confirmpccfor(e, t, r) {  var n = "https://unipass.customs.go.kr:38010/ext/rest/persEcmQry/retrievePersEcm?crkyCn=q220h210p071h371l060m020c3" + ("&persEcm=" + t + "&pltxNm=" + e + "&cralTelno=" + r.toString().replaceAll("-", "")),    a = await fetch(n),    o = await a.text();  var c = xmlToObject((new DOMParser).parseFromString(o, "text/xml"));  return console.log(c), "1" == c.persEcmQryRtnVo.tCnt ? {    res: !0  } : c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo.errMsgCn ? {    res: !1,    error: c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo.errMsgCn.replace("납세의무자명(pltxNm) 파라미터가 깨질경우 UTF-8로 변환하여 실행하십시오.", "").replace("입력하신 ", "").trim()  } : {    res: !1,    error: c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo[0].errMsgCn.replace("납세의무자명(pltxNm) 파라미터가 깨질경우 UTF-8로 변환하여 실행하십시오.", "").replace("입력하신 ", "").trim()  }}

Manual popup lookup

popup.js
async function confirmpccfor(e, t, r) {  var n = "https://unipass.customs.go.kr:38010/ext/rest/persEcmQry/retrievePersEcm?crkyCn=q220h210p071h371l060m020c3" + ("&persEcm=" + t + "&pltxNm=" + e + "&cralTelno=" + r.toString().replaceAll("-", "")),    a = await fetch(n),    o = await a.text();  var c = xmlToObject((new DOMParser).parseFromString(o, "text/xml"));  return console.log(c), "1" == c.persEcmQryRtnVo.tCnt ? {    res: !0  } : c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo.errMsgCn ? {    res: !1,    error: c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo.errMsgCn.replace("납세의무자명(pltxNm) 파라미터가 깨질경우 UTF-8로 변환하여 실행하십시오.", "").replace("입력하신 ", "").trim()  } : {    res: !1,    error: c.persEcmQryRtnVo.persEcmQryRtnErrInfoVo[0].errMsgCn.replace("납세의무자명(pltxNm) 파라미터가 깨질경우 UTF-8로 변환하여 실행하십시오.", "").replace("입력하신 ", "").trim()  }}

External destination used by this workflow

    • unipass.customs.go.kr

    Korean Customs Unipass personal customs-code lookup endpoint receiving the query-string fields.

Naver session cookies removed before analysis

MediumunwantedCWE-200Dynamic sandbox

Starting review or option analysis runs a cookie cleanup before fetching Naver data: it lists cookies, checks SmartStore domains, removes matches for smartstore.naver.com/brand.naver.com.

What actually happens

You did this

You start review or option analysis from the extension popup.

The extension did this

The extension removes Naver store cookies before continuing with the analysis workflow.

The affected domains are smartstore.naver.com and brand.naver.com.

Cookie fields affected by the cleanup path

  • Cookie domain
    smartstore.naver.com

    This decides which signed-in Naver store session can be removed from your browser.

  • Cookie name
    NID_AUT

    The extension reuses each matching cookie name when it asks Chrome to remove the cookie.

  • Removal URL
    https://brand.naver.com

    The cleanup is applied to Naver SmartStore and Brand Naver cookie stores.

The code that does this

Cookie cleanup and the review-analysis entry point

Readable version

Popup cookie cleanup

popup.js
async function secretOn() {  var e = await chrome.cookies.getAll({});  for (var t of e) t.domain.includes("smartstore.naver.com") && (await chrome.cookies.remove({    name: t.name,    url: "https://smartstore.naver.com"  }), await chrome.cookies.remove({    name: t.name,    url: "https://brand.naver.com"  }));  return console.log("secret On"), "시크릿 모드 On"}

Popup review parsing calls cleanup first

popup.js
async function reviewparsing() {  await secretOn(), await async function() {    let [e] = await chrome.tabs.query({      active: !0,      currentWindow: !0    }), t = await chrome.scripting.executeScript({      target: {        tabId: e.id      },      world: "MAIN",      func: fetchpageinfo,      args: [e.url]    });    if (console.log(t[0].result), !t[0]?.result) return;    var r = e.url,      n = t[0].result.merchantno,      a = t[0].result.productno,      o = r.slice(0, r.search(".com") + 4);    o.search("shopping") > 0 || (o.search("brand") > 0 ? o += "/n" : o += "/i");    var c = o + "/v1/contents/reviews/query-pages",      s = {        headers: {          accept: "application/json, text/plain, */*",          "accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",          "content-type": "application/json",          priority: "u=1, i",          "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',          "sec-ch-ua-mobile": "?0",          "sec-ch-ua-platform": '"Windows"',          "sec-fetch-dest": "empty",          "sec-fetch-mode": "cors",          "sec-fetch-site": "same-origin",          "x-client-version": "20240729102925"        },        referrerPolicy: "no-referrer-when-downgrade",        body: '{"checkoutMerchantNo":' + n + ',"originProductNo":' + a + ',"page":1,"pageSize":20,"reviewSearchSortType":"REVIEW_RANKING"}',        method: "POST",        mode: "cors",        credentials: "include"      };    const i = (await chrome.scripting.executeScript({      target: {        tabId: e.id      },      func: fetchScriptingToJson,      args: [c, s]    }))[0].result;    maxpage = i.totalPages, lastpage = i.totalPages;    for (var l = 0; l < maxpage; l++) {      await sleep(500);      r = o + "/v1/contents/reviews/query-pages";      s = {        headers: {          accept: "application/json, text/plain, */*",          "accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",          "content-type": "application/json",          priority: "u=1, i",          "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',          "sec-ch-ua-mobile": "?0",          "sec-ch-ua-platform": '"Windows"',          "sec-fetch-dest": "empty",          "sec-fetch-mode": "cors",          "sec-fetch-site": "same-origin",          "x-client-version": "20240729102925"        },        referrerPolicy: "no-referrer-when-downgrade",        body: '{"checkoutMerchantNo":' + n + ',"originProductNo":' + a + ',"page":' + (l + 1) + ',"pageSize":30,"reviewSearchSortType":"REVIEW_RANKING"}',        method: "POST",        mode: "cors",        credentials: "include"      }, document.querySelector("#reviewprogress").innerText = parseInt((l + 1) / maxpage * 100), document.querySelector("#optionprogress").innerText = parseInt((l + 1) / maxpage * 100);      var d = await chrome.scripting.executeScript({          target: {            tabId: e.id          },          func: fetchScriptingToText,          args: [r, s]        }),        u = await d[0].result;      if (console.log(u), u.length < 10) return;      {        const e = JSON.parse(u);        for (var m of e.contents) reviewdata.push({          "구매id": m.writerId,          "리뷰날짜": m.createDate,          "구매옵션": m.productOptionContent,          "리뷰내용": m.reviewContent,          "리뷰점수": m.reviewScore        })      }    }  }()}

Background retry path also clears SmartStore cookies

background.js
async function secretOn() {  var e = await chrome.cookies.getAll({});  for (var t of (console.log(e), e)) t.domain.includes("smartstore.naver.com") && (await chrome.cookies.remove({    name: t.name,    url: "https://smartstore.naver.com"  }), await chrome.cookies.remove({    name: t.name,    url: "https://brand.naver.com"  }));  return console.log("secret On"), "시크릿 모드 On"}

The code that does this

Manifest grants cookie access across every host

Readable version
{"update_url": "https://clients2.google.com/service/update2/crx",    "name": "스마트스토어 쿠팡 분석 - SMART DATA 스마트데이터",    "description": "스마트스토어 쿠팡 이커머스 통합 분석 솔루션",    "version": "3.8",    "manifest_version": 3,    "background": {      "service_worker": "background.js"    },    "permissions": ["activeTab", "scripting", "tabs","cookies","declarativeNetRequest"],    "action": {      "default_popup": "popup.html",      "default_icon": {        "16": "/images/icon.png",        "32": "/images/icon.png",        "48": "/images/icon.png",        "128": "/images/icon.png"      }    },    "icons": {      "16": "/images/icon.png",      "32": "/images/icon.png",      "48": "/images/icon.png",      "128": "/images/icon.png"    },    "content_scripts": [      {        "matches": ["*://*/*"],        "match_origin_as_fallback": true,        "js": ["script.js"]      }    ],    "host_permissions": [      "*://*/*"    ],    "declarative_net_request": {      "rule_resources": [{        "id": "ruleset_1",        "enabled": true,        "path": "rules.json"      }]    }  }

What it can do

Permissions this extension asks for, as declared in version 3.8. 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 every site you visit

    *://*/*

  • Act on the current tab, but only after you click the extension

    activeTab

  • Run its own code inside the pages you visit

    scripting

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

    tabs

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

    cookies

  • Block and redirect the requests your browser makes

    declarativeNetRequest

Where it sends data

Destinations our analysis observed 스마트스토어 쿠팡 분석 - SMART DATA 스마트데이터 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.

  • smartdata-env.eba-uqvs9y7q.ap-northeast-2.elasticbeanstalk.com

    스마트스토어 쿠팡 분석 - SMART DATA 스마트데이터 sends data to smartdata-env.eba-uqvs9y7q.ap-northeast-2.elasticbeanstalk.com. No other extension we have analyzed sends data here.

  • unipass.customs.go.kr

    스마트스토어 쿠팡 분석 - SMART DATA 스마트데이터 sends data to unipass.customs.go.kr. No other extension we have analyzed sends data here.

Updated 30 September 2026anoebfcjjlckhnlbmbpghickjbjjfike