(Browser) Server GET /login 200 OK <html> login page Set-cookie: csrfToken POST /login {username, password, csrftoken} Enter username Enter password Enter login url Assert CSRF token Assert not logged in Asser user exist Calculate hash Compare hashes (Re)Start session 302 Found Location: /home Set-cookie: session Assert not logged in Render form
loss. - Bruteforce (online) - Bruteforce (offline, in case of leak). ~ Adversary in the middle (network) ~ Password logging. ~ User enumeration Security issues:
(Browser) Server POST /login/start {username, csrftoken} 200 OK GET /login/complete/:user_id/:token Click on “lost password” link Assert CSRF Assert user Generate token Add email to queue Render form 200 OK Set-cookie: session Smtp Server Goto email Click on link Assert user / token relationship Assert token status Assert token expiry Invalidate token
- Man in the middle ~ Replay attack - Email logging / intercept Security issues: ~ User training + Vague error messages & constant time? + HTTPs required, no HTTP fallback + One-off use, expiry date + TLS for SMTP, relays, etc. Implementation considerations: - Context switch, email delays, etc. UX issues: - Email client “preview” counts as a click?
Server GET /mfa/sms 200 OK POST /mfa/sms {code, csrfToken} Assert CSRF Assert user Generate token Add SMS to queue Render form 200 OK Set-cookie: session SMS Service Grab code Enter code Assert user / token relationship Assert token status Assert token expiry Invalidate token
/mfa/totp {totp, csrfToken} Get TOTP Enter TOTP Assert user Assert settings Assert TOTP 200 OK Set-cookie: mfa Mfa required 200 OK Set-cookie: csrfToken Assert user Assert settings GET /mfa/totp
public static function generateTotpUri(IdentityInterface $uac): string { // RFC 4226 recommend a key length of 160 bits. // The key is represented as a base32 string, which stores 5 bits per character, // so the string in the QR code should be 32 characters (and without padding) $secret = trim(Base32::encode(random_bytes(32)), '='); $totp = TOTP::create($secret); // label: string shown below the code digits in TOTP app $totp->setLabel($uac->getUsername()); // issuer: string shown above the code digits in TOTP app $totp->setIssuer(self::getIssuer()); return $totp->getProvisioningUri(); } }
// @var ..\Model\Entity\MfaUserSetting Entity (or DTO) representing the user settings protected $settings; //.. Constructor, etc. public function validationDefault(Validator $validator): Validator { return $validator //.. after type, length, etc. check ->add('totp', ['isValidOtp' => [ 'rule' => [$this, 'isValidOtp'], 'message' => __('The TOTP is not valid.'), ]]); } public function isValidOtp(string $value): bool { // uri is something like 'otpauth://totp/alice%40google.com?secret=JBSWY3DPEHPK3PXP&foo=bar' return Factory::loadFromProvisioningUri($this->settings->getTotpProvisioningUri()) ->verify($value); }
BaconQrCode\Renderer\Image\SvgImageBackEnd; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; class QrCodeCell extends Cell { public function display(string $provisioningUri): void { $renderer = new ImageRenderer( new RendererStyle(256), new SvgImageBackEnd() ); $writer = new Writer($renderer); $inlineSvg = $writer->writeString($provisioningUri, Encoder::DEFAULT_BYTE_MODE_ECODING); $qrcode = str_replace('<?xml version="1.0" encoding="UTF-8"?>', '', $inlineSvg); $this->set('qrcode', $qrcode); } }
/sso/start 302 Found Set-cookie: state GET /sso/redirect?code=..?state=.. Cookie: state=.. Click on SSO button Generate nonce Generate state 200 OK Set-cookie: session Authorization Server GET /authorize?client_id=..&response_type=code& state=..&nonce=..&scope=openid email&redirect_url=.. 302 Found Location: <redirect_url> Assert state POST /token?grant_type=authorization_code &code=..&client_id=..&client_secret=.. 200 OK {id_token,..} Assert JWT (signature, expiry, iss) Assert nonce Assert email, verified_email
- Does not support mapping resource owner as id_token (JWT) - Mixed support for URL discovery using .well-kown endpoint Library choice considerations: + Assert the state with SSO provider settings versions ~ Make admin complete the flow before enabling SSO - Build SSO token expiry reminders (e.g. Azure) Other implementation considerations:
The web-browser & client side software (JavaScript) Authenticator Proves you are you, either on the device (platform) or off device (roaming). CTAP 2.0 Client to authenticator protocol WebAuthn Web Authentication HTTPS FIDO2 Project A joint effort between the FIDO Alliance and the W3C Examples: iOS Keychain Microsoft Hello Yubikey Dashlane Examples: Chrome Firefox Safari Examples: Google etc.
authenticate and that can be synced across multiple devices (as opposed to hardware bound). Client data Private Key (Asymmetric Key) Sig Hash Sign Auth Data Sig Public Key (Asymmetric Key) Verify Client Data’ Parse & Compare Sign | Verify || Data sent Client Generated by authenticator
{authData, signature, user, ..} Relying Party Verify user Sign / create assertion 200 OK publicKey (PublicKeyCredentialRequestOptions): {challenge, rpId, allowCredentials, userVerification, ..} authenticatorGetAssertion() {rpId, clientDataHash, ..} POST /webauthn/assertion/options {username} POST /webauthn/assertion/response AuthenticatorAssertionResponse: {clientDataJSON, authenticatorData, signature, userHandle} navigator.credentials.get(publicKey) 200 OK Set-cookie: session Verify sig Assert RP ID etc.
keychain escrow, which is also protected against brute-force attacks, even by Apple. [...] To recover a keychain, a user must authenticate with their iCloud account and password and respond to an SMS sent to their registered phone number. After they authenticate and respond, the user must enter their device passcode. iOS, iPadOS, and macOS allow only 10 attempts to authenticate. After several failed attempts, the record is locked and the user must call Apple Support to be granted more attempts. After the tenth failed attempt, the escrow record is destroyed. Optionally, a user can set up an account recovery contact [...].” Ref. https://support.apple.com/en-gb/guide/security/sec3e341e75d/web
middle (phishing). - Passwordkeys loss. - Bruteforce (online) - Bruteforce (offline, in case of leak). - Adversary in the middle (network) - Password logging. ~ User enumeration Security issues: + Checking against breaches & entropy ~ User training ~ Account recovery + Captcha (+GDPR) / WAF / Alerts + “Costly” hashing mechanism (bcrypt) + HTTPs pinned and well configured + Additional client side hashing? + See small prints Implementation considerations:
Authenticator gatekeeping? - Pay to play / Diversity? - Open-source ecosystem support Other issues: ~ UX Working group ~ Traction? ~ Monkey patching? Fines? ~ Get involved? ~ Get involved! Other considerations: