はじめに
④の続きです。
データベース関連
ウェブサイト、データベースと来て一番最初に考えなければならないのはSQLインジェクションという攻撃である。
この攻撃はデータベースを操作するときのコマンド上でユーザが悪意のあるデータを入れると意図しないデータを持ってこれるという攻撃である。
--ユーザの入力したreplay_idに合致するreplayのメタデータを取得するSQL
SELECT * from replays where replay_id = {ユーザの入力}
--ユーザの入力を [1 OR 1=1] とすることで全てのカラムで条件を満たし
--全てのreplayのメタデータを取得するSQL
SELECT * from replays where replay_id = 1 OR 1=1
これは国の独立行政法人IPA曰くインシデント届出のうち11%に上り、非常にメジャーな脆弱性である。資料ページの一番最初に出てくる単語という時点でお察しである。
それ用のライブラリを使って対策を行った。
パスワード関連
旧ロイヤルフレアでは1つのリプレイに対して1つの削除用パスワードが紐付く。
よって今回の実装でも削除パスワードを何らかの形で保管することにした。
しかしパスワードをそのまま保管しておくと万が一不正アクセスでパスワードを見られたときの被害が大きくなる。何よりサーバ管理する未来の自分がパスワードを使って良からぬことを企まないか心配である。
そこでハッシュという複合不可なデータ変換手法を使う。
リプレイ投稿時にパスワードをハッシュ化しておき、削除依頼が来たときは送られてきたパスワードをハッシュ化して手元のハッシュ化済パスワードと等しいか比べる。
ハッシュの安全性はハッシュのアルゴリズムによって異なる。コンピュータの発達によって昔は安全だとされていたハッシュアルゴリズムも危険になってしまう事がある。
また、安全とされるハッシュもレインボーテーブルという攻撃によって突破される可能性がある。これは事前に平文とハッシュ対応表のようなもの1を作っておくことでハッシュが複合出来てしまうというものである。
アルゴリズムが固定ならそれ用のレインボーテーブルを作っておけば突破されてしまうのでハッシュに自分なりに一工夫加える必要がある。
一般にユーザの入力したパスワードに対してソルトやペッパーと言われるノイズを含ませたり、何回もハッシュ化させるストレッチングという手法を使うことで破られにくくする。
フロントエンド
vueとvuetify
一般にユーザが使用しているブラウザはJavaScriptに対応している。
このJavaScriptを使うことで動く画面を作ったり、ユーザがコマンドラインを叩かなくても画面を通してバックエンドのAPIを叩くことができる。
フロントエンドサーバはユーザ側ブラウザで実行してほしいJavaScriptを定義し、ユーザがアクセスしてきたときにそれを提供する役目を持つ。
フロントエンドを実装するにあたりJavaScriptでプログラミングしても良いのだがJavaScriptをラッピングしたvueというものがあり、使うだけでそれっぽい画面が作れるvuetifyというライブラリを使うことでそれらしい画面を作った。
vueもvuetifyも日本語ドキュメントがまとまっており、調べながら実装するのがバックエンド実装より容易だった。
CORS
しかしフロントエンドからバックエンドに向かって通信しようとしたところうまくいかなかった。
これはどうやら CORS
と SOP
というものが関わっているらしい。
同一サーバの同一ポートで動くサービスをオリジンが等しいという。
同一オリジンでないとき、 SOP
( Same Origin Policy
) というものが働き、ブラウザが自主的に通信をブロックする。
これがどういうときに効果を発揮するかというと
以下のように意図せず悪意のあるJavaScriptをブラウザが入手してしまった場合である。
これを回避するためにブラウザはあらかじめJavaScriptによって通信される先のオリジンにはJavaScriptの発行元オリジンのことを知っているか聞いてから通信することになっている。
よってバックエンドで動いているfastapiにフロントエンドのオリジンを登録してあげなければならない。こうすることで初めて通信ができる。これを CORS
( Cross-Origin Resource Sharing
)という。
ただしこれはあくまでブラウザが SOP
に対応していないといけない。脆弱なブラウザを使うと普通に通信出来てしまうので注意である。
次回
アプリ開発が終わったのでネットワークの配置について勉強していく
参考文献
-
正確には違うだろうけど許してくれ。 ↩