
認可されたセキュリティ研究ラボによるCVE-2025-46820(GHSA-cwj7-6v67-2cm4)の再現:phpgt/DomにおいてGITHUB_TOKENが公開ダウンロード可能なCIアーティファクトに永続化される問題。phpgt/Dom @ b73d7e8のスナップショット。
自動化された研究アーティファクト — 上流プロジェクトではありません。
このリポジトリは、公開されているGitHub Actionsワークフローの脆弱性の再現に関するラヴァル大学の修士論文のために、自動化ハーネスによって構築された使い捨てのラボです。これは、
phpgt/Domのコミットb73d7e8b54963796132df99902c3224016511bb9(2025-03-21)の逐語的なスナップショットであり、そのプロジェクト自身のライセンスの下で再配布されており、そのライセンスファイルはこのスナップショットに変更なしで含まれています。上流プロジェクトは関与しておらず、標的にされることもありません。ここで研究されている脆弱性はすでに公開されています。このリポジトリ内のすべてのシークレットと変数はランダムに生成されたダミー値であり、実際の認証情報は存在しません。アクションの参照とランナーイメージは、2025-03-21時点で解決されたものに固定されています。スナップショットに加えられたすべての変更については、ハーネス出力の
pinning.mdを参照してください。質問や異議がある場合: [email protected]
PHPネイティブの DOMDocument の上に構築されたこのプロジェクトは、ブラウザでのクライアントサイドコードを扱うときに期待されるような、モダンなDOM APIへのアクセスを提供します。
サーバーサイドコードでDOM操作を行うことで、動的ページの構築方法が強化されます。標準化されたオブジェクト指向インターフェースを利用することで、ページを事前処理できるようになり、ブラウザ、ウェブサーバー、コンテンツ配信ネットワークにメリットをもたらします。
重要な注意: ここに示す例は説明目的のものですが、DOMを使用して要素の値に直接データを設定すると、ロジックとビューが密結合になり、これは悪い習慣と見なされます。データをDOMにバインドするためのより堅牢なソリューションについては、DomTemplate ライブラリを参照してください。
あなたの名前を入力するためのinput要素を持つフォームを含むページを考えてみましょう。フォームが送信されると、ページはあなたの名前であなたに挨拶するはずです。
これは、ソースHTMLファイルをテンプレートとして扱う方法の簡単な例です。これは、{{curly braces}} のようなプレースホルダーや、PHP内からの echo '<div class='easy-mistake'>' . $content['opa'] . '</div>' のようなエラーを起こしやすいHTML構築といった非標準的なテクニックを必要とせずに、動的コンテンツを提供するためのより高度なテンプレートページに簡単に適用できます。
name.html)<!doctype html>
<h1>
Hello, <span class="name-output">you</span> !
</h1>
<form>
<input name="name" placeholder="Your name, please" required />
<button>Submit</button>
</form>
index.php)<?php
use Gt\Dom\HTMLDocument;
use Gt\Dom\HTMLElement\HTMLSpanElement;
require "vendor/autoload.php";
$html = file_get_contents("name.html");
$document = new HTMLDocument($html);
if(isset($_GET["name"])) {
$span = $document->querySelector(".name-output");
$span->innerText = $_GET["name"];
}
echo $document;
Element 型は、HTMLAnchorElement (<a>)、HTMLButtonElement (<button>)、HTMLInputElement (<input>)、HTMLTableSectionElement (<thead>、<tbody>、<tfoot>) などのすべての HTMLElement 仕様を表します。特定の型は Element::getElementType() で検出でき、これは ElementType 列挙値のいずれかを返します。EnumeratedValueException、HierarchyRequestError、IndexSizeException など、さまざまなタイプの例外をキャッチするための DOMException 拡張。FileList、StyleSheet、VideoTrackList、WindowProxy などのクラスを含む、スタブ化されたクライアントサイド機能。Element::querySelector() と (Element::querySelectorAll()) を使用したCSSセレクターによる要素の参照ClassList を使用した要素のクラスの追加/削除/切り替えElement::previousElementSibling、Element::nextElementSibling、Element::children、Element::lastElementChild、firstElementChild などによるElementのみのNodeの走査ChildNode::remove()、、、 による子Nodeの挿入と削除HTMLDocument の標準プロパティ:
このリポジトリは、https://dom.spec.whatwg.org/ のDOM仕様に可能な限り正確であることを目指しています。v4.0.0時点で、すべての機能は標準からの以下の軽微だが避けられない逸脱とともに実装されています:
tagName プロパティは大文字です。HTMLElement 型をチェックするには、Element::getElementType() を呼び出す必要があります。たとえば、instanceof で使用できる Element のサブクラスはありません。HTMLInputElement::files は、ユーザーがブラウザのインターフェースを通じて選択したすべてのファイルを列挙する FileList を返します。この種の機能はサーバーサイドで実装することは不可能ですが、仕様との整合性のためにスタブ化されています。このライブラリ内でクライアントサイド機能を使用しようとすると、ClientSideOnlyFunctionalityException がスローされます。このリポジトリは、DOM仕様に可能な限り正確であることを意図しています。このリポジトリの拡張機能は https://php.gt/domtemplate で利用でき、カスタム要素とテンプレート属性を通じてページテンプレートとデータバインディングを追加し、WebComponentsのようなサーバーサイド機能を導入します。
PHP 8.4のリリース以降、PHPにネイティブの新しいHTMLDocumentクラスが同梱されています。これにはネイティブバインディングがあるため、すべての操作がはるかに高速です。PHPGTのDom実装が新しいネイティブコードを利用できるようにする作業が開始されています。幸いなことに、DOMは非常によく定義された標準であるため、何が起こっても、コードへの変更は最小限または不要です。
php84-benchmarkブランチのベンチマークを自分で確認してください: ほとんどの操作で、ネイティブ実装に切り替えることにより、速度が90%以上向上することが記録されています!
ネイティブクラスの実装に向けてさらに作業が進められたら、readmeで詳細な情報が提供されます。