<?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>Lin-Snow — CraftedSignal Threat Feed</title><link>https://feed.craftedsignal.io/vendors/lin-snow/</link><description>Trending threats, MITRE ATT&amp;CK coverage, and detection metadata. Fed continuously.</description><generator>Hugo</generator><language>en</language><managingEditor>hello@craftedsignal.io</managingEditor><webMaster>hello@craftedsignal.io</webMaster><lastBuildDate>Thu, 07 May 2026 21:34:01 +0000</lastBuildDate><atom:link href="https://feed.craftedsignal.io/vendors/lin-snow/feed.xml" rel="self" type="application/rss+xml"/><item><title>Ech0 'Never Expire' Access Tokens Cannot Be Revoked</title><link>https://feed.craftedsignal.io/briefs/2024-04-29-ech0-token-revocation/</link><pubDate>Thu, 07 May 2026 21:34:01 +0000</pubDate><author>hello@craftedsignal.io</author><guid isPermaLink="true">https://feed.craftedsignal.io/briefs/2024-04-29-ech0-token-revocation/</guid><description>Ech0's access tokens with the 'never expire' option cannot be revoked through logout or deletion, leading to persistent access until the JWT secret is rotated instance-wide.</description><content:encoded><![CDATA[<p>Ech0, a self-hosted platform, has a vulnerability concerning the revocation of access tokens created with the &ldquo;never expire&rdquo; option. These tokens, lacking an <code>exp</code> (expiration) claim, bypass three revocation mechanisms. Specifically, the logout function panics when attempting to process these tokens due to a nil pointer dereference, while the admin&rsquo;s &ldquo;Delete token&rdquo; function removes the database record without blacklisting the JTI (JWT ID). This means that if a &ldquo;never expire&rdquo; token is compromised, it remains valid until the <code>JWT_SECRET</code> is rotated, an action that affects all users on the platform. This issue was found by aisage.io. Version 4.5.6 is affected.</p>
<h2 id="attack-chain">Attack Chain</h2>
<ol>
<li>An administrator creates an access token with the &ldquo;never expire&rdquo; option. This token lacks the <code>exp</code> claim in its JWT.</li>
<li>The attacker obtains a &ldquo;never expire&rdquo; token through theft or compromise (e.g., stolen laptop, exposed configuration file).</li>
<li>The attacker uses the stolen token in an HTTP Authorization header to access protected resources. The middleware accepts the token since it has a valid signature.</li>
<li>The legitimate owner attempts to revoke the token via logout. The logout handler attempts to parse the token and extract the expiration time.</li>
<li>Parsing of the token in the logout handler leads to a panic because it attempts to access <code>.Time</code> field of a nil <code>ExpiresAt</code> claim (present only on tokens with expiry). The token revocation is skipped.</li>
<li>The administrator attempts to delete the access token via the admin panel. This action removes the metadata for the token from the database, but does not blacklist the JTI.</li>
<li>The attacker continues to use the token for authorized requests, bypassing revocation attempts.</li>
<li>The attacker maintains perpetual access to the system, leveraging the scopes associated with the stolen token.</li>
</ol>
<h2 id="impact">Impact</h2>
<p>Compromised &ldquo;never expire&rdquo; tokens grant attackers persistent authenticated access to Ech0 instances. This access remains valid until the <code>JWT_SECRET</code> is rotated, forcing a platform-wide reset. Administrators are misled by the &ldquo;Delete token&rdquo; function, which appears to revoke access but does not. The need to rotate the <code>JWT_SECRET</code> for proper revocation introduces a blast radius, requiring every user to log in again.</p>
<h2 id="recommendation">Recommendation</h2>
<ul>
<li>Replace &ldquo;never expire&rdquo; tokens with very long-lived tokens, ensuring an <code>exp</code> claim exists. See code example in the overview section.</li>
<li>Modify the logout handler to gracefully handle tokens with a nil <code>ExpiresAt</code> field. See code example in the overview section.</li>
<li>When deleting an access token through the admin panel, blacklist the corresponding JTI. See code example in the overview section.</li>
<li>Rotate the JWT secret immediately if a &ldquo;never expire&rdquo; token is suspected of being compromised. This invalidates all active tokens and prevents further unauthorized access.</li>
</ul>
]]></content:encoded><category domain="severity">high</category><category domain="type">advisory</category><category>credential-access</category><category>token-revocation</category><category>web-application</category></item></channel></rss>