Skip to content

Latest commit

ย 

History

History
158 lines (127 loc) ยท 11.8 KB

File metadata and controls

158 lines (127 loc) ยท 11.8 KB

โบ State Continuation (ะฝะต ะฟัƒั‚ะฐั‚ัŒ ั CSRF state ะฟะฐั€ะฐะผะตั‚ั€ะพะผ) โ€” ัั‚ะพ ะผะตั…ะฐะฝะธะทะผ ะทะฐั‰ะธั‚ั‹ ะพั‚ ะฟะพะดะดะตะปะบะธ/ะฟะพะฒั‚ะพั€ะฐ ะทะฐะฟั€ะพัะพะฒ ะฒ OAuth2-ะฟะพะดะพะฑะฝั‹ั… ะฟะพั‚ะพะบะฐั…, ะพัะพะฑะตะฝะฝะพ ะฟั€ะธ ะพะฑะผะตะฝะต refresh token ะฝะฐ access token.


ะคะพั€ะผะฐะปัŒะฝะฐั ะผะพะดะตะปัŒ

  1. ะฃะณั€ะพะทะฐ

ะ—ะปะพัƒะผั‹ัˆะปะตะฝะฝะธะบ ะฟะตั€ะตั…ะฒะฐั‚ั‹ะฒะฐะตั‚ ะทะฐะฟั€ะพั ะฝะฐ ะพะฑะผะตะฝ ั‚ะพะบะตะฝะฐะผะธ ะธ:

  • ะŸะพะดะผะตะฝัะตั‚ grant_type, client_id, scope
  • ะŸะพะฒั‚ะพั€ัะตั‚ ัั‚ะฐั€ั‹ะน ะทะฐะฟั€ะพั (replay attack)
  • ะœะพะดะธั„ะธั†ะธั€ัƒะตั‚ claims (ะฝะฐะฟั€ะธะผะตั€,UID, email)
  1. ะ—ะฐั‰ะธั‚ะฐ ั‡ะตั€ะตะท State Continuion

A. ะคะฐะทะฐ ะธะฝะธั†ะธะฐะปะธะทะฐั†ะธะธ (AuthManager โ†’ AccountManager)

Client โ†’ AccountManager.getAuthToken(account, scope, null)

ะ“ะตะฝะตั€ะฐั†ะธั state: state = HMAC-SHA256( key = device_secret, data = { "account_id": account_id, "scope_hash": SHA256(scope_string), "timestamp": now(), "nonce": random(128bits) } )

State ะฟะตั€ะตะดะฐั‘ั‚ัั ะบะฐะบ opaque ะฟะฐั€ะฐะผะตั‚ั€ ะฒ Intent extras.


B. ะคะฐะทะฐ ะพะฑะผะตะฝะฐ (ChimeraGetToken.smali)

ะ—ะฐะฟั€ะพั ะฝะฐ /token ะฒะบะปัŽั‡ะฐะตั‚: POST /token { "grant_type": "refresh_token", "refresh_token": "...", "client_id": "...", "scope": "...", "state": "<ัะณะตะฝะตั€ะธั€ะพะฒะฐะฝะฝั‹ะน state>" # โ† ะšะ›ะฎะงะ•ะ’ะžะ™ ะฟะฐั€ะฐะผะตั‚ั€ }


  1. ะ’ะฐะปะธะดะฐั†ะธั State ะฝะฐ ัะตั€ะฒะตั€ะต

ะกะตั€ะฒะตั€ (ะฒ ะบะพะฝั‚ะตะบัั‚ะต Google โ€” Google Play Services) ั…ั€ะฐะฝะธั‚ expected_state ะดะปั:

  • ะŸะฐั€ั‹ (account_id, scope)
  • ะšะพะฝะบั€ะตั‚ะฝะพะณะพ nonce
  • ะขะฐะนะผั„ั€ะตะนะผะฐ (ะพะฑั‹ั‡ะฝะพ ยฑ5 ะผะธะฝัƒั‚)

ะŸั€ะพะฒะตั€ะบะฐ: def validate_state(received_state, account_id, scope): # 1. ะŸั€ะพะฒะตั€ัะตะผ ะฟะพะดะฟะธััŒ if not HMAC-SHA256(device_secret, payload) == received_state: return ERROR_INVALID_SIGNATURE

  # 2. ะŸั€ะพะฒะตั€ัะตะผ ะฐะบั‚ัƒะฐะปัŒะฝะพัั‚ัŒ (one-time use)
  if state_already_used(received_state.nonce):
      return ERROR_STATE_REPLAYED

  # 3. ะŸั€ะพะฒะตั€ัะตะผ scope (ะฝะต ั€ะฐััˆะธั€ะตะฝ ะปะธ ะฑะตะท ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธั)
  if scope_hash != received_state.scope_hash:
      return ERROR_SCOPE_MISMATCH

  # 4. ะŸะพะผะตั‡ะฐะตะผ nonce ะบะฐะบ ะธัะฟะพะปัŒะทะพะฒะฐะฝะฝั‹ะน (idempotency key)
  mark_state_used(received_state.nonce)

  return VALID

  1. ะ—ะฐั‰ะธั‚ะฐ ะพั‚ ะบะพะฝะบั€ะตั‚ะฝั‹ั… ะฐั‚ะฐะบ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ะั‚ะฐะบะฐ โ”‚ ะ‘ะตะท state continuation โ”‚ ะก state continuation โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Replay โ”‚ ะŸั€ะธะฝัั‚ ัั‚ะฐั€ั‹ะน ั‚ะพะบะตะฝ โ”‚ nonce ัƒะถะต ะฟะพะผะตั‡ะตะฝ โ†’ ะพั‚ะบะปะพะฝั‘ะฝ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Scope escalation โ”‚ ะœะพะถะฝะพ ะดะพะฑะฐะฒะธั‚ัŒ https://www.googleapis.com/auth/youtube.upload โ”‚ scope_hash ะฝะต ัะพะฒะฟะฐะดั‘ั‚ โ†’ ะพั‚ะบะปะพะฝั‘ะฝ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Account substitution โ”‚ ะœะพะถะฝะพ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ token ะดั€ัƒะณะพะณะพ ะฐะบะบะฐัƒะฝั‚ะฐ โ”‚ account_id ะฒ HMAC โ‰  received โ†’ ะพั‚ะบะปะพะฝั‘ะฝ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ MITM modification โ”‚ ะŸะพะดะผะตะฝะฐ grant_type โ”‚ HMAC-ะฟะพะดะฟะธััŒ ะฝะตะฒะฐะปะธะดะฝะฐ โ†’ ะพั‚ะบะปะพะฝั‘ะฝ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


  1. ะšั€ะธะฟั‚ะพะณั€ะฐั„ะธั‡ะตัะบะธะต ะพัะฝะพะฒั‹

State = HMAC-SHA256(K, M) ะณะดะต:

  • K = device secret (ะฟั€ะธะฒัะทะฐะฝ ะบ SafetyNet/KeyStore, ะฝะตะดะพัั‚ัƒะฟะตะฝ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŽ)
  • M = account_id || scope_hash || timestamp || nonce

Security properties:

  1. Unforgeability: ะ‘ะตะท ะทะฝะฐะฝะธั K ะฝะตะปัŒะทั ัะณะตะฝะตั€ะธั€ะพะฒะฐั‚ัŒ ะฒะฐะปะธะดะฝั‹ะน state
  2. Binding: State ะฟั€ะธะฒัะทะฐะฝ ะบ ะบะพะฝะบั€ะตั‚ะฝะพะผัƒ account_id ะธ scope
  3. One-time use: nonce ั…ั€ะฐะฝะธั‚ัั ะฒ persistent storage (Keystore/SharedPreferences)
  4. Freshness: timestamp ะพะณั€ะฐะฝะธั‡ะตะฝ (TLL ~15 ะผะธะฝ)

  1. ะŸั€ะธะผะตั€ ะธะท APK (cre.smali โ†’ TokenWorkflow)

ะŸัะตะฒะดะพะบะพะด ะธะท TokenWorkflowClient

invoke-virtual {v0, v1, v2}, Lcom/google/android/gms/auth/TokenWorkflowClient;->getTokenWithState( Landroid/accounts/Account; [Ljava/lang/String; Landroid/os/Bundle; )

Bundle ัะพะดะตั€ะถะธั‚:

bundle.putByteArray("state", generated_state) bundle.putString("caller_package", package_name) bundle.putLong("timestamp", System.currentTimeMillis())

ะะฐ ัั‚ะพั€ะพะฝะต ัะตั€ะฒะตั€ะฐ (ChimeraGetToken): // ะ’ะฐะปะธะดะฐั†ะธั if (!stateValidator.validate(state, account, scope)) { throw new SecurityException("State verification failed"); }


  1. ะœะพะดะตะปัŒ ัƒะณั€ะพะท (STRIDE)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ะฃะณั€ะพะทะฐ โ”‚ ะšะฐะบ ะทะฐั‰ะธั‰ะฐะตั‚ state โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Spoofing โ”‚ HMAC ั ัƒัั‚ั€ะพะนัั‚ะฒะตะฝะฝะพ-ะฟั€ะธะฒัะทะฐะฝะฝั‹ะผ ะบะปัŽั‡ะพะผ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Tampering โ”‚ ะ›ัŽะฑะฐั ะผะพะดะธั„ะธะบะฐั†ะธั payload ะปะพะผะฐะตั‚ HMAC โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Repudiation โ”‚ State ะฟั€ะธะฒัะทะฐะฝ ะบ account_id + nonce ะปะพะณะธั€ัƒะตั‚ัั โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Information Disclosure โ”‚ State = ciphertext, ะฝะต ัะพะดะตั€ะถะธั‚ raw ะดะฐะฝะฝั‹ั… โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Denial of Service โ”‚ Nonce-ะบััˆ ะพะณั€ะฐะฝะธั‡ะตะฝ ะฟะพ ั€ะฐะทะผะตั€ัƒ (LRU) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Elevation of Privilege โ”‚ Scope mismatch ะฟั€ะพะฒะตั€ัะตั‚ัั ัะฒะฝะพ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


  1. ะกั€ะฐะฒะฝะตะฝะธะต ั CSRF-state

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ CSRF state (web) โ”‚ State continuation (mobile) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ ะฆะตะปัŒ โ”‚ ะ—ะฐั‰ะธั‚ะฐ ะพั‚ cross-site request โ”‚ ะ—ะฐั‰ะธั‚ะฐ ะพั‚ replay + scope escalation โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ ะฅั€ะฐะฝะตะฝะธะต โ”‚ Cookie/session โ”‚ Keystore/device secret โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Transfer โ”‚ Form hidden field / header โ”‚ Intent extras / HTTP body โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Validation โ”‚ Session equality โ”‚ HMAC equality + nonce check โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


ะšะพั€ะพั‚ะบะพ: State continuation = HMAC(device_secret, account+scope+nonce) ะฟั€ะธะฒัะทะฐะฝะฝั‹ะน ะบ ัƒัั‚ั€ะพะนัั‚ะฒัƒ, ะพะดะฝะพั€ะฐะทะพะฒั‹ะน, ั ะพะณั€ะฐะฝะธั‡ะตะฝะธะตะผ ะฟะพ ะฒั€ะตะผะตะฝะธ. ะ›ะพะผะฐะตั‚ replay, scope escalation ะธ account substitution ะฐั‚ะฐะบะธ ั‡ะตั€ะตะท ะฝะตะฒะพะทะผะพะถะฝะพัั‚ัŒ ะฟะพะดะฟะธัะธ ะฑะตะท device secret.