アプリケーションの開発を行うときに気をつけなれけばいけないポイントの1つとしてあげられるのがセキュリティ対策です。
最近では顧客情報が漏洩したなどのニュースを見る機会も多くなってきたのではないでしょうか?
基本的に性善説で生きたいと思う世の中ですが、アプリケーションを開発する上では悪いことする人がいるという前提で開発を進めないと、貴重なデータや信用を失ってしまいます。
この記事ではよくありそうな脆弱性についてとそれの対策について5つ紹介します。
筆者がLaravelを中心に開発を行っているため対応が基本的にLaravelでの対応策になります。
脆弱性とは
コンピュータのOSやソフトウェアにおいて、プログラムの不具合や設計上のミスが原因となって発生した情報セキュリティ上の欠陥のことを言います。脆弱性は、セキュリティホールとも呼ばれます。脆弱性が残された状態でコンピュータを利用していると、不正アクセスに利用されたり、ウイルスに感染したりする危険性があります。
脆弱性(ぜいじゃくせい)とは? – 総務省
世の中には悪い人もいるため、こういった脆弱性を見つけては攻撃してきたりします。
すべての脆弱性を対策することはかなり難しいですが、開発者側としては基本的に脆弱性がないように開発をしていきたいものです。
自分たちだけでは開発しているアプリケーションに脆弱性がないかを判定することは難しいです。
そういったときに脆弱性診断を専門とされている企業さんもいらっしゃるので、そこに依頼するのも一つの手です。
第三者にアプリケーションを診断してもらうことで自分たちでは気づけなかった脆弱性も教えてくれるので、安全性への担保にも繋がります。
脆弱性① HTTPSのCookieにSecure属性がない
Secure属性がないために、HTTPS通信のみ送信されるべきCookieがHTTP通信でも送信されてしまいます。
リスク度的に高い且つ対策は難しくないので今すぐ確認したほうが良い項目です。
HTTPのザックリとした解説は【初心者向け】CORSについて理解しよう!に書いています。
影響
悪意ある第三者がHTTP通信を簡単に盗聴できる状態でありCookie情報が漏洩してしまいます。
これにより情報漏洩やデータ改ざん、なりすましなどが行われてしまうリスクがあります。
対策
session.php
のsecureキーの値をtrue
にすることで対策可能です。
Laravelのデフォルトでは環境変数が設定されているだけなので、env関数の第2引数のデフォルト値にtrueを設定してあげます。
もしくは環境変数SESSION_SECURE_COOKIE
にtrueを指定してあげます。
後者で注意するべきなのが、ローカルで開発するときです。
ローカル環境は基本的にHTTP通信になるのでローカルでは.env
ファイルでfalseを指定してあげる必要があります。
ローカル環境なのでSecure属性がなくても特に問題はないですね。
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you when it can't be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', true), // 追加
脆弱性② クロスサイトスクリプティング
クロスサイトスクリプティング(XSS)とはアプリケーションの脆弱性を利用して悪意あるスクリプトを埋め込み実行させる攻撃手法です。
IPA(情報処理推進機構)の2020年度の調査ではWebサイトの脆弱性の届け出状況において、クロスサイトスクリプティングが半数以上を占めていました。
ユーザーからの入力値に対してエスケープ処理が行われていないと、下記のようなスクリプトを埋め込むと実行されてしまいます。
<script>alert('Hello World');</script>
影響
攻撃者がスクリプトを実行しユーザーのCookie情報を取得したり、ブラウザを不正に操作したりすることが可能になります。
対策
アプリケーションが出力するHTMLページにユーザーから送信された値を含める場合はエスケープ処理をして出力させます。
Laravelのbladeでは{{ }}
を使うことでエスケープ処理を行ってくれます。
例) <div>ユーザー名:{{ $user['name'] }}</div>
脆弱性③ クリックジャッキング
WEBブラウザを悪用してユーザーに不利益をもたらす攻撃の1つです。
ボタンやリンクなどを透明にして、通常のWEBページの上にかぶせて表示させることでユーザーに気づかれず悪意のあるボタンやリンクを押させるといった手法です。
よくあるのはiframe
を使って透明なページをかぶせる方法です。
影響
悪意あるサイトに誘導されたユーザーが意図せずに標的サイト上で購入や退会など重要な処理を実行させられる可能性があります。
また、マルウェアに感染させ情報を搾取したりパソコンなどの端末を乗っ取るなどの危険性があります。
対策
HTTPのレスポンスヘッダーであるX-Frame-Options
を追加することで外部サイトの埋め込みを無効化することが可能です。
X-Frame-Optionsには2つの設定が可能です。
- DENY:同じサイトであってもフレーム内にページを表示させることができなくなります。
- SAMEORIGIN:同じオリジンのフレーム内であれば表示されます。
nginx
add_header X-Frame-Options SAMEORIGIN always;
Apache
Header always append X-Frame-Options SAMEORIGIN
Laravelであればミドルウェアでレスポンスにセットしてあげるのも方法の1つかと思います。
class XFrameOptions
{
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('X-Frame-Options', 'sameorigin');
return $response;
}
}
脆弱性④ ブラウザのキャッシュ保存
影響
共有のパソコンを使いまわすときなど、ブラウザにキャッシュされた秘密情報を含むコンテンツが本人以外に表示され、情報漏えいのリスクがあります。
対策
HTTPのレスポンスヘッダーのCache-Control
にno-store
を設定します。
Cache-Controlにはいくつかの指定が可能ですが、no-storeとすることでキャッシュの保存を禁止します。
似たような指定でno-cache
というものがありますが、中身は異なります。
no-cacheはレスポンスをキャッシュに保存が可能ですが、そのキャッシュを利用するときはWebサーバーに対して有効かどうかの検証を通さなければいけません。
こちらもLaravelのミドルウェアを利用して対策が可能です。
class NoStoreCache
{
public function handle($request, Closure $next)
{
/** @var Response $response */
$response = $next($request);
$response->header('Cache-Control', ['no-store']);
$response->header('Pragma', ['no-cache']);
return $response;
}
}
脆弱性⑤ Refererヘッダーの改ざん
HTTPリクエストには直前に見ていたWEBページのURLを含むReferer
ヘッダーという項目があります。
このヘッダーを利用してどこからアクセスしに来たかを識別し、分析などに利用することができます。
LaravelではIlluminate/Routing/UrlGenerator
というクラスにprevious()
というメソッドが存在します。
例えば、キャンセルボタンなどをbladeで下記のように指定した場合は、キャンセルボタンを押す直前のページへ遷移することが可能です。
<a href="{{ url()->previous() }}">キャンセル</a>
しかし、このpreviousメソッドはリクエストヘッダーのrefererの値から遷移元を取得しているため、書き換えることが可能になります。
影響
refererヘッダーを書き換えることで、キャンセルボタンを押した際に直前のページではなく、悪意あるサイトへ転送されてしまう危険性があります。
対策
基本的にpreviousメソッドは利用せず、キャンセルボタンを押された場合でもルーティングを明示的に指定してあげることで意図したURLへ遷移されるようにします。
<a href="{{ route('users.index') }}>キャンセル</a>
最後に
この記事を書いているときにちょうどJavaのloggingライブラリであるlog4jに脆弱性が見つかり、界隈を賑わしているそうです。
私はJavaを使ったことがないためあまり実感としてはないですが、log4jはJavaのloggingライブラリでも有名らしく使われているところも多いみたいなので対応がすごく大変そうです。
開発者として脆弱性を気にしながら開発を進めることはもちろん、使用するライブラリも無思考で使うのは危険だなと思った所存です。
コメント