<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Wed, 30 Sep 2026 23:33:46 +0000</lastBuildDate>
    <item>
      <title>CVE-2026-102269 — PyJWT: Non-canonical signature segments enable raw-token revocation bypass</title>
      <link>https://vulnerability.circl.lu/vuln/cve-2026-102269</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; jpadilla pyjwt&lt;/p&gt;
&lt;p&gt;PyJWT is a Python implementation of JSON Web Token standards. Prior to 2.14.0, PyJWT signature segment is affected because signature segment decoding accepts characters outside the canonical Base64URL representation. This occurs when non-Base64URL characters are appended to a valid compact JWS signature segment. As a result, base64url_decode produces the same signature bytes for different serialized segments. Consequently, raw-token revocation checks can fail to recognize an equivalent modified token. This issue is fixed in version 2.14.0.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; jpadilla pyjwt&lt;/p&gt;
&lt;p&gt;PyJWT is a Python implementation of JSON Web Token standards. Prior to 2.14.0, PyJWT signature segment is affected because signature segment decoding accepts characters outside the canonical Base64URL representation. This occurs when non-Base64URL characters are appended to a valid compact JWS signature segment. As a result, base64url_decode produces the same signature bytes for different serialized segments. Consequently, raw-token revocation checks can fail to recognize an equivalent modified token. This issue is fixed in version 2.14.0.&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/cve-2026-102269</guid>
    </item>
    <item>
      <title>GHSA-hxm8-2xgr-2p9m — PyJWT: Non-canonical signature segments enable raw-token revocation bypass</title>
      <link>https://vulnerability.circl.lu/vuln/ghsa-hxm8-2xgr-2p9m</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: PyJWT&lt;/p&gt;
&lt;p&gt;## Summary&lt;/p&gt;
&lt;p&gt;PyJWT 2.13.0 accepts compact JWS signature segments containing characters that
are not in the Base64URL alphabet. Appending `!!!!` to a valid signature does
not change the decoded signature bytes or authenticated claims, but it changes
the serialized token and its SHA-256 hash. An application that indexes logout
or revocation state by the raw token therefore rejects the logged-out token and
accepts its no-key alternate serialization.&lt;/p&gt;
&lt;p&gt;This report separates two issues: permissive compact-JWS decoding is the
library behavior, while using raw serialized JWT text as a security identity is
a dangerous application composition. A `jti`-indexed control blocks both
representations.&lt;/p&gt;
&lt;p&gt;## Affected Version&lt;/p&gt;
&lt;p&gt;Confirmed with PyJWT 2.13.0 on CPython 3.13. The mutation changes only the
signature segment and requires no signing key.&lt;/p&gt;
&lt;p&gt;## End-to-End Reproduction&lt;/p&gt;
&lt;p&gt;```bash
.venv-research/bin/python 06-practical-testing/revocation-bypass-lab.py
```&lt;/p&gt;
&lt;p&gt;The loopback-only lab performs:&lt;/p&gt;
&lt;p&gt;1. Issue a valid HS256 admin token.
2. Access `/protected` successfully.
3. Log out the canonical token and store `SHA256(raw_token)`.
4. Confirm canonical replay returns HTTP 401.
5. Append `!!!!` to only the signature segment.
6. Confirm the mutated token has the same verified claims and signature bytes,
   a different raw hash, and receives HTTP 200.
7. Repeat with `jti`-indexed revocation and confirm both forms return HTTP 401.&lt;/p&gt;
&lt;p&gt;Observed statuses for raw-token revocation were `200 -&amp;gt; logout -&amp;gt; 401` for th…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: PyJWT&lt;/p&gt;
&lt;p&gt;## Summary&lt;/p&gt;
&lt;p&gt;PyJWT 2.13.0 accepts compact JWS signature segments containing characters that
are not in the Base64URL alphabet. Appending `!!!!` to a valid signature does
not change the decoded signature bytes or authenticated claims, but it changes
the serialized token and its SHA-256 hash. An application that indexes logout
or revocation state by the raw token therefore rejects the logged-out token and
accepts its no-key alternate serialization.&lt;/p&gt;
&lt;p&gt;This report separates two issues: permissive compact-JWS decoding is the
library behavior, while using raw serialized JWT text as a security identity is
a dangerous application composition. A `jti`-indexed control blocks both
representations.&lt;/p&gt;
&lt;p&gt;## Affected Version&lt;/p&gt;
&lt;p&gt;Confirmed with PyJWT 2.13.0 on CPython 3.13. The mutation changes only the
signature segment and requires no signing key.&lt;/p&gt;
&lt;p&gt;## End-to-End Reproduction&lt;/p&gt;
&lt;p&gt;```bash
.venv-research/bin/python 06-practical-testing/revocation-bypass-lab.py
```&lt;/p&gt;
&lt;p&gt;The loopback-only lab performs:&lt;/p&gt;
&lt;p&gt;1. Issue a valid HS256 admin token.
2. Access `/protected` successfully.
3. Log out the canonical token and store `SHA256(raw_token)`.
4. Confirm canonical replay returns HTTP 401.
5. Append `!!!!` to only the signature segment.
6. Confirm the mutated token has the same verified claims and signature bytes,
   a different raw hash, and receives HTTP 200.
7. Repeat with `jti`-indexed revocation and confirm both forms return HTTP 401.&lt;/p&gt;
&lt;p&gt;Observed statuses for raw-token revocation were `200 -&amp;gt; logout -&amp;gt; 401` for th…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/ghsa-hxm8-2xgr-2p9m</guid>
    </item>
  </channel>
</rss>
