Fix SEC-01: require password for TOTP enroll
- REST handleTOTPEnroll now requires password field in request body - gRPC EnrollTOTP updated with password field in proto message - Both handlers check lockout status and record failures on bad password - Updated Go, Python, and Rust client libraries to pass password - Updated OpenAPI specs with new requestBody schema - Added TestTOTPEnrollRequiresPassword with no-password, wrong-password, and correct-password sub-tests Security: TOTP enrollment now requires the current password to prevent session-theft escalation to persistent account takeover. Lockout and failure recording use the same Argon2id constant-time path as login. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -401,9 +401,15 @@ func (c *Client) RenewToken() (token, expiresAt string, err error) {
|
||||
// Returns a base32 secret and an otpauth:// URI for QR-code generation.
|
||||
// The secret is shown once; it is not retrievable after this call.
|
||||
// TOTP is not enforced until confirmed via ConfirmTOTP.
|
||||
func (c *Client) EnrollTOTP() (*TOTPEnrollResponse, error) {
|
||||
//
|
||||
// Security (SEC-01): the current password is required to prevent a stolen
|
||||
// session token from being used to enroll attacker-controlled TOTP.
|
||||
func (c *Client) EnrollTOTP(password string) (*TOTPEnrollResponse, error) {
|
||||
var resp TOTPEnrollResponse
|
||||
if err := c.do(http.MethodPost, "/v1/auth/totp/enroll", nil, &resp); err != nil {
|
||||
body := struct {
|
||||
Password string `json:"password"`
|
||||
}{Password: password}
|
||||
if err := c.do(http.MethodPost, "/v1/auth/totp/enroll", body, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
|
||||
Reference in New Issue
Block a user