Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

パッケージレジストリのセキュリティ

最終更新 Markdown で表示Agent セットアップ

Gateway は、7 つの主要なパッケージエコシステムでソフトウェアパッケージのダウンロードを検出し、サプライチェーンのトラフィックをポリシーで制御できます。開発者または CI/CD パイプラインが Gateway 経由でパッケージをダウンロードすると、プロキシはリクエスト URL からレジストリプロトコルを識別し、パッケージのエコシステム、名前、バージョン、名前空間を抽出します。その後、pkg.* セレクターを使った HTTP ポリシーを書き、エコシステム全体のブロックから単一パッケージバージョンの制限まで、必要な粒度でパッケージダウンロードを許可またはブロックできます。

仕組み

パッケージ検出は、HTTP リクエストの URL 構造だけを使います。Gateway が認識するのは、トラフィックを配信しているホスト名ではなく、対応する各レジストリプロトコルの API 契約です。そのため、公式のパブリックレジストリ、セルフホストのミラー、Artifactory や Nexus などの社内プロキシレジストリ、その他の互換エンドポイントのいずれへ向かうトラフィックでも、検出の動作は同じです。URL パスが既知のレジストリダウンロードの形に一致すれば、Gateway はそれを分類します。

検出はフェイルオープンです。URL をパッケージダウンロードとして分類できない場合、リクエストは通常の非パッケージトラフィックとしてそのまま進みます。分類の失敗が、パッケージインストールをブロックしたり壊したりすることはありません。

対応エコシステム

Gateway は、次のエコシステムのパッケージダウンロードを検出します。

Ecosystem Example artifact pattern Namespace
npm /{package}/-/{package}-{version}.tgz スコープ(例: @babel
PyPI /packages/{hash}/{hash}/{hash}/{package}-{version}.whl
RubyGems /gems/{package}-{version}.gem
Cargo /crates/{package}/{package}-{version}.crate
Go /{module}/@v/{version}.zip モジュールパス
Maven /maven2/{group}/{artifact}/{version}/{artifact}-{version}.jar Group ID
NuGet /{package}/{version}/{package}.{version}.nupkg

検出する操作

最初のリリースでは、download 操作だけを検出します。download は、対応するすべてのレジストリで、パッケージ名、バージョン、エコシステムを URL パスから導ける唯一の操作です。resolve(メタデータの参照)や publish など、ほかの操作は、URL パス以外の追加シグナルが必要な、別のエンドポイント、ホスト、HTTP メソッドを使います。

セレクター

次のセレクターは、Allow および Block アクションの HTTP ポリシー で使えます。

Selector UI name API example Description
pkg.ecosystem Package Ecosystem pkg.ecosystem == "npm" リクエスト URL から検出したパッケージエコシステムです。
pkg.name Package Name pkg.name == "lodash" ダウンロード URL から抽出したパッケージ名です。
pkg.version Package Version pkg.version == "4.17.21" ダウンロード URL から抽出したパッケージバージョンです。完全一致と、エコシステム固有の比較演算子に対応します。
pkg.namespace Package Namespace pkg.namespace == "@babel" パッケージの名前空間です。エコシステムが名前空間に対応している場合に使えます。npm ではスコープ、Maven では Group ID、Go ではモジュールパスです。
pkg.purl Package URL pkg.purl == "pkg:npm/[email protected]" 検出した座標から導いた Package URL(PURL) です。API でのみ利用できます。

ダッシュボードで式を組み立てる

ダッシュボードでは、Package Ecosystem が主要なセレクターです。これを選ぶと、パッケージ名、バージョン、名前空間を指定する入れ子フィールドが表示されます。次のルールが適用されます。

  • ほかのパッケージフィールドを使う前に、エコシステムを選ぶ必要があります。
  • 入れ子フィールドを有効にするには、エコシステムをちょうど 1 つ選ぶ必要があります。in または not in 演算子で複数のエコシステムに一致させると、入れ子のパッケージ名、バージョン、名前空間フィールドは無効になります。
  • バージョン制約を追加する前に、パッケージ名を追加する必要があります。
  • 名前空間フィールドは、名前空間に対応しているエコシステムだけで使えます。ラベルは選んだエコシステムに応じて変わります。npm では Scope、Maven では Group ID、Go では Module namespace です。
  • pkg.purl(Package URL)セレクターはダッシュボードでは使えません。PURL で一致させる式は API で書いてください。

API を直接使う場合、これらの制約なしに、wirefilter 式でセレクターを自由に組み合わせられます。

バージョン比較演算子

pkg.version セレクターは、完全な文字列一致に加えて、エコシステム固有の比較演算子に対応しています。各エコシステムは、それぞれのネイティブなバージョニング意味論を使います。

Ecosystem Versioning standard
npm SemVer
Cargo SemVer
PyPI PEP 440
RubyGems Gem::Version
Go Go module versions
Maven Maven version ordering
NuGet NuGet normalization and ordering

次の比較演算子に対応しています。

Operator API syntax Description
equals == エコシステム固有の同一性ルールを使った正規化後の等価比較です。
not equals != 正規化後の等価比較の否定です。
greater than > ネイティブな順序で、指定した値より大きいバージョンです。
greater than or equal >= 指定した値以上のバージョンです。
less than < ネイティブな順序で、指定した値より小さいバージョンです。
less than or equal <= 指定した値以下のバージョンです。

バージョン文字列をエコシステムのバージョニングルールで解析できない場合、または検出したエコシステムが比較のコンテキストと一致しない場合、比較は不一致になります。これには != も含まれます。解析できないバージョンは、何にも一致しません。

ポリシーの例

特定のエコシステムからのダウンロードをすべてブロックする

組織全体で PyPI パッケージのダウンロードをブロックするには:

Selector Operator Value Action
Package Ecosystem is pypi Block

wirefilter 式:

pkg.ecosystem == "pypi"

特定のパッケージをブロックする

バージョンに関係なく、既知の悪意のある、または不要な npm パッケージをブロックするには:

Selector Operator Value Logic Action
Package Ecosystem is npm And Block
Package Name is event-stream

wirefilter 式:

pkg.ecosystem == "npm" and pkg.name == "event-stream"

パッケージの脆弱なバージョンをブロックする

CVE-2021-23337 を修正したバージョンである 4.17.21 より前の lodash をすべてブロックするには:

Selector Operator Value Logic Action
Package Ecosystem is npm And Block
Package Name is lodash And
Package Version less than 4.17.21

wirefilter 式:

pkg.ecosystem == "npm" and pkg.name == "lodash" and pkg.version < "4.17.21"

承認したレジストリミラーにパッケージを制限する

社内の Artifactory インスタンス経由の npm パッケージダウンロードだけを許可し、ほかの npm ダウンロードをすべてブロックするには、2 つのポリシーを作成します。

ポリシー 1 - 承認したミラーを許可する(優先度を高くする):

Selector Operator Value Logic Action
Package Ecosystem is npm And Allow
Host is npm.internal.example.com

wirefilter 式:

pkg.ecosystem == "npm" and http.request.host == "npm.internal.example.com"

ポリシー 2 - その他の npm ダウンロードをすべてブロックする(優先度を低くする):

Selector Operator Value Action
Package Ecosystem is npm Block

wirefilter 式:

pkg.ecosystem == "npm"

検出はホスト名ではなくレジストリプロトコルに基づくため、パブリックの registry.npmjs.org と社内ミラーの npm.internal.example.com の両方が npm トラフィックとして検出されます。ポリシー 1(優先度が高い)が承認したミラーを許可し、ポリシー 2 がその他をすべてブロックします。

承認したホスト以外からの特定パッケージをブロックする

社内レジストリ経由でのみ機密の内部パッケージのダウンロードを許可し、ほかのすべてのソースからはブロックするには:

ポリシー 1 - 承認したホストからのダウンロードを許可する(優先度を高くする):

Selector Operator Value Logic Action
Package Ecosystem is npm And Allow
Package Namespace is @acme And
Package Name is internal-sdk And
Host is npm.internal.example.com

wirefilter 式:

pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk" and http.request.host == "npm.internal.example.com"

ポリシー 2 - その他のホストからのダウンロードをブロックする(優先度を低くする):

Selector Operator Value Logic Action
Package Ecosystem is npm And Block
Package Namespace is @acme And
Package Name is internal-sdk

wirefilter 式:

pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk"

検出とミラー

パッケージ検出は、各レジストリのダウンロード API の URL パス構造に基づいてトラフィックを分類します。既知のレジストリホスト名のリストとの照合には依存しません。この設計により、互換性のある URL レイアウトでパッケージを配信するサーバーは、次のいずれであっても同じように検出されます。

  • 公式のパブリックレジストリ(例: registry.npmjs.org または pypi.org
  • JFrog Artifactory、Sonatype Nexus、AWS CodeArtifact などの社内プロキシレジストリ
  • セルフホストのミラー
  • CDN の前段にあるレジストリエンドポイント

特定のレジストリホストを区別する必要があるポリシーでは、これまでどおり http.request.host セレクターを使えます。pkg.* セレクターと http.request.host を組み合わせると、パッケージの取得元に応じて異なるアクションを取るルールを書けます。

ログ

Gateway がパッケージダウンロードを検出すると、パッケージのメタデータが Gateway HTTP ログに含まれます。このデータは Gateway アクティビティログLogpush で利用できます。

Activity Log のフィールド

Gateway Activity Log では、次のパッケージフィールドを利用できます。

Field Description
Package Ecosystem 検出したレジストリの種類です(例: npmpypicargo)。
Package URL (PURL) 検出した座標から導いた Package URL 文字列です(例: pkg:npm/[email protected])。

Logpush のフィールド

パッケージのメタデータは、gateway_http Logpush データセットの PackageInfo オブジェクトで利用できます。

Field Type Description
PackageInfo.Ecosystem string 検出したパッケージエコシステムです。
PackageInfo.Namespace string パッケージの名前空間です。該当する場合のみです。
PackageInfo.Name string パッケージ名です。
PackageInfo.Version string パッケージのバージョン文字列です。
PackageInfo.Purl string Package URL 文字列です。

制限事項

  • パッケージ検出には TLS 復号 をオンにする必要があります。Do Not Inspect ポリシーや 検査制限の一覧 のアプリケーションにより TLS 検査をバイパスする接続でダウンロードされたパッケージは検出されません。
  • 一部の言語ランタイムと HTTP クライアントは、オペレーティングシステムとは別の証明書トラストストアを持っています。検査に使う証明書(Cloudflare 管理証明書など)が OS のトラストストアにだけインストールされている場合、これらのクライアントからのパッケージダウンロードは証明書検証エラーで失敗することがあります。Python、Node.js、Ruby、Rust、Java、Go を含む、アプリケーション固有のトラストストアへの証明書追加手順は、証明書を手動でインストールする を参照してください。
  • 検出されるのは download 操作だけです。メタデータの参照(resolve)、パッケージの公開、その他のレジストリ操作は分類されません。
  • バージョン比較は、各エコシステムのネイティブな順序ルールを使います。エコシステムをまたぐバージョン比較には対応していません。
  • エコシステム固有の範囲構文(npm の ^1.2.3、PyPI の ~=1.4、Maven の区間記法など)には対応していません。代わりに個別の比較演算子(><>=<=)を使ってください。

役に立ちましたか?