#️⃣

fastlaneでApple IDがロックされた事件はなぜ起きたのか

2023/03/03に公開

xcodesやFastlaneなどのツールを使用すると、Apple IDがロックされてしまう問題が発生しました。

https://twitter.com/fastlanetools/status/1628788397304123393?s=61&t=-ADi06PN5Q9pEQlpeJDcng

記事を書いている3/3現在は、fastlaneとXcodes.appはこの問題が解決しているようです。
一体何が起きていたのでしょうか。

fastlaneのPR #21073を見ると、この問題に対応するため、hashcashと呼ばれるアルゴリズムを使ってApple IDの認証を行うように変更されました。
https://github.com/fastlane/fastlane/pull/21073

急な変更によりfastlaneなどのツールは、Appleが要求する証明計算を行わずにApple IDにアクセスしたため、Appleはこれらのリクエストを不審なものとして処理し、Apple IDをロックしてしまったということなのでしょう。

ちなみにhashcashを使っていることや、その仕様は https://appfigures.com が突き止めたようです。

https://twitter.com/joshdholtz/status/1628994906273337344?s=61&t=nuTXfaVV34n4Mub3qFmsFw

hashcashは、ウェブメールのスパム対策として開発されたアルゴリズムで、電子メールの送信者がメールサーバーに対してコンピュータ資源を消費することによって、メールがスパムでないことを証明するものです。
これによって安価に大量のリクエストをすることができなくなります。

hashcashの解き方は、ハッシュ関数を利用して、特定の条件(今回はAppleから返されるX-Apple-HC-Bitsの値)を満たすハッシュ値を生成することです。
条件を満たすハッシュ値を生成するためには、ランダムなデータを繰り返しハッシュ関数にかけて、条件を満たすまで繰り返す必要があります。

fastlaneのPRをみると、それが行われていることを確認することができます。

counter = 0
# loopで成功するまで繰り返している
loop do
  # ↓ dateは現在時刻なので毎回異なるhcが生成される
  hc = [
    version, bits, date, challenge, ":#{counter}"
  ].join(":")
  
  # ↓ hcのhashを計算して、先頭が与えられたbitと同じなら証明成功
  if Digest::SHA1.digest(hc).unpack1('B*')[0, bits.to_i].to_i == 0
    return hc
  end
  counter += 1
end

https://github.com/fastlane/fastlane/pull/21073/files#diff-431b91c178cba00c3e9fc4c30aa254a6f6f4dab3e0a67f58b05694d5636dbc13R39-R49

同様に、Swiftで書かれたXcodes.appでも同じ処理が行われていることが確認できます。

https://github.com/RobotsAndPencils/XcodesApp/pull/361/files#diff-34cf37ba6020d528a67d853be891e653b6b930b2d9a5bfa1685d38203b3e66bcR48-R79

AppStore ConnectへはAPIキーを利用する方法が推奨されているものの、権限周りの小回りが効かないこともありfastlaneのspaceshipを使っていた方も多いと思います。
今回の問題は、各種ツールをアップデートすることで対応できますが、せっかくなのでその裏側を覗いてみると面白いかもしれません。
意外にも簡単な仕組みでspamを対策できるのですね。

Discussion