Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2段階認証のバックアップコード #3566

Closed
YuzuRyo61 opened this issue Dec 9, 2018 · 19 comments · Fixed by #11766
Closed

2段階認証のバックアップコード #3566

YuzuRyo61 opened this issue Dec 9, 2018 · 19 comments · Fixed by #11766
Labels
✨Feature This adds/improves/enhances a feature 🔥high priority 🔒Security Security related issue/PR

Comments

@YuzuRyo61
Copy link
Contributor

YuzuRyo61 commented Dec 9, 2018

Summary

万が一認証コードを搭載した端末を無くしてしまった場合にバックアップコードを発行する仕組みを作ったほうが良いと思った。

Environment


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

nokotaro pushed a commit to nokotaro/misskey that referenced this issue Mar 25, 2022
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 9.2.7 to 9.2.8.
- [Release notes](https://github.com/TypeStrong/ts-loader/releases)
- [Changelog](https://github.com/TypeStrong/ts-loader/blob/main/CHANGELOG.md)
- [Commits](TypeStrong/ts-loader@v9.2.7...v9.2.8)

---
updated-dependencies:
- dependency-name: ts-loader
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@acid-chicken acid-chicken added ✨Feature This adds/improves/enhances a feature 🔒Security Security related issue/PR labels Dec 21, 2022
@nenohi
Copy link
Contributor

nenohi commented Apr 27, 2023

これ必要になってきたかも

@CyberRex0
Copy link
Contributor

というかMUSTなやつでは?

@u1-liquid
Copy link
Contributor

const secret = new OTPAuth.Secret();

これをシード値として生成して、あってるか確認する程度ならすぐできるかも

@syuilo
Copy link
Member

syuilo commented May 20, 2023

バックアップコードについての詳細求

@syuilo
Copy link
Member

syuilo commented May 20, 2023

two factor authentication backup codes で調べたけど詳細な情報が見つけられなかった

@tamaina
Copy link
Contributor

tamaina commented May 20, 2023

createdAtの+0分〜+n分までのステップでも許可するとか?

ref https://www.npmjs.com/package/otpauth

@u1-liquid
Copy link
Contributor

  • 2FAを設定したらその画面で一度だけDLできるテキストファイル
  • 2FAを解除したらSEED初期化
  • コードは8個くらい提供すれば十分
  • 一度使ったコードは再利用不可

実装の案としては

  • OTPAuth SecretにユーザーIDなどのsaltを入れたデータのSHA512ハッシュを入れたを8*8ビットずつ分割してコードのSEEDにする
  • https://bitwarden.com/password-generator/ のPassphrase生成みたいな生成ライブラリに投げてその結果をコードとして使えばいいかも、同じSEEDで同じ結果が帰ってくるライブラリなら保存する必要もなさそう
  • 使ったコードの情報はpersonに保存させて、次回使おうとするとはじく
  • OTPを再作成するか2FAの設定が解除された場合関連データは片付けて再度作られるようにする

@syuilo
Copy link
Member

syuilo commented May 20, 2023

🙏🙏🙏

@syuilo
Copy link
Member

syuilo commented May 20, 2023

なんか難しそう

@acid-chicken
Copy link
Member

不可逆でない状態でパスワードを複数持つようなものなので別に難しく考える必要はない

@acid-chicken
Copy link
Member

(というか不可逆でもいい)

@u1-liquid
Copy link
Contributor

面倒だったらOTPのSecretに使う値以外にOTPAuth.Secretを8回呼び出してそれをそのままバックアップコードにしてもいいかも

@acid-chicken
Copy link
Member

例えば(擬似コード)

fn on_enable(id: user.id) {
  let user = await(tables.users.get_row(id));
  let salt = user.salt;
  let mut codes = vec();
  for (let mut i = 0..8) {
    let code = crypto.generate_secure_password_string();
    let hash = hasher.hash(code, salt);
    codes.append(code);
    await(tables.backup_codes.add_row(BackupCode {
        id: auto(),
        user_id: id,
        hash: hash,
    }));
  }
  client.display.show(codes);
}

fn on_disable(id: user.id) {
  await(tables.backup_codes.find_to_delete_row_bulk(BackupCodeFinder {
    user_id: id,
  }));
}

fn on_reset(id: user.id, code: string) -> Result<()> {
  // FIXME: add rate limit
  let user = await(tables.users.get_row(id));
  let salt = user.salt;
  let hash = hasher.hash(code, salt);
  let matched = await(tables.backup_codes.find_to_delete_row(BackupCodeFinder {
    user_id: id,
    hash: hash,
  }));
  if matched {
    let remaining = await(tables.backup_codes.count(BackupCodeFinder {
      user_id: id,
    }));
    if remaining == 0 {
      client.display.show("all of your backup codes are no longer available\nyou should reset 2FA immediately");
    }
    return Ok();
  } else {
    // FIXME: add rate limit
    return Err("invalid code");
  }
}

@tamaina
Copy link
Contributor

tamaina commented May 20, 2023

createdAt

シークレットをUserProfileに突っ込んでるだけだったので使えない感()

@tamaina
Copy link
Contributor

tamaina commented May 20, 2023

Secretが生で突っ込んでるんだし…

  • バックアップコードは乱数6桁なりを生で保存
  • 使ったバックアップコードは消す

みたいにしちゃって良さそうな気がしてきた

@daima3629
Copy link
Contributor

GoogleやDiscordも不可逆で保存はしてないので生で保存して問題ないと思います

@yuriha-chan
Copy link
Contributor

yuriha-chan commented Jun 16, 2023

  • secureRndstrを使うべき
    • 乱数が予測可能となるリスクの回避
  • リカバリーコードを長くする(せめて16文字)
    • パスワードより弱いリカバリーコードでは2FAを導入した意義が薄い
  • リカバリーコードを使用すると2FAはすべて解除されるので、リカバリーコードは一つだけ生成すればよいのでは?
    • リカバリーコードを長くする分、ユーザーがメモするときの負担を小さくしたい
    • ユーザーが2FAを再登録したら、再度リカバリコードを生成してもらう
  • DBの内容が流出したときにアカウントがただちに乗っ取られることを防ぐため、生コードではなくhashをDBに保管するメリットはある
    • FIDO の公開鍵認証ならサーバー側にユーザーの秘密が保管されていることはないはず
    • そもそも生コードを保管する理由がない
  • 不審なリカバリーコードの使用を監査できるとベター
  • パスワードレスログインを有効にしていてパスワードを忘却している場合(そんなことがあったら困るのだが)、リカバリーコードを使用するとかえってアクセス不能になる可能性があるので注意喚起が必要かもしれない

@tamaina
Copy link
Contributor

tamaina commented Jul 31, 2023

ioの実装

MisskeyIO#121

@syuilo
Copy link
Member

syuilo commented Aug 21, 2023

持ってくるか

@syuilo syuilo mentioned this issue Aug 27, 2023
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨Feature This adds/improves/enhances a feature 🔥high priority 🔒Security Security related issue/PR
Projects
None yet
9 participants