各セキュリティとその対策方法

皆さんセキュリティ対策はバッチリでしょうか？？？

今回は、こういうセキュリティ問題があって主な事象、解決方法を紹介していきます
この記事によって皆さんのセキュリティ意識が上がればなと思います！

# セキュリティとは
IT分野では暗号や防御のためのソフトウェア、アクセスの制限などを用いて、データやシステム、通信経路などを保護し、機密漏洩や外部からの攻撃、改ざんなどの危険を排除すること全般を指します。その中でも具体的な問題を説明していきます。
# SQLインジェクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545871/f7bb3845-6343-4169-1440-0434057240e3.png)

SQLインジェクションの脆弱性がある場合、悪意あるリクエストによってデータベースの不正利用を招く可能性があります！！

## 脆弱性のある実装
```
String sql = "SELECT * FROM user WHERE id = '" + id + "'";
```
<span style="color: red; ">" + id + "</span>の部分に攻撃のための文字列が代入された場合、変数sqlの値として、下のSQL文が構成されます。

```
SELECT * FROM user WHERE id='aiueo' or 'A'='A'
```

## 解説
WHERE句に注目すると、検索条件は<span style="color: red; ">「id(データベース中の氏名)が'aiueo'と同値、もしくは、'A'が'A'と同値かどうか」</span>です。idがどんな値でも、'A'と'A'は常に同値となるので、検索条件は常に真となってしまいます。そのため、データベース内の全ての行で検索条件が真となり、全ての行が選択されてしまいます。

## 対策
**プレースホルダを使用します！**

```
String sql = "SELECT * FROM user WHERE id = ?";

// プリペアドステートメントオブジェクトの用意
PreparedStatement ps = conn.prepareStatement(sql);

// SQL文の1番目の?を、id（ユーザから受け取った攻撃のための文字列）に置き換え
ps.setString(1, id);
```

# XSS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545871/15120ae0-d2e4-2478-fb37-1c42bf1ccbd4.png)

XSS(クロスサイトスクリプティング)とは、掲示板などの動的なWebサイトにある入力フォームに罠（脆弱性のあるサイトへ誘導するスクリプトを含んだリンク）を設置します。リンクをクリックしてこのようなサイトに誘導されると、ユーザーのブラウザ上で不正なスクリプトが実行され、入力した情報やCookieなどが攻撃者へ漏洩、マルウェアへの感染、なりすましなどの被害が発生します。
XSSが起こってしまう要因は、入力値が制限されていなかったり、入力したスクリプトをそのまま実行できる状態にあり、攻撃者が容易に不正なスクリプトを入力できてしまうことが挙げられます。

## 脆弱性のある実装
```
<div>
    検索結果:<?php echo $keyword?>
</div>
```

## 対策
**HTMLテキストの入力を許可しないように、エスケープ処理を施します！**

```
<div>
    検索結果:<?php echo htmlspecialchars($keyword,ENT_QUOTES)?>
</div>
```

# CSRF
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545871/485ae910-dab2-d6e3-4e6d-25754cce2d2b.png)

CSRF(クロスサイトリクエストフォージェリ)とは、掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他サイトからのリクエストを受信し処理してしまいます。直訳すると**サイトを跨ぐ偽造リクエスト送信**です。
XSSと似ていますが、XSSは掲示板など動的なWebサイトにある入力フォームの脆弱性を狙ったものですが、CSRFはセッション管理における脆弱性を狙う攻撃です。

## 対策
**指定のフォームを利用して投稿していることを確認します！**
①セッション開始時にトークンを発行
②送信用フォームにトークンをhidden要素で埋め込む
③トークンをPOSTメソッドのリクエストで渡す
④トークンが正しいか検証

```
//サーバー側:token発行
<?php

session_start();

if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = sha1(random_bytes(30));
}

?>

...

<input type="hidden" name="csrf_token" value="<?=$_SESSION['csrf_token']?>">

```
```
//フロント側
<input type="hidden" name="csrf_token" value="<?=sha1(session_id())?>">
```
```
//サーバー側(リクエスト受取時)
<?php

session_start();

if ($_POST['csrf_token'] !== sha1(session_id())) {
    exit('invalid token');
}
```

# クリックジャッキング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545871/f00199e6-66f1-c12e-4386-3e3731fcd032.png)

サイトの上にiframeで重ね合わせ、見た目は分からないようにして、罠ページのクリックを誘導する仕組みです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545871/82ce0bee-3b44-e593-f06f-2e5c437e6478.png)



## 注意が必要なウェブサイトの特徴
ログイン後の利用者のみが利用可能な機能（サービスや設定）を、マウス操作のみで実行可能なウェブサイトが、クリックジャッキング攻撃による影響を受ける可能性があります。

## 対策
HTTPレスポンスヘッダに、**X-Frame-Optionsヘッダフィールド**を出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限します！


CloudFrontでレスポンスヘッダを設定することが出来ます！！
https://dev.classmethod.jp/articles/cloudfront-support-response-headers-policies/#toc-1

**X-Frame-Optionsがあるかどうか確認方法**
ページの<span style="color: red; ">検証ボタン</span>を押す
↓
<span style="color: red; ">ネットワーク</span>を押す
↓
リロード
↓
ヘッダのタブでレスポンスヘッダを確認

# さいごに
セキュリティの件は奥深すぎて理解できていない部分も多くありますが、これからも習得していってアウトプットできればいいなと思います