nikkie-ftnextの日記

イベントレポートや読書メモを発信

#djangocongress やられサイトアップデート:マルチステージビルドを使えば、READMEでの.env作成案内が不要にできるじゃん!

はじめに

10/12(木)のみんなのPython勉強会#98がお祭り騒ぎ!ぜひ!! nikkieです。

先日DjangoCongress JP 2023で登壇しました1(登壇報告エントリは改めて)。
脆弱性を作り込んだWebアプリをDjangoで実装し、トークの時間は自作やられサイトにみんなで一緒に悪いことしました!

一緒に悪いことをしようとして手を動かしてくださった方からは、「docker compose upで立ち上がらなかった」というフィードバックもいただいています(Twitterや懇親会)。
これは完全に私の準備不足なのですが、ふと「Dockerfileでカバーできたよな」と気づいたので、今回1本したためます。

目次

当初の想定:「READMEで.env作成をカバー」

今回のアプリを開発するにあたり、私はローカル環境で動かしてからDocker化という手順を踏みました。
django-environ2を使っていて、SECRET_KEYDATABASE_URL.envで管理しています。
このファイルは.gitignoreに記載しているので、GitHubにpushされることはありません。

私の環境ではdocker compose upすると、すでに作ってある.envを含めてソースコードをDockerイメージにコピーして、アプリケーションは問題なく動きます。
一方、このリポジトリをcloneした方には、.envを作っていただく必要があります

https://github.com/ftnext/django-bad-apps/tree/659a1dc974565813d49c6848adee09e0718200d3/cross-site-scripting#%E6%8E%A8%E5%A5%A8-docker-compose%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99

vim bad_xss/.env

(.envファイルの中身が続きます)

これはめちゃめちゃいい方法ではなく、あくまで最低限という自覚はありました。
一方、限られた登壇準備の時間では他の箇所を優先し、READMEの案内から掘り下げることはできませんでした。
当日「一緒に手を動かしたい」と思ってくださった方には本当に感謝しています。
私の案内や準備が不十分だったばっかりに手元で攻撃できず申し訳ありません。

閃いた!「Dockerfile工夫してビルド中に.env作っちゃえばいいじゃん」

マルチステージビルドしているので、前段で.env作ってそれをコピー、これでREADMEに記載した手順をなくせることに気付きました。

FROM python:3.11-bookworm as builder
WORKDIR /code
COPY requirements.lock /code/
RUN pip install --no-cache-dir -r requirements.lock
+RUN SECRET_KEY=$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())') && \
+cat <<ENV_FILE > .env
+DEBUG=True
+SECRET_KEY=${SECRET_KEY}
+DATABASE_URL=postgres://developer:mysecretpassword@db/badapp
+ENV_FILE

FROM python:3.11-bookworm
WORKDIR /code
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY bad_xss /code/
+COPY --from=builder /code/.env /code/.env
COPY environments/webapp/entrypoint.sh /code/
CMD [ "./entrypoint.sh" ]

手元で(.envを消した後)攻撃デモが動かせたので、リポジトリをcloneした方もこれですぐに動かせるはず!
技術で殴って小さなめんどくささを排除できた感🙌

現状、テスト駆動開発でいうところのGreenだと思っていて、Refactorにあたるブラッシュアップは必要そうです。
ただドキュメントで込み入った説明をするより、技術で殴って込み入った説明をなくすeasyさは好むところであり、この方向性は気に入っています。
手を動かす中でわかったことがあれば追記や追いエントリします。

終わりに

DjangoCongress JP 2023のやられサイトについて、登壇後のフィードバックを踏まえて.envの用意を自動化するアイデアをしたためました。
この閃きが登壇前に降ってきていたら、もっとよかったな〜(悔しくって死にそう
Dockerのマルチステージビルドは面白いですね〜

P.S. 「Djangoアプリに作り込んで学ぶ脆弱性SQLインジェクションXSS篇)」関連リンク

発表中の反応はTogetterをどうぞ(kashewさんありがとうございます!)

質問で気付きがあり、延長戦しました