flawopen.com/Teardowns/cve-2026-63277-libreoffice-calc-jdbc-classpath-rce
CVE-2026-63277:Calc文書を開いた際のJava実行
細工されたCalc文書は外部データマッピングを利用し、利用者が表計算を開いた際に、LibreOfficeがローカル以外のJava class pathからJDBCドライバーのクラスを解決する可能性がありました。LibreOffice 26.2.5と26.8.0では、この項目にfileスキームのみを許可します。文書を開く操作が必要であり、ゼロクリックのネットワーク脆弱性ではありません。[1], [2], [3]
表計算には、データベースドライバーをどこから探すかというメモを保存できます。修正前は、そのメモがリモートアドレスを指す場合があり、ファイルを開いたときにそこからJavaコードが読み込まれる可能性がありました。修正後はfile:スキームのアドレスだけを受け入れます。経路は限定されますが、このラベルだけで各対象が物理的にローカルにあるとは証明できません。[1], [4], [5]
主要な概念と専門用語
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-829
根本原因の分析 (Root Cause)
脆弱な jvmaccess::ClassPath::translateToUrls 経路は、各Java class path項目を展開し、スキームを先に制限せずJava URLコンストラクターへ渡していました。26.2.5.2のソースではURI解析を追加し、Java URLを作る前にスキームがfile以外の項目を拒否します。ベンダー勧告は、この経路をCalcの外部データマッピングとJDBCドライバーの読み込みに結び付けています。細工された文書を人が開く必要があります。引用した資料はゼロクリックでの到達性や実環境での悪用を示していません。チェック対象はスキームです。一般的な認可方針と説明したり、すべてのリモート共有を拒否すると主張したりしないでください。[1], [4], [5]
CVE-2026-63277:CalcからJava読み込みに至る条件
ステップ・バイ・ステップの攻撃フロー
Java class pathをURLへ変換する
修正前はtranslateToUrlsが展開済みの項目をJava URLコンストラクターに渡し、スキームがローカルファイルか確認していませんでした。[4]
ソースコード比較:脆弱 vs 堅牢化
これらの抜粋は、バージョンを固定したupstreamのtranslateToUrls実装から採っています。26.2.4.2は項目を展開した後、そのままJava URLを作成します。26.2.5.2ではURI解析を追加し、URL作成前にfile以外のスキームを拒否します。差分はスキーム検証を示し、ベンダー勧告はCalc/JDBC文書経路を裏付けます。これはソース分析であり、実行可能な概念実証ではありません。[4], [5], [1]
ソース抜粋: jvmaccess/source/classpath.cxx — translateToUrls関数
// LibreOffice 26.2.4.2 — jvmaccess/source/classpath.cxx(脆弱なバージョン)
if (!url.isEmpty()) {
css::uno::Reference< css::uri::XVndSunStarExpandUrlReference >
expUrl(
css::uri::UriReferenceFactory::create(context)->parse(url),
css::uno::UNO_QUERY);
if (expUrl.is()) {
css::uno::Reference< css::util::XMacroExpander > expander =
css::util::theMacroExpander::get(context);
try {
url = expUrl->expand( expander );
} catch (const css::lang::IllegalArgumentException & e) {
css::uno::Any anyEx = cppu::getCaughtException();
throw css::lang::WrappedTargetRuntimeException(
"com.sun.star.lang.IllegalArgumentException: "
+ e.Message,
nullptr, anyEx );
}
}
jvalue arg;
arg.l = environment->NewString(
reinterpret_cast< jchar const * >(url.getStr()),
static_cast< jsize >(url.getLength()));
if (arg.l == nullptr) {
return nullptr;
}
jobject o(environment->NewObjectA(classUrl, ctorUrl, &arg));
if (o == nullptr) {
return nullptr;
}
urls.push_back(o);
}
// LibreOffice 26.2.5.2 — jvmaccess/source/classpath.cxx(修正済みバージョン)
if (!url.isEmpty()) {
css::uno::Reference< css::uri::XVndSunStarExpandUrlReference >
expUrl(
css::uri::UriReferenceFactory::create(context)->parse(url),
css::uno::UNO_QUERY);
if (expUrl.is()) {
css::uno::Reference< css::util::XMacroExpander > expander =
css::util::theMacroExpander::get(context);
try {
url = expUrl->expand( expander );
} catch (const css::lang::IllegalArgumentException & e) {
css::uno::Any anyEx = cppu::getCaughtException();
throw css::lang::WrappedTargetRuntimeException(
"com.sun.star.lang.IllegalArgumentException: "
+ e.Message,
nullptr, anyEx );
}
}
css::uno::Reference< css::uri::XUriReference > uriRef(
css::uri::UriReferenceFactory::create(context)->parse(url));
if (!uriRef.is() || !uriRef->getScheme().equalsIgnoreAsciiCase("file"))
{
throw css::lang::IllegalArgumentException(
"non-local Java class path entry: " + url,
css::uno::Reference< css::uno::XInterface >(), 0);
}
jvalue arg;
arg.l = environment->NewString(
reinterpret_cast< jchar const * >(url.getStr()),
static_cast< jsize >(url.getLength()));
if (arg.l == nullptr) {
return nullptr;
}
jobject o(environment->NewObjectA(classUrl, ctorUrl, &arg));
if (o == nullptr) {
return nullptr;
}
urls.push_back(o);
}
エンジニアリング&システム堅牢化チェックリスト
- ✓26.2系列ではLibreOffice 26.2.5以降、26.8系列では26.8.0以降へ更新し、ディストリビューションの実パッケージとバックポートを確認します。[1], [2]
- ✓信頼できない送信元のCalc文書を開く業務と、JDBCドライバーに依存する外部データマッピングを洗い出します。
- ✓Java URL作成前に
file以外のclass pathスキームを拒否し、対応するローカルファイル項目は引き続き使えることを確認する回帰テストを追加します。[5] - ✓マクロ警告をこのJava class path経路の防御と見なさず、文書を開く運用とJava設定を別々に評価します。[1]
- ✓Apache の勧告によると、LibreOffice は同じ問題を
CVE-2026-63277として報告し、Apache OpenOffice はCVE-2026-59265として追跡しています。AOO 固有の影響版・修正版と緩和策を確認し、LibreOffice のバージョン情報を流用しないでください。[8], [1] - ✓テストで流通している文書やリモート Java ペイロードを再現しないでください。scheme 検証を確認する、制御された非実行のアサーションを使用してください。[1]