v1.25.2(Security Patch)
@February 24, 2022
概要
API仕様書に記載のSignup/Login Flowに関して、お伝えしていたフローの署名検証に問題がありました。なんらかの方法で他者のEOAの電子署名を取得でき、かつStartrailの仕組みを高い精度で理解している人に限り、その他者のEOAになりすますことが可能なことが分かりました。
Startrail-sdk-jsのパッチ・バージョン:1.25.2
1.25.2
フロー上で必要な変更(色線が変更箇所)
Before
After
# 差分のまとめ(番号はAfter図参照)
20.messageからprefixに変更
21.メッセージから接頭辞(=prefix)に変更
(Before:22.は削除)
24. 文字列から接頭文字に変更
25. 文字列から接頭文字を足し合わせた文字列に変更
セキュリティ脆弱性について
Signup/Login Flow図の中で以下のフローがありますが、

18. ランダムな文字列(=message)を生成し、EOAとマッピングさせる
22. カスタマイズしたメッセージ(=messageToBeSigned)を文字列として置き換える
26. 文字列、ユーザ情報、シグネチャを送信
27. 文字列、シグネチャからEOAを復元
22でカスタマイズしたメッセージ(=messageToBeSigned)を文字列に置き換えてサーバサイドに送信するため、サーバ側では18で生成したランダムな文字列(=message)と27で復元に使う文字列が同等の値であることを判断することは、22で使うカスタマイズのロジックを共有していないことから、困難だと言えます。
このことは、ユーザが任意のmessageToBeSigned、signatureを取得して、26のエンドポイントにリクエストを投げることで、27で他者のEOAを復元し、バリデーションを通過させてしまう可能性につながる。
メッセージのカスタマイズについて
Startrail-sdk-js内部では、署名を行う前に下記の処理を実行し、メッセージを変換しております。
理由は、ウォレットとして利用しているTorus社の実装に準拠したものであり、これによりメッセージに署名を行う際、ユーザはポップアップの確認ボタンを押す必要が無くなり、UIUXの改善につながります。
コード上で必要な変更点
クライアント様のコード内にバリデーション用のロジックを追加する
影響範囲と内容
Startrail-sdk-jsの更新後、
signMessage()
のレスポンス値が// 現状 export interface SignMessage { signature: string messageHash: any message: string } // 新たな仕様 export interface MessageSignature { signature: string prefix: string | undefined }
上記のように変更されています。
messageHash
とmessage
を送信する替わりにprefix
をサーバサイドに送信してください。クライアント様側のサーバサイドに下記のようなロジックを追加いただきたいです
要点:
originalMessageを再取得する
originalMessageからmessageToBeSignedを生成するロジックを追加
// ① DBからEOAを元に最初に生成し文字列を取り出す const originalMessage = await this.findOne(eoa) let messageToBeSigned if (prefix) { // ② DBから取得したoriginalMessageを基に実際に署名を行った文字列を復元する messageToBeSigned = `${prefix}${originalMessage.length.toString()}${originalMessage}`; } else { // ポップアップを隠さない場合も考慮し、prefixがundefinedである場合のロジックも記述 messageToBeSigned = originalMessage } // HTTP call to Validator-API (message: messageToBeSigned, signature, address )
上記変更が難しい場合の代替案以下の動画にあるような追加のポップアップをログイン時に許容していただける場合は、messageToBeSignedの生成ロジックは必要なく、お使いのStartrail-sdk-jsでもご対応が可能となりますので、その際は別途、詳細を共有させてください。
Last updated
Was this helpful?