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
45Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-522
SourceAI SANDBOX

Buyer customs details sent to Unipass

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.

01EvidenceCAUSE EFFECT
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.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://unipass.customs.go.kr:38010/ext/rest/persEcmQry/retrievePersEcm?crkyCn=q220h210p071h371l060m020c3
XML response parsed by the extension
03EvidenceFIELD TABLE
Query-string fields sent to the customs endpoint
FieldValueWhy it matters
Bundled API key
q220h210p071h371l060m020c3Anyone with the extension package can read the API credential used for the customs lookup.
Recipient name
Kim MinseoThis identifies the person whose customs clearance record is being checked.
Customs clearance code
P123456789012This links the lookup to a Korean personal customs clearance record.
Phone number
01012345678This adds another direct identifier to the customs lookup.
04EvidenceCODE COMPARE
The code that does this

Customs lookup functions and the embedded API key

What it actually does
Order-grid customs verificationpopup.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 keypopup.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 lookuppopup.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()
  }
}
05EvidenceTHIRD PARTY LIST
External destination used by this workflow
  • unipass.customs.go.kr

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

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Naver session cookies removed before analysis

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.

One test run missed this; later proof confirmed it.

01EvidenceCAUSE EFFECT
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.

02EvidenceFIELD TABLE
Cookie fields affected by the cleanup path
FieldValueWhy it matters
Cookie domain
smartstore.naver.comThis decides which signed-in Naver store session can be removed from your browser.
Cookie name
NID_AUTThe extension reuses each matching cookie name when it asks Chrome to remove the cookie.
Removal URL
https://brand.naver.comThe cleanup is applied to Naver SmartStore and Brand Naver cookie stores.
03EvidenceCODE COMPARE
The code that does this

Cookie cleanup and the review-analysis entry point

What it actually does
Popup cookie cleanuppopup.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 firstpopup.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 cookiesbackground.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"
}
04EvidenceCODE COMPARE
The code that does this

Manifest grants cookie access across every host

What it actually does
{
"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"
      }]
    }
  }

Data recipients

unipass.customs.go.krsmartdata-env.eba-uqvs9y7q.ap-northeast-2.elasticbeanstalk.com
Updated 17 September 2026anoebfcjjlckhnlbmbpghickjbjjfike