先日学んだセキュリティについてまとめてみたの巻

セキュリティって、この情報化社会においてますます必要不可欠になってきている分野だと日々私は思うんですね。
警察も国境もなく盗みの蔓延る世界で、資産を家に置いたまま、鍵をかけずに外出する人がいるでしょうか？
現実の日本では、島国で比較的治安も良く、警察のしっかり機能して下さっているにも関わらず、家の鍵は二重にするなどしっかりかけ、更にSECOMなどお金を払ってホームセキュリティを利用している家庭も数多くあります。


IoTを筆頭に、あらゆるものの情報化の進歩に伴って、セキュリティの対策に対して社会全体で注意を払うべきだと私は思います。また、日本の情報セキュリティ分野のマンパワー不足によって引き起こされる脆弱性は深刻です。このことを高校生の時に知り、「理系の知恵を使って社会の役に立ちたい」と小学生の頃から漠然と考えていたので、将来は情報セキュリティ分野に従事したいな〜と思いました。(ESばりの文章通りました)

ここでは、数ヶ月間前にインターンで学習して面白いと感じた、SQLインジェクションなどの攻撃手法とその対策などを、セキュリティ分野の初歩の初歩として、ここにまとめておきたいと思います。

##SQLインジェクションとは

SQLインジェクションのSQLとは、Structured Query Languageの略称である。つまり、組み立てたれた(Structured)データベースへの問合わせ(Query)命令文を実行するためのコンピュータの言語(Language)と直訳することができる。
つまり、SQLとは「データベースサーバを操作する命令文」のこと。
そして、インジェクション（injection）とは「注入・挿入」という意味。
それぞれの言葉の意味はなんとなく理解できただろうか。

つまりSQLインジェクションは、SQLに別のSQL文が「注入 (inject)」されることである。
「ダイレクトSQLコマンドインジェクション」または「SQL注入」と呼ばれることもある。
[参考:Cyber Security TIMES]
(https://www.shadan-kun.com/blog/glossary/285/)

サイバー攻撃におけるSQLインジェクションとは、データベースを利用したサービスにおいて、SQLの命令文の文法の利用した攻撃手法である。
実際に見てみよう

##SQLインジェクションの手法について

ここでは、user nameとpasswordを入力してuser_infoというユーザ情報が格納されたデータベースと照合し、ユーザネームに登録されたパスワードが合致すればログインできる、というサービスを考える。
ユーザが入力したデータは以下のように格納される。

```
$username = $_POST["username"];
$userpass =  $_POST["password"];
```
そのデータはこのようにデータ照合される。

```
SELECT * FROM user_info WHERE name = '$username' AND password = '$userpass';
```
この命令文によって、ユーザが入力したユーザ名に紐づけて登録されたパスワードが、入力されたパスワードと合致しているかどうかを調べ、ログインの可否が確認できる。

このサービスにおいて不正ログインをするにはどうするのか。

AND文、OR文がわかる人がみれば一瞬で理解できるだろう。
入力を以下のようにするのである。

```
$username : user1
$userpass : ' OR 'A' = 'A'
```
すると、userpassの部分が先ほどとは異なり、データベースにかける命令文は以下のようになる。

```
SELECT * FROM user_info WHERE name = 'user1' AND password = '' OR 'A' = 'A';
```
この命令文が意味するところは、nameが入力されたユーザネームである、かつpasswordが空欄もしくは「A=A」であるならばログインが成功するということである。
入力の部分で、__' OR 'A' = 'A'__となっているのは、一文字目にクオテーションマークを入力することで、password = という条件式を一回終わらせるためである。
そのあと、ORに続けて、A = Aという確実に成り立つ条件文を入れることで、OR以下の条件式は必ず正を返すことになる。
usernameと合致するpasswordをデータベースから探索する命令文だったわけだが、これによって、__passwordに何を入れても正を返す__命令文が出来上がったのである。

お分かりいただけただろうか？
入力によって命令文であるSQL文が操作されてしまった。

##SQL対策を考えてみよう
以上のように、入力によってSQLの命令文が操作されないようにするためには、入力された文字列をパラメータとしてではなく、ただの文字列として受け取りたい。
そんな時に使うのが、__プレースホルダー__。
プレースホルダーとは、SQL 文の中で可変な項目を後から変更可能なパラメーターとして処理する方法。
プレースホルダでは、以下の ? の部分を単純な文字列として扱うので、先ほどのような不正なパラメーターが入ったとしても問題なく処理することができる。

```
"SELECT * FROM LOGIN WHERE ID = ? AND PASSWORD = ? ;"
```

##XSSとは

続いて、他の脆弱性についても見てみよう。
XSS(Cross Site Scripting)を取り上げてみる。ニュースなどで耳にする機会がなきにしもあらずではないか。
頭文字をとったらCSSじゃん！！と思いますかね、私は思いました。
でもよく考えてみたら、CSS って Cascading Style Sheets に名前を取られてたんだった。。
むしろ、クロスって文字をXが表現しているようで良いのでは！

名前のことはさておき、クロスサイトスクリプティングとは、他人のWebサイトに悪意のあるプログラムを埋め込むことである。

##XSSの挙動について
ここでは、JavaScriptを用いたログイン画面について考えてみることにする。

Webページにおけるログインの画面で、ユーザが悪意を持って入力するケースを見てみよう。
今回も、ユーザ名とパスワードを入力し、合致するものが存在すれば、「ログイン成功　(ユーザ名)さんこんにちは」、存在しなければ以下のように、「ログイン失敗　(ユーザ名)さんが見つかりませんでした...」などと表示されるフォームに関して考える。
![スクリーンショット 2019-05-26 22.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411088/f1165376-d2c9-ae24-d2c0-aa0926906ac6.png)

JavaScriptでは、ご存知の通り<>タグを使ってコードを記述する。
よって、ユーザ側が入力する際に、<>タグを使ったコードをフォームの欄に入力してログインボタンを押し、入力された文字列が読みこまれると、ユーザが埋め込んだコードが実行されるのである。
悪意を持ったユーザは、これによって他人のクッキー情報を抜き取ったり、フェイクのWebページを表示させたりして個人情報を入力させて盗み取る。

XSSの例としては、

```
<script>alert('XSS');</script>
```
のように入力すると、XSSと表示されたアラート文が表示されるものがある。
これだけではXSSの脅威は感じられないが、ここにHTMLタグを埋め込めば、個人情報不正取得用のWebページを表示したり、クリックしただけでCookieの情報を自動的に送信してしまう仕組みを仕掛けることも可能になる。

##XSSの対策
なぜクロスサイトスクリプティングが起きてしまうかというと、<>タグなどの特殊文字を読み込んでしまうからである。ならば、<>タグなどの特殊文字を読み込まない処理を施せばよいのである。
この操作を一般に__エスケープ__と呼ぶ。
<>など、言語において特別な意味を持つ特殊文字をただの文字列として読み込むべく、他の文字列に置き換えるのである。
HTML中に悪意のあるコードが埋め込まれるのを防ぐためには、

```
 $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
```
読み込む文字列をstrとし、特殊文字も以上のように文字参照すればよい。

参考：http://blog.katty.in/95


##最後に

いかがだったでしょうか？
私自身、まだまだ初歩的な部分しか学習できていないと感じるので、これからもっと沢山の手法を学び、その度にここで記録・共有していきたいと思います。
日本を守るサイバーセキュリティになるために、これから沢山のことを学んでいくぞう！^o^