PHPのセキュリティ対策

こちらの記事は以下の書籍を参考に執筆しました

[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版［リフロー版］　脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)

#クロスサイトスクリプティング(XSS)
エンドユーザからの入力などによって生成されるページでは
不正なスクリプトが混入/実行されてしまう可能性があります。
このような脆弱性のことを**クロスサイトスクリプティング**といいます。

綴は**Cross Site Scripting**で略すと**CSS**ですが、
略すると**Cascading StyleSheet**と混同してしまうので、
クロスサイトスクリプティングは**XSS**と略すのが一般的です。

##対策
XSS脆弱性を回避するには、動的に生成される
すべての値に対してエスケープ処理をすることです。

しかしエスケープ処理ですべてのケースに対応できるわけでありません。
例えばJavaScript疑似プロトコルによるコードの埋め込みや、
不正なマルチバイト、nullバイトを埋め込み、
タグを意図的に「破壊」してスクリプトを混入させる等の攻撃でを避けるためには、入力値の妥当性検証も必要です。

#タグ文字列の許可
エンドユーザからのタグ文字列を容認したい場合も、全てのタグを無条件に受け入れることは危険です。

安全なタグだけを残すために、一旦文字解析して、安全なタグと属性だけで文字列を組み立て直す作業を自分でおなうのは大変です。

そこで**HTML Purifer**ライブラリを使用します。
HTML Puriferはcomposerからインストールできます。

#SQLインジェクション
**SQL命令に不正なパラメータを引き渡すことで、開発者が意図しないSQL命令が生成/実行されてしまう脆弱性を指します。**

エンドユーザによってもともとのSQL命令が書き換えられてしまう大きな問題で、
もともとのSQLに対して、別のSQL命令を注入(**injection**)するという意味でSQLインジェクションと呼ばれます。

##対策
**SQLエスケープ**が有効です。
SQLエスケープは終了文字「'」を「''」に置き換えることで予約文字「'」を無効化します。

値一つ一つにエスケープ処理をするのは大変なので、PDOを利用しているなら**プレイスホルダ**を利用すべきです。

プレイスホルダを利用することでエスケープ処理をPDOStatementクラスが内部的に色々やってくれるので開発者は気にせず開発をすすめることができます。

#OSコマンドインジェクトション
OSコマンドに対して不正な命令を注入することを**OSコマンドインジェクション**といいます。

具体例を示すと以下となります。

```php5:shell.php
<?php
$result=shell_exec("dir {$_GET['param']}");
```

>出典：[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版［リフロー版］　脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)


PHPではスクリプトからOSコマンドを実行する方法として

- shell_exec関数
- exec
- passthru関数
- 「`」演算子

等の命令を利用できます。

ここではdirコマンドに対してクエリ情報paramの値をパラメータとして引き渡そうとしていますが、脆弱性を含んでいます。

例えばshell.phpに対して
`~shell.php?param=|%20mkdir%20test`
のようにアクセスすると、以下のようなコマンドが生成されることになります。

```bash
$ dir | mkdir test
```
クエリ情報の内容を変更すれば、フォルダを削除することもファイルの内容を出力することも可能となってしまいます。

コマンド実行系の命令はできるだけ利用しないようにしたいですが、どうしても使用する場合にも**外部からの入力をそのまま容認してしまうのは避けるべきです。**

それでも**どうしてもやむを得ない**という場合にはユーザの入力を**escapeshellarg関数**でエスケープ処理をします。

```php5
$param=escapeshellarg($_GET['param']);
$result=shell_exec("dir {$param}");
```
>出典：[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版［リフロー版］　脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)



ちなみに、コマンド文字列をエスケープするためにescapeshellcmd関数もありますが、
**そもそも外部入力からコマンドそのものを生成するのは避けるべきです。**
>出典：[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版［リフロー版］　脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)