Amplifyを使った個人開発でのヒヤリハットとその対策

## はじめに

AWS Amplifyを使ってTASUKUというタスク管理サービスを開発しています。
カンバンボードとガントチャート使ったテッパンのタスク管理ができます。
今のところ誰でも無料でご利用いただけます。
https://tasuku.works/

さて、今回はAmplifyを使った個人開発でのヒヤリハットとその対策ということでセキュリティ対策について書いていきます。
主に以下の様な方向けの記事です。

* AWSを使用している人、特にAmplifyを使用している人
* 個人開発をしている人
* フリーランスの開発者

自分もまだまだ勉強中であまり偉そうなことは書けないのですが、今までやってきたことの備忘録として書いてみます。

## AWSベストプラクティス

AWSのサービスって多すぎてセキュリティ対策と言っても何からやっていいかわからない...。
という状態であればまず最初に確認すべきはやっぱり公式ドキュメントですよね。

https://docs.aws.amazon.com/ja_jp/audit-manager/latest/userguide/aws-foundational-security-best-practices.html

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/fsbp-standard.html

AWSのサービス毎に標準が書かれていて自分に必要なサービスのものだけ掻い摘んで読むこともできます。
ざっと見ただけでも、あ～これやっちゃってるわ～とか、逆にやってないわ～というものが結構あるのでヒヤリ案件です。

公式ドキュメントを読んでもよくわからないということもありますが、「AWS ベストプラクティス」とかで検索するとわかりやすい資料がたくさん見つかります。感謝です。

https://speakerdeck.com/koheiyoshikawa/awschu-xin-zhe-xiang-ke-besutopurakuteisukaraxue-bu-awssekiyuriteinogao-mefang

https://business.ntt-east.co.jp/content/cloudsolution/ih_column-20.html


## Lambdaの関数URLがパブリック

AWSベストプラクティスにも書かれていますがLambdaの関数URLはパブリックにするべきではありません。

https://dev.classmethod.jp/articles/lambda-function-policies-should-prohibit-public-access/

とある機能の実装でLambdaを直接呼出す必要があったため手っ取り早くパブリックな関数URLにして呼んでいたことがありました。
これはよろしくない、ということでパブリックな関数URLはやめてAPI Gatewayを挟んだ構成に変更します。
使用量プランで1秒あたりのリクエスト数などを制限しておきます。

※AmplifyのREST API追加でもできるかもしれませんがまだ試せていません。

## LambdaへのDDos攻撃

https://qiita.com/naka345/items/98582cfb45ab09c3df9f

こちらの記事を目にしまして、はて...自分のサービスは大丈夫なんだろうか...と冷や汗をかきました。
Amplifyを使用するとGraphQLのAPIはAppSyncが使われることになります。
幸いAppSyncがいい感じに保護をしてくれているみたいです。ちょっとヒヤッとしましたが一安心です。

https://aws.amazon.com/jp/blogs/mobile/graphql-security-appsync-amplify/

https://qiita.com/shinonome_taku/items/9628c503c3b6896f55a2

https://zenn.dev/maromero/scraps/58c0b843c19e8d

## GraphQLのクエリが深すぎて余計な情報まで見えてしまう

TASUKUはマルチテナント型のサービスです。Amplify自体にマルチテナント型のサービスを実装するフレームワークが存在するわけではないのでかなり試行錯誤しながら実装しています。
詳しくはこちらのTASUKU開発日誌で掲載していますので興味のある方はご覧ください。

https://note.com/aoi/n/ndc338165056b?magazine_key=mfa2372e593ec

タスクはプロジェクトという単位で管理されます。1テナント=1プロジェクトとして、一人のユーザーが複数のプロジェクトに関わることができます。
その様なデータ構造だと、ユーザーの情報を取得した時にそのユーザーが所属しているプロジェクトの一覧がくっついて取得されてしまうということが起こりえます。特に自動生成されたGraphQLスキーマだとリレーションまで親切に全部つけてくれるので。
同じプロジェクトにAさん、Bさんという二人のユーザーがいた場合に、AさんがBさんが他にどんなプロジェクトに所属しているのか見えてしまったりするわけです。

その様なことがあるので、自動生成されるスキーマ(codegenディレクトリに生成される)はそのまま使用せずに、適宜修正したスキーマを使用しています。
またリゾルバーに手を加えて、schema.graphqlだけでは設定できない細かい認可処理を実装しています。

## Amplify + WAF

みんな大好きWAF。とりあえず入れたいWAF。
そもそもAmplifyにWAFって必要なのかなという疑問はあるのですが、入れておいた方が良いんですかね。良いんでしょうね。

AmplifyはWAFを簡単にいれる仕組みがなくてかなり苦労して試したことがあるのですが、つい最近正式にサポートされました。

https://dev.classmethod.jp/articles/amplif-waf-integration-preview/

自分もまだ上記の記事を読んだだけで実際に試したわけではないですが、導入が超簡単になっているみたいです。素晴らしい。

後は料金がネックです。WAF、個人開発のレベルだとちょっと高いんですよね...。
コスト抑制するノウハウがあったら知りたいです。

## 料金アラート

料金アラートを設定していれば最悪の最悪、何か悪さをされたとしても高額な料金になる前に気づくことができます。

https://aws.amazon.com/jp/aws-cost-management/aws-budgets/

※「AWS 料金アラート」などで検索すると[こちら](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
)のCloudWatchを使った方法がヒットしますがAWS Budgetを使った方が簡単です。

https://zenn.dev/sakojun/articles/20210618-aws-cost-alart

ただし、アラート機能だけでは予算上限になった場合に自動でサービスを止めるようなことはできません。
AWS BudgetsとLambdaを組み合わせてサービスを止めるような手法もあるようです。

https://dev.classmethod.jp/articles/aws-cost-saver/

Amplifyの場合にどうするかまではまだ試せていないので、時間があるときに挑戦してみたいと思います。

## コストの内訳を確認

これはセキュリティインシデントと少し違う話になるかもしれませんが、クラウドサービスあるあるな話なので書いておきます。

TASUKUはAmplifyを用いたサーバーレスアーキテクチャなので利用がなければ少額のコストしかかかりません。
情けない話この記事を書いている時点ではほぼアクティブユーザーは0なので(涙)何もなければ月額1ドルくらいです。
しかし、今年のある月で70ドルくらい課金されてしまったことがありました。
原因はAmplifyではなくて、自分が試しに使ってみたサービスを消し忘れてしまっていたせいです。
コストの使用状況を確認すると「EC2 その他」でした。
あ～あれのことかなぁと心当たりのサービスを削除して一安心。
と思っていたのですが、翌月確認するとまた数十ドルの課金が!
「EC2 その他」ってなんやねん! もっと詳しく教えてくれ! とググったところこちらの記事に助けられました。

https://qiita.com/beajourneyman/items/9cc6984e97b04d9a4460

AWSはサービスが多いですし、盲目的にチュートリアルなどやっていると気づかないところで副次的に作られてしまうサービスもあるので、ちゃんと確認するようにしましょう。反省。

## 保険

情報漏洩などのセキュリティインシデントを起こしてしまうと世間からめちゃくちゃに叩かれてしまいますが、そういったニュースやSNSでの反応を見ていると、この人達も被害者なのになぁと思わなくもありません。
無知で杜撰な開発、運用をしているせいでセキュリティインシデントを起こしてしまったということもあるでしょうが、全ては結局人がやっていることです。対策をしているつもりでもミスは起きます。

断罪されるべきは情報を盗んだ犯人の方であるべきだと思うのですが、犯人が捕まったというニュースは聞いたことがありません。いつも泣き寝入りです。
平和ボケした日本人的感覚からはかけ離れていますが海外旅行に行く時、持ち物は取られないように対策するみたいな心構えに似ているんでしょうか。やられた方が悪い、みたいな。

そういう風潮がありますがそれってどうなんだろうと思ってしまいます。むしろそういう風潮があった方がセキュリティの会社的には儲かるので敢えてそうしているのでは、みたいな陰謀論めいたことまで想像してしまいます。(この辺でやめておこう。)

じゃあどうするの? と言われると小学生が道徳の授業で言うようなことしか言えませんが、自分が生きているうちにその辺のパラダイムシフトって起きないかなと想像します。

さて、空想していても仕方ないのでこの章の本題に入ります。
いくら対策をしていてもミスはありますし、特に個人開発に至っては予算や割ける人的リソースにもほぼありません。
何か起こってしまった時のために保険に入るのも一つの手だと思います。

情報漏洩などの被害を補償してくれる保険は探せばたくさんありますが、自分の場合は日本イラストレーション協会(JILLA)に加入しているため福利厚生として保険が自動付帯されています。(限度額的には心許ないのかもしれませんが一旦はこれで良いかなと。)

https://jilla.or.jp/

フリーランスのWeb開発者にとってJILLAは超おススメです。フリーランスに人気のある文芸美術国民健康保険組合(文美国保)にも加入できますし、Adobeの割引などいろいろなメリットがあります。
「イラストレーション」という単語から判断して自分の様な職種には関係ないのかなとスルーしてしまった時期もあるのですが、よくよく調べてみるとwebデザインやCGワークも対象なので、プログラマーという肩書の人でもwebデザインなどのデザイン寄りの実績があれば加入できる可能性があります。
文美国保の様なお得な国保に加入できる開発者向けの組合というのが見当たらなかったのですが、なんでないんでしょうね。あればいいのに。
もしどこにも加入していなければ是非検討してみてください。JILLA良いですよ。