コンテンツにスキップ

︎ネットワークセキュリティ@セキュリティ

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. 【L2L4】ネットワークファイアウォール

ネットワークファイアウォールとは

L2 (データリンク層) からL4 (トランスポート層) までに対するサイバー攻撃 (例:そもそものネットワークへの侵入、ポートスキャンなど) を防御する。


ネットワークファイアウォールの種類

Webアプリファイアウォールの種類 説明
ソフトウェア型 記入中... 記入中...
アプライアンス型 記入中... 記入中...
クラウド型 クラウドプロバイダーが提供するネットワークファイアウォールを配置する。 AWS NF (L2L3のみ)など

security_protection-type


パケットフィルタリング型ネットワークファイアウォール

▼ パケットフィルタリング型ネットワークファイアウォールとは

パケットのヘッダー情報の送信元IPアドレスやポート番号などに基づいて、パケットを許可する必要があるか否かを決める。

パケットのペイロードは検査しない。

ネットワークファイアウォールとwebサーバーの間には、NATルーターやNAPTルーターが配置されている。

パケットフィルタリング

▼ iptables (Linux/Ubuntu) による標準的ネットワークファイアウォール

Linux/Ubuntuでのiptablesは、標準的なNAPTルーターかつパケットフィルタリング型ネットワークファイアウォールである。

特に、パケットフィルタリングのルールは、/etc/sysconfig/iptablesファイルのfilterテーブルで設定する。

iptables-saveコマンドでこのファイルを作成できる。

filterテーブルで使用できるチェイン配下の通りである。

PREROUTINGPOSTROUTINGは使用できない。

filterテーブルで使用できるチェイン名 説明
INPUT 受信を許可/拒否する対象のパケットを定義する。
OUTPUT 送信を許可/拒否する対象のパケットを定義する。
FORWARD 転送を許可/拒否する対象のパケットを定義する。

*例*

$ cat /etc/sysconfig/iptables

...

*filter
:INPUT DROP [5:300]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [32:3205]
# 22番ポートと80番ポート宛てのTCPスリーウェイハンドシェイクを許可する。
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT

...

▼ firewalld (CentOS) による標準的ネットワークファイアウォール

CentOSでのfirewalldは、標準的なパケットフィルタリング型ネットワークファイアウォールである。

デフォルトでは、全てのインバウンド通信が拒否、全てのアウトバウンド通信が許可、となっている。

*例*

アクセスが許可されているポート番号を確認する。

$ firewall-cmd --list-all

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: ssh dhcpv6-client
  ports: 22/tcp 80/tcp 443/tcp # アクセスを許可するポート番号
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

アクセスが許可されている送信元IPアドレスを確認する。

$ firewall-cmd --get-active-zones

foo-cidr
  sources: 192.168.128.0/23
public
  interfaces: ens192

▼ Windowsネットワークファイアウォール (Windows) による標準的ネットワークファイアウォール

Windowsネットワークファイアウォールは、Windowsにおけるネットワークファイアウォールである。

パケットフィルタリングの設定

*例*


ゲートウェイ型ネットワークファイアウォール (プロキシサーバー型)

パケットのペイロードに基づいて、パケットを許可する必要があるか否かを決める。


サーキットレベル型ネットワークファイアウォール

L4 (トランスポート層) の段階でサイバー攻撃を遮断するネットワークファイアウォールのこと。


02. 【L3L6】IPS:Intrusion Prevention System

IPSとは

L3 (ネットワーク層) からL6 (プレゼンテーション層) までに対するサイバー攻撃 (Dos攻撃、Synフラッド攻撃、パケットフラグメンテーション攻撃など) を遮断するセキュリティシステムのこと。

security_protection-type


03. 【L3L6】IDS:Intrusion Detection System

IDSとは

L3 (ネットワーク層) からL6 (プレゼンテーション層) までに対するサイバー攻撃を防御する。

不正アクセスと思われるパケットを検出する。

また、検出内容を管理者に通知する。

あくまで通知するのみで、攻撃を防御することはしない。

IDS


04. 【L3L7】暗号化プロトコル

L3 (ネットワーク層) からL7 (アプリケーション層) までに対するサイバー攻撃を防御する。


05. 【L7】Webアプリファイアウォール:Web Application Firewall

Webアプリファイアウォールとは

L7 (アプリケーション層) に対するサイバー攻撃 (SQLインジェクション、XSS、OSコマンドインジェクションなど) を防御する。

L7を防御できていない場合、より低いレイヤー (例:L3) を突破できれば (例:送信元IPアドレスの乗っ取り) 、L7のサイバー攻撃 (SQLインジェクション、XSS、OSコマンドインジェクションなど) を実施できてしまうことになる。

security_protection-type


Webアプリファイアウォールの種類

Webアプリファイアウォールの種類 説明
ソフトウェア型 Webアプリファイアウォールの能力を持つソフトウェアを自社サーバーにセットアップし、これを配置する。 SuiteGuard、SmartCloudなど
アプライアンス型 Webアプリファイアウォールのソフトウェアがすでにセットアップされたハードウェアを購入し、これを配置する。 FortiWeb、Imperva SecureSphere、SiteGuardなど
クラウド型 クラウドプロバイダーが提供するWebアプリファイアウォールを配置する。 AWS WAF、Google Cloud Armor、Cloudbric、Scutum、CrowdStrikeなど


06. 【L7】チェックサム

チェックサムとは

L7 (アプリケーション層) に対するサイバー攻撃を防御する。

sha256によって作成された文字列をファイル情報として添付し、これを送受信の両方のアプリケーション側で照合することにより、通知途中でファイルが改竄されていないことを保証する。

L7のペイロードを暗号化/復号化するわけではない。


07. 【L7】ワンタイムトークン

ワンタイムトークンとは

L7 (アプリケーション層) に対するサイバー攻撃 (例:CSRF) を防御する。

認証時に、セッションIDのみでなく、ワンタイムトークンも併用する。

認証フォームがリクエストされた時、サーバー側では、ワンタイムトークンを発行し、これをSet-Cookieヘッダーのcsrftokenパラメーター (フレームワークによっては、これに相当するパラメーター) や自前ヘッダーに割り当てて、レスポンスを返信する。

csrf-token


ワンタイムトークンの仕組み

200 OK
---
Set-Cookie: csrftoken=<トークン>
# 自前ヘッダー
X-CSRF-TOKEN: <トークン>
(1)

ブラウザではレスポンスヘッダーからワンタイムトークンを取り出し、認証フォームのinputタグのhidden属性に割り当てる。

他に、metaタグにトークンを割り当てることもある。

<form method="POST" action="http://example.com/bar-form.php">
  <input type="hidden" name="csrftoken" value="<csrfトークン>" />
  <input type="text" name="email" />
  <input type="text" name="password" />
  <input type="submit value="ログイン">
</form>
<head>
  <meta name="csrftoken" content="<ヘッダーから取り出したトークン>" />
</head>
(2)

認証のためのPOSTリクエスト時に、リクエストボディや自前ヘッダーにトークンを割り当て、リクエストを送信する。

どちらを使用するかは、バックエンド側の仕様によって異なる。

POST https://example.com/bar-form.php
---
# 自前ヘッダー
x-csrf-token: <トークン>
---
# ボディ
{_token=<トークン>}
(3)

サーバー側では、POSTリクエストによって送信されたトークンとワンタイムトークンを比較し、認証を実行する。

以降、POSTリクエストの場合はそのワンタイムトークンを使い回し、GETリクエストの場合は使用しない。

トークンが変更されていれば、誤った入力フォームからのリクエストとして判定し、401ステータスを返却する。


08. 【L7】パラメーターの制限

パラメーターの制限とは

L7 (アプリケーション層) に対するサイバー攻撃 (例:SQLインジェクション) を防御する。

アプリケーションで、任意のパラメーターを入力できないようにする。


特殊な文字列の無効化

DBのSQLクエリのパラメーターとなる入力では、『シングルクオーテーション』や『バックスラッシュ』などはSQLで特別な意味を持つ。

そのため、これらのパラメーターが割り当てられているリクエストを拒否する。

例えば、Webアプリファイアウォールを使用する。


プレースホルダー

プリペアードステートメントのSQL中にパラメーターを設定し、値をパラメーターに渡した上で、SQLとして発行する。

処理速度が速い。

また、パラメーターに誤ってSQLが渡されても、型をチェックすることにより、実行できなくなるようにできる。

そのため、SQLインジェクションの対策になる。


09. 【L7】CORS:Cross-Origin Resource Sharing (オリジン間リソース共有)

CORSとは

L7 (アプリケーション層) に対するサイバー攻撃 (例:CSRF、XSS) を防御する。

異なるドメインで表示されるページからのリクエストを許可する仕組みのこと。

デフォルトでは、異なるドメインで表示されるページからのリクエストは拒否されるようになっている。

異なるドメインで表示されるページからのリクエストを許可したい場合は、ページからのリクエストとサーバーからのレスポンスの両方で対応が必要である。

cors


CORSの仕組み

*実装例*

(1)

リクエストのOriginヘッダーに送信元オリジンを設定する。

加えて、Cookieヘッダーを持つリクエストを送信したい場合は、JavaScriptの実装でwithCredentialsオプションにtrueを割り当てる。

JavaScriptのパッケージによってオプション名が異なるため注意する。

GET https://example.com/bar
---
# 送信元オリジン
Origin: https://example.com
import axios from "axios";

const client = axios.create({
  baseURL: "https://foo.co.jp",
  withCredentials: "true", // オプションの有効化
});

return new Promise((resolve, reject) => {
  client
    .get("/bar")
    .then((data) => {
      resolve(data);
    })
    .catch((err) => {
      reject(err);
    });
});
(2)

次に、レスポンスのAccess-Control-Allow-Originヘッダーに、許可された送信元オリジンを割り当てて返信する。

Cookieヘッダーを持つリクエストを許可する場合、同じくレスポンスのAccess-Control-Allow-Credentialsヘッダーにtrueを割り当てる。

その他、許可するHTTPメソッドやHTTPヘッダーを定義できる。

例えば、許可されていないHTTPメソッドを使用して、異なるオリジンにリクエストを送信すると、405ステータスでエラーレスポンスが返信される。

200 OK
---
# 許可された送信元オリジン
Access-Control-Allow-Origin: https://example.com
# リクエストがCookieヘッダーを持つことを許可する場合
Access-Control-Allow-Credentials: "true"
# 許可するHTTPメソッド
Access-Control-Allow-Methods: GET,POST,HEAD,OPTIONS
# その他、許可するHTTPヘッダー
Access-Control-Allow-Headers: Content-Type

補足として、Cookieヘッダーを持つリクエストを許可しない場合に限り、全てのオリジンやヘッダーを許可できる。

200 OK
---
# 全てのオリジンを許可
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: *


L7 (アプリケーション層) に対するサイバー攻撃 (例:XSS) を防御する。

属性を有効化することにより、リクエストヘッダーの作成を制限できる。


Domain属性

▼ Domain属性とは

リクエストがCookieヘッダーを持つことを許可した場合、サブドメイン名のオリジンにもCookieヘッダーの送信を許可するか否かを制御できる。

サブドメイン名のレスポンスのSet-Cookieヘッダーにて、Domain属性にドメインが割り当てなかった場合は、ページを表示するサーバーのドメインにのみCookieヘッダーを持つリクエストを許可でき、サブドメイン名への送信を拒否できる。

一方で、ドメインが割り当てた場合は、そのページからサブドメイン名に対しても、Cookieヘッダーを持つリクエストを許可できる。

ドメインではなく、オリジンであることに注意する。

▼ Domain属性の仕組み

*実装例*

Domain属性にexample.comが割り当てられていたとする。

最初にドットがついているドメイン (.example.com) でも、同じ値として認識される。

この場合、example.comに加えて、サブドメイン名 (foo.example.com) に対しても、Cookieヘッダーを持つリクエストを送信できる。

200 OK
---
Set-Cookie: domain=example.com
POST http://foo.example.com/bar-form.php
---
# 送信元オリジン
Origin: https://example.com
Cookie: sessionid=<セッションID>; csrftoken=<トークン>


HttpOnly属性

▼ HttpOnly属性とは

これを有効化した場合、Set-CookieヘッダーにHttpOnly属性が割り当てられるようになる。

JavaScriptからCookieヘッダーにアクセスできなくできる。

200 OK
---
Set-Cookie: HttpOnly


sameSite属性

▼ sameSite属性とは

属性値 説明
None 異なるドメインから受信した全てのリクエストがCookieヘッダーを持つことを許可する。
Lax 異なるドメインから受信した一部のリクエストがCookieヘッダーを持つことを許可する。
Strict 異なるドメインから受信した全てのリクエストがCookieヘッダーを持つことを拒否する。

異なるドメインからのリクエストがCookieヘッダーを持つことを許可/拒否する。

ここでリクエストを制御しているのは、オリジンではなく、ドメインであることに注意する。

200 OK
---
Set-Cookie: SameSite=None


Secure属性

▼ Secure属性とは

これを有効化した場合、Set-CookieヘッダーにSecure属性が割り当てられるようになる。HTTPSプロトコルを使用した場合のみ、リクエストにCookieヘッダーを割り当てられるようになる。

200 OK
---
Set-Cookie: Secure


11. 【L7】認証/認可情報の複雑化

認証/認可情報の複雑化とは

L7 (アプリケーション層) に対するサイバー攻撃 (例:SQLインジェクション) を防御する。

認証/認可で必要になる情報を簡単に特定できないようにする。


BCryptによるハッシュ化

▼ BCryptによるハッシュ化

BCryptを使用して、Blowfish方式に基づく暗号化を実行する。

Blowfish方式では、同じパスワードの文字列であっても異なるハッシュ値が作成されるため、レインボー攻撃を防げる。

Blowfish方式で作成されたハッシュ値は、異なるルールで作成された複数のハッシュ値の組み合わせである。

▼ 構造

# <アルゴリズムバージョン> + <ストレッチング回数> + <ランダム文字列> + <パスワードハッシュ値>
$2y$10$1QVmWNzk.TsaZQLQ/zeI9OAZL02AWP.VdFPPyAc9hSc2Cp4yOXKtG
文字列 説明
$2y$ (4文字) 暗号アルゴリズムのバージョンを表す。他に、22a2b2xがある。
$10$ (4文字) ストレッチング (ハッシュ化の反復) の回数を表す。10とした場合は、2^10回反復でハッシュ化を実行する。
1QVmWNzk.TsaZQLQ/zeI9O (22文字) ソルト (ランダムな文字列) を表す。
AZL02AWP.VdFPPyAc9hSc2Cp4yOXKtG (31文字) パスワードそのもののハッシュ値を表す。


12. 【L7】アプリケーションのリクエスト数制限

リクエスト数制限とは

L7に対するサイバー攻撃 (例:Dos攻撃、DDos攻撃など) を防御する。


POSTリクエストのリクエスト制限

*実装例*

php.iniファイルにて、一度に受信できるPOSTリクエストの上限値を設定できる。

max_input_vars = 1000


同一送信元のリクエスト制限

同じ送信元からの1分間当たりのリクエスト数を制限する。

例えば、AWS WAF、AWS API Gatewayを使用する。