ヒープバッファオーバーフロー

「ヒープバッファオーバーフロー」は、コンピュータのセキュリティとプログラミングの文脈で用いられる概念で、プログラムが動的に割り当てられたメモリ(ヒープと呼ばれるエリア)を超えてデータを書き込むことによって発生する脆弱性や不具合を指します。

具体的には、以下のような特徴があります。

  1. ヒープ領域とは: ヒープは、動的にメモリを割り当てたり解放したりするための領域で、スタックとは異なり、メモリの確保や解放のタイミングが不定であることが特徴です。
  2. オーバーフローの原因: プログラムが、ヒープ領域のバッファの容量を超えてデータを書き込もうとした場合、他のメモリ領域にも影響を及ぼす可能性があります。これが「オーバーフロー」と呼ばれる現象です。
  3. セキュリティへの影響: 攻撃者がこの脆弱性を悪用すると、任意のコードの実行やシステムの不正な動作を引き起こす可能性があります。
  4. 防御策: ヒープバッファオーバーフローを防ぐためには、メモリへの書き込み時の境界チェックを正しく行う、セキュアなプログラミング手法を使用する、または特定のセキュリティ機能(例えば、アドレス空間配置のランダム化 (ASLR))を活用するなどの方法が考えられます。

このようなバッファオーバーフローの問題は、プログラミングにおける注意深い設計と実装によって回避できます。

もっと簡単に…

あなたが小さなバケツ(ヒープバッファ)を持っていて、そこに水(データ)を注いでいるとしましょう。このバケツには限られた容量があります。しかし、注ぐ水の量を間違えて、バケツの容量を超えてしまったら、水はバケツの外に溢れますよね。

この「水が溢れる」現象が、コンピュータの世界での「ヒープバッファオーバーフロー」です。コンピュータでは、データが「バケツ」から溢れると、他の大切な情報が書き換えられてしまったり、予期しない動きをすることがあります。

さらに、悪意のある人々はこの「溢れ」を利用して、コンピュータを攻撃することができます。したがって、プログラムを作る際には、「バケツ」の容量を超えて「水」(データ)を注がないように気をつける必要があります。

それが、ヒープバッファオーバーフローの簡単な説明です。

サードパーティとは

「サードパーティ」とは、第三者という意味で、主に2つの主要な関係者以外の第三の関係者を指します。テクノロジーの文脈で使われる場合、特定の製品やサービスの主要な提供者や製造者とは異なる外部の企業や個人を指すことが多いです。

例えば、コンピューターのオペレーティングシステム(OS)を考えてみましょう。あるOSの製造元が「第一者」、OSを使用するユーザーが「第二者」となります。そして、そのOS向けにアプリやソフトウェアを開発している外部の企業や個人は「サードパーティ」となります。

もう少し具体的に分かりやすく例えると、あなたが主催するパーティーにおいて、あなた自身が「第一者」、あなたの友人や家族が「第二者」で、パーティーに招待された他の人たちや外部の業者(たとえば、ケータリング業者やエンターテイメントの業者)は「サードパーティ」となる、と考えることができます。

このように、「サードパーティ」という言葉は、主要な関係者以外の人や組織を指す時に使われることが多いです。

ゼロデイ脆弱(Zero-Day Vulnerability)

公に知られていない、または未修正のセキュリティ脆弱性を指します。この種の脆弱性は、開発者やベンダーがその存在を知った「ゼロの日」から修正されるまでの期間中、攻撃者に悪用される可能性があります。

ゼロデイ脆弱性は特に危険です。なぜなら、修正パッチが存在しないため、システムやアプリケーションは攻撃に対して無防備な状態にあるからです。これを悪用したゼロデイ攻撃は、防御策が整う前に発生することが多いため、被害が拡大する可能性が高いです。

通常、ゼロデイ脆弱性が発見されると、関係するソフトウェアやハードウェアのベンダーはできるだけ早くセキュリティパッチをリリースしてこの問題を解決します。ただし、そのパッチが開発され、テストされ、配布されるまでの間には時間がかかる場合があり、その間に攻撃が行われる可能性があります。

このような脆弱性を最小限に抑えるための一般的な対策には、ソフトウェアを常に最新に保つ、信頼されていないソースからのファイルやリンクを開かない、セキュリティソフトウェアを使用する、などがあります。特定のゼロデイ脆弱性に対応するためには、ベンダーからの公式な指示やアップデートに従うことが最も確実です。

「ゼロデイ脆弱性」のシナリオ

  1. 開発者すら気づいていない脆弱性: このケースでは、開発者やベンダーは脆弱性の存在をまだ知らない状態です。その脆弱性が攻撃者によって発見(または購入)され、悪用されると、それが「ゼロデイ攻撃」となります。この攻撃が公になった瞬間、開発者やベンダーは「ゼロの日」(発覚日)を迎え、問題の修正に取り組むことになります。
  2. 開発者は存在を知ったがまだ修正されていない脆弱性: このケースでは、開発者やベンダーは脆弱性の存在を知っているが、まだパッチ(修正プログラム)をリリースしていない状態です。この期間中に攻撃者がその脆弱性を悪用すると、それも「ゼロデイ攻撃」と呼ばれる場合があります。

「ゼロデイ」の名前は、攻撃が行われるまでの間、開発者が修正措置を講じる時間が「ゼロ日」であるという事象に由来しています。つまり、脆弱性が公に知られた瞬間から修正が行われるまでの期間が非常に短い、またはまったくない状態を指します。

どちらのケースも、修正が適用される前の脆弱性を悪用した攻撃が非常に危険であるという点で共通しています。これは防御策が限られているため、攻撃者による被害が大きくなる可能性が高いからです。

ゼロデイ脆弱性(Zero-Day Vulnerability)は、その存在が公に知られた瞬間(または攻撃者によって悪用された瞬間)から修正措置(パッチ)が適用されるまでの期間に存在する脆弱性です。この期間中、システムは「無防備な」状態とされ、攻撃者によって悪用される可能性が高まります。

ゼロデイ脆弱性は、開発者やベンダーがその存在に気づいていない場合もあれば、気づいてはいるがまだ修正されていない場合もあります。どちらにしても、この脆弱性が存在する間はシステムが攻撃に対して非常に脆弱であると言えます。

したがって、ゼロデイ脆弱性は「まだ何も対策されていない無防備な脆弱性」と言えるでしょう。これが悪用された場合には「ゼロデイ攻撃」と呼ばれます。

JavaScriptのdeferとasync属性

JavaScriptファイルやスクリプトにdeferasync属性を使用することで、ページのレンダリングをブロックすることなく非同期にスクリプトを読み込むことができます。

  • defer: スクリプトの読み込みと実行をページの解析(パース)が完了してからにします。
  • async: スクリプトを非同期に読み込みますが、読み込みが終わり次第すぐに実行します。
<!-- defer属性を使った場合 -->
<script src="example.js" defer></script>

<!-- async属性を使った場合 -->
<script src="example.js" async></script>

また、JavaScriptで「スクロール位置」や「ユーザーのインタラクション」に応じて動的にコンテンツ(例えば、画像やその他の要素)を読み込むような処理を書くこともあります。このようなケースでは、確かに「必要なときだけ読み込む」という原則が適用できます。

ただし、JavaScriptに関しては最適化が少し複雑で、何をいつ読み込むかは具体的なケースによって異なるため、一概に「これを設定した方がいい」とは言い切れません。パフォーマンス改善には多くの要素が影響するため、具体的な状況に応じて適切な最適化を行う必要があります。

deferasyncの違い

  • async: スクリプトはページのレンダリングとは独立して非同期でダウンロードされます。ダウンロードが完了したら、ページのレンダリングを中断してスクリプトが即座に実行されます。
  • defer: スクリプトはページのレンダリングとは独立して非同期でダウンロードされますが、実行はページの解析が完了した後に行われます。複数のdeferスクリプトがある場合、それらは指定された順序で実行されます。

いつどれを使うべきか?

  1. ページ上で即座に実行する必要があるスクリプト: これにはasyncdeferは一般的には不適です。このようなスクリプトは、<head>タグ内か<body>の最上部に置かれることが多いです。
  2. 依存関係のないスクリプト: これはページのレンダリングとは独立して実行できるスクリプトです。このような場合、asyncが適しています。
  3. 依存関係のあるスクリプトまたは順序が重要なスクリプト: これは他のスクリプトやページの解析が完了するまで待つ必要があるスクリプトです。このような場合、deferが適しています。
  4. ユーザーのインタラクションに基づくスクリプト: たとえば、ボタンクリックで何かが起こるようなスクリプトは、deferを使ってページの解析後に読み込むようにすることが多いです。

それぞれのスクリプトやその用途によって、最適な選択が異なります。一概に「これを設定すれば良い」とは言い切れないのが、ウェブパフォーマンスの複雑なところです。最適な設定は、ページの内容、ユーザーの行動、その他の技術的な要因によって異なる可能性があります。ですから、具体的なケースに応じて適切な設定を選ぶ必要があります。

もう少し簡単に。

  • async: この設定がされたスクリプトは、「ダウンロードが終わったらすぐに動かしても大丈夫だよ」という意味になります。ページがまだ読み込み途中でも、このスクリプトはすぐに動き始めます。
  • defer: この設定がされたスクリプトは、「ページ全体の読み込みが終わってから動かしてね」という意味になります。このスクリプトは、ページのすべてが読み込まれてから動き始めます。

使いどきの例

  • 「今すぐ動かせ!」(async: 例えば、広告を表示するスクリプトなど、すぐに動かして問題ないものに使います。
  • 「ちょっと待って、準備ができたら動かして」(defer: 例えば、ページのレイアウトやデザインに影響を与えるスクリプトに使います。全部の情報が揃ってから動かしたい場合に使います。

このように、それぞれの設定は「いつスクリプトを動かすか」というタイミングを制御しています。どちらを使うかは、そのスクリプトがどれだけ急いで動かさなければならないか、あるいは待ってから動かした方がいいかによります。

loading=”lazy”について

loading="lazy"属性は、ウェブページがロードされたときにその場で必要ない画像(例えば、すぐには表示されないスクロール先の画像など)を、後回しにして読み込むための設定です。この属性を使うことで、ページの表示速度を向上させることができます。

通常、ウェブブラウザはページを開いたときにページ内のすべての画像を読み込もうとします。これにより、特に画像が多いページでは表示が遅くなる場合があります。しかし、loading="lazy"が設定された画像は、その画像が画面に表示されるまで読み込まれません。これにより、ページ上部のコンテンツが早く表示され、ユーザー体験が向上します。

例えば、次のように<img>タグにloading="lazy"を追加することができます。

<img src="example-image.jpg" loading="lazy" alt="説明文" />

この設定によって、このexample-image.jpgという画像はユーザーがページをスクロールしてその画像が表示範囲に入るまで読み込まれません。最初にページを開いたときの速度が向上し、画像が必要になったときにだけ読み込むようになります。

簡単に言うと、「必要なときにだけ画像を読み込もう」というのがloading="lazy"の主な役割です。これにより、ページがより早く表示されるようになります。

基本的には、ファーストビュー(初めて画面に表示される部分)以外の画像にloading="lazy"を設定することで、ページの初期ロード速度が向上する可能性が高いです。ファーストビューに表示される画像はページロード時にすぐに必要なので、これにloading="lazy"を設定すると逆に表示が遅れる場合があります。

CLS に関する問題

サーチコンソールの「CLSに関する問題」について

CLS(Cumulative Layout Shift)は、Webページのビジュアルスタビリティを測定するためのメトリックの一つです。これはGoogleがWeb Vitalsプログラムで推奨する3つのコアWebバイタルメトリック(LCP、FID、CLS)のうちの一つです。CLSが高いと、ユーザーがページで何かをタップしようとしたときに予期せず要素が移動する可能性があり、これがユーザーエクスペリエンスを悪化させる可能性があります。

Google Search Consoleでは、このCLSメトリックを報告し、問題があるページを特定する機能があります。もしCLSが高いと判断された場合、それは以下のような原因による可能性があります。

  1. 画像や広告が遅延してロードされる: ページ上での遅延ロードは、その他の要素が既に表示されているときに新しい要素が突然表示される可能性があります。
  2. フォントの遅延: カスタムフォントが遅れてロードされると、テキストが突然リフロー(再配置)される可能性があります。
  3. 動的コンテンツの挿入: JavaScriptによって動的にコンテンツが挿入される場合、ページのレイアウトがシフトする可能性があります。
  4. アニメーションとトランジション: サムーズなトランジションやアニメーションが不適切に実装されていると、CLSが高くなる可能性があります。

このような問題を修正することで、CLSスコアを改善し、よりよいユーザーエクスペリエンスを提供することが可能です。具体的な修正方法には、予約容量(widthheight属性の明示)、loading="lazy"属性の使用、不必要なレイアウトシフトを引き起こすJavaScriptの修正などがあります。

ビジュアルスタビリティって?

ビジュアルスタビリティ(Visual Stability)とは、ウェブページやアプリの画面がどれだけ「安定している」かを示す概念です。言い換えれば、ページを閲覧しているときに画面上のボタンやテキスト、画像などが突然動いたり、場所が変わったりしないかどうか、ということです。

例えば、あなたがオンラインショッピングサイトで「購入する」ボタンを押そうとしているとき、そのボタンが突然別の場所に移動してしまうと、うっかり違うボタンを押してしまう可能性がありますよね。このような不意の「動き」は、ユーザーにとってストレスを感じさせるものであり、ビジュアルスタビリティが低いと言えます。

ビジュアルスタビリティが高いウェブページやアプリは、使いやすく感じられることが多いです。それは、ユーザーが期待通りの操作ができるからです。このような理由から、ウェブページの品質を評価する際にビジュアルスタビリティも重要な要素とされています。