WebApiGoodpartsを読んだ

WebApiGoodpartsを読んだ。前の投稿の続き

# APIのバージョン管理
外部に公開するAPIであれば、APIの修正時には影響が大きい。
バージョンで管理し、アクセスする側が切り替えることができれば新旧が同時に稼働でき影響を小さくできる


## バージョン管理のベストプラクティス
- URLに含ませるパターン
- クエリパラメータで指定する場合
- メディアタイプに含ませるパターン

3つのパターンがあるが、「URLに含ませるパターン」がおすすめとのこと。
URLに含ませるのにも、整数で表現するか小数点で表現するかがあるが、**小数点をつけない方法がおすすめ**とのこと
1. https://aiueo.com/v1/accounts
2. https://aiueo.com/v1.1/accounts

上記1のパターンがベストってこと。

# APIのセキュリティ

## HTTPSで実装しても100%安全ではない

HTTPSでやり取りを行っても、その情報は100%正しいものになるとは限らない。
どういう攻撃手段が存在するかを理解し、対策を打つことは必須。

### 不正な証明書
HTTPS通信を行う際は、通信先の証明書を入手し公開鍵を使用し暗号化して送信するという流れになるが、アクセスしたサイトから入手した証明書が正しいもので無ければ、暗号化した情報であってもか暗号化に使用した情報が不正なので、攻撃者に情報は見られてしまう。

公衆wifiの仕様が推奨されないのはこういった背景がるようだ。
通信経路にこういった情報を仕組まれる危険性があるので、セキュリティが担保されていないネットワークに接続するのは危険だと言われれるのはこのあたりの問題があるから。

したがって証明書の発行元が正しいかの検証は行う必要がある。

これはクライアントからしか対応できない？
APIの提供元から対応できることはあるのかな？
という状況だけど、HTTPSは重要なのでまずはHTTPSにしとけと。

## XSS(クロスサイトスクリプティング)
悪意のあるコードがクライアントで実行されてしまいう事象。
結果、ユーザーのセッション情報や個人情報がダッシュされ不正アクセスに繋がったりする。
これもサーバー側からは防ぎにくい。

サーバー側の対処は**入力チェックや、content-typeを明示して情報の種類を限定させること。**
こうすることでサーバー側には不正な値は入りにくいし、送信されたデータが実行されることを防ぐことができる。
content-typeの対策はJSONハイジャックの対策にもなるみたい。
これは必ず入れておきたい。


この辺りはフレームワークがよしなにしてくれたらいいな。

https://qiita.com/tamura__246/items/85c61dc06695ca1da89a
うーん、ダメみたい。

まぁ、認証トークンを用意してトークンが認可されたら処理を開始する形にすればもう少しはましになるかも。

## 悪意のあるユーザー
他社からの盗難や改ざんをもし100％防げても、ユーザー自身が悪意を持ってサイトに攻撃をしてくることも考慮する必要があります。
その対策も必須

### クエリパラメータの改ざん
APIを使用を公開していたとして、そのAPIに隠しパラメータがあったとする。
それをユーザーが発見し、想定外の情報にアクセスされるなんてこともあるみたい。
本来アクセスできない情報は正確に制御しなければならない。

例えばテスト用の便利パラメータを本番環境で稼働させてしまいそれが発見されてしまい情報が漏れたなんてことはありそう。
そうならないためにも隠しパラメータを使用するルールを設けるべき。
「このパラメータの仕様は、特定のサーバーからしかアクセスできない」とか。

他にも、ソーシャルゲーム内のパラメータを簡単に更新されるようなAPIに仕様にするのもNG。
通常であれば操作できない情報だけど、APIを実行すれば簡単にアイテム数が増加できるような仕様は避けておきたい。
実装としてはそのほうが簡単だが、システム運用的には内部ロジックで変更できるようにしたい。

### 再送信処理防止
同じAPIアクセスを複数回実行された際の対策について。
例えば、回数に意味のある事象(動画再生数とか)はURLのアクセスが何度も起こればその分カウントが上がり、悪意のあるユーザーによって簡単に操作できてしまう。

そうならないように短期間での同じアクセスはカウントしないような実装がサーバー側には求められる。

## HTTPのヘッダを理解する
ヘッダー情報でも様々な制御を行うことができる。
なかでも「x」で始まるヘッダー構文はいくつか種類があり、この定義だけで実装が不要になることもあるので考慮しておきたい。

これみとけばよさそう
http://hasegawa.hatenablog.com/entry/20110107/p1

## レートリミットを設定する
Dos攻撃は簡単にできるけど、やられるほうはたまったもんじゃない。
そのような攻撃を防ぐことができるのがレートリミット
レートリミットは単位時間当たりのアクセス上限を設定できる機能。

使用しているフレームワークに実装されていれば実装してみるのも良いかも。
ヘッダーで定義できるみたいですね。
https://asnokaze.hatenablog.com/entry/2019/09/06/020716

# API開発チェックリスト
付録にチェックリストついてたので、理解したこととこのチェックリストでアプリケーションを作っていくか

- 付録BWebAPIチェックリスト最後に本書の内容を簡単に確認するためのチェックリストを用意しました。WebAPI開発時のチェックにお役立てください。
- URIが短く入力しやすくなっているか
- URIが人間が読んで理解できるようになっているか
- URIが小文字のみで構成されているか
- URIが改造しやすくなっているか
- URIにサーバ側のアーキテクチャが反映されていないか
- URIのルールは統一されているか
- 適切なHTTPメソッドを利用しているか
- URIで利用する単語は多くのAPIで同じ意味に利用されているものを選んでいるか
- URIで使われている名詞は複数形になっているか
- URI中にスペースやエンコードを必要とする文字が入っていないか
- URI中の単語はハイフンでつないでいるか
- ページネーションは適切に設計されているか
- ログインには0Auth2.0を利用しているか
- レスポンスのデータ形式はJSONがデフォルトになっているか
- データ形式の指定にはクエリパラメータを使う方法をサポートしているか
- 不要なJSONPに対応していないか
- レスポンスのデータ内容はクライアントから指定できるようになっているか
- レスポンスデータに不要なエンベロープが入っていないか
- レスポンスデータの構造は可能なかぎりフラットになっているか
- レスポンスデータが配列ではなくオプジェクトになっているか
- レスポンスのデータ名として多くのAPIで同じ意味に利用されている一般的な単語を選んでいるか
- レスポンスのデータ名はなるぺく少ない単語数で表現しているか
- レスポンスのデータ名として複数の単語を連結する場合、その連結方法はAPI全体を通して統一してあるか
- レスポンスのデータ名として変な省略形を使用していないか
- レスポンスのデータ名の単数形／複数形はデータの内容と合っているか
- エラ一時のレスポンスはクライアントが原因を切り分けられるような情報を含んでいるか
- エラーの際にHTMLが返っていないか適切なステータスコードが返るようになっているか
- メンテナンス時には503を返すようになっているか
- 適切なメデイアタイプを返しているか
- 必要な場合はCORSに対応しているか
- クライアントが適切にキャッシュを行えるようにcache-Control、ETag、Last-Modified、Varyなどのレスポンスヘッダを返しているか
- キャッシュをさせたくないデータにはcache-Control:no-cacheが付けられているか
- APIはバージョンで管理されているか
- APIのバージョンはセマンティックバージョニングに沿ったものになっているか
- メジャーバージョン番号がURIに入っており、ひと目でわかるようになっているか
- APIの提供を終了する際のことを考慮に入れているか
- APIの最低提供期間をドキュメントに明記しているか
- HTTPSでAPIを提供しているか
- JSONのエスケープをきちんと行っているか
- JSONはX-Requested-Withヘッダを認識するなど、SCRIPT要素では読み込めないようになっているか
- プラウザからアクセスさせるAPIではXSRFトークンを利用しているか
- APIが受け取るパラメータはきちんと不正値（マイナスの値など）をチェックしているか
- リクエストが再送信されてもデータを再度更新してしまわないようになっているか
- レスポンスにセキュリティ対策用の各種ヘッダをきちんと付けているか
- レートリミットによる制限を行っているか
- レートリミットの制限回数は想定されるユースケースに対して少なすぎないか