C/C++ ライブラリ構成識別#
概要#
脆弱性を継続的に管理するには、利用中のソフトウェアとバージョンを正確に把握する構成管理が欠かせません。 しかし、C/C++ プロジェクトではパッケージマネージャーを使わずに依存ライブラリのソースコードを直接プロジェクトへ取り込むケースが多くあります。 標準的な手法だけでは、構成管理や脆弱性特定が困難でした。

こうした状況を踏まえ、FutureVuls では C/C++ ライブラリ構成識別機能を提供しています。 本機能は、取り込んだ C/C++ ライブラリのソースコードからハッシュ値を生成し、FutureVuls 上でリポジトリやバージョンを自動同定・管理できるようにします。 具体的には、製品によく同梱される zlib、libxml2、expat などの主要ライブラリに幅広く対応しています。

【コラム】C/C++ ライブラリの構成管理が複雑になる背景
C/C++ ライブラリの構成管理が複雑になる背景は、FutureVuls Blog の記事「C/C++のライブラリ構成管理はなぜ難しいのか。同梱ライブラリのバージョンをソースから同定する」で解説しています。
対応環境#
バイナリは静的リンク済みで、追加の依存関係はありません。
| OS / architecture |
|---|
linux/amd64 |
linux/arm64 |
windows/amd64 |
同定対象#
本機能で解析・同定できるファイル形式、対応ライブラリ、および送信データの仕様は以下のとおりです。
対象ファイル#
指定したディレクトリ内に含まれる、以下の拡張子を持つファイルが対象です。
.c,.cc,.cpp,.h,.hh,.hpp(小文字の拡張子のみ。.Cや.Hは対象外です)
サブディレクトリも対象です。ただし、名前が . で始まるディレクトリ(.git など)とシンボリックリンクは対象外です。
改行コードが CRLF のファイルは同定できません
ファイルの内容は、改行コードを変換せずにそのままハッシュ化します。
照合先のハッシュは改行コードが LF のソースから作られているため、CRLF に変換されたファイルは一致しません。
Windows で Git の core.autocrlf を有効にして取得したソースなど、改行コードが CRLF のファイルを含む場合は、futurevuls-cpp-fingerprint が警告を表示します。
改行コードが LF のままのソースを指定してください。
対応ライブラリ#
現在は Google/OSS-Fuzz で管理されている C/C++ オープンソースプロジェクトを対象としています(プロジェクト一覧)。 FutureVuls が、受け取ったハッシュ値を外部サービスの OSV(Open Source Vulnerabilities)に問い合わせることで、リポジトリとバージョンを同定します。
送信されるデータ#
- FutureVuls に送信されるデータ: 指定したディレクトリの末尾名(コンポーネント名として利用)、および各ファイルの MD5 ハッシュ値
- 送信されないデータ: ソースコードの本文、ファイル名、絶対・相対パス情報
FutureVuls から OSV へは、ハッシュ値のみを問い合わせます。
利用手順例#
本機能は、主に以下の流れで利用します。
- 構成識別データの生成:専用コマンド
futurevuls-cpp-fingerprintを実行し、ソースコードの構成情報(ハッシュ値)を記録したfuturevuls-cpp-library.jsonを生成する - FutureVuls への送信:生成された JSON ファイルをローカルまたは CI/CD パイプラインなどから FutureVuls API へ送信する
- 自動同定:FutureVuls がハッシュ値を照合してライブラリのリポジトリとバージョンを特定する
- 同定結果の確認:同定結果をコンソール画面または FutureVuls API から確認する
送信は、初回は Lockファイル追加 API(POST /v1/lockfile)、登録済みの futurevuls-cpp-library.json を更新する場合は Lockファイル更新 API(PUT /v1/lockfile/{lockfileID})を使用します。
lockfileID は「lockfileIDの取得方法」で確認できます。
以下の利用例では、初回の送信(POST)を紹介します。
事前準備#
グループ設定で「CPE 自動割当」を有効にしてください。 同定したライブラリには、スキャン時に CPE 自動割当で CPE が割り当てられます。 無効の場合は CPE が割り当てられず、脆弱性を検知できません。 詳しくは「CPEの自動割当」を参照してください。
API 送信には、API 権限に「更新」を含むグループトークンを発行してください。
このトークンを FVULS_TOKEN に指定します。
SERVER_ID:serverIDの取得方法FVULS_TOKEN:FutureVuls APIのトークン管理FVULS_SERVER_UUID:UUIDの取得方法(CI/CD 環境への組み込み の場合のみ)
以下の例では、取得スクリプトのダウンロードや構成識別データの生成に失敗した場合は処理を中止し、古い JSON ファイルを送信しないようにしています。
Linux#
set -euo pipefail
# 取得スクリプトで、指定したディレクトリのソースをハッシュ化し、futurevuls-cpp-library.json を生成する
curl -fsSL -o futurevuls-cpp-fingerprint.sh https://installer.vuls.biz/futurevuls-cpp-fingerprint.sh
bash futurevuls-cpp-fingerprint.sh <library-directories> # 同定対象のライブラリのディレクトリを 1 つ以上指定する
# 例: bash futurevuls-cpp-fingerprint.sh third_party/*/
# 例: bash futurevuls-cpp-fingerprint.sh third_party/zlib third_party/libxml2
# 生成したファイルを Base64 化してリクエストボディを作り、POST
# (ファイルが大きいとコマンドの引数に収まらないため、ボディはファイルに書き出して送る)
SERVER_ID=<server-id> # 事前準備した SERVER_ID を指定する
FVULS_TOKEN=<api-token> # 事前準備した FVULS_TOKEN を指定する
{
printf '{"serverID":%s,"path":"futurevuls-cpp-library.json","fileContent":"' "${SERVER_ID}"
base64 -w 0 futurevuls-cpp-library.json
printf '"}'
} > futurevuls-cpp-request.json
curl -fsS -X POST 'https://rest.vuls.biz/v1/lockfile' \
-H 'Content-Type: application/json' \
-H "Authorization: ${FVULS_TOKEN}" \
--data-binary @futurevuls-cpp-request.json
Windows#
$ErrorActionPreference = "Stop"
# 取得スクリプトを保存
curl.exe -fsS -o futurevuls-cpp-fingerprint.bat https://installer.vuls.biz/futurevuls-cpp-fingerprint.bat
if ($LASTEXITCODE -ne 0) { throw "futurevuls-cpp-fingerprint download failed: $LASTEXITCODE" }
# futurevuls-cpp-library.json を生成
cmd /c ".\futurevuls-cpp-fingerprint.bat <library-directories>" # 同定対象のライブラリのディレクトリを 1 つ以上指定する
# 例: cmd /c ".\futurevuls-cpp-fingerprint.bat third_party\zlib third_party\libxml2"
# 例: third_party 配下の各ディレクトリを指定する場合(パスに空白を含まないこと)
# $dirs = (Get-ChildItem -Directory third_party).FullName
# cmd /c ".\futurevuls-cpp-fingerprint.bat $dirs"
if ($LASTEXITCODE -ne 0) { throw "futurevuls-cpp-fingerprint failed: $LASTEXITCODE" }
# 生成したファイルを Base64 化して POST
$fileContent = [Convert]::ToBase64String([IO.File]::ReadAllBytes((Resolve-Path .\futurevuls-cpp-library.json).ProviderPath))
$serverID = <server-id> # 事前準備した SERVER_ID を指定する
$fvulsToken = "<api-token>" # 事前準備した FVULS_TOKEN を指定する
$body = @{ serverID = $serverID; path = "futurevuls-cpp-library.json"; fileContent = $fileContent } | ConvertTo-Json -Compress
Invoke-RestMethod -Method Post -Uri "https://rest.vuls.biz/v1/lockfile" -Headers @{ Authorization = $fvulsToken } -ContentType "application/json" -Body $body
プロキシ環境の場合
取得スクリプトとバイナリのダウンロードには、プロキシの設定が必要です。
Linux は「プロキシ設定」を参考に環境変数 https_proxy を設定してください。
Windows は環境変数 VULS_PROXY にプロキシサーバの URL を設定し、curl.exe には --proxy を指定してください。
CI/CD 環境への組み込み#
GitHub Actions では、構成識別データを生成した後に futurevuls/fvuls-lockfile-uploader でアップロードします。
path には futurevuls-cpp-library.json を指定してください。
name: Upload C/C++ library identification data
on:
push:
branches:
- <branch-name> # リリース対象のブランチ名を指定する
paths:
- "<library-directory>/**" # 同定対象のライブラリ配置ディレクトリを指定する
permissions:
contents: read
jobs:
upload-cpp-library:
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Generate C/C++ library identification data
shell: bash
run: |
set -euo pipefail
curl -fsSL -o futurevuls-cpp-fingerprint.sh https://installer.vuls.biz/futurevuls-cpp-fingerprint.sh
bash futurevuls-cpp-fingerprint.sh <library-directories> # 同定対象のライブラリのディレクトリを 1 つ以上指定する
# 例: bash futurevuls-cpp-fingerprint.sh third_party/*/
# 例: bash futurevuls-cpp-fingerprint.sh third_party/zlib third_party/libxml2
- name: Upload C/C++ library identification data
uses: futurevuls/fvuls-lockfile-uploader@9245e71ad5a5833acf0196650027fc4a6be78921 # v2
env:
# GitHub Repository Secret を設定する
FVULS_SERVER_UUID: ${{ secrets.FVULS_SERVER_UUID }}
FVULS_TOKEN: ${{ secrets.FVULS_TOKEN }}
with:
repoName: ${{ github.repository }}
path: "./futurevuls-cpp-library.json"
結果の確認#
同定結果は、アプリケーション詳細ページ および FutureVuls API GET /v1/lockfile/{lockfileID} から確認できます。
構成識別できない場合についても同ページ、API からエラーメッセージを確認できます。

制限事項#
ファイルの上限#
1 ファイルには最大 50 コンポーネントを含められます。
1 コンポーネントには最大 5,000 個のハッシュを含められます。
上限を超えたファイルは、FutureVuls がファイル全体を拒否します。
なお、futurevuls-cpp-fingerprint コマンドは上限超過時に警告を表示しますが、JSON 自体は出力します。
同定結果と再試行#
FutureVuls はコンポーネント単位で構成識別を行います。 一致するリポジトリがない場合、候補リポジトリが複数残る場合、またはバージョンを特定できない場合は、該当するコンポーネントを登録しません。
また、OSV への照会が 1 件でも失敗した場合、同定できた他のコンポーネントも含めて登録しません。 ネットワークエラー等で OSV に接続できなかった場合は、再アップロードにより再試行が可能です。
CPE が採番されていないライブラリの扱い#
本機能によってリポジトリおよびバージョンが正しく同定された場合であっても、対象のソフトウェアに対して NVD などで公式の CPE が採番されていない場合は、FutureVuls 上で CPE としての登録および CPE に基づく脆弱性の紐付けは行われません。