## Summary
The Echo proxy middleware (`middleware/proxy.go`) preserves an incoming `X-Real-IP` header verbatim and forwards it to the upstream service when `Echo#IPExtractor` is not configured — which is the default. Because any HTTP client can supply an arbitrary `X-Real-IP` value, an attacker can cause Echo to relay a spoofed client IP address to every upstream service behind the proxy, undermining upstream IP-based access controls, rate limiting, audit logging, and geo-restriction.
## Affected Component
- `middleware/proxy.go` — `ProxyConfig.ToMiddleware()`, header-rewriting block (lines 351–355)
## Description
### The header-preservation condition passes spoofed values to upstream
`ProxyConfig.ToMiddleware()` (`proxy.go:338-405`) prepares forwarding headers before dispatching each request. The `X-Real-IP` rewrite logic at lines 351-355 reads:
```go
// proxy.go:351-355
// Basically it's not good practice to unconditionally pass incoming x-real-ip header to upstream.
// However, for backward compatibility, legacy behavior is preserved unless you configure Echo#IPExtractor.
if req.Header.Get(echo.HeaderXRealIP) == "" || c.Echo().IPExtractor != nil {
req.Header.Set(echo.HeaderXRealIP, c.RealIP())
}
```
The condition is `TRUE` (and therefore overwrites the header with a derived value) only when:
- The header is absent — `req.Header.Get(echo.HeaderXRealIP) == ""`; **or**
- `IPExtractor` is explicitly configured — `c.Echo().IPExtractor != nil`
The condition is `FALSE` — and the header is left **unchanged** — when the request arrives with an `X-Real-IP` header already set **and** `IPExtractor` is `nil`. Because `Echo.New()` leaves `IPExtractor` as `nil`, this is the out-of-the-box behaviour for every application that uses `Proxy()` or `ProxyWithConfig()` without extra configuration.
An attacker who sets `X-Real-IP` to any value causes Echo to forward exactly that value to the upstream, with no modification or validation.
### The comment in the source code confirms intent and the security gap
The inline comment at line 351-352 explicitly states:
> "Basically it's not good practice to unconditionally pass incoming x-real-ip header to upstream. However, for backward compatibility, legacy behavior is preserved unless you configure Echo#IPExtractor."
The framework is aware that the default is insecure and retains it for backward compatibility. No warning appears in the `Proxy()` or `ProxyWithConfig()` documentation, so operators who follow the standard setup example receive a silently insecure proxy configuration.
This is structurally identical to the documented insecurity in `ip.go:27`:
> "Note: if you don't set `Echo#IPExtractor` explicitly, Echo fallback to legacy behavior, which is not a good choice."
### Full execution chain
1. Attacker sends `GET /api/admin` to the Echo proxy with header `X-Real-IP: 203.0.113.1` (a trusted corporate IP)
2. `ToMiddleware()` evaluates the guard at line 353: header is present (`!= ""`), `IPExtractor` is `nil` → condition is `FALSE`
3. `req.Header.Set` is **not** called; the upstream request carries the original, attacker-supplied `X-Real-IP: 203.0.113.1`
4. Upstream service checks `X-Real-IP` against its IP allowlist → finds `203.0.113.1` → grants access
5. Attacker reaches an endpoint that should be restricted to the corporate IP range
Secondary impact path (audit poisoning):
- All upstream log entries, rate-limit counters, and geo-restriction checks are evaluated against `203.0.113.1` rather than the real client IP, rendering audit trails and security analytics unreliable.
## Proof of Concept
```go
package main
import (
"fmt"
"log"
"net/http"
echo "github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)
func main() {
// Upstream server: echoes back the X-Real-IP it received
upstream := http.NewServeMux()
upstream.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "upstream sees X-Real-IP: %s\n", r.Header.Get("X-Real-IP"))
})
go http.ListenAndServe(":9000", upstream)
// Echo proxy — IPExtractor deliberately NOT set (the default)
e := echo.New()
targets := []*middleware.ProxyTarget{{URL: mustParse("http://127.0.0.1:9000")}}
e.Use(middleware.Proxy(middleware.NewRoundRobinBalancer(targets)))
log.Fatal(e.Start(":1323"))
}
```
```bash
# Without spoofed header — upstream sees actual peer address
curl http://127.0.0.1:1323/
# upstream sees X-Real-IP: 127.0.0.1
# With spoofed header — upstream sees attacker-supplied value
curl -H 'X-Real-IP: 198.51.100.77' http://127.0.0.1:1323/
# upstream sees X-Real-IP: 198.51.100.77
```
The attacker-supplied IP `198.51.100.77` arrives at the upstream unchanged.
## Impact
- Upstream IP-based access controls (allowlists, blocklists, geo-restrictions) can be bypassed by supplying the expected IP in `X-Real-IP`
- Upstream rate limiters that key on `X-Real-IP` are bypassable (same class as the Echo rate-limiter fi
## Summary
The `/credentials/signurl` endpoint decides authorization from the client-supplied `X-Rucio-Account` HTTP header instead of the authenticated token's account. Any client holding **any** valid auth token (even a low-privilege account they legitimately own) can send `X-Rucio-Account: root` to pass the root-only permission check and have the Rucio server mint a presigned **read / write / delete** URL for an **arbitrary** object, signed with the RSE's stored S3 / GCS / Swift credentials.
## Details
`SignURL.get()` takes the authorization principal from a request header and
never uses the token-authenticated identity:
```python
# lib/rucio/web/rest/flaskapi/v1/credentials.py
account = request.headers.get('X-Rucio-Account', default=None) # L165 (attacker-controlled)
...
result = get_signed_url(account, rse=rse, service=service, # L194
operation=operation, url=url, lifetime=lifetime, vo=vo)
```
The gateway then uses that header value as the `issuer` for the permission check:
```python
# lib/rucio/gateway/credential.py
auth_result = permission.has_permission(issuer=account, vo=vo, # L57
action='get_signed_url', kwargs=kwargs, ...)
```
and the permission function is root-only:
```python
# lib/rucio/core/permission/generic.py
def perm_get_signed_url(issuer, kwargs, session):
return _is_root(issuer) # _is_root(x) -> x.external == 'root'
```
`InternalAccount('root', vo).external == 'root'` unconditionally, so the gate passes whenever the header is `root`. The endpoint is on `AuthenticatedBlueprint`, whose `before_request` hook validates the token and sets `request.environ['issuer']` **from the token** — but nothing ever compares `X-Rucio-Account` to it:
```python
# lib/rucio/web/rest/flaskapi/v1/common.py (request_auth_env)
flask.request.environ['issuer'] = auth.get('account') # L168 (the real account; unused by SignURL)
```
This is anomalous: every other authenticated handler derives the account from `request.environ['issuer']`; `credentials.py` is the only one that trusts the header. Additionally, `core.credential.get_signed_url` never checks that the supplied `url`'s host/bucket belongs to the target RSE, so even a legitimate `root` caller gets an arbitrary-object signing oracle. In multi-VO the VO is also read from the `X-Rucio-VO` header, allowing cross-tenant targeting.
## Proof of concept
Request (any valid token + spoofed account):
```
GET /credentials/signurl?rse=<cloudRSE>&svc=s3&op=delete&url=https://victim-bucket.s3.amazonaws.com/important/dataset.root HTTP/1.1
X-Rucio-Auth-Token: <any valid token, even a low-privilege account>
X-Rucio-Account: root
Accept: application/octet-stream
```
Response: `200 OK` with a presigned DELETE URL the attacker replays directly against the storage backend.
## Impact
A low-privilege Rucio user can read, overwrite, and delete arbitrary objects on any cloud-backed (S3/GCS/Swift) RSE using the server's stored credentials — enabling data exfiltration, tampering, and destruction, and cross-tenant access in multi-VO deployments.
## Credit
Reported by seankohjs. Found via static analysis + manual verification.
## Summary
With `SslMode` set to `VerifyCA` or `VerifyFull` with no configured CA certificate, an unvalidated TLS connection is treated as secure and a clear-text password can be sent before the certificate is checked. This can occur when relying on the password to validate a self-signed cert, e.g., MariaDB's [zero-configuration TLS](https://mariadb.com/docs/server/security/encryption/data-in-transit-encryption/zero-configuration-ssl).
## Impact
An attacker who can deploy a man-in-the-middle MySQL proxy presenting any self-signed certificate can capture the plaintext database password of a client that:
- uses `SslMode = VerifyCA` or `VerifyFull`, and
- does not use the `SslCa` connection string option, and
- uses a non-empty password.
The attacker completes the TLS handshake with its own cert, requests a clear-text password authentication scheme (`mysql_clear_password`, or forces the `caching_sha2_password`/`sha256_password` clear-text fallback), and receives the password before the fingerprint check rejects the connection, defeating the man-in-the-middle protection `VerifyFull` is expected to provide.
Not affected: a configured CA (`SslCa`), CA-validated TLS, local connections (Unix socket / loopback), or empty passwords. Using `SslMode` set to `Preferred` or `Required` is out of scope (this is documented as not authenticating the server).
## Workarounds
Provide `SslCa` with `VerifyCA`/`VerifyFull`, use a local/Unix-socket connection, or avoid clear-text authentication.
## References
- https://mariadb.org/mission-impossible-zero-configuration-ssl/
A CSV formula injection vulnerability exists in the registrations export feature of the Joomla extension iCagenda versions 3.5.0 through 4.0.16. This vulnerability allows malicious formulas to be injected into exported CSV files, potentially leading to unintended execution when the CSV is opened in spreadsheet software.
The Rich Showcase for Google Reviews plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 7.1.6 This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with contributor-level access and above, to retrieve the plugin's 127-character site-wide grw_auth_code authentication secret and use it to impersonate the WordPress site to the RichPlugins backend service at app.richplugins.com.
Red Hat OpenShift Container Platform is Red Hat's cloud computing
Kubernetes application platform solution designed for on-premise or private
cloud deployments.
This advisory contains the RPM packages for Red Hat OpenShift Container
Platform 4.16.74. See the following advisory for the container images for
this release:
https://access.redhat.com/errata/RHSA-2026:89715
Security Fix(es):
* net/http/internal/http2: golang: golang.org/x/net: Go HTTP/2: Denial of
Service via malformed SETTINGS_MAX_FRAME_SIZE frame (CVE-2026-33814)
* cri-o: cri-o: Sandbox state poisoning via pod annotations may expose
runtime socket (CVE-2026-62146)
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.
All OpenShift Container Platform 4.16 users are advised to upgrade to these
updated packages and images when they are available in the appropriate
release channel. To check for available updates, use the OpenShift CLI (oc)
or web console. Instructions for upgrading a cluster are available at
https://docs.redhat.com/en/documentation/openshift_container_platform/4.16/html-single/updating_clusters/index#updating-cluster-cli.
Private keys for eight eMudhra intermediate CA certificates have been compromised https://emudhra.we-have-a-problem.com/ , which impacts certificate trust for outbound network request features of HCL Notes Client. An unauthenticated network attacker could spoof server certificates to execute a man in the middle (MITM) attack, enabling them to intercept and/or modify the content of outbound TLS connections.
Private keys for eight eMudhra intermediate CA certificates have been compromised https://emudhra.we-have-a-problem.com/ , which impacts certificate trust for outbound network request features of HCL Domino Server. An unauthenticated network attacker could spoof server certificates to execute a man in the middle (MITM) attack, enabling them to intercept and/or modify the content of outbound TLS connections.
A vulnerability in github.com/klauspost/compress/zstd versions prior to 1.20.2 causes a panic due to an out-of-range slice index when decompressing crafted two-block zstd frames. The flaw arises from improper handling of Huffman-weight tables in the FSE decoder, leading to reuse of stale state and an invalid decode table. This can crash any program decompressing untrusted zstd input. The issue is fixed in version 1.20.2.
A vulnerability in github.com/eclipse-keypont/crypto11/v2 versions from 2.0.0-rc3 through 2.0.0-rc8 allows an attacker to compromise the confidentiality of shared secrets. The ML-KEM key-pair lookup functions do not verify that the public key matches the private key, enabling an attacker who can open an unauthenticated session and plant a public key object with victim identifiers to receive shared secrets intended for the victim. Versions prior to 2.0.0-rc3 and after 2.0.0-rc8, as well as v1 module paths, are not affected.
CVE-2026-102800 is a high-severity stored cross-site scripting (XSS) vulnerability in the DJ-HelpfulArticles extension for Joomla versions 1.0.0 through 1.2.0. The vulnerability arises from an unauthenticated voting widget that accepts a client-supplied 'ip' field via AJAX without proper output escaping. This field is stored and later rendered in the Joomla administrator backend without HTML escaping, enabling stored XSS attacks. The lack of CSRF tokens and rate limiting exacerbates the risk by allowing repeated exploitation.
An unauthenticated SQL injection vulnerability exists in the Gridbox extension for Joomla versions 1.0.0 through 2.20.4.1. The flaw occurs on store product list pages where the sort-by URL parameter is improperly handled, allowing injection into the ORDER BY clause of a SQL query. This vulnerability is critical with a CVSS score of 9.3.
CVE-2026-102789 is a critical improper access control vulnerability in the Gridbox extension for Joomla by balbooa.com. Versions from 1.0.0 up to 2.20.4.1 are affected. The flaw exists because the EditorController::getBlogPosts() task lacks an authorization check that other controller tasks perform, allowing unauthorized users to invoke this function. This could lead to unauthorized access to blog post data or actions within the extension.
Red Hat issued a security advisory for osbuild-composer, a service that builds customized OS artifacts and uploads images to cloud environments. The update addresses multiple vulnerabilities including authorization bypass, cross-site scripting (XSS), arbitrary code execution via XSS, unauthorized information disclosure, and man-in-the-middle attacks via untrusted intermediate certificates. These vulnerabilities stem from components such as gRPC-Go, golang.org/x/net/html, github.com/labstack/echo, and crypto/x509. The update is rated as Important by Red Hat Product Security and applies to Red Hat Enterprise Linux 8.6 variants.
The general-purpose data-binding functionality and tree-model for Jackson Data Processor. It builds on core streaming parser/generator package, and uses Jackson Annotations for configuration.
Security Fix(es):
* com.fasterxml.jackson.core/jackson-databind: tools.jackson.core/jackson-databind: jackson-databind: CPU Denial of Service via unbounded numeric parsing (CVE-2026-68497)
* com.fasterxml.jackson.core/jackson-databind: tools.jackson.core:jackson-databind: Jackson-databind: Denial of Service via quadratic forward-reference completion (CVE-2026-91777)
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.
### Impact
An attacker who uses this vulnerability can craft a PDF which leads to long runtimes. This requires cross-reference streams with repeated malformed cross-reference streams.
### Patches
This has been fixed in [pypdf==6.21.2](https://github.com/py-pdf/pypdf/releases/tag/6.21.2).
### Workarounds
If you cannot upgrade yet, consider applying the changes from PR [#4240](https://github.com/py-pdf/pypdf/pull/4240).
### Notes
This is a follow-up to https://github.com/py-pdf/pypdf/security/advisories/GHSA-55h5-xmcq-c37v, which had the side-effect of still loading the whole stream again despite the cache being present.
### Impact
An attacker who uses this vulnerability can craft a PDF which leads to long runtimes. This requires opening a file with large/wrong upper limits in the xref table.
### Patches
This has been fixed in [pypdf==6.21.2](https://github.com/py-pdf/pypdf/releases/tag/6.21.2).
### Workarounds
If you cannot upgrade yet, consider applying the changes from PR [#4239](https://github.com/py-pdf/pypdf/pull/4239).