Highcharts Grid: `<path>`要素に対して、生の`setAttribute`を使用して記述されたカスタムアイコン定義オブジェクト。
### 影響
`rendering.icons`の下にカスタムアイコン定義オブジェクトとして提供されるカスタムアイコンは、各子要素に対してSVGパスを作成し、その要素のすべてのキーをパスの属性として設定することで構築されます。この際、属性名のフィルタリングは行われず、オプションの文字列形式のみがマークアップの許可リストを通過します。したがって、Gridの設定を制御できる攻撃者は、子要素のキーとしてイベントハンドラ名を指定し、それらのハンドラがGridをホストするページのオリジンで実行される可能性があります。カスタムアイコンは、組み込みのアイコンよりも優先されるため、攻撃者は、追加の設定なしでレンダリングされるアイコン(例えば、デフォルトで各列ヘッダーに表示されるソートアイコンや、ページネーションが有効になっている場合のページネーションコントロールなど)を置き換えることができ、カスタムアイコンの名前を参照する必要はありません。この脆弱性を悪用するには、信頼できないデータがGridの設定に到達し、ユーザーが影響を受けるアイコンにマウスオーバーまたはアクティブ化する必要があります。
### 対策
Gridの設定が完全に制御できないソースからのものである場合、Gridモジュールをインポートした直後に、以下のコードを貼り付けてください。
```ts
(function () {
const GridNS = typeof Grid !== 'undefined' ? Grid : undefined;
const GridClass = GridNS && GridNS.Grid;
if (!GridClass || !GridClass.prototype.loadUserOptions) {
return; // Gridがロードされていない
}
const allowedPathAttributes = [
'd',
'fill',
'opacity',
'stroke',
'stroke-width',
'stroke-linecap',
'stroke-linejoin',
'transform'
];
const originalLoadUserOptions = GridClass.prototype.loadUserOptions;
function sanitizeIconValue(value) {
if (!value || typeof value === 'string') {
return value;
}
const children = value.children || [];
const sanitizedChildren = [];
```
```
for (let i = 0; i < children.length; i++) {
const child = children[i] || {};
const clean = {};
for (let j = 0; j < allowedPathAttributes.length; j++) {
const attr = allowedPathAttributes[j];
if (child[attr] !== undefined && child[attr] !== null) {
clean[attr] = child[attr];
}
}
sanitizedChildren.push(clean);
}
return {
width: value.width,
height: value.height,
viewBox: value.viewBox,
fill: value.fill,
children: sanitizedChildren
};
}
function sanitizeIconsMap(icons) {
if (!icons) {
return icons;
}
const out = {};
for (const key in icons) {
if (Object.prototype.hasOwnProperty.call(icons, key)) {
out[key] = sanitizeIconValue(icons[key]);
}
}
return out;
}
GridClass.prototype.loadUserOptions = function (newOptions) {
if (
newOptions &&
newOptions.rendering &&
newOptions.rendering.icons
) {
newOptions.rendering.icons = sanitizeIconsMap(
newOptions.rendering.icons
);
}
return originalLoadUserOptions.apply(this, arguments);
};
}());
```
### パッチ版の入手方法
パッチが適用されたバージョンは、通常の配布チャネルから入手できます。npmを使用している場合は、影響を受けるパッケージをパッチ版にアップグレードしてください。例えば、`npm install @highcharts/grid-lite@3.2.0`。Highcharts GridをCDNから読み込んでいる場合は、バージョン番号付きのURLを使用してください。例えば、`https://cdn.jsdelivr.net/npm/@highcharts/grid-lite@3.2.0/grid-lite.js`。各インストール方法の詳細については、[インストールガイド](https://www.highcharts.com/docs/grid/installation)を参照してください。
影響を受けるパッケージ:
- npm (JavaScript) @highcharts/grid-lite: 影響を受けるバージョンは 2.3.0 以降、3.1.0 以下。3.2.0 で修正済み。
- npm (JavaScript) @highcharts/grid-pro: 影響を受けるバージョンは 2.3.0 以降、3.1.0 以下。3.2.0 で修正済み。