Front-End Security — уязвимости безопасности зависимостей, которых следует остерегаться

внешний интерфейс Безопасность

из-за нарушения безопасности

Lodashочень популяренnpmбиблиотека с более чем 100 загрузками в месяц8000десять тысяч раз,GitHubЕсть более чем400десять тысяч. некоторое время назадLodashВзорвалась одна из брешей безопасности в кругу друзей.Давайте сначала вспомним эту брешь в безопасности:

Злоумышленник может пройтиLodashНекоторые функции перезаписывают или загрязняют приложение. Например: черезLodashфункции в библиотекеdefaultsDeepможно изменитьObject.prototypeхарактеристики.

мы все знаем,JavaScriptПри чтении свойства в объекте, если он не может его найти, он переходит к своей цепочке прототипов, чтобы найти его. Представьте, что изменяемое свойствоtoStringметод:

const payload = '{"constructor": {"prototype": {"toString": true}}}'
_.defaultsDeep({}, JSON.parse(payload))

Каждый объект имеетtoString()метод, вызываемый автоматически, когда объект представлен как буквальное значение или когда на объект ссылаются ожидаемым строковым способом. по умолчанию,toString()метод каждогоObjectНаследование объекта. Если этот метод не переопределен в пользовательском объекте,toString()возвращение[object type]typeявляется типом объекта. если перезаписатьtoString()метод, то влияние на приложение очень велико.

На самом деле вышеуказанная проблема относится к очень распространенной уязвимости безопасности — загрязнению прототипа.

Загрязнение прототипа: злоумышленник каким-то образом модифицирует прототип объекта JavaScript.

Однако это неLodashЭто первое нарушение безопасности. На самом деле подобные уязвимости безопасности могут существовать и в тысячах различных зависимостей с открытым исходным кодом, которые мы используем, и если мы не будем обращать на них внимание, потери для нашего проекта в случае возникновения проблемы будут неизмеримыми. Это равносильно тому, что в вашем проекте закопано много бомб, которые взорвутся, не зная, когда.

Расследование безопасности

На самом деле разработчики доверяют безопасности открытого исходного кода больше, чем безопасности собственного кода, но в инструментах, обеспечивающих безопасность и качество кода, по-прежнему много недостатков. существуетnpmПрежде чем появится совершенный механизм обнаружения безопасности,npmиNodeJsКоманда работала с десятками тысячJavaScriptРазработчики запустили опрос, и первый вопрос касался безопасности, в частности, как разработчики оценивают безопасность кода, который они пишут, и проектов с открытым исходным кодом, которые они используют.

Результаты опроса показывают, что:97%изJavaScriptРазработчики полагаются на открытый исходный код в своих проектах.77%разработчиков выражают озабоченность по поводу безопасности используемого ими открытого исходного кода. Что еще интересно, есть87%человек выразили обеспокоенность по поводу безопасности своего кода.

Кроме того, более половиныJavaScriptРазработчики считают, что инструменты, которые они используют для оценки безопасности и качества открытого исходного кода, недостаточно хороши.

npm audit

Основываясь на менее оптимистичных результатах опроса, приведенных выше,npm@6Добавлено крупное обновление:npm auditЗаказ. сверхуlogoВидно, что эта версия является основной безопасностью.npm auditКоманда рекурсивно анализирует дерево зависимостей для выявления небезопасных зависимостей, и если вы используете в своем проекте зависимости с известными проблемами безопасности, вы получите уведомление с предупреждением. Эта команда запустится автоматически после обновления или установки новых зависимостей.

npmЧиновник ведет список уязвимостей. Когда разработчик или профессиональная группа безопасности обнаружит проблему безопасности в пакете зависимостей, об этом будет сообщеноnpmОфициальный, а затем официальный уведомит разработчика проекта о ремонте, после завершения ремонтаnpmПодробное описание уязвимости и решения будут опубликованы:

npm aduitГлавное — отправить информацию о зависимостях, которую необходимо проверить, на официальный интерфейс проверки.Структура определит, содержит ли текущая информация о зависимостях уязвимости в базе данных уязвимостей, зарегистрированных в истории, а затем сгенерирует имя пакета, серьезность уязвимости, введение , путь и т. д. Отчет об ошибке возвращается разработчику.

Теперь мы напрямую устанавливаем уязвимость безопасностиlodash@4.17.4версии видно, что после завершения установки вам напомнят, что только что добавленная вами зависимость содержит 3 уязвимости.

воплощать в жизньnpm auditМы можем увидеть детали уязвимости, эта версияlodashЕсть 3 уязвимости безопасности, давайте подробно рассмотрим одну:

  • High: Уровень уязвимости безопасности таблицы
  • Package: имя уязвимого пакета
  • Dependency of: Имя пакета, от которого напрямую зависит текущий проект.
  • Path: Полный путь зависимостей уязвимости
  • More info: сведения об уязвимости

Обратите внимание, что не только пакеты, от которых вы напрямую зависите, имеют уязвимости для получения предупреждений, но пока узел в вашем дереве зависимостей зависит от пакетов с уязвимостями, вы будете получать предупреждения. пример:

Проект напрямую не зависит отlodash, но@commitlint/cliзависимый@commitlint/loadзависел отlodashЭто будет считаться уязвимостью, поэтому для некоторых крупных проектов с длительными циклами итерации вполне нормально содержать десятки тысяч уязвимостей безопасности.

Нажмите на ссылку, чтобы узнать подробности об уязвимости:https://www.npmjs.com/advisories/1065

Мы видим конкретное описание уязвимости и решения.С правой стороны указано конкретное время сообщения об уязвимости и время раскрытия уязвимости.

Раздел безопасности GitHub

Обычно мы можем часто получать что-то вроде следующегоGitHubПисьма с предупреждением о нарушении безопасности.

Откройте ссылку, мы увидим страницу конкретных сведений об уязвимости:

GitHubоткрыл один только для него,Securityпанель для отображенияGitHubОбнаруженные уязвимости безопасности зависимостей показывают, что этих уязвимостей достаточно, чтобы привлечь всеобщее внимание, и их необходимо быстро исправить:

Кроме того,GitHubОн также предоставляет функцию восстановления одним щелчком мыши для каждой уязвимости, которую можно исправить, нажмитеAutomated security updatesкнопка,GitHubавтоматически исправит эти зависимости и отправитPull Requestв ваш репозиторий:

Политика устранения уязвимостей безопасности

npmтакже обеспечиваетnpm audit fixчтобы помочь нам автоматически исправить уязвимости, и продолжайте использовать приведенный выше пример,Lodashсуществует4.17.12Все предыдущие версии имеют уязвимости прототипа загрязнения.Давайте рассмотрим конкретные стратегии исправления:

Уязвимость прямой зависимости

В настоящее время мы напрямую полагаемся на уязвимость безопасностиlodash@4.17.4Версия:

  "dependencies": {
    "lodash": "^4.17.4"
  }

так как^4.17.4Диапазон зависимостей>=3.0.3 < 4.0.0, фиксированная версия4.17.12в этом диапазоне, то фактическиnpm audit fixЛогика выполнения таковаnpm update lodash@4.17.12.

lodash@^4.17.4 -> lodash@^4.17.12

Уязвимость косвенной зависимости

Предположим, теперь у нас есть очень глубокий путь зависимости:@commitlint/cli^7.1.2>@commitlint/load^1.0.1>lodash^3.0.0

так как@commitlint/loadправильноlodashЗависимость^3.0.0(>=3.0.0 <4.0.0),4.17.12Не в этом диапазоне, поэтому мы не можем пройти обновление напрямую.LodashЧтобы исправить уязвимость, нам нужно проанализировать зависимости верхнего уровня.

Предположим, в это время@commitlint/loadесть обновленная версия@commitlint/load^1.0.2правильноlodashЗависимость^4.0.0(>=4.0.0 <5.0.0),lodash@4.17.12В пределах этого диапазона зависимости стратегия восстановленияnpm update @commitlint/load@1.0.2 --depth=2.

npm update будет проверять только обновления зависимостей верхнего уровня.Для обновления более глубоких версий зависимостей необходимо использовать параметр --depth, чтобы указать глубину обновления.

Согласно этой логике, если@commitlint/loadЕсли обновляемый пакет не найден, перейдите к поиску зависимостей верхнего уровня, пока не найдете уровень зависимости, который может устранить уязвимость.

Принудительное исправление ошибок

В соответствии с вышеописанной стратегией ищем от зависимости нижнего уровня к верхнему уровню.Если есть ремонтная версия, удовлетворяющая требованиям до зависимости верхнего уровня, то напрямуюnpm updateОбновите зависимости верхнего уровня.

Продолжая приведенный выше пример, если@commitlint/cli^7.1.2( >=7.1.2 <8.0.0 )Пока не могу найти исправимую версию, тогдаnpm audit fixЭта команда ничего не делает.

В этот момент мы можем попробоватьnpm audit fix --force(Принудительное исправление аудита для установки последних зависимостей (верхний уровень)) для исправления, логика такова:npm install @commitlint/cli@patchedVersion --save

Эта команда будет напрямую пересекать текущий указанныйsemverДиапазон версий, заставляющий зависимости обновляться до последней версии, следует использовать с осторожностью.

npm также предоставляет некоторые другие команды исправления

  • npm audit fix --package-lock-only: без измененийnode_modulesвыполнять в случаеaudit fix, все равно изменитсяpkglock
  • npm audit fix --only=prod: пропустить обновлениеdevDependencies

Неисправимая уязвимость

Конечно, ни одна из вышеперечисленных стратегий исправления не может решить эту уязвимость безопасности, а это означает, что эту уязвимость нельзя исправить автоматически, и ее необходимо обрабатывать вручную.

Отключить проверки безопасности

Если вас не волнуют эти дыры в безопасности, вы также можете вручную указать некоторые конфигурации, чтобы отключить эти проверки безопасности:

  • Установите один пакет, чтобы отключить проверку безопасности:npm install example-package-name --no-audit
  • Установить все пакеты отключить проверку безопасности - запуститьnpm set audit false
  • вручную~/.npmrcв файле конфигурацииauditпревратиться вfalse

Конечно, делать это настоятельно не рекомендуется, и вы должны нести ответственность за проекты, которые вы разрабатываете до конца~

Интерпретация отчетов об уязвимостях зависимостей

воплощать в жизньnpm audit --jsonраспечатает подробныйjsonОтформатируйте отчет о безопасности, в котором вы можете увидеть подробную информацию об этих уязвимостях, а также конкретные стратегии устранения уязвимостей.

В связи с этимJSONОн относительно большой, поэтому я не буду публиковать его здесь, вы можете выбрать проект для локального выполнения.npm audit --jsonПроверять.

Обзор данных об уязвимостях

существуетmetadataВ свойствах: видим обзор данных проверки на уязвимости:

  {
    "vulnerabilities": {
      "info": 0,
      "low": 0,
      "moderate": 4,
      "high": 29,
      "critical": 0
    },
    "dependencies": 18594,
    "devDependencies": 891090,
    "optionalDependencies": 9514,
    "peerDependencies": 0,
    "totalDependencies": 909785
  }

vulnerabilitiesКоличество уязвимостей для каждого уровня показано наinfo,low,moderate,high,criticalСлева направо соответствующие уровни уязвимости безопасности расположены от низкого к высокому.

Ниже приведено количество обнаружений для каждой зависимости, с которой мы знакомы.dependencies,devDependenciesи Т. Д.

Стратегия ремонта

существуетactionsВ атрибуте будут перечислены все уязвимые стратегии восстановления, такие как следующие, для@commitlint/loadВыполните обновление с глубиной2, чинить@commitlint/cli>@commitlint/load>lodashУязвимости на этом пути:

{
      "action": "update",
      "module": "@commitlint/load",
      "target": "1.0.2",
      "resolves": [
        {
          "id": 1184,
          "path": "@commitlint/cli>@commitlint/load>lodash",
          "dev": false,
          "optional": false,
          "bundled": false
        }
      ],
      "depth": 2
    }

Кроме того,actionЕсть еще несколько операций, о которых мы упоминали выше:

  • install(исправить прямые зависимости)
  • install major(зависимости принудительного обновления, охватывающие основные версии)
  • review(Невозможно исправить автоматически, требуется ручная проверка)

Сведения об уязвимости

advisoriesСвойства содержат подробную информацию о каждой уязвимости:

"1065": {
      "cves": [
        "CVE-2019-10744"
      ],
      "access": "public",
      "severity": "high",
      "metadata": "",
      "reviewers": "",
      "confirmors": "",
      "id": 1065,
      "repo_from": "npm",
      "title": "Prototype Pollution",
      "module_name": "lodash",
      "found_by_link": "",
      "found_by_user_name": "Snyk Security Team",
      "reported_by_link": "",
      "reported_by_user_name": "Snyk Security Team",
      "vulnerable_versions": "<4.17.12",
      "patched_versions": ">=4.17.12",
      "overview": "Versions of `lodash` before 4.17.12 are vulnerable to Prototype Pollution.  The function `defaultsDeep` allows a malicious user to modify the prototype of `Object` via `{constructor: {prototype: {...}}}` causing the addition or modification of an existing property that will exist on all objects.\n\n",
      "recommendation": "Update to version 4.17.12 or later.",
      "references": "- [Snyk Advisory](https://snyk.io/vuln/SNYK-JS-LODASH-450202)",
      "cwe": "CWE-471",
      "url": "https://npmjs.com/advisories/1065",
      "gmt_create": "2019-07-16T02:28:32.000Z",
      "gmt_modified": "2019-09-11T04:49:11.000Z",
      "deleted_at": null,
      "findings": [
        {
          "version": "4.17.11",
          "paths": [
            "@commitlint/cli>@commitlint/load>@commitlint/rules>@commitlint/ensure>lodash",
            "@commitlint/cli>@commitlint/load>lodash",
            "@commitlint/cli>@commitlint/load>@commitlint/resolve-extends>lodash",
            "@commitlint/cli>@commitlint/load>lodash",
            "@commitlint/cli>lodash"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ]
    }

Поскольку атрибутов много, давайте рассмотрим несколько ключевых моментов:

  • cves: номер уязвимости CVE
  • severity: Уровень уязвимости
  • found_by_user_name: пользователь, обнаруживший уязвимость (здесьSnyk Security Teamизвестная служба безопасности)
  • vulnerable_versions: затронутая версия
  • patched_versions: исправленная версия
  • findings: все эксплойты, зависящие от этого пути
  • overview: Краткое описание уязвимости, упомянутой здесьLodashизdefaultsDeepсклонность к загрязнению прототипа
  • references: Справочник по уязвимостям, как правило, отчет, опубликованный некоторыми профессиональными платформами безопасности.

безопасная платформа

В приведенном выше отчете упоминалось несколько профессиональных платформ безопасности, которые легко запутать людей.Давайте рассмотрим их подробно ниже:

HackerOne

HackerOne(http://hackerone.com)была основана в2012Nian — это платформа для сбора и раскрытия уязвимостей в системе безопасности. Хакеры могут раскрывать уязвимости в системе безопасности, которые они обнаружили на веб-сайте, и сообщать о них соответствующим веб-сайтам или компаниям. После подтверждения эти веб-сайты или компании могут предоставлять хакерам различные благодарности, такие как бонусы.HackerOneКоличество зарегистрированных хакеров на платформе зашкалило3010 000 человек, общее количество отправленных действительных уязвимостей превышает1010 000, а выплачиваемая награда за обнаружение ошибок превышает4200Десять тысяч долларов США.

"references": "- [HackerOne Report](https://hackerone.com/reports/541502)"

Мы видим в отчете о безопасности, что некоторые уязвимости также будут иметь копию.HackerOneдля справки.

Snyk

Snykэто платформа анализа зависимостей для нескольких стеков разработки, охватывающаяJavaScript,Java,.Net,Ruby,Python,PHP,GolangиScala.Snykподдерживает всеобъемлющую базу данных уязвимостей с открытым исходным кодом, которая включаетSnykУязвимости, обнаруженные собственной специальной исследовательской группой, а также те, которые отслеживаются из общедоступных источников данных.

SnykБаза данных уязвимостей предоставляет исчерпывающие данные об уязвимостях через свою систему анализа угроз, обеспечивая лучший охват и возможность отображать и сообщать о еще не полученныхCVEлазейки. Например,npmПредлагаются лазейки72%был впервые добавлен вSnykв базе данных.

SnykОн также предоставляет механизм для сканирования уязвимостей в системе безопасности по сравнению сnpm audit, его преимущество в том, что его можно легко иGitHubилиGitLabизCIПроцесс интегрирован, для большего сравнения механизмов сканирования вы можете увидеть эту статью:https://www.nearform.com/blog/comparing-npm-audit-with-snyk/.

"references": "- [Snyk Advisory](https://snyk.io/vuln/SNYK-JS-LODASH-450202)"

Как видно из приведенного выше отчета о безопасности, некоторые уязвимости также будут иметь копию.Snykдля справки иLodashЭто нарушение безопасности также вызваноSnykОбнаружено и доложено службой безопасности.

CVE

CVEПредставляет Common Vulnerability and Disclosure Standard, некоммерческую организацию, которая является спонсируемым государством центром исследований и разработок. Его цель — выявить уязвимости в программном обеспечении или прошивке и занести их в бесплатную базу данных для повышения безопасности организации.

использоватьCVE IDВыявляя конкретные уязвимости или риски, организации могут быстро и точноCVEПолучайте информацию из совместимых источников. Сравнивая различные инструменты и службы безопасности,CVEМожет помочь организациям выбрать контент, который лучше всего соответствует их потребностям.

"cves": [
        "CVE-2019-10744"
      ]

Мы видим, что оба вышеперечисленныхnpm auditотчет илиSnyk,HackerOneОтчеты других платформ безопасности будут содержать уязвимостьCVEНумерация.

Ссылаться на

резюме

Надеюсь, что чтение этой статьи поможет вам в следующем:

  • Понимать контекст зависимости от нарушений безопасности
  • учитьсяnpmМеханизмы автоматического исправления уязвимостей безопасности
  • Получите некоторые общие знания о безопасности и уделите больше внимания вопросам безопасности переднего плана.

Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь.

Если вы хотите читать больше качественных статей, вы можете подписаться на меняблог на гитхабе, твоя звезда✨, лайки и внимание - движущая сила моего постоянного творчества!

Рекомендую обратить внимание на мой паблик WeChat [code secret garden], каждый день выкладывать качественные статьи, будем общаться и расти вместе.