<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DeviceCode on IAMDevBox</title><link>https://www.iamdevbox.com/tags/devicecode/</link><description>Recent content in DeviceCode on IAMDevBox</description><image><title>IAMDevBox</title><url>https://www.iamdevbox.com/IAMDevBox.com.jpg</url><link>https://www.iamdevbox.com/IAMDevBox.com.jpg</link></image><generator>Hugo -- 0.146.0</generator><language>en-us</language><lastBuildDate>Tue, 02 Jun 2026 21:00:36 -0400</lastBuildDate><atom:link href="https://www.iamdevbox.com/tags/devicecode/index.xml" rel="self" type="application/rss+xml"/><item><title>OAuth Device Code Flow Security: How to Detect and Prevent Device Code Phishing</title><link>https://www.iamdevbox.com/posts/oauth-device-code-flow-security-prevent-device-code-phishing/</link><pubDate>Wed, 03 Jun 2026 00:58:09 +0000</pubDate><guid>https://www.iamdevbox.com/posts/oauth-device-code-flow-security-prevent-device-code-phishing/</guid><description>OAuth device code phishing (RFC 8628 abuse) bypasses MFA and steals M365 refresh tokens without a password. Learn how to disable device authorization grant in Entra ID, Keycloak, Auth0, and detect attacks with SIEM rules.</description><content:encoded><![CDATA[<p>OAuth&rsquo;s Device Authorization Grant (RFC 8628) was designed for TVs, CLIs, and IoT devices that can&rsquo;t open a browser. Unfortunately, attackers have turned it into one of the most effective MFA-bypass techniques of 2024–2026, targeting thousands of Microsoft 365 organizations per campaign. This guide explains how the attack works at the protocol level and gives you specific, actionable steps to block it in every major identity platform.</p>
<h2 id="how-device-code-phishing-works-protocol-level">How Device Code Phishing Works (Protocol-Level)</h2>
<p>The Device Authorization Grant flow involves three parties: the <strong>device</strong> (attacker&rsquo;s script), the <strong>authorization server</strong> (Microsoft, your IdP), and the <strong>user</strong>. Here&rsquo;s the normal flow — and where attackers hijack it:</p>
<p><strong>Legitimate flow:</strong></p>
<ol>
<li>Device calls <code>/oauth2/v2.0/devicecode</code> → receives <code>device_code</code>, <code>user_code</code>, and <code>verification_uri</code></li>
<li>Device polls <code>/oauth2/v2.0/token?grant_type=urn:ietf:params:oauth:grant-type:device_code</code></li>
<li>User visits <code>https://microsoft.com/devicelogin</code>, enters the code, authenticates</li>
<li>Device receives access token + refresh token</li>
</ol>
<p><strong>Attacker&rsquo;s flow:</strong></p>
<ol>
<li>Attacker runs SquarePhish, Graphish, or a custom script to request a fresh <code>device_code + user_code</code></li>
<li>Attacker sends a spear-phishing email to the target: <em>&ldquo;Your Microsoft account requires device verification. Visit [legitimate Microsoft URL] and enter code: ABCD-1234&rdquo;</em></li>
<li>Target enters the code and authenticates — <strong>including completing MFA</strong></li>
<li>Attacker&rsquo;s polling script receives a <strong>fully authorized refresh token</strong> (valid 90 days by default)</li>
<li>Attacker uses the refresh token to access Exchange, Teams, SharePoint, OneDrive</li>
</ol>
<p><strong>Why MFA doesn&rsquo;t stop it:</strong> The user completes MFA against the legitimate Microsoft login page. The user <em>is</em> the one granting consent — they just don&rsquo;t realize they&rsquo;re authorizing an attacker&rsquo;s application session.</p>
<p><strong>Why it&rsquo;s hard to detect:</strong> The attacker&rsquo;s token request comes from a Microsoft IP range (via <code>device_code</code> polling against <code>login.microsoftonline.com</code>). The initial phishing step may use only email, not a phishing site.</p>
<h2 id="mitigation-1-disable-device-code-flow-in-microsoft-entra-id">Mitigation 1: Disable Device Code Flow in Microsoft Entra ID</h2>
<p>The most effective mitigation is blocking device code flow entirely for users who don&rsquo;t legitimately need it (almost everyone).</p>
<h3 id="conditional-access-policy-recommended">Conditional Access Policy (Recommended)</h3>



<div class="goat svg-container ">
  
    <svg
      xmlns="http://www.w3.org/2000/svg"
      font-family="Menlo,Lucida Console,monospace"
      
        viewBox="0 0 528 233"
      >
      <g transform='translate(8,16)'>
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='0' y='36' fill='currentColor' style='font-size:1em'>N</text>
<text text-anchor='middle' x='0' y='68' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='0' y='164' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='0' y='212' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='8' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='8' y='68' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='8' y='164' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='8' y='212' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='16' y='36' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='16' y='68' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='16' y='84' fill='currentColor' style='font-size:1em'>U</text>
<text text-anchor='middle' x='16' y='100' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='16' y='116' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='16' y='164' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='16' y='180' fill='currentColor' style='font-size:1em'>G</text>
<text text-anchor='middle' x='16' y='212' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='24' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='24' y='68' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='24' y='84' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='24' y='100' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='24' y='116' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='24' y='164' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='24' y='180' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='24' y='212' fill='currentColor' style='font-size:1em'>b</text>
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='32' y='36' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='32' y='68' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='32' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='32' y='100' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='32' y='116' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='32' y='132' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='32' y='164' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='32' y='180' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='32' y='212' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='40' y='68' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='40' y='84' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='40' y='100' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='40' y='116' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='40' y='132' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='40' y='164' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='40' y='180' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='40' y='212' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>B</text>
<text text-anchor='middle' x='48' y='68' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='48' y='84' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='48' y='100' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='48' y='116' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='48' y='132' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='48' y='180' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='56' y='68' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='56' y='84' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='56' y='116' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='56' y='132' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='56' y='164' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='56' y='180' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='56' y='212' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='64' y='4' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='64' y='68' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='64' y='100' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='64' y='116' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='64' y='132' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='64' y='164' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='64' y='212' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='72' y='36' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='72' y='68' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='72' y='84' fill='currentColor' style='font-size:1em'>I</text>
<text text-anchor='middle' x='72' y='100' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='72' y='116' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='72' y='132' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='72' y='164' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='72' y='180' fill='currentColor' style='font-size:1em'>B</text>
<text text-anchor='middle' x='72' y='212' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>k</text>
<text text-anchor='middle' x='80' y='68' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='80' y='84' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='80' y='100' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='80' y='116' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='80' y='132' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='80' y='164' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='80' y='180' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='80' y='212' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='88' y='68' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='88' y='84' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='88' y='100' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='88' y='116' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='88' y='132' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='88' y='164' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='88' y='180' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='88' y='212' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='96' y='36' fill='currentColor' style='font-size:1em'>D</text>
<text text-anchor='middle' x='96' y='84' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='96' y='100' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='96' y='116' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='96' y='132' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='96' y='164' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='96' y='180' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='96' y='212' fill='currentColor' style='font-size:1em'>y</text>
<text text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='104' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='104' y='84' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='104' y='132' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='104' y='164' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='104' y='180' fill='currentColor' style='font-size:1em'>k</text>
<text text-anchor='middle' x='104' y='212' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='112' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='112' y='36' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='112' y='84' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='112' y='100' fill='currentColor' style='font-size:1em'>I</text>
<text text-anchor='middle' x='112' y='132' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='112' y='164' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='120' y='36' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='120' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='120' y='100' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='120' y='132' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='120' y='164' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='120' y='180' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='120' y='212' fill='currentColor' style='font-size:1em'>O</text>
<text text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='128' y='36' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='128' y='100' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='128' y='132' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='128' y='180' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='128' y='212' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='136' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='136' y='84' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='136' y='100' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='136' y='132' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='136' y='180' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='144' y='84' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='144' y='100' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='144' y='180' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='152' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='152' y='36' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='152' y='84' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='152' y='100' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='152' y='132' fill='currentColor' style='font-size:1em'>f</text>
<text text-anchor='middle' x='152' y='180' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='160' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='160' y='84' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='160' y='100' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='160' y='132' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='160' y='180' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='168' y='4' fill='currentColor' style='font-size:1em'>P</text>
<text text-anchor='middle' x='168' y='36' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='168' y='132' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='176' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='176' y='84' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='176' y='100' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='176' y='132' fill='currentColor' style='font-size:1em'>w</text>
<text text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='184' y='84' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='184' y='100' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='184' y='132' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='192' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='192' y='36' fill='currentColor' style='font-size:1em'>F</text>
<text text-anchor='middle' x='192' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='192' y='100' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='192' y='132' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='200' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='200' y='36' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='200' y='84' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='200' y='100' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='208' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='208' y='84' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='208' y='132' fill='currentColor' style='font-size:1em'>D</text>
<text text-anchor='middle' x='216' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='216' y='36' fill='currentColor' style='font-size:1em'>w</text>
<text text-anchor='middle' x='216' y='84' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='216' y='100' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='216' y='132' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='224' y='100' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='224' y='132' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='232' y='100' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='232' y='132' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='240' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='240' y='100' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='240' y='132' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='248' y='100' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='248' y='132' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='256' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='264' y='100' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='264' y='132' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='272' y='100' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='272' y='132' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='280' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='280' y='100' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='280' y='132' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='288' y='100' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='288' y='132' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='296' y='100' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='304' y='132' fill='currentColor' style='font-size:1em'>f</text>
<text text-anchor='middle' x='312' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='312' y='132' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='320' y='132' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='328' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='328' y='132' fill='currentColor' style='font-size:1em'>w</text>
<text text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='344' y='132' fill='currentColor' style='font-size:1em'>✓</text>
<text text-anchor='middle' x='352' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='368' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='376' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='384' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='392' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='400' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='408' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='424' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='440' y='4' fill='currentColor' style='font-size:1em'>N</text>
<text text-anchor='middle' x='448' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='456' y='4' fill='currentColor' style='font-size:1em'>w</text>
<text text-anchor='middle' x='472' y='4' fill='currentColor' style='font-size:1em'>P</text>
<text text-anchor='middle' x='480' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='488' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='496' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='504' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='512' y='4' fill='currentColor' style='font-size:1em'>y</text>
</g>

    </svg>
  
</div>
<p><strong>Important</strong>: Exclude accounts that genuinely need device code (service TV accounts, lab testing). Assign to a separate group and exempt them.</p>
<h3 id="using-powershell-microsoft-graph">Using PowerShell (Microsoft Graph)</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-powershell" data-lang="powershell"><span style="display:flex;"><span><span style="color:#75715e"># Install module if needed: Install-Module Microsoft.Graph</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Connect-MgGraph -Scopes <span style="color:#e6db74">&#34;Policy.ReadWrite.ConditionalAccess&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$policy = @{
</span></span><span style="display:flex;"><span>  displayName = <span style="color:#e6db74">&#34;Block Device Code Flow&#34;</span>
</span></span><span style="display:flex;"><span>  state = <span style="color:#e6db74">&#34;enabled&#34;</span>
</span></span><span style="display:flex;"><span>  conditions = @{
</span></span><span style="display:flex;"><span>    users = @{ includeUsers = @(<span style="color:#e6db74">&#34;All&#34;</span>) }
</span></span><span style="display:flex;"><span>    applications = @{ includeApplications = @(<span style="color:#e6db74">&#34;All&#34;</span>) }
</span></span><span style="display:flex;"><span>    authenticationFlows = @{ transferMethods = <span style="color:#e6db74">&#34;deviceCodeFlow&#34;</span> }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  grantControls = @{
</span></span><span style="display:flex;"><span>    operator = <span style="color:#e6db74">&#34;OR&#34;</span>
</span></span><span style="display:flex;"><span>    builtInControls = @(<span style="color:#e6db74">&#34;block&#34;</span>)
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>New-MgIdentityConditionalAccessPolicy -BodyParameter $policy
</span></span></code></pre></div><h3 id="authentication-methods-policy-tenant-wide">Authentication Methods Policy (Tenant-Wide)</h3>
<p>For tenants without Entra P1/P2 (no Conditional Access), you can restrict device code via the Authentication Flows policy:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># GET current policy</span>
</span></span><span style="display:flex;"><span>GET https://graph.microsoft.com/beta/policies/authenticationFlowsPolicy
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># PATCH to disable device code</span>
</span></span><span style="display:flex;"><span>PATCH https://graph.microsoft.com/beta/policies/authenticationFlowsPolicy
</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#34;selfServiceSignUp&#34;</span>: <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;isEnabled&#34;</span>: false
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>Note: Full device code suppression via Graph API requires <code>Policy.ReadWrite.AuthenticationFlows</code> scope.</p>
<h2 id="mitigation-2-disable-device-code-grant-in-keycloak">Mitigation 2: Disable Device Code Grant in Keycloak</h2>
<p>Keycloak enables Device Authorization Grant per-client. If you&rsquo;re using Keycloak as a federation proxy for M365/Entra, disable it at the realm and client level.</p>
<h3 id="disable-at-realm-level-keycloak-21">Disable at Realm Level (Keycloak 21+)</h3>



<div class="goat svg-container ">
  
    <svg
      xmlns="http://www.w3.org/2000/svg"
      font-family="Menlo,Lucida Console,monospace"
      
        viewBox="0 0 392 105"
      >
      <g transform='translate(8,16)'>
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='0' y='36' fill='currentColor' style='font-size:1em'>O</text>
<text text-anchor='middle' x='0' y='84' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='8' y='36' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='8' y='84' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='16' y='36' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='16' y='52' fill='currentColor' style='font-size:1em'>[</text>
<text text-anchor='middle' x='16' y='84' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='24' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='24' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='32' y='36' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='32' y='52' fill='currentColor' style='font-size:1em'>]</text>
<text text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>2</text>
<text text-anchor='middle' x='48' y='52' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'>.</text>
<text text-anchor='middle' x='56' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='64' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>0</text>
<text text-anchor='middle' x='64' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='72' y='52' fill='currentColor' style='font-size:1em'>b</text>
<text text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>D</text>
<text text-anchor='middle' x='80' y='52' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='88' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='88' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='96' y='36' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='104' y='36' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='104' y='52' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='112' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='112' y='36' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='112' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='120' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='120' y='52' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'>R</text>
<text text-anchor='middle' x='128' y='52' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='136' y='36' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='136' y='52' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='144' y='36' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='144' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='152' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='152' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='160' y='4' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='160' y='36' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='160' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='168' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='168' y='52' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='176' y='36' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='176' y='52' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='184' y='36' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='184' y='52' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='192' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='192' y='36' fill='currentColor' style='font-size:1em'>z</text>
<text text-anchor='middle' x='192' y='52' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='200' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='200' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='200' y='52' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='208' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='208' y='52' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='216' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='216' y='36' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='216' y='52' fill='currentColor' style='font-size:1em'>z</text>
<text text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='224' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='224' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='232' y='36' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='232' y='52' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='240' y='52' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='248' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='248' y='36' fill='currentColor' style='font-size:1em'>G</text>
<text text-anchor='middle' x='248' y='52' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='256' y='36' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='256' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='264' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='264' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='272' y='36' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='272' y='52' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='280' y='4' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='280' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='280' y='52' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='288' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='296' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='304' y='52' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='312' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='320' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='328' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='336' y='52' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='344' y='52' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='352' y='4' fill='currentColor' style='font-size:1em'>b</text>
<text text-anchor='middle' x='352' y='52' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='360' y='52' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='368' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='376' y='52' fill='currentColor' style='font-size:1em'>t</text>
</g>

    </svg>
  
</div>
<p>Or via REST API:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get realm settings</span>
</span></span><span style="display:flex;"><span>curl -s -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  <span style="color:#e6db74">&#34;https://keycloak.example.com/admin/realms/your-realm&#34;</span> | <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  python3 -m json.tool | grep <span style="color:#e6db74">&#34;oauth2Device&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Disable device authorization grant</span>
</span></span><span style="display:flex;"><span>curl -X PUT -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#39;{&#34;oauth2DeviceAuthorizationGrantEnabled&#34;: false}&#39;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  <span style="color:#e6db74">&#34;https://keycloak.example.com/admin/realms/your-realm&#34;</span>
</span></span></code></pre></div><h3 id="disable-per-client">Disable Per-Client</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -X PUT -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#39;{
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;attributes&#34;: {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      &#34;oauth2.device.authorization.grant.enabled&#34;: &#34;false&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  }&#39;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  <span style="color:#e6db74">&#34;https://keycloak.example.com/admin/realms/your-realm/clients/{client-uuid}&#34;</span>
</span></span></code></pre></div><h3 id="verify-the-endpoint-is-blocked">Verify the Endpoint is Blocked</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Should return 400 or 404 after disabling</span>
</span></span><span style="display:flex;"><span>curl -X POST <span style="color:#e6db74">&#34;https://keycloak.example.com/realms/your-realm/protocol/openid-connect/auth/device&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;client_id=test-client&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Expected: {&#34;error&#34;:&#34;not_supported&#34;,&#34;error_description&#34;:&#34;...&#34;}</span>
</span></span></code></pre></div><h2 id="mitigation-3-disable-device-code-grant-in-auth0">Mitigation 3: Disable Device Code Grant in Auth0</h2>
<p>In Auth0, the Device Authorization Flow is a <strong>grant type</strong> enabled per-application.</p>
<h3 id="via-auth0-dashboard">Via Auth0 Dashboard</h3>



<div class="goat svg-container ">
  
    <svg
      xmlns="http://www.w3.org/2000/svg"
      font-family="Menlo,Lucida Console,monospace"
      
        viewBox="0 0 520 105"
      >
      <g transform='translate(8,16)'>
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='0' y='36' fill='currentColor' style='font-size:1em'>G</text>
<text text-anchor='middle' x='0' y='84' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='8' y='36' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='8' y='84' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='16' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='16' y='52' fill='currentColor' style='font-size:1em'>[</text>
<text text-anchor='middle' x='16' y='84' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='24' y='36' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='24' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='32' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='32' y='52' fill='currentColor' style='font-size:1em'>]</text>
<text text-anchor='middle' x='40' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='40' y='84' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='48' y='52' fill='currentColor' style='font-size:1em'>U</text>
<text text-anchor='middle' x='48' y='84' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'>y</text>
<text text-anchor='middle' x='56' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='56' y='84' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='64' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='64' y='52' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='64' y='84' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='72' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='72' y='52' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='72' y='84' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='80' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='80' y='84' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='88' y='52' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='88' y='84' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='96' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='96' y='52' fill='currentColor' style='font-size:1em'>k</text>
<text text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='104' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='112' y='36' fill='currentColor' style='font-size:1em'>b</text>
<text text-anchor='middle' x='112' y='52' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'>[</text>
<text text-anchor='middle' x='120' y='36' fill='currentColor' style='font-size:1em'>:</text>
<text text-anchor='middle' x='120' y='52' fill='currentColor' style='font-size:1em'>D</text>
<text text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'>Y</text>
<text text-anchor='middle' x='128' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='136' y='52' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='144' y='52' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='152' y='4' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='152' y='52' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='160' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='168' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='176' y='52' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'>p</text>
<text text-anchor='middle' x='184' y='52' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='192' y='4' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='192' y='52' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='200' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='200' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='208' y='52' fill='currentColor' style='font-size:1em'>"</text>
<text text-anchor='middle' x='216' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='240' y='4' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='248' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='256' y='4' fill='currentColor' style='font-size:1em'>]</text>
<text text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='312' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='328' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'>s</text>
<text text-anchor='middle' x='360' y='4' fill='currentColor' style='font-size:1em'>→</text>
<text text-anchor='middle' x='376' y='4' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='384' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='392' y='4' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='400' y='4' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='408' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='416' y='4' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='424' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='432' y='4' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='448' y='4' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='456' y='4' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='464' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='472' y='4' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='480' y='4' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='488' y='4' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='496' y='4' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='504' y='4' fill='currentColor' style='font-size:1em'>s</text>
</g>

    </svg>
  
</div>
<h3 id="via-auth0-management-api">Via Auth0 Management API</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># List current grant types</span>
</span></span><span style="display:flex;"><span>curl -s -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$MGMT_TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  <span style="color:#e6db74">&#34;https://YOUR_DOMAIN.auth0.com/api/v2/clients/</span>$CLIENT_ID<span style="color:#e6db74">&#34;</span> | <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  jq <span style="color:#e6db74">&#39;.grant_types&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Remove device_code from grant types</span>
</span></span><span style="display:flex;"><span>curl -X PATCH <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$MGMT_TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#39;{
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;grant_types&#34;: [&#34;authorization_code&#34;, &#34;refresh_token&#34;, &#34;client_credentials&#34;]
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  }&#39;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  <span style="color:#e6db74">&#34;https://YOUR_DOMAIN.auth0.com/api/v2/clients/</span>$CLIENT_ID<span style="color:#e6db74">&#34;</span>
</span></span></code></pre></div><h3 id="tenant-level-lockdown">Tenant-Level Lockdown</h3>
<p>For Auth0 Enterprise, you can disable the grant at the tenant level by removing it from the allowlist in the Tenant Settings → Advanced → Grant Types.</p>
<h2 id="detection-siem-rules-for-device-code-phishing">Detection: SIEM Rules for Device Code Phishing</h2>
<p>Disabling device code is the best fix. If you can&rsquo;t disable it immediately, add detection:</p>
<h3 id="microsoft-sentinel-kql">Microsoft Sentinel (KQL)</h3>
<pre tabindex="0"><code class="language-kql" data-lang="kql">// Detect device code authentication that deviates from normal CLI/device sources
SigninLogs
| where AuthenticationProtocol == &#34;deviceCode&#34;
| where ResultType == &#34;0&#34;  // Successful auth
| where DeviceDetail.operatingSystem !in (&#34;Windows&#34;, &#34;macOS&#34;, &#34;Linux&#34;)  // Unexpected OS
    or ClientAppUsed == &#34;Mobile Apps and Desktop clients&#34;  // Unusual client
| project TimeGenerated, UserPrincipalName, IPAddress, 
          DeviceDetail, AppDisplayName, Location
| order by TimeGenerated desc
</code></pre><pre tabindex="0"><code class="language-kql" data-lang="kql">// Alert: Device code auth from same user_code polled from multiple IPs
// (indicates attacker polling from different IP than user login)
SigninLogs
| where AuthenticationProtocol == &#34;deviceCode&#34;
| where ResultType == &#34;0&#34;
| summarize IPList = make_set(IPAddress), Count = count() 
  by UserPrincipalName, bin(TimeGenerated, 1h)
| where Count &gt; 2 and array_length(IPList) &gt; 1
</code></pre><h3 id="splunk-spl">Splunk (SPL)</h3>
<pre tabindex="0"><code class="language-spl" data-lang="spl">index=azure_ad sourcetype=azure:aad:signin
AuthenticationProtocol=deviceCode
ResultType=0
| stats count by UserPrincipalName, IPAddress, AppDisplayName, DeviceOperatingSystem
| where count &gt; 1 AND (DeviceOperatingSystem=&#34;Unknown&#34; OR DeviceOperatingSystem=&#34;&#34;)
| table _time, UserPrincipalName, IPAddress, AppDisplayName, DeviceOperatingSystem
</code></pre><h3 id="audit-log-indicators">Audit Log Indicators</h3>
<p>Look for these patterns in Entra ID / Unified Audit Log:</p>
<ul>
<li><code>Operation: UserLoginFailed</code> with <code>ErrorCode: AADSTS70019</code> (device code expired — attacker is requesting many codes hoping one gets used)</li>
<li><code>Operation: Sign-in</code> + <code>AuthenticationProtocol: deviceCode</code> from known VPN exit IPs or anonymizers</li>
<li>User logs in via device code, then immediately accesses Exchange or SharePoint from a different IP than their normal workstation</li>
</ul>
<h2 id="response-playbook-if-device-code-phishing-succeeded">Response Playbook: If Device Code Phishing Succeeded</h2>
<p>If a user&rsquo;s M365 account was compromised via device code phishing:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-powershell" data-lang="powershell"><span style="display:flex;"><span><span style="color:#75715e"># 1. Revoke all refresh tokens for the user</span>
</span></span><span style="display:flex;"><span>Revoke-MgUserSignInSession -UserId <span style="color:#e6db74">&#34;user@corp.example.com&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 2. Reset the user&#39;s password (forces new authentication)</span>
</span></span><span style="display:flex;"><span>Update-MgUser -UserId <span style="color:#e6db74">&#34;user@corp.example.com&#34;</span> -PasswordProfile @{
</span></span><span style="display:flex;"><span>  ForceChangePasswordNextSignIn = $true
</span></span><span style="display:flex;"><span>  Password = <span style="color:#e6db74">&#34;TempPass!</span>$(Get-Random)<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 3. Revoke all OAuth app consents (Microsoft Graph)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># GET delegated permission grants</span>
</span></span><span style="display:flex;"><span>GET https<span style="color:#960050;background-color:#1e0010">:</span>//graph.microsoft.com/v1.<span style="color:#ae81ff">0</span>/users/{userId}/oauth2PermissionGrants
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># DELETE specific grant</span>
</span></span><span style="display:flex;"><span>DELETE https<span style="color:#960050;background-color:#1e0010">:</span>//graph.microsoft.com/v1.<span style="color:#ae81ff">0</span>/oauth2PermissionGrants/{id}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 4. Review mail rules (attackers often create inbox rules to forward email)</span>
</span></span><span style="display:flex;"><span>Get-InboxRule -Mailbox <span style="color:#e6db74">&#34;user@corp.example.com&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 5. Check MFA registrations (attackers may add their own MFA method)</span>
</span></span><span style="display:flex;"><span>GET https<span style="color:#960050;background-color:#1e0010">:</span>//graph.microsoft.com/v1.<span style="color:#ae81ff">0</span>/users/{userId}/authentication/methods
</span></span></code></pre></div><h2 id="faq">FAQ</h2>
<p><strong>Q: Does disabling device code flow in Entra ID break legitimate TV/IoT apps?</strong></p>
<p>Yes, if those apps use the device authorization grant. Exclude them from the Conditional Access policy using a named group (e.g., &ldquo;Device Code Exempt Accounts&rdquo;). Only service accounts used by TVs or kiosk devices should be in this group, never regular user accounts.</p>
<p><strong>Q: Our users regularly use Azure CLI — does <code>az login</code> use device code?</strong></p>
<p><code>az login</code> defaults to browser-based authentication on machines with a browser. Device code is used when you run <code>az login --use-device-code</code> explicitly or when running in a headless environment. Your policy should allow device code for your DevOps service accounts but block it for all standard users.</p>
<p><strong>Q: Can attackers use device code phishing against non-Microsoft IdPs?</strong></p>
<p>Yes — any IdP that implements RFC 8628 is potentially vulnerable if users can be socially engineered to enter a code on the legitimate authorization server. Okta, Google Workspace, and Ping Identity all support device code. Defense is the same: disable it or restrict it to specific client IDs.</p>
<p><strong>Q: How do I detect if my tenant has already been compromised?</strong></p>
<p>Run this KQL query against the last 90 days (refresh token lifetime) in Microsoft Sentinel:</p>
<pre tabindex="0"><code class="language-kql" data-lang="kql">SigninLogs
| where TimeGenerated &gt; ago(90d)
| where AuthenticationProtocol == &#34;deviceCode&#34;
| where ResultType == &#34;0&#34;
| summarize DeviceCodeLogins = count() by UserPrincipalName
| order by DeviceCodeLogins desc
</code></pre><p>Any user with device code logins who doesn&rsquo;t operate a TV or CLI service warrants investigation.</p>
<p><strong>Q: Will blocking device code break the <code>mstsc /remotepc</code> Remote Desktop flow?</strong></p>
<p>No. Remote Desktop uses a separate authentication flow (MS-RDPBCGR), not device authorization grant. Blocking device code does not affect RDP, Windows Hello, or SSPR.</p>
<h2 id="internal-linking">Internal Linking</h2>
<p>For the broader category of non-human identity threats that device code phishing enables (service account compromise, long-lived refresh tokens), see <a href="/posts/nhi-secrets-sprawl-fixing-the-non-human-identity-credential-crisis/">NHI Secrets Sprawl: Fixing the Non-Human Identity Credential Crisis</a>.</p>
<p>For news coverage of active device code phishing campaigns against M365 organizations, see <a href="/posts/device-code-phishing-campaign-targets-340-microsoft-365-organizations-using-oauth-abuse/">Device Code Phishing Campaign Targets 340+ Microsoft 365 Organizations</a>.</p>
<p>For MFA bypass techniques that pair with device code phishing in layered attack chains, see <a href="/posts/mfa-bypass-attacks-understanding-threats-and-implementing-phishing-resistant-authentication/">MFA Bypass Attacks: Understanding Threats and Implementing Phishing-Resistant Authentication</a>.</p>
]]></content:encoded></item></channel></rss>