This site is a mirror of ama.ne.jp.

Netlifyの裏側とSHA-1

(2020-09-27) もうこのサイトのバックエンドはNetlifyではありません。言及されているファイルへのリンクはama.ne.jp上のものに戻されています。

先日投稿したSHA-1をぶつけたに対して、たくさんの反応ありがとうございました。

さて、この記事で生成したSHA-1ハッシュが一致する異なるPDFファイルへのリンクが、ama.ne.jp上のものからGitHub上のものへ変わったことにはお気づきでしょうか?

旧(on ama.ne.jp): a.pdfb.pdf

新(on GitHub): a.pdfとb.pdf

それぞれのリンクを開くとおかしな点に気付きませんか? 今回はこの問題についての報告です。

Netlifyって何?

Netlifyはイケイケのホスティングサービスで、以下のような特徴があります。

  • GitHubとかのpushを契機にビルド、デプロイしてくれる。ビルドのタイミングはもちろん手動でも。
  • 適当にやりたい時は、ファイルを直接アップロードしても公開できる。
  • Let's Encryptに対応(向こうで取得と更新をしてくれる)している。
  • 複数のブランチデプロイを使ってA/Bテストみたいなことができるみたい。
  • スクリプトをくっつけたりとか自動minifyとか画像の最適化とか、他にも色んな細かい機能があるよ。

静的サイトの公開のために作られている上にホスティングまでくっついているので、他のCIを使ってシコシコタスクを書いてgh-pagesにpushして……よりは楽な気がする。分からん。

何が起こったの?

そんな素晴らしいNetlifyですが、先程の旧リンクでは、どちらのリンクも赤い大仏のPDFファイルを指してしまいます。ファイルのアップロードミスでもリンクのミスでもなく、Netlifyの仕様のせいです。

Netlifyでは、SHA-1ハッシュをキーにしてファイルを管理しているそうです1。そのため、同じSHA-1ハッシュを持つ複数のファイルが全て同じファイルとして取り扱われました。ただし、このインデックスはサイトごとに独立したもので、他のサイトのファイルを差し替えるというような攻撃はできないそうです。

おそらく、データを先頭から比較して最も小さいファイルが代表になるようです。

赤い大仏の方がデータが小さい(?)

$ python
>>> red = open("red.pdf", "rb").read()
>>> blue = open("blue.pdf", "rb").read()
>>> red[:193]
b'%PDF-1.3\n%\xe2\xe3\xcf\xd3\n\n\n1 0 obj\n<</Width 2 0 R/Height 3 0 R/Type 4 0 R/Subtype 5 0 R/Filter 6 0 R/ColorSpace 7 0 R/Length 8 0 R/BitsPerComponent 8>>\nstream\n\xff\xd8\xff\xfe\x00$SHA-1 is dead!!!!!\x85/\xec\t#9u\x9c9\xb1\xa1\xc6<L\x97\xe1\xff\xfe\x01s'
>>> blue[:193]
b'%PDF-1.3\n%\xe2\xe3\xcf\xd3\n\n\n1 0 obj\n<</Width 2 0 R/Height 3 0 R/Type 4 0 R/Subtype 5 0 R/Filter 6 0 R/ColorSpace 7 0 R/Length 8 0 R/BitsPerComponent 8>>\nstream\n\xff\xd8\xff\xfe\x00$SHA-1 is dead!!!!!\x85/\xec\t#9u\x9c9\xb1\xa1\xc6<L\x97\xe1\xff\xfe\x01\x7f'
>>> red[192]
115
>>> blue[192]
127

ファイル名に関係なく赤い大仏が出てくる

どうやって直すの?

ユーザーでできる対策はないようです。順次、SHA-256を使ったインデックスに切り替えているとのことですが、詳細は分かりません。

最後に

というようなことを教えてもらった情報源のチャットログを紛失してしまいました。信頼ならない噂程度ということで。すみません。


  1. URL→SHA-1ハッシュ→ファイルみたいな感じなのかな? 

「読んだ」を押すと、あなたがボタンを押した事実を明示的に通知してこのページに戻ります。
このページに戻ってからブラウザの「戻る」ボタンを押すと、何度か同じページが表示されることがあります。