Workload exposure through an Ingress controller

Ingress can create an unintended public route when it exposes a workload intended for internal use.

Description

Ingress connects Services to HTTP and HTTPS requests. Depending on the controller and load balancer configuration, access may come from the internet or an internal network. Verify that workloads intended for internal use are not publicly exposed.

Not every service needs an Ingress. Select only those that require external access and restrict the rest to internal communication.

Potential impact

  • Internal services may become reachable from the internet or other external networks.
  • Exposure without required authentication, rate limits or other protections can increase the attack surface.
  • Incorrect routing can send external requests to unintended services.

Remediation

  • Remove public Ingress routes for internal workloads or use an internal-only controller.
  • Restrict exposed services and paths to those that need external access.
  • Review authentication, access controls, TLS and rate limits, and test actual external reachability.

Examples

The first excerpt retains the historical extensions/v1beta1 format for illustration. Kubernetes stopped serving that Ingress API in 1.22; use the supported networking.k8s.io/v1 format for current deployments.

Before

yaml
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: ClusterIP
  ports:
    - port: 3000
      targetPort: 3000
  selector:
    app: app
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
    - host: app.acme.org
      http:
        paths:
          - backend:
              serviceName: app
              servicePort: 3000

After

yaml
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: ClusterIP
  ports:
    - port: 3000
      targetPort: 3000
  selector:
    app: app

Explanation:

  • Before: Defines a route through a controller to the app Service. Internet exposure also depends on controller configuration.
  • After: Retains only the internal ClusterIP Service. Omitting an Ingress from this file does not delete an existing resource; remove the existing app-ingress and check for other public routes.

References