Docker Containers Running with Privileged Mode

Critical Risk Infrastructure Security
dockercontainersprivileged-accesscontainer-escapehost-securitylinux-capabilitiesdevice-accesskernel-modules

What it is

A critical security vulnerability where Docker containers are executed with the --privileged flag, granting them root-level access to the host system. This breaks container isolation, allowing containers to access all devices, mount filesystems, load kernel modules, and potentially escape to the host system. Privileged containers essentially run with the same security context as the Docker daemon itself.

# VULNERABLE: Docker with privileged flag
docker run -d --name monitor \
  --privileged \
  -v /:/rootfs:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  monitoring/system-monitor:latest

# VULNERABLE: Docker Compose with privileged
version: '3.8'
services:
  webapp:
    image: my-webapp:latest
    privileged: true
    ports:
      - "8080:8080"

# VULNERABLE: Kubernetes with privileged containers
apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-monitor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: monitor
  template:
    metadata:
      labels:
        app: monitor
    spec:
      containers:
      - name: monitor
        image: system-monitor:latest
        securityContext:
          privileged: true
          runAsUser: 0
        volumeMounts:
        - name: docker-sock
          mountPath: /var/run/docker.sock
      volumes:
      - name: docker-sock
        hostPath:
          path: /var/run/docker.sock
# SECURE: Docker with specific capabilities
docker run -d --name monitor \
  --user 1000:1000 \
  --cap-drop ALL \
  --cap-add SYS_PTRACE \
  --cap-add NET_ADMIN \
  --security-opt no-new-privileges:true \
  -v /proc:/host/proc:ro \
  monitoring/system-monitor:latest

# SECURE: Docker Compose without privileged
version: '3.8'
services:
  webapp:
    image: my-webapp:latest
    user: "1000:1000"
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    ports:
      - "8080:8080"

# SECURE: Kubernetes with proper security context
apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-monitor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: monitor
  template:
    metadata:
      labels:
        app: monitor
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
      containers:
      - name: monitor
        image: system-monitor:latest
        securityContext:
          privileged: false
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1000
          capabilities:
            drop: ["ALL"]
            add: ["SYS_PTRACE"]
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc

💡 Why This Fix Works

The vulnerable examples show containers running with --privileged flag, granting unlimited access to the host system. The secure alternatives use specific Linux capabilities, non-root users, read-only filesystems, security policies, and runtime monitoring to provide necessary functionality while maintaining strong isolation and security boundaries.

Why it happens

Developers use the --privileged flag when running Docker containers to bypass permission issues or access hardware devices. This is often done as a quick fix for permission problems without understanding the security implications. The privileged flag removes all security restrictions imposed by the Linux kernel on the container.

Root causes

Docker Run Command with --privileged Flag

Developers use the --privileged flag when running Docker containers to bypass permission issues or access hardware devices. This is often done as a quick fix for permission problems without understanding the security implications. The privileged flag removes all security restrictions imposed by the Linux kernel on the container.

Preview example – YAML
# VULNERABLE: Running container with full host access
docker run --privileged -d my-app:latest

# VULNERABLE: Docker compose with privileged containers
version: '3.8'
services:
  webapp:
    image: my-webapp:latest
    privileged: true  # Grants full host access
    ports:
      - "8080:8080"
  
  database:
    image: postgres:13
    privileged: true  # Unnecessary privileged access
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db_data:/var/lib/postgresql/data

Kubernetes Privileged Pod Security Context

Kubernetes pods configured with privileged: true in their security context inherit the same risks as privileged Docker containers. This is commonly seen in system-level pods, monitoring agents, or when trying to access host resources like the Docker socket or system devices.

Preview example – YAML
# VULNERABLE: Kubernetes deployment with privileged containers
apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-monitor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: system-monitor
  template:
    metadata:
      labels:
        app: system-monitor
    spec:
      containers:
      - name: monitor
        image: system-monitor:latest
        securityContext:
          privileged: true  # VULNERABLE: Full host access
          runAsUser: 0      # Running as root
        volumeMounts:
        - name: docker-sock
          mountPath: /var/run/docker.sock
        - name: host-proc
          mountPath: /host/proc
          readOnly: true
      volumes:
      - name: docker-sock
        hostPath:
          path: /var/run/docker.sock
      - name: host-proc
        hostPath:
          path: /proc

CI/CD Pipeline with Privileged Docker-in-Docker

Continuous Integration systems often use privileged containers for Docker-in-Docker (DinD) builds, allowing build containers to create and manage other containers. This is particularly common in GitLab CI, Jenkins, and other CI systems that need to build Docker images as part of their pipeline.

Preview example – YAML
# VULNERABLE: GitLab CI with privileged Docker service
# .gitlab-ci.yml
image: docker:20.10.16

services:
  - name: docker:20.10.16-dind
    alias: docker
    command: ["--tls=false"]

variables:
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: ""
  DOCKER_DRIVER: overlay2

build:
  stage: build
  # VULNERABLE: Privileged mode for Docker-in-Docker
  tags:
    - privileged
  script:
    - docker info
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    # VULNERABLE: Container can access host filesystem
    - docker run --rm --privileged -v /:/host alpine chroot /host /bin/bash
  only:
    - main

# VULNERABLE: Jenkins pipeline with privileged containers
// Jenkinsfile
pipeline {
    agent {
        docker {
            image 'docker:20.10.16'
            args '--privileged -v /var/run/docker.sock:/var/run/docker.sock'
            // VULNERABLE: Privileged access and Docker socket mounting
        }
    }
    stages {
        stage('Build') {
            steps {
                script {
                    // VULNERABLE: Can access host system
                    sh 'docker run --rm --privileged alpine:latest /bin/sh -c "fdisk -l"'
                    sh 'docker build -t myapp:${BUILD_NUMBER} .'
                }
            }
        }
    }
}

System Administration and Monitoring Containers

System administrators often deploy monitoring, logging, or administrative containers with privileged access to collect host metrics, manage system resources, or perform maintenance tasks. These containers require elevated permissions but are frequently over-privileged beyond their actual needs.

Preview example – BASH
# VULNERABLE: Monitoring container with excessive privileges
docker run -d --name node-exporter \
  --privileged \
  --restart unless-stopped \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  prom/node-exporter:latest \
  --path.rootfs=/host

# VULNERABLE: Log aggregation with privileged access
docker run -d --name log-collector \
  --privileged \
  -v /var/log:/var/log:ro \
  -v /var/lib/docker/containers:/var/lib/docker/containers:ro \
  -v /proc:/host/proc:ro \
  -v /sys:/host/sys:ro \
  fluent/fluentd:latest

# VULNERABLE: System backup container
docker run --rm \
  --privileged \
  -v /:/backup-source \
  -v backup-storage:/backup-destination \
  backup-tool:latest \
  /usr/bin/backup.sh --source / --destination /backup-destination

# VULNERABLE: Network troubleshooting container
docker run -it --rm \
  --privileged \
  --net host \
  --pid host \
  nicolaka/netshoot:latest

Fixes

1

Use Specific Linux Capabilities Instead of Privileged Mode

Replace privileged containers with specific Linux capabilities that grant only the minimum required permissions. Use --cap-add to add specific capabilities and --cap-drop to remove unnecessary ones. This follows the principle of least privilege while maintaining required functionality.

View implementation – YAML
# SECURE: Using specific capabilities instead of privileged mode

# Instead of --privileged, use specific capabilities
docker run -d --name secure-monitor \
  --cap-drop ALL \
  --cap-add SYS_PTRACE \
  --cap-add NET_ADMIN \
  --read-only \
  --tmpfs /tmp \
  monitoring-app:latest

# SECURE: Docker Compose with limited capabilities
version: '3.8'
services:
  network-monitor:
    image: network-monitor:latest
    cap_drop:
      - ALL
    cap_add:
      - NET_ADMIN
      - NET_RAW
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges:true
    user: "1000:1000"
  
  file-processor:
    image: file-processor:latest
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - DAC_OVERRIDE
    read_only: true
    tmpfs:
      - /tmp
    volumes:
      - ./data:/app/data:ro
    security_opt:
      - no-new-privileges:true
      - label:type:container_file_t

# SECURE: Kubernetes with specific capabilities
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-system-monitor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: secure-system-monitor
  template:
    metadata:
      labels:
        app: secure-system-monitor
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: monitor
        image: system-monitor:latest
        securityContext:
          privileged: false
          readOnlyRootFilesystem: true
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1000
          capabilities:
            drop: ["ALL"]
            add: ["SYS_PTRACE", "NET_ADMIN"]
        volumeMounts:
        - name: tmp-volume
          mountPath: /tmp
        - name: host-proc
          mountPath: /host/proc
          readOnly: true
        resources:
          limits:
            memory: "256Mi"
            cpu: "250m"
          requests:
            memory: "128Mi"
            cpu: "100m"
      volumes:
      - name: tmp-volume
        emptyDir:
          sizeLimit: 1Gi
      - name: host-proc
        hostPath:
          path: /proc
          type: Directory
2

Implement Security Profiles and Policies

Use security profiles like AppArmor, SELinux, and seccomp to restrict container behavior. Implement Pod Security Standards in Kubernetes and use security scanning tools to detect privileged containers. Create organization-wide policies that prevent privileged container deployment.

View implementation – YAML
# SECURE: Pod Security Policy preventing privileged containers
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted-psp
spec:
  privileged: false  # Deny privileged containers
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  seccompProfile:
    type: 'RuntimeDefault'
  fsGroup:
    rule: 'RunAsAny'
---
# SECURE: ClusterRole and binding for PSP
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: restricted-psp-user
rules:
- apiGroups: ['policy']
  resources: ['podsecuritypolicies']
  verbs: ['use']
  resourceNames: ['restricted-psp']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: restricted-psp-binding
roleRef:
  kind: ClusterRole
  name: restricted-psp-user
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

# SECURE: OPA Gatekeeper constraint preventing privileged containers
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredsecuritycontext
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredSecurityContext
      validation:
        type: object
        properties:
          allowPrivileged:
            type: boolean
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredsecuritycontext
        
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged == true
          not input.parameters.allowPrivileged
          msg := "Privileged containers are not allowed"
        }
        
        violation[{"msg": msg}] {
          container := input.review.object.spec.initContainers[_]
          container.securityContext.privileged == true
          not input.parameters.allowPrivileged
          msg := "Privileged init containers are not allowed"
        }
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredSecurityContext
metadata:
  name: deny-privileged-containers
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
      - apiGroups: ["apps"]
        kinds: ["Deployment", "ReplicaSet", "DaemonSet", "StatefulSet"]
  parameters:
    allowPrivileged: false

# SECURE: Docker security scanning and policy enforcement
#!/bin/bash
# docker-security-check.sh
set -euo pipefail

IMAGE_NAME="$1"
SECURITY_THRESHOLD="HIGH"

# Scan image for vulnerabilities
echo "Scanning $IMAGE_NAME for security vulnerabilities..."
trivy image --severity $SECURITY_THRESHOLD --exit-code 1 "$IMAGE_NAME"

# Check for privileged configuration
echo "Checking container configuration..."
docker inspect "$IMAGE_NAME" | jq -r '.[0].Config' | grep -q '"Privileged": true' && {
  echo "ERROR: Container is configured to run in privileged mode"
  exit 1
} || echo "OK: Container is not privileged"

# Check for excessive capabilities
docker inspect "$IMAGE_NAME" | jq -r '.[0].HostConfig.CapAdd[]?' | grep -E '(SYS_ADMIN|SYS_MODULE|DAC_READ_SEARCH)' && {
  echo "WARNING: Container has dangerous capabilities"
} || echo "OK: No dangerous capabilities detected"

echo "Security check completed for $IMAGE_NAME"
3

Use Rootless Containers and User Namespaces

Deploy rootless Docker daemon or use user namespace remapping to isolate container users from host users. This prevents privilege escalation even if containers are compromised. Configure proper user mapping and use non-root users inside containers.

View implementation – YAML
# SECURE: Rootless Docker daemon configuration
# /etc/docker/daemon.json
{
  "userns-remap": "default",
  "storage-driver": "overlay2",
  "userland-proxy": false,
  "experimental": false,
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "security-opts": ["seccomp=unconfined"],
  "no-new-privileges": true
}

# SECURE: User namespace mapping
# /etc/subuid
dockeruser:100000:65536

# /etc/subgid
dockeruser:100000:65536

# SECURE: Dockerfile with non-root user
FROM alpine:3.18

# Create non-root user
RUN addgroup -g 1001 appgroup && \
    adduser -D -u 1001 -G appgroup appuser

# Install application
COPY --chown=appuser:appgroup . /app
WORKDIR /app

# Switch to non-root user
USER appuser

# Run application as non-root
CMD ["./my-application"]

# SECURE: Docker Compose with user namespaces and security options
version: '3.8'
services:
  webapp:
    build:
      context: .
      dockerfile: Dockerfile.secure
    user: "1001:1001"
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=100m
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
      - apparmor:docker-default
    sysctls:
      - net.core.somaxconn=1024
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    ports:
      - "8080:8080"
    environment:
      - NODE_ENV=production
    volumes:
      - app-data:/app/data
    networks:
      - app-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  app-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/app-data

networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

# SECURE: Kubernetes with user namespace and security context
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-webapp
  namespace: production
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: secure-webapp
  template:
    metadata:
      labels:
        app: secure-webapp
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: runtime/default
        apparmor.security.beta.kubernetes.io/webapp: runtime/default
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1001
        runAsGroup: 1001
        fsGroup: 1001
        seccompProfile:
          type: RuntimeDefault
        supplementalGroups: []
      automountServiceAccountToken: false
      containers:
      - name: webapp
        image: secure-webapp:1.0.0
        imagePullPolicy: Always
        securityContext:
          privileged: false
          readOnlyRootFilesystem: true
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1001
          runAsGroup: 1001
          capabilities:
            drop: ["ALL"]
            add: ["NET_BIND_SERVICE"]
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "8080"
        volumeMounts:
        - name: tmp-volume
          mountPath: /tmp
        - name: app-data
          mountPath: /app/data
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "256Mi"
            cpu: "200m"
      volumes:
      - name: tmp-volume
        emptyDir:
          sizeLimit: 1Gi
          medium: Memory
      - name: app-data
        persistentVolumeClaim:
          claimName: webapp-pvc
          readOnly: false
      nodeSelector:
        kubernetes.io/os: linux
      tolerations:
      - key: "node.kubernetes.io/not-ready"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 300
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 300
4

Implement Container Runtime Security and Monitoring

Deploy runtime security tools like Falco, Sysdig, or Twistlock to monitor container behavior and detect privilege escalation attempts. Use admission controllers, network policies, and regular security audits to maintain a secure container environment.

View implementation – BASH
# SECURE: Falco rules for detecting privileged containers
# falco-rules.yaml
- rule: Detect Privileged Container
  desc: Detect containers running with privileged flag
  condition: >
    spawned_process and
    container and
    k8s_audit and
    ka.verb in (create, update) and
    ka.target.kind=pods and
    ka.req.pod.spec.containers[*].securityContext.privileged=true
  output: >
    Privileged container detected (
    user=%ka.user.name 
    verb=%ka.verb 
    pod=%ka.target.name 
    ns=%ka.target.namespace 
    image=%ka.req.pod.spec.containers[*].image)
  priority: CRITICAL
  tags: [k8s, privileged, security]

- rule: Container with Sensitive Capabilities
  desc: Detect containers with dangerous Linux capabilities
  condition: >
    spawned_process and
    container and
    k8s_audit and
    ka.verb in (create, update) and
    ka.target.kind=pods and
    ka.req.pod.spec.containers[*].securityContext.capabilities.add[*] in 
    (SYS_ADMIN, SYS_MODULE, SYS_CHROOT, DAC_READ_SEARCH, DAC_OVERRIDE)
  output: >
    Container with sensitive capabilities detected (
    user=%ka.user.name 
    pod=%ka.target.name 
    ns=%ka.target.namespace 
    capabilities=%ka.req.pod.spec.containers[*].securityContext.capabilities.add)
  priority: HIGH
  tags: [k8s, capabilities, security]

# SECURE: Falco configuration
# falco.yaml
rules_file:
  - /etc/falco/falco_rules.yaml
  - /etc/falco/falco_rules.local.yaml
  - /etc/falco/k8s_audit_rules.yaml

time_format_iso_8601: true
json_output: true
json_include_output_property: true
log_stderr: true
log_syslog: false
log_level: info

output_timeout: 2000

# Kubernetes audit log settings
k8s_audit_endpoint: /k8s-audit

# Output channels
file_output:
  enabled: true
  keep_alive: false
  filename: /var/log/falco/events.log

stdout_output:
  enabled: true

syslog_output:
  enabled: false

program_output:
  enabled: false
  keep_alive: false
  program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/..."

http_output:
  enabled: false
  url: "http://some.url"

grpc_output:
  enabled: false

# SECURE: Kubernetes Network Policy for container isolation
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: secure-app-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: secure-webapp
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: database
    ports:
    - protocol: TCP
      port: 5432
  - to: []  # Allow DNS
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379

# SECURE: Security scanning pipeline
#!/bin/bash
# security-scan.sh
set -euo pipefail

NAMESPACE="production"
THRESHOLD="HIGH"

echo "Scanning for privileged containers in namespace: $NAMESPACE"

# Get all pods in namespace
kubectl get pods -n "$NAMESPACE" -o json | jq -r '.items[] | 
  select(.spec.containers[]?.securityContext?.privileged == true) | 
  .metadata.name' | while read -r pod_name; do
    echo "CRITICAL: Privileged pod detected: $pod_name"
    kubectl describe pod "$pod_name" -n "$NAMESPACE"
    
    # Get pod security context
    kubectl get pod "$pod_name" -n "$NAMESPACE" -o jsonpath='{.spec.securityContext}' | 
      jq '.' > "/tmp/${pod_name}-security-context.json"
done

# Check for containers with dangerous capabilities
echo "Checking for dangerous capabilities..."
kubectl get pods -n "$NAMESPACE" -o json | jq -r '.items[] | 
  select(.spec.containers[]?.securityContext?.capabilities?.add[]? | 
    test("SYS_ADMIN|SYS_MODULE|DAC_OVERRIDE")) | 
  .metadata.name' | while read -r pod_name; do
    echo "WARNING: Pod with dangerous capabilities: $pod_name"
    kubectl get pod "$pod_name" -n "$NAMESPACE" -o jsonpath='{.spec.containers[*].securityContext.capabilities}'
done

# Scan container images for vulnerabilities
echo "Scanning container images..."
kubectl get pods -n "$NAMESPACE" -o jsonpath='{.items[*].spec.containers[*].image}' | 
  tr ' ' '\n' | sort -u | while read -r image; do
    echo "Scanning image: $image"
    trivy image --severity "$THRESHOLD" --exit-code 1 "$image" || {
      echo "FAILED: Security vulnerabilities found in $image"
      exit 1
    }
done

echo "Security scan completed successfully"

Detect This Vulnerability in Your Code

Sourcery automatically identifies docker containers running with privileged mode and many other security issues in your codebase.