A critical vulnerability (CVE-2026-28498) exists in the Authlib Python library used by kimi-cli that allows bypassing cryptographic verification of OIDC ID Token hash claims. The flaw causes the library to incorrectly accept tokens with unsupported cryptographic algorithms by returning a successful validation result instead of failing. This enables token substitution attacks in OIDC Hybrid or Implicit flows, violating OpenID Connect and JWT specifications. A patch is available that enforces fail-closed behavior on unsupported algorithms.
The kimi-cli FastMCP authentication integration allows a confused deputy attack leading to account takeover. The FastMCP server acts both as an OAuth client to a downstream authorization server (e.g., Entra ID) and as an authorization server to its clients. Due to the use of a static client registration in Entra ID and persistent user consent cookies, an attacker controlling their own MCP client can leverage the victim's prior consent to the static client to bypass re-authorization prompts. This enables the attacker to obtain authorization codes and potentially take over the victim's account. A patch is available for this vulnerability.
FastMCP versions prior to 2.14.0 allowed usage of MCP SDK versions earlier than 1.23, which are vulnerable to CVE-2025-66416. FastMCP itself does not directly use the affected MCP SDK components. Users should upgrade to FastMCP 2.14.0 or later to avoid exposure to this vulnerability.
A denial of service vulnerability exists in the pyasn1 library's BER/CER/DER decoders and encoders when processing OBJECT IDENTIFIER and RELATIVE-OID values. The vulnerability arises from quadratic time complexity relative to the number of arcs in these values, allowing crafted payloads with many arcs to consume excessive CPU time. This affects applications decoding untrusted ASN.1 data such as certificates, LDAP, SNMP, and Kerberos. The issue is fixed in pyasn1 version 0.6.4, which improves the processing to linear time. Users should upgrade to this version or later to mitigate the risk.
Authlib's OAuth 2.0 authorization endpoint in kimi-cli versions prior to 1.6.10, certain 1.7.x versions, and some 2.x versions contains an open redirect vulnerability. This occurs when an unsupported response_type is used along with an attacker-controlled redirect_uri, allowing redirection without client validation or user authentication. The flaw exists because the server returns a redirect response to the supplied redirect_uri before validating the client or redirect URI. This vulnerability has a CVSS score of 5.4 (medium severity) and affects multiple versions as specified. A patch is available to address this issue.
A denial of service vulnerability exists in the python-multipart library used for parsing multipart/form-data requests. The flaw allows an attacker to cause excessive CPU usage by sending requests with many repeated headers without termination or a single very large header value. This affects ASGI applications using frameworks like Starlette or FastAPI that rely on python-multipart. The issue is mitigated by upgrading to python-multipart version 0.0.27 or later. If immediate upgrade is not possible, limiting request body size at the server or proxy can reduce exposure but does not fully resolve the vulnerability.
### Summary
`joserfc.jwt.decode` accepts attacker-forged HMAC-signed tokens when the
caller-supplied verification key is the empty string or `None`.
`HMACAlgorithm.sign` and `HMACAlgorithm.verify` in
[`src/joserfc/_rfc7518/jws_algs.py:62-70`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/jws_algs.py#L62-L70) feed whatever
`OctKey.get_op_key(...)` produced into `hmac.new(...)`, and `OctKey.import_key`
only emits a `SecurityWarning` when the raw key is shorter than 14 bytes
without rejecting zero-length input. Any application whose JWT secret is
sourced from an unset environment variable, an unset Redis / DB row, a key
finder fallback that returns `""`, or a `Hash.new("")`-style default verifies
attacker tokens forged with `HMAC(key=b"", signing_input)` because the
attacker trivially reproduces the same digest with no secret knowledge.
This is a cross-language sibling of jwt/ruby-jwt GHSA-c32j-vqhx-rx3x /
CVE-2026-45363 (HS256/HS384/HS512 verify accepted an empty/nil HMAC key,
filed 2026-05-13). ruby-jwt v3.2.0 added an `ensure_valid_key!` precondition
that rejects empty keys at both sign and verify entry; joserfc has no
equivalent. (The same primitive lives in the deprecated `authlib.jose`
module by the same maintainer; filing this advisory against joserfc
alongside a separate `authlib` advisory because the codebases are
independent shipping artifacts on PyPI.)
### Affected versions
`joserfc` (PyPI) `<= 1.6.7` (latest published release reproduces). No
patched release.
### Privilege required
Unauthenticated. Any HTTP / RPC endpoint that calls `joserfc.jwt.decode`
with a verification key sourced from configuration is reachable. The
condition that makes the bug observable is operator-side: the configured
secret resolves to `""` or `None`. Common patterns that produce this state
in production:
- `OctKey.import_key(os.environ.get("JWT_SECRET", ""))`
- A key finder callable that returns `""` / `None` for an unknown `kid`
- Default values like `os.getenv("SECRET") or ""`, `cfg.get("secret", "")`
- Database / Redis row lookup that returns `""` for a missing row
### Vulnerable code
[`src/joserfc/_rfc7518/jws_algs.py:43-70`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/jws_algs.py#L43-L70):
```python
class HMACAlgorithm(JWSAlgModel):
SHA256 = hashlib.sha256
SHA384 = hashlib.sha384
SHA512 = hashlib.sha512
def __init__(self, sha_type, recommended=False):
self.name = f"HS{sha_type}"
self.description = f"HMAC using SHA-{sha_type}"
self.recommended = recommended
self.hash_alg = getattr(self, f"SHA{sha_type}")
self.algorithm_security = sha_type
def sign(self, msg: bytes, key: OctKey) -> bytes:
op_key = key.get_op_key("sign")
return hmac.new(op_key, msg, self.hash_alg).digest()
def verify(self, msg: bytes, sig: bytes, key: OctKey) -> bool:
op_key = key.get_op_key("verify")
v_sig = hmac.new(op_key, msg, self.hash_alg).digest()
return hmac.compare_digest(sig, v_sig)
```
[`src/joserfc/_rfc7518/oct_key.py:52-63`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/oct_key.py#L52-L63):
```python
@classmethod
def import_key(cls, value, parameters=None, password=None) -> "OctKey":
key: OctKey = super(OctKey, cls).import_key(value, parameters, password)
if len(key.raw_value) < 14:
# https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final
warnings.warn("Key size should be >= 112 bits", SecurityWarning)
return key
```
The `< 14` check only warns; `len(key.raw_value) == 0` falls through and is
returned to the caller. `HMACAlgorithm.verify` then calls
`hmac.compare_digest(sig, hmac.new(b"", signing_input, sha256).digest())`,
and Python's `hmac.new(b"", ...)` accepts the empty key.
Cross-language sibling of ruby-jwt's fix in [`lib/jwt/jwa/hmac.rb`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/lib/jwt/jwa/hmac.rb):
```ruby
def ensure_valid_key!(key)
raise_verify_error!('HMAC key expected to be a String') unless key.is_a?(String)
raise_verify_error!('HMAC key cannot be empty') if key.empty?
end
```
invoked from both `sign(signing_key:)` and `verify(verification_key:)`.
PyJWT landed an equivalent guard in 2.13.0 (`HMACAlgorithm.prepare_key`
raises `InvalidKeyError("HMAC key must not be empty.")` for `len(key_bytes) == 0`).
firebase/php-jwt rejects empty material in `Key.__construct`. jjwt enforces a
256-bit minimum in `DefaultMacAlgorithm.validateKey`. joserfc has the
strongest existing length-warning logic but stops at `< 14 bytes` warn
rather than `== 0` reject.
### How an empty `JWT_SECRET` reaches `hmac.new`
1. The application calls `joserfc.jwt.decode(value, key, algorithms=["HS256"])`
where `key = OctKey.import_key("")` (or `OctKey.import_key(b"")`,
or any custom path t
Satellite provides a container image that you can use to run an MCP server locally. The MCP server for Satellite is designed for advanced reporting and data analysis that leverages AI capabilities. You can use it to generate dynamic and comprehensive reports from your Satellite inventory.
This update for python-python-multipart fixes the following issues
- CVE-2026-53537: multipart/form-data with extended parameters can lead to file or parameter smuggling (bsc#1268506).
- CVE-2026-53538: urlencoded requests containing semicolons can lead to form field smuggling (bsc#1268496).
- CVE-2026-53539: small crafted body can cause a denial of service (bsc#1268500).
- CVE-2026-53540: crafted request buffers can lead to degrading availability (bsc#1268488).
This update for python-starlette fixes the following issues
- CVE-2026-48817: arbitrary HTTP method dispatched to `HTTPEndpoint` attributes via `getattr` (bsc#1268389).
- CVE-2026-54282: request path that lacks a leading forward slash can lead to request.url.hostname manipulation
(bsc#1268520).
- CVE-2026-54283: urlencoded request body with an oversized data can lead to a denial of service (bsc#1268517).
Satellite provides a container image that you can use to run an MCP server locally. The MCP server for Satellite is designed for advanced reporting and data analysis that leverages AI capabilities. You can use it to generate dynamic and comprehensive reports from your Satellite inventory.
PyJWKClient in the kimi-cli library allows fetching JSON Web Key Sets (JWKS) from URLs with schemes beyond HTTP and HTTPS, including file://, ftp://, and data:. This can lead to server-side request forgery (SSRF) on local files and other protocols. An attacker who can influence the jku URL and write to a local file path can forge JWT tokens that the application accepts as valid. The vulnerability affects PyJWT versions 2.11.0 and 2.12.1 and likely earlier versions. A fix is available that restricts allowed URL schemes to HTTP and HTTPS.
### Summary
`set_key()` and `unset_key()` in python-dotenv follow symbolic links when rewriting `.env` files, allowing a local attacker to overwrite arbitrary files via a crafted symlink when a cross-device rename fallback is triggered.
### Details
The `rewrite()` context manager in `dotenv/main.py` is used by both `set_key()` and `unset_key()` to safely modify `.env` files. It works by writing to a temporary file (created in the system's default temp directory, typically `/tmp`) and then using `shutil.move()` to replace the original file.
When the `.env` path is a symbolic link and the temp directory resides on a different filesystem than the target (a common configuration on Linux systems using tmpfs for `/tmp`), the following sequence occurs:
1. `shutil.move()` first attempts `os.rename()`, which fails with an `OSError` because atomic renames cannot cross device boundaries.
2. On failure, `shutil.move()` falls back to `shutil.copy2()` followed by `os.unlink()`.
3. `shutil.copy2()` calls `shutil.copyfile()` with `follow_symlinks=True` by default.
4. This causes the content to be written to the **symlink target** rather than replacing the symlink itself.
An attacker who has write access to the directory containing a `.env` file can pre-place a symlink pointing to any file that the application process has write access to. When the application (or a privileged process such as a deploy script, Docker entrypoint, or CI pipeline) calls `set_key()` or `unset_key()`, the symlink target is overwritten with the new `.env` content.
This vulnerability does not require a race condition and is fully deterministic once the preconditions are met.
### Impact
The primary impacts are to **integrity** and **availability**:
- **File overwrite / destruction (DoS):** An attacker can cause an application or privileged process to corrupt or destroy configuration files, database configs, or other sensitive files it would not normally have access to modify.
- **Integrity violation:** The target file's original content is replaced with `.env`-formatted content controlled by the attacker.
- **Potential privilege escalation:** In scenarios where a privileged process (running as root or a service account) calls `set_key()`, the attacker can leverage this to write to files beyond their own access level.
The scope of impact depends on the application using python-dotenv and the privileges under which it runs.
### Proof of Concept
The following script demonstrates the vulnerability. It requires `/tmp` and the user's home directory to reside on different devices (common on systemd-based Linux systems with tmpfs).
```python
import os
import sys
import tempfile
from dotenv import set_key
# Pre-condition: /tmp must be on a different device than the target directory.
tmp_dev = os.stat("/tmp").st_dev
home_dev = os.stat(os.path.expanduser("~")).st_dev
assert tmp_dev != home_dev, "Skipped: /tmp and ~ are on the same device (no cross-device move)"
with tempfile.TemporaryDirectory(dir=os.path.expanduser("~")) as workdir:
# File an attacker wants to overwrite
target = os.path.join(workdir, "victim_config.txt")
with open(target, "w") as f:
f.write("DB_PASSWORD=supersecret\n")
# Attacker pre-places a symlink at the path the application will use as .env
env_symlink = os.path.join(workdir, ".env")
os.symlink(target, env_symlink)
before = open(target).read()
# Application writes a new key -- triggers the cross-device fallback
set_key(env_symlink, "INJECTED", "attacker_value")
after = open(target).read()
print("Before:", repr(before))
print("After: ", repr(after))
print("Symlink target overwritten:", target)
```
**Expected output:**
```
Before: 'DB_PASSWORD=supersecret\n'
After: "DB_PASSWORD=supersecret\nINJECTED='attacker_value'\n"
Symlink target overwritten: /home/user/tmp806nut2g/victim_config.txt
```
### Remediation
The fix changes the `rewrite()` context manager in the following ways:
1. **Symlinks are no longer followed by default.** When the `.env` path is a symlink, `rewrite()` now resolves it to the real path before proceeding, or (by default) operates on the symlink entry itself rather than the target.
2. **A `follow_symlinks: bool = False` parameter** is added to `set_key()` and `unset_key()` for users who explicitly need the old behavior.
3. **Temp files are written in the same directory** as the target `.env` file (instead of the system temp directory), eliminating the cross-device rename condition entirely.
4. **`os.replace()` is used instead of `shutil.move()`**, providing atomic replacement without symlink-following fallback behavior.
Users are advised to upgrade to the patched version as soon as it is available on PyPI.
### Timeline
| Date | Event |
| ------------ | ---------------
The fence-agents packages provide a collection of scripts for handling remote power management for cluster devices. They allow failed or unreachable nodes to be forcibly restarted and removed from the cluster.
Security Fix(es):
* python-pyjwt: PyJWT: Authentication bypass due to forged JSON Web Tokens (CVE-2026-48526)
For more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.
This update for python-Pygments fixes the following issue:
- CVE-2026-4539: Denial of Service via inefficient regular expression processing in AdlLexer (bsc#1260796).
A vulnerability exists in the idna.encode() function of the kimi-cli package used by python-pip, allowing specially crafted inputs to bypass a previous fix and cause excessive resource consumption leading to potential denial-of-service. This issue is due to insufficient early rejection of overly long inputs. Versions prior to 3.14 lack the improved input length checks. The vulnerability has a medium severity with a CVSS score of 5.3. Official patches addressing this issue are available starting from version 3.14.
Satellite provides a container image that you can use to run an MCP server locally. The MCP server for Satellite is designed for advanced reporting and data analysis that leverages AI capabilities. You can use it to generate dynamic and comprehensive reports from your Satellite inventory.