情報処理安全確保支援士 2011年 秋期 午後1 問01
セキュアプログラミングに関する次の記述を読んで、設問1〜3に答えよ。
E社は、従業員数100名の自動車部品販売会社であり、販売先は日本各地に散在している。5年前に社内LANを導入した際、営業報告管理システム(以下、Xシステムという)を開発し、社内LAN上で運用を始めた。XシステムはC++で開発したWebアプリケーション(以下、XシステムのWebアプリケーションをX-Webアプリという)、Webサーバ及びデータベースで構成されている。
〔Xシステムへの新たな要望とその対応〕
これまで営業報告は、その日の営業活動終了後に営業社員が会社に戻り、Xシステムを用いて営業報告書を作成して、更にXシステム上で営業部長に提出し、必要な場合は口頭によって補足する方法がとられてきた。また、遠方の販売先に出張した場合には電話で報告を行い、後日出社した際に営業報告書を作成して営業部長に提出してきた。
インターネットが普及したことから、会社に戻らなくても出張先で営業報告を行えるようにしてほしいという要望が営業社員から出されていた。さらに、他社との競争も激しくなっていることから、E社としても営業力強化が必要であると経営者が判断し、この要望に対応することになった。具体的には、営業活動の都度、インターネットを利用して報告することで、営業部長が営業活動の状況を逐次把握し、必要に応じて指示ができるようにすることにした。情報システム部のB君がX-Webアプリの改修を担当することになった。
なお、Xシステムのデータベースは現状のものを使うことにした。現状のX-Webアプリは、社外からインターネット経由でアクセスすることを想定しておらず、脆弱性対策も行われていない。
〔代表的な脆弱性への対策方法の確認〕
社内の他のWebアプリケーションはJavaで開発されている。B君は、X-WebアプリをJavaで書き直す案もあると考え、先輩のD主任に相談した。D主任から、“一般的にはJavaが良いと言われているよ”という助言をもらったが、B君は、C++とJavaのそれぞれを採用するメリットとデメリットを比較することにした。B君は、X-Web
アプリの中で SQL インジェクションの脆弱性がある関数を一つ見つけたので、C++ と Java での対策方法を比較してみることにした。その関数 getReport の仕様を図1に示す。


SQL インジェクション対策前の C++ コードを図2に示す。

B君は、このコードに対し、SQLインジェクション対策を行ってみた。この対策は、aを用いてSQL文を組み立てるというものである。対策後のC++コードを図3に示す。


B君は、図3のC++コードと同様の対策を実施した同じ仕様のプログラムをJavaで作成してみた。そのコードを図4に示す。

この後、図2~4のコードにはSQLインジェクション以外にも①代表的な脆弱性の原因となるコードが含まれていることが分かり、B君は、cをd処理するという対策を図3と図4のコードにそれぞれ追加した。
次に、B君は、インターネット上の信頼できるWebサイトを調査し、図5に示すような、脆弱性につながるC++の特性の解説を見つけた。

B君は、このC++の特性に対して、Javaの特性を図6に整理した。


B君は、以上の調査結果を踏まえ、X-Webアプリの改修でどちらの言語を採用するかを検討するために、両言語を採用する場合のメリット、デメリットを整理した。両言語の比較表を表1に示す。

〔その後の状況〕
今回の対応では、C++を用いた場合にf対策が多くの部分で必要となることが確認されたので、表1を基にB君はJavaを採用することを提案した。その提案を受けて、情報システム部内で検討を重ね、情報システム部長がJavaを採用することを承認した。言語を変更したことでX-Webアプリを書き直すことになったが、B君はこの改修を無事に行うことができた。
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(1)図2でSQLインジェクションの原因となるコーディング部分が複数ある。そのコーディング部分に書かれた変数名を、コード上から選び、全て答えよ。
模範解答
user, day
解説
解答の論理構成
- 図2には、SQL 文を組み立てる処理として
"string query = "SELECT report FROM reports WHERE user = '" + user + "'";"
"query += " AND day = '" + day + "'";"
の二行が掲載されています。 - 上記のように user と day をそのまま文字列連結していると、利用者が入力欄に
' OR '1'='1 のようなコード片を埋め込んだ場合でも、SQL 文がそのまま実行されてしまいます。 - これは「入力値をエスケープせずに SQL 文字列へ直接結合する」という典型的な SQL インジェクションの原因です。
- したがって、SQL インジェクションの原因となるコーディング部分に書かれた変数名は user, day の二つになります。
誤りやすいポイント
- query 変数そのものを答えてしまう。query は完成した SQL 文を格納するもので、原因はその中に差し込まれる user, day です。
- rep や con など、データ取得後に使われる変数を挙げてしまう。これらは SQL 文の生成に関与しません。
- 図3・図4のプレースホルダ利用コードと混同し、「脆弱性は除去済み」と誤認してしまう。
FAQ
Q: 文字列連結さえしなければ user と day を使っても安全ですか?
A: プレースホルダ付きの PreparedStatement を用いれば、両変数を安全にバインドできます。連結が問題なのではなく、未加工で SQL に埋め込むことが危険です。
A: プレースホルダ付きの PreparedStatement を用いれば、両変数を安全にバインドできます。連結が問題なのではなく、未加工で SQL に埋め込むことが危険です。
Q: rep も表示処理で HTML に出力されていますが、XSS の原因とはならないのですか?
A: rep の内容がユーザ入力由来であれば XSS になり得ます。ただし今回の設問は「SQL インジェクションの原因となるコーディング部分」を問うため、解答対象外です。
A: rep の内容がユーザ入力由来であれば XSS になり得ます。ただし今回の設問は「SQL インジェクションの原因となるコーディング部分」を問うため、解答対象外です。
Q: day は日付だけなので安全では?
A: 想定どおりの日付フォーマットで入力される保証がなければ攻撃者は任意文字列を注入できます。日付フィールドでも PreparedStatement でバインドすべきです。
A: 想定どおりの日付フォーマットで入力される保証がなければ攻撃者は任意文字列を注入できます。日付フィールドでも PreparedStatement でバインドすべきです。
関連キーワード: SQLインジェクション、文字列連結、入力値検証、プレースホルダ、エスケープ
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(2)本文中のaに入れる適切なプログラミング技法を12字以内で答えよ。
模範解答
a:プレースホルダ
解説
解答の論理構成
- 問題文は「B君は、このコードに対し、SQLインジェクション対策を行ってみた。この対策は、aを用いてSQL文を組み立てるというものである。」と明言しています。
- 図3のSQL文は SELECT report FROM reports WHERE user = ? AND day = ? のように ? を挿入しており、図4でも同様に ? を使っています。? は SQL の「値を後からバインドする位置」を示す記号です。
- この記号を使う手法は JDBC でも ODBC でも「プレースホルダ(置き換え文字)」と呼ばれます。
- したがって、a に入る適切なプログラミング技法は「プレースホルダ」です。
誤りやすいポイント
- 「パラメータバインド」と答えてしまう
⇒ バインドは 実行時の操作、技法名として問われているのは ? を使った「プレースホルダ」です。 - PreparedStatement=プレースホルダと混同
⇒ PreparedStatement は API クラス名、プレースホルダは SQL 文中に埋め込む仕組みです。 - 「バインド変数」と書く
⇒ 意味は近いものの、問題文の用語と合致せず減点リスクがあります。
FAQ
Q: プレースホルダを使うと必ず SQL インジェクションを防げますか?
A: 送信データが文字列・数値ともにエスケープ不要でバインドされるため、少なくとも「文字列連結型」の攻撃は無効化できます。ただし動的に列名やテーブル名を連結している場合など、他の部分で生成系の脆弱性が残ることがあります。
A: 送信データが文字列・数値ともにエスケープ不要でバインドされるため、少なくとも「文字列連結型」の攻撃は無効化できます。ただし動的に列名やテーブル名を連結している場合など、他の部分で生成系の脆弱性が残ることがあります。
Q: ? 以外のプレースホルダ記法は存在しますか?
A: データベースやドライバによって「名前付きパラメータ」 :name をサポートするものもあります。基本概念は同じで、SQL 文中に「値の代入位置」を示すトークンを置き、実行時にバインドします。
A: データベースやドライバによって「名前付きパラメータ」 :name をサポートするものもあります。基本概念は同じで、SQL 文中に「値の代入位置」を示すトークンを置き、実行時にバインドします。
Q: プレースホルダを使うとパフォーマンスが向上すると聞きましたが?
A: 多くの DB では文を一度パース・最適化して「実行計画」をキャッシュできます。そのため同一 SQL 文字列で繰り返し実行する場合、動的連結より高速になるケースが多いです。
A: 多くの DB では文を一度パース・最適化して「実行計画」をキャッシュできます。そのため同一 SQL 文字列で繰り返し実行する場合、動的連結より高速になるケースが多いです。
関連キーワード: SQLインジェクション、プレースホルダ、PreparedStatement, パラメータバインド、セキュアコーディング
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(3)図4中のbに入れる適切な文字列を英字で答えよ。
模範解答
b:prepareStatement
解説
解答の論理構成
-
図3の C++ コードには、SQL インジェクション対策として
“pstmt = con->prepareStatement(query);”
という記述があります。ここで "prepareStatement" はデータベース接続オブジェクトがプレースホルダ付き SQL を扱うために呼び出す関数名です。
【問題文】
“pstmt = con->prepareStatement(query);” (図3) -
図4の Java コードは同じ対策を Java で実装したものと明記されています。
【問題文】
“B君は、図3のC++コードと同様の対策を実施した同じ仕様のプログラムをJavaで作成してみた。” -
Java でデータベースアクセスを行う場合、java.sql.Connection インタフェースには C++ と同名の
prepareStatement(String sql)
というメソッドが定義されています。従って、図4の
ps = con.b(query);
には "prepareStatement" が入ります。 -
以上より、b に入る英字は
prepareStatement
となります。
誤りやすいポイント
- createStatement と混同する
SQL 文字列をそのまま渡す場合は createStatement() ですが、プレースホルダを使う今回は prepareStatement() です。 - メソッド名の大文字小文字
Java は大文字小文字を区別します。PrepareStatement や prePAREstatement などは誤りです。 - “Statement” と “PreparedStatement” の役割の混同
PreparedStatement はコンパイル済み SQL を扱い、バインド変数で値を安全に渡せる点が違いです。
FAQ
Q: なぜ CallableStatement ではないのですか?
A: CallableStatement はストアドプロシージャ呼び出し用です。今回の SQL は通常の検索文なので PreparedStatement を得る prepareStatement() が適切です。
A: CallableStatement はストアドプロシージャ呼び出し用です。今回の SQL は通常の検索文なので PreparedStatement を得る prepareStatement() が適切です。
Q: prepareStatement() に渡すのは SQL だけで良いのですか?
A: 基本形は prepareStatement(String sql) です。必要に応じて結果セットの型や生成鍵を指定するオーバーロードもありますが、本問のような単純な検索では SQL 文字列だけで問題ありません。
A: 基本形は prepareStatement(String sql) です。必要に応じて結果セットの型や生成鍵を指定するオーバーロードもありますが、本問のような単純な検索では SQL 文字列だけで問題ありません。
関連キーワード: PreparedStatement, SQLインジェクション、JDBC, プレースホルダ、Connection
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(4)本文中の下線①の代表的な脆弱性を解答群の中から選び、記号で答えよ。
解答群
ア:クロスサイトスクリプティング
イ:クロスサイトリクエストフォージェリ
ウ:コマンドインジェクション
エ:セッションフィクセーション
模範解答
ア
解説
解答の論理構成
- 【図2】【図3】の C++ コード、【図4】の Java コードでは、入力値である user、day、rep を次のようにそのまま HTML へ出力しています。
- cout << "user = '" << user << "'
"; - out.write("user = '" + user + "'
");
- cout << "user = '" << user << "'
- これらの変数は「利用者画面の入力データから取り出され」ると【図1】で明記されています。したがって外部から任意の文字列(例:)を混入させることが可能です。
- 上記のような未加工の出力は、ブラウザ上でスクリプトが実行される「クロスサイトスクリプティング」を招きます。
- 本文には「cをd処理するという対策を図3と図4のコードにそれぞれ追加した」とあり、対策対象はまさに HTML へ出力するデータであることが示唆されています。これはクロスサイトスクリプティングの典型的な防御手法であるエスケープ処理に一致します。
- 以上より、下線①の代表的な脆弱性は「クロスサイトスクリプティング」であり、解答群では「ア」に該当します。
誤りやすいポイント
- SQL インジェクション対策コードが示されているため、つい同系統の「コマンドインジェクション(ウ)」と誤認しやすい。
- 「セッション」や「リクエスト」という語に引きずられて「クロスサイトリクエストフォージェリ(イ)」や「セッションフィクセーション(エ)」を選んでしまう。
- 入力値の検証=サーバ側のバリデーションと早合点し、出力時のエスケープ不足が脆弱性になる点を見落とす。
FAQ
Q: SQL をパラメタ化しているのに、まだ脆弱なのですか?
A: パラメタ化はデータベースに対する攻撃(SQL インジェクション)を防止しますが、ブラウザに送る HTML へのエスケープは別問題です。今回は後者が不足しています。
A: パラメタ化はデータベースに対する攻撃(SQL インジェクション)を防止しますが、ブラウザに送る HTML へのエスケープは別問題です。今回は後者が不足しています。
Q: 文字列連結をやめてテンプレートエンジンに変えれば解決しますか?
A: テンプレートエンジンを使っても、最終的に HTML に埋め込む前に適切なエスケープを行わなければクロスサイトスクリプティングは防げません。
A: テンプレートエンジンを使っても、最終的に HTML に埋め込む前に適切なエスケープを行わなければクロスサイトスクリプティングは防げません。
Q: rep はデータベースから取得した値なので安全では?
A: データベース内にも攻撃コードが登録されている可能性があります。保存元が利用者入力かどうかに関わらず、出力時エスケープが必須です。
A: データベース内にも攻撃コードが登録されている可能性があります。保存元が利用者入力かどうかに関わらず、出力時エスケープが必須です。
関連キーワード: クロスサイトスクリプティング、入力値検証、出力エスケープ、HTMLエンコード
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(5)本文中のc、dについて、dに入れる適切なプログラミング技法を10字以内で、その技法の対象を明確に示すcに入れる適切な字句を20字以内で答えよ。
模範解答
c:HTMLにおける特別な記号
d:エスケープ
解説
解答の論理構成
-
脆弱性の特定
- 図3・図4には、cout << "user = '" << user << "'
"; や out.write("user = '" + user + "'
"); など、利用者入力(user、day、rep)をそのまま HTML へ出力する記述があります。 - 本文には「この後、図2~4のコードにはSQLインジェクション以外にも①代表的な脆弱性の原因となるコードが含まれている」とあり、ここで想定される代表的脆弱性は XSS(クロスサイトスクリプティング)です。
- 図3・図4には、cout << "user = '" << user << "'
-
どの値を保護するか
- XSS は「HTML へ直接出力される文字列」に悪意あるタグやスクリプトを混入させることで成立します。従って防御対象は「HTMLにおける特別な記号」(<、>、"、'、& など)です。
-
採るべき対策技法
- XSS への第一の防御策は、前項の特別な記号を無害化する「エスケープ」です。
- 問題文の指示「cをd処理する」という形式に合わせると、
・c=攻撃ベクトルとなる文字集合そのもの
・d=適用する処理名
となるため、- c「HTMLにおける特別な記号」
- d「エスケープ」
が妥当です。
誤りやすいポイント
- 「入力値をそのまま表示」が必ずしも XSS とは限らないと誤解してバリデーション(長さチェックなど)だけで済ませてしまう。
- SQL インジェクション対策で PreparedStatement を導入したことで「もう安全」と思い込み、表示処理の脆弱性に気付かない。
- エスケープとサニタイジングの使い分けを混同し、タグ除去のような別技法を書いてしまう。
FAQ
Q: バリデーションでも XSS を防げませんか?
A: 値を完全に禁止するのでなければ、< や & などの文字は通過してしまいます。XSS では「表示前のエスケープ」が本質的対策です。
A: 値を完全に禁止するのでなければ、< や & などの文字は通過してしまいます。XSS では「表示前のエスケープ」が本質的対策です。
Q: どのタイミングでエスケープすれば良いですか?
A: 原則として「信頼できないデータを HTML に出力する直前」です。保存時に行うと、再利用(CSV 出力など)で問題が起こる場合があります。
A: 原則として「信頼できないデータを HTML に出力する直前」です。保存時に行うと、再利用(CSV 出力など)で問題が起こる場合があります。
Q: Java では標準 API だけで対応できますか?
A: StringEscapeUtils.escapeHtml4()(Apache Commons Text)など外部ライブラリが一般的ですが、自作関数で replace("&"、"&") などを順に実施しても構いません。
A: StringEscapeUtils.escapeHtml4()(Apache Commons Text)など外部ライブラリが一般的ですが、自作関数で replace("&"、"&") などを順に実施しても構いません。
関連キーワード: XSS, HTMLエスケープ、クロスサイトスクリプティング、PreparedStatement, 入力値検証
設問1:図2〜4のコードについて、(1)〜(6)に答えよ。
(6)上記(5)の技法の対象となる変数が図3中に複数ある。その変数名を図3中から選び、全て答えよ。
模範解答
user, day, rep
解説
解答の論理構成
- 【問題文】では「B君は、cをd処理するという対策を図3と図4のコードにそれぞれ追加した」とあります。この“①代表的な脆弱性”は、ユーザや DB から取得したデータをそのまま HTML へ出力しているために発生する XSS であり、対策は「HTML エスケープ(出力時エンコード)」です。
- XSS は「利用者入力や DB 取得値を、ブラウザが解釈可能な形で返す」箇所が攻撃点になります。図3のコードで該当する行を確認します。
- cout << "user = '" << user << "'
"; - cout << "day = '" << day << "'
"; - string rep = res->getString("report");
cout << "report = '" << rep << "'
";
いずれも
タグを含む文字列連結で直接 HTML に書き出しています。
- cout << "user = '" << user << "'
- ここで使われる変数は
- user …… 利用者画面からの入力(図1「user ― 利用者画面からの入力を基に作成した営業社員名」)
- day …… 利用者画面からの入力(図1「day ― 利用者画面からの入力を基に作成した、表示したい営業報告の日付情報」)
- rep …… DB から取得した営業報告本文(図3 string rep = res->getString("report");)
以上3つです。
- したがって、出力時にエスケープ対象となる変数は
user, day, rep
となります。
誤りやすいポイント
- rep を見落とす
DB 取得値も攻撃者が登録していれば XSS が成立します。入力値だけを対象にすると失点します。 - 変数名の綴りミス
【問題文】に合わせて小文字で「user」「day」「rep」と書かないと誤答扱いになります。 - XSS と SQL インジェクションを混同
どちらも入力値が関与しますが、前者は「出力時エスケープ」、後者は「プリペアドステートメント」で対策が異なります。
FAQ
Q: rep は DB 由来なので安全ではないのですか?
A: 安全とは限りません。攻撃者が営業報告にスクリプトを埋め込んで登録すれば、閲覧時に実行されるため XSS になります。
A: 安全とは限りません。攻撃者が営業報告にスクリプトを埋め込んで登録すれば、閲覧時に実行されるため XSS になります。
Q: 変数をエスケープする具体的な方法は?
A: 代表的には &、<、>、"、' を &、<、>、"、' に置換するライブラリ関数を利用します。C++ では独自実装やテンプレートライブラリ、Java では StringEscapeUtils.escapeHtml4() などが使えます。
A: 代表的には &、<、>、"、' を &、<、>、"、' に置換するライブラリ関数を利用します。C++ では独自実装やテンプレートライブラリ、Java では StringEscapeUtils.escapeHtml4() などが使えます。
Q: SQL インジェクション対策にプリペアドステートメントを導入したのに XSS も残るのはなぜ?
A: SQL インジェクションは「SQL 文生成時」、XSS は「HTML 出力時」に発生箇所が異なるため、別々の防御が必要です。
A: SQL インジェクションは「SQL 文生成時」、XSS は「HTML 出力時」に発生箇所が異なるため、別々の防御が必要です。
関連キーワード: クロスサイトスクリプティング、エスケープ処理、出力値検証、プリペアドステートメント、入力データ検証
設問2:
図5中のeに入れる適切な字句を6字以内で、図5中、表1中及び本文中のf、並びに図6中及び表1中のgに入れる適切な字句を、それぞれ12字以内で答えよ。
模範解答
e:ポインタ
f:バッファオーバフロー
g:ガーベジコレクション
解説
解答の論理構成
-
C++ の脆弱性要因
問題文は「〔脆弱性の要因となる問題〕 ・データを転記する際のメモリ領域の境界チェック漏れ ・eによる誤った領域へのアクセス …」と示しています。
C++ でメモリ領域を直接扱う代表的な仕組みはポインタです。したがって、誤った領域へのアクセス原因となる e は「ポインタ」と判断できます。 -
代表的な脆弱性名
続けて「〔上記問題が引き起こす代表的な脆弱性〕 ・f ・整数オーバフロー」と列挙されています。
境界チェック漏れやポインタ誤操作が招く典型的な脆弱性はバッファサイズを超えた書き込み・読み込み、すなわち「バッファオーバフロー」です。よって f は「バッファオーバフロー」になります。 -
Java が抱える性能面の注意点
図6の説明では「長時間連続動作させる場合にはgの実行による応答性への影響を考慮する必要がある」と述べられています。
Java で応答性に影響を与える自動メモリ回収機構は「ガーベジコレクション」です。表1の Java デメリット欄も同じ文脈で g を示しているため、答えは「ガーベジコレクション」となります。
誤りやすいポイント
- ポインタと配列添字を同一視してしまい、e に「配列」などを書いてしまう。
- C++ の脆弱性で「ヒープオーバフロー」や「スタッククラッシュ」を挙げ、f を細分類で答えて減点される。
- Java の性能低下要因をスレッド切り替えや Just-In-Time コンパイルと誤認し、g を「JIT コンパイル」としてしまう。
FAQ
Q: ポインタを安全に使う一般的な手法はありますか?
A: ポインタ演算を極力避け、スマートポインタやサイズチェック付き API を使うことが推奨されます。
A: ポインタ演算を極力避け、スマートポインタやサイズチェック付き API を使うことが推奨されます。
Q: バッファオーバフローはなぜ依然として多いのですか?
A: C/C++ には境界チェックを自動で行う組込み機構がなく、旧来のライブラリ関数も残っているため、コーディング規約と静的解析が徹底されない限り混入しやすいからです。
A: C/C++ には境界チェックを自動で行う組込み機構がなく、旧来のライブラリ関数も残っているため、コーディング規約と静的解析が徹底されない限り混入しやすいからです。
Q: Java でガーベジコレクションの影響を抑える方法は?
A: 世代別 GC のチューニング、メモリ使用量の上限設定、リアルタイム GC を備えた JVM の利用などが挙げられます。
A: 世代別 GC のチューニング、メモリ使用量の上限設定、リアルタイム GC を備えた JVM の利用などが挙げられます。
関連キーワード: ポインタ、バッファオーバフロー、ガーベジコレクション、SQLインジェクション、メモリ管理
設問3:
図6及び表1には、脆弱性を狙ったf攻撃がC++では問題となるのに、Javaでは問題とならない根本的な理由が具体的に記述されていない。図5の内容を踏まえて、根本的な理由であるJavaの言語仕様上の特徴を20字以内で述べよ。
模範解答
アドレスを計算対象にできないから
解説
解答の論理構成
- 【問題文】図5には「C++は、メモリ内容への柔軟なアクセスが可能である」とあり、その要因として「eによる誤った領域へのアクセス」「データへのeと、関数へのeを混同したアクセス」が列挙されています。ここでeはポインタを指し、メモリアドレスを自由に計算・参照できることが分かります。
- 同じく図5の〔上記問題が引き起こす代表的な脆弱性〕には「f」が挙げられています。すなわち「バッファオーバフロー」はポインタ操作に起因する典型的脆弱性です。
- 図6では「Javaが提供しているメモリ内容へのアクセス手段は限定的であり、メモリマネジメントは…Java VMが行う」と記述されています。ここから、Javaはポインタを公開しておらず、アドレス自体をプログラムから直接扱うことができない仕様であることが読み取れます。
- したがって、C++と異なり「アドレスを計算対象にできない」ことが、Javaでf攻撃が成立しにくい根本理由です。
誤りやすいポイント
- 「境界チェックを自前で書けるから Java でもバッファオーバフローは起こり得る」と誤解するケース
→ Javaは配列境界を超えるアクセス時に例外を送出し、任意の領域を書き換える前に実行が停止します。 - 「ガベージコレクションがあるから安全」として理由を GC に限定してしまうケース
→ GC はメモリ解放の自動化であり、ポインタ不在という根本仕様とは異なる観点です。 - 「Java の ‘unsafe’ ライブラリを使えばアドレス操作できる」と考え、例外的手段を一般仕様と混同するケース
→ 標準言語仕様の話題であり、特殊 API の使用は前提外です。
FAQ
Q: Java でも ByteBuffer などを使えばメモリを直接扱えるのでは?
A: それらは論理的なバッファであり、実際のメモリアドレスはプログラムに公開されません。境界外アクセス時には自動で検出・例外送出が行われます。
A: それらは論理的なバッファであり、実際のメモリアドレスはプログラムに公開されません。境界外アクセス時には自動で検出・例外送出が行われます。
Q: C++ で安全にするにはどうすれば良いのですか?
A: 標準ライブラリの範囲で境界チェック付き API を用いる、もしくはスマートポインタや静的解析ツールを併用し、ポインタ演算の安全性を確認することが基本的対策となります。
A: 標準ライブラリの範囲で境界チェック付き API を用いる、もしくはスマートポインタや静的解析ツールを併用し、ポインタ演算の安全性を確認することが基本的対策となります。
Q: バッファオーバフロー以外のポインタ関連脆弱性は Java でも起こりますか?
A: 典型的なメモリ破壊系脆弱性(Use-After-Free など)はポインタ不在のため発生しませんが、論理上の配列境界チェック漏れや DoS など別種の脆弱性は存在します。
A: 典型的なメモリ破壊系脆弱性(Use-After-Free など)はポインタ不在のため発生しませんが、論理上の配列境界チェック漏れや DoS など別種の脆弱性は存在します。
関連キーワード: ポインタ、バッファオーバフロー、メモリ安全、ガベージコレクション、言語仕様


