ページの先頭です

ページ内を移動するためのリンク
本文へ (c)

ここから本文です。

GitLab CI で自動化 製品のセキュリティ情報をbotでWebexに通知させる

ライター:猪子 亮
2019年ネットワンシステムズに新卒入社。

社内/外 向けサービス開発、事業部門の支援などを行っています。
主にWeb アプリケーションのフロントエンド、バックエンド開発(オンプレ/AWS)。

他には社内の自動化推進(Ansible)、業務改善活動、開発エンジニア育成などに取り組んでいます。

目次

2024/1/22 現在、本記事で紹介している方法での情報取得は不可となりました。詳細は以下を参照ください。

https://www.redhat.com/en/blog/future-red-hat-security-data#

新たな方法でのセキュリティ情報の取得に関しては今後記事を執筆予定です。

はじめに

日々の運用において、使用している製品の脆弱性情報の取得に手間がかかっていませんでしょうか。

本記事では、特定製品における脆弱性情報を取得し、チャットツールであるWebex に通知させる自動化をご紹介します。

ここでは、Red Hat 社の製品を例に、どのような構成で自動化したかご紹介します。

脆弱性を一意に特定するためのCVE

現在、情報セキュリティにおける脆弱性情報はCVE(共通脆弱性識別子) と呼ばれる識別子で管理するのが一般的となっています。

ベンダーによらず、CVE が同じであれば、同じ脆弱性を指します。

ベンダーやリサーチャー、一般の開発者などによって脆弱性が発見されると、CNA と呼ばれるCVE の採番機関によって一意のCVE ID が割り振られます。
※ 厳密には条件を満たした脆弱性に対してCVE ID が割り振られます。

脆弱性が発見されるとCVE ID が割り振られますが、セキュリティーアドバイザリーが公開されるまで、脆弱性情報は公開されません。

先にCVE だけが公開されると、攻撃者に悪用される恐れがあるためです。

セキュリティーアドバイザリーは各ベンダーが公開する脆弱性情報のことであり、以下のような情報が含まれます。

  • 重大度
  • 脆弱性に関する情報
  • 影響を受ける製品
  • 対処法
  • 影響を受けたCVE

一般的に、ベンダーはCVE の報告を受けると、その脆弱性対策の開発やテストを行った後、セキュリティーアドバイザリーとして公開します。

Red Hat 製品における脆弱性情報の確認方法

Red Hat Product Errata

Red Hat 社 は、脆弱性やバグ情報をエラッタと呼ばれる形で情報を公開しています。

エラッタはRed Hat Product Errata から検索できます。

https://access.redhat.com/errata-search/#/ より引用

Red Hat 社の場合、3つの区分でエラッタを公開しています。(文献2 より引用)

  • RHSA (Red Hat Security Advisory): RHSA アドバイザリーには、1 つ以上のセキュリティーの修正と、バグ修正または機能強化が含まれます。 RHSA アドバイザリーは、RHBA および RHEA アドバイザリーよりも優先されます。
  • RHBA (Red Hat Bug Advisory): RHBA アドバイザリーには、1 つ以上のバグ修正、そして機能強化が含まれる場合があります。ただし、セキュリティーの修正は含まれません。 RHBA アドバイザリーはバグ修正のためにリリースされるため、RHBA は RHEA アドバイザリーよりも優先されます。
  • RHEA (Red Hat Enhancement Advisory): RHEA アドバイザリーには、1 つ以上の機能強化または新機能が含まれますが、バグとセキュリティーの修正は含まれません。RHEA は、本来、新しい機能が追加されたり、パッケージがアップデートされた場合にリリースされます。

Web 上でRed Hat 製品の脆弱性情報を検索する場合、上記サイトから製品とそのバージョン、重大度などを指定して検索します。

自動化前の問題点

前述の通り、Red Hat Product Errata を使うと気軽に製品の脆弱性情報を確認できます。

しかし、単体では更新を検知し、通知させるなどの仕組みは用意されていません

そのため、最新の脆弱性情報を常に取得したい場合、RPA などを使って変更を検知するか、都度Web サイトを訪問して確認する必要があります。

API による脆弱性情報の取得

Red Hat Security Dataでは、daysofrisk.pl(現在はアクセス不可)というスクリプトが公開されており、これを使うと特定製品の脆弱性情報を簡単に取得できます。

まずはスクリプトに必要なテキストファイルとスクリプト本体をダウンロードします。


          curl -OL https://www.redhat.com/security/data/metrics/release_dates.txt
          curl -OL https://www.redhat.com/security/data/metrics/rhsamapcpe.txt
          curl -OL https://www.redhat.com/security/data/metrics/cve_dates.txt
          curl -OL https://www.redhat.com/security/data/metrics/daysofrisk.pl
          chmod 700 daysofrisk.pl
        

スクリプトの使い方は --help オプションで確認できます。


          ./daysofrisk.pl --help
        

取得する脆弱性情報は製品名や重大度等で絞り込むことができ、それぞれ--cpe--severity オプションで指定します。

CPE はCommon Platform Enumeration の略で、例えばRHEL 8 の場合はredhat:enterprise_linux:8 となります。

Red Hat 社におけるCPE のリストはcpe-dictionary.xml(現在はアクセス不可)で公開されています。

重大度はCVSS などをもとにRed Hat社が総合的に評価した評価指数(詳細は文献4 を参照)を用います。

重大度順でCritical、Important 、Moderate 、Low Impactとなっており、それぞれの頭文字で指定します。

例えば、CriticalImportant のみ指定する場合、--severity CI となります。

RHEL8 におけるCritical のセキュリティーアドバイザリーを期間指定して取得する場合、以下のようなスクリプトになります。


          ./daysofrisk.pl --cpe redhat:enterprise_linux:8 --severity C --dates 20220101-20221231
          ** Product: Red Hat Enterprise Linux 8 (all packages)
          ** CPE: redhat:enterprise_linux:8
          ** Severity: Critical 
          ** Dates: 20220101 - 20221231 (365 days)
          ** 5 advisories (C=4 I=1 )
          ** 5 vulnerabilities (C=5 )
          ** Advisory Workload index is 0.01
          ** Vulnerability Workload index is 0.01
          ** Average is 5 days
          ** Median is 5 days
          ** 20% were 0day
          ** 20% were within 1 day
          ** 100% were within 7 days
          ** 100% were within 14 days
          ** 100% were within 31 days
        

結果はサマリーが標準出力に出力される他、デフォルトではCVE 情報がsummary.xml として出力されます。

summary.xml

                <summary>
                <item>
                  <cve>CVE-2021-44142</cve>
                  <severity>C</severity>
                  <source>relationship</source>
                  <reportedon>20220126</reportedon>
                  <cvss3>9.9</cvss3>
                  <fixedby>RHSA-2022:0332</fixedby>
                  <fixedon>20220131</fixedon>
                  <publicon>20220131</publicon>
                  <daysdiff>0</daysdiff>
                </item>
                <item>
                  <cve>CVE-2022-1529</cve>
                  <severity>C</severity>
                  <source>relationship</source>
                  <reportedon>20220520</reportedon>
                  <cvss3>8.8</cvss3>
                  <fixedby>RHSA-2022:4769</fixedby>
                  <fixedby>RHSA-2022:4776</fixedby>
                  <fixedon>20220527</fixedon>
                  <publicon>20220520</publicon>
                  <daysdiff>7</daysdiff>
                </item>
                <item>
                  <cve>CVE-2022-1802</cve>
                  <severity>C</severity>
                  <source>relationship</source>
                  <reportedon>20220520</reportedon>
                  <cvss3>8.8</cvss3>
                  <fixedby>RHSA-2022:4769</fixedby>
                  <fixedby>RHSA-2022:4776</fixedby>
                  <fixedon>20220527</fixedon>
                  <publicon>20220520</publicon>
                  <daysdiff>7</daysdiff>
                </item>
                <item>
                  <cve>CVE-2022-26485</cve>
                  <severity>C</severity>
                  <source>relationship</source>
                  <reportedon>20220308</reportedon>
                  <cvss3>8.8</cvss3>
                  <fixedby>RHSA-2022:0818</fixedby>
                  <fixedby>RHSA-2022:0845</fixedby>
                  <fixedon>20220310</fixedon>
                  <publicon>20220305</publicon>
                  <daysdiff>5</daysdiff>
                </item>
                <item>
                  <cve>CVE-2022-26486</cve>
                  <severity>C</severity>
                  <source>relationship</source>
                  <reportedon>20220308</reportedon>
                  <cvss3>8.8</cvss3>
                  <fixedby>RHSA-2022:0818</fixedby>
                  <fixedby>RHSA-2022:0845</fixedby>
                  <fixedon>20220310</fixedon>
                  <publicon>20220305</publicon>
                  <daysdiff>5</daysdiff>
                </item>
                <filter><distrib>Red Hat Enterprise Linux 8 (all packages)</distrib><cpe>cpe:/o:redhat:enterprise_linux:8</cpe><cvssmin>0</cvssmin><cvssmax>10</cvssmax><cvss3min>0</cvss3min><cvss3max>10</cvss3max><severity>Critical </severity><start>20220101</start><end>20221231</end></filter>
                <totals>
                <num>5</num><av>5</av><median>5</median><oneday>20</oneday>
                </totals></summary>
            

上記summary.xml からCVE IDを抽出し、API を使うと、JSON 形式で詳細を取得できます。


          # Extract CVE from XML then convert to CSV
          cve_ids="$(xmllint --nowarning --xpath '/summary/item/cve' summary.xml | \
          sed -e 's///g' | sed -e 's/<\/cve>/\n/g' | sort -r | paste -sd ',' -)"
          
# Get CVE detail usng API request_url="https://access.redhat.com/hydra/rest/securitydata/cve.json?ids=$cve_ids" curl -s -H 'accept: application/json' ${request_url} > cve_detail.json

cve_detail.json

                [
                    {
                        "CVE": "CVE-2022-1802",
                        "severity": "critical",
                        "public_date": "2022-05-20T00:00:00Z",
                        "advisories": [
                            "RHSA-2022:4773",
                            "RHSA-2022:4772",
                            "RHSA-2022:4730",
                            "RHSA-2022:4774",
                            "RHSA-2022:4766",
                            "RHSA-2022:4776",
                            "RHSA-2022:4765",
                            "RHSA-2022:4768",
                            "RHSA-2022:4767",
                            "RHSA-2022:4769",
                            "RHSA-2022:4729",
                            "RHSA-2022:4770"
                        ],
                        "bugzilla": "2089217",
                        "bugzilla_description": "CVE-2022-1802 Mozilla: Prototype pollution in Top-Level Await implementation",
                        "cvss_score": null,
                        "cvss_scoring_vector": null,
                        "CWE": "CWE-843",
                        "affected_packages": [
                            "thunderbird-0:91.9.1-1.el8_4",
                            "thunderbird-0:91.9.1-1.el8_1",
                            "thunderbird-0:91.9.1-1.el9_0",
                            "thunderbird-0:91.9.1-1.el8_2",
                            "firefox-0:91.9.1-1.el8_6",
                            "thunderbird-0:91.9.1-1.el7_9",
                            "firefox-0:91.9.1-1.el7_9",
                            "thunderbird-0:91.9.1-1.el8_6",
                            "firefox-0:91.9.1-1.el8_2",
                            "firefox-0:91.9.1-1.el8_1",
                            "firefox-0:91.9.1-1.el9_0",
                            "firefox-0:91.9.1-1.el8_4"
                        ],
                        "resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2022-1802.json",
                        "cvss3_scoring_vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
                        "cvss3_score": "8.8"
                    },
                    {
                        "CVE": "CVE-2022-1529",
                        "severity": "critical",
                        "public_date": "2022-05-20T00:00:00Z",
                        "advisories": [
                            "RHSA-2022:4773",
                            "RHSA-2022:4772",
                            "RHSA-2022:4730",
                            "RHSA-2022:4774",
                            "RHSA-2022:4766",
                            "RHSA-2022:4776",
                            "RHSA-2022:4765",
                            "RHSA-2022:4768",
                            "RHSA-2022:4767",
                            "RHSA-2022:4769",
                            "RHSA-2022:4729",
                            "RHSA-2022:4770"
                        ],
                        "bugzilla": "2089218",
                        "bugzilla_description": "CVE-2022-1529 Mozilla: Untrusted input used in JavaScript object indexing, leading to prototype pollution",
                        "cvss_score": null,
                        "cvss_scoring_vector": null,
                        "CWE": "CWE-843",
                        "affected_packages": [
                            "thunderbird-0:91.9.1-1.el8_4",
                            "thunderbird-0:91.9.1-1.el8_1",
                            "thunderbird-0:91.9.1-1.el9_0",
                            "thunderbird-0:91.9.1-1.el8_2",
                            "firefox-0:91.9.1-1.el8_6",
                            "thunderbird-0:91.9.1-1.el7_9",
                            "firefox-0:91.9.1-1.el7_9",
                            "thunderbird-0:91.9.1-1.el8_6",
                            "firefox-0:91.9.1-1.el8_2",
                            "firefox-0:91.9.1-1.el8_1",
                            "firefox-0:91.9.1-1.el9_0",
                            "firefox-0:91.9.1-1.el8_4"
                        ],
                        "resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2022-1529.json",
                        "cvss3_scoring_vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
                        "cvss3_score": "8.8"
                    },
                    {
                        "CVE": "CVE-2022-26486",
                        "severity": "critical",
                        "public_date": "2022-03-05T00:00:00Z",
                        "advisories": [
                            "RHSA-2022:0816",
                            "RHSA-2022:0815",
                            "RHSA-2022:0847",
                            "RHSA-2022:0824",
                            "RHSA-2022:0845",
                            "RHSA-2022:0843",
                            "RHSA-2022:0853",
                            "RHSA-2022:0850",
                            "RHSA-2022:0818",
                            "RHSA-2022:0817"
                        ],
                        "bugzilla": "2061735",
                        "bugzilla_description": "CVE-2022-26486 Mozilla: Use-after-free in WebGPU IPC Framework",
                        "cvss_score": null,
                        "cvss_scoring_vector": null,
                        "CWE": "CWE-416",
                        "affected_packages": [
                            "thunderbird-0:91.7.0-2.el8_2",
                            "thunderbird-0:91.7.0-2.el8_1",
                            "firefox-0:91.7.0-3.el7_9",
                            "firefox-0:91.7.0-3.el8_2",
                            "thunderbird-0:91.7.0-2.el8_5",
                            "firefox-0:91.7.0-3.el8_4",
                            "thunderbird-0:91.7.0-2.el8_4",
                            "firefox-0:91.7.0-3.el8_5",
                            "thunderbird-0:91.7.0-2.el7_9",
                            "firefox-0:91.7.0-3.el8_1"
                        ],
                        "resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2022-26486.json",
                        "cvss3_scoring_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
                        "cvss3_score": "8.8"
                    },
                    {
                        "CVE": "CVE-2022-26485",
                        "severity": "critical",
                        "public_date": "2022-03-05T00:00:00Z",
                        "advisories": [
                            "RHSA-2022:0816",
                            "RHSA-2022:0815",
                            "RHSA-2022:0847",
                            "RHSA-2022:0824",
                            "RHSA-2022:0845",
                            "RHSA-2022:0843",
                            "RHSA-2022:0853",
                            "RHSA-2022:0850",
                            "RHSA-2022:0818",
                            "RHSA-2022:0817"
                        ],
                        "bugzilla": "2061736",
                        "bugzilla_description": "CVE-2022-26485 Mozilla: Use-after-free in XSLT parameter processing",
                        "cvss_score": null,
                        "cvss_scoring_vector": null,
                        "CWE": "CWE-416",
                        "affected_packages": [
                            "thunderbird-0:91.7.0-2.el8_2",
                            "thunderbird-0:91.7.0-2.el8_1",
                            "firefox-0:91.7.0-3.el7_9",
                            "firefox-0:91.7.0-3.el8_2",
                            "thunderbird-0:91.7.0-2.el8_5",
                            "firefox-0:91.7.0-3.el8_4",
                            "thunderbird-0:91.7.0-2.el8_4",
                            "firefox-0:91.7.0-3.el8_5",
                            "thunderbird-0:91.7.0-2.el7_9",
                            "firefox-0:91.7.0-3.el8_1"
                        ],
                        "resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2022-26485.json",
                        "cvss3_scoring_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
                        "cvss3_score": "8.8"
                    },
                    {
                        "CVE": "CVE-2021-44142",
                        "severity": "critical",
                        "public_date": "2022-01-31T00:00:00Z",
                        "advisories": [
                            "RHSA-2022:0329",
                            "RHSA-2022:0328",
                            "RHSA-2022:0458",
                            "RHSA-2022:0457",
                            "RHSA-2022:0664",
                            "RHSA-2022:0663",
                            "RHSA-2022:0332",
                            "RHSA-2022:0331",
                            "RHSA-2022:0330"
                        ],
                        "bugzilla": "2046146",
                        "bugzilla_description": "CVE-2021-44142 samba: Out-of-bounds heap read/write vulnerability in VFS module vfs_fruit allows code execution",
                        "cvss_score": null,
                        "cvss_scoring_vector": null,
                        "CWE": "CWE-787",
                        "affected_packages": [
                            "samba-0:4.11.6-116.el7rhgs",
                            "samba-0:4.14.5-206.el8rhgs",
                            "samba-0:4.11.2-19.el8_2",
                            "samba-0:4.10.16-18.el7_9",
                            "samba-0:4.10.4-103.el8_1",
                            "samba-0:4.8.3-7.el7_6",
                            "samba-0:4.13.3-9.el8_4",
                            "samba-0:4.9.1-12.el7_7",
                            "samba-0:4.14.5-9.el8_5"
                        ],
                        "resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-44142.json",
                        "cvss3_scoring_vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
                        "cvss3_score": "9.9"
                    }
                ]
            

Webex に通知するには

Webex ではBot が用意されており、Bot を作成して特定のルームに参加させると、Bot を通じてメッセージを発信できます。

脆弱性情報取得から通知までを自動化

自動化の流れ

脆弱性情報を取得するスクリプトの他に、Webex のAPI を使ってメッセージを送信するスクリプトも必要になります。

コミュニティベースでのサポートにはなりますが、Webex のAPI を扱えるPython のSDK(WebexPythonSDK) が存在します。

また、Python はJSON の操作を手軽に行えるため、Webex に通知する部分のスクリプトにはPython を用いることにしました。

シェルスクリプトで事項する部分

  1. daysofrisk.pl を使って脆弱性情報を取得
  2. 発見された脆弱性情報の詳細をJSON 形式で取得

Python で実行する部分

  1. 上記JSON ファイルから情報を取得し、Webex に送信するメッセージをMarkdown 形式に整形
  2. 上記メッセージをWebexPythonSDK を使ってWebex に通知

実行基盤としてGitLab CI を使う

上記スクリプト(シェルスクリプトとPython) を定期的に実行する手段は様々ありますが、今回はGitLabCI 機能を使って実現します。

今回のようなケースにおいて、GitLab CI 使うと、以下のようなメリットがあります。

  • 元々SCM としてGitLab を使用しているため、新たな実行基盤を考慮せずに済む
  • 定期的な実行が可能であり、スケジュール毎に環境変数を設定できる
  • GitLab 内で完結するため、容易に再利用できる
    (プロジェクトをフォークし、変数とスケジュールの設定のみで実行可能)

以下の例では、2つの製品を対象に脆弱性情報の取得を行っています。

それぞれ、脆弱性情報を取得する製品のCPE、Severity、Webex の認証情報と通知先のルームID を環境変数として設定しています。

Interval Pattern では、cron 形式で任意スケジュールを指定可能です。

上記例では毎日9時に実行されるよう設定しています。

まとめ

今回は特定製品における脆弱性情報の定期取得とWebex への通知をGitLab CI を使って自動化しました。

自動化実行のために必要なミドルウェアの条件が厳しくない場合、GitLab CI を使って自動化を実現できました。

RedHat 社に限らず、セキュリティーアドバイザリーをスクリプトベースで取得可能なベンダーであれば、同様の自動化が実現可能です。

商標について

  • 記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。

参考文献

  1. CVE とは
    https://www.redhat.com/ja/topics/security/what-is-cve
    https://www.nic.ad.jp/ja/basics/terms/cve.html
  2. RHSA、RHBA、および RHEA アドバイザリーの説明
    https://access.redhat.com/ja/articles/2280941
  3. 製品ごとのセキュリティリスクの調査
    https://rheb.hatenablog.com/entry/list_of_security_fixes_for_product
  4. Red Hat におけるセキュリティー評価について
    https://access.redhat.com/ja/security/updates/classification

※本記事の内容は執筆者個人の見解であり、所属する組織の見解を代表するものではありません。

RECOMMEND