@runsec/mcp 1.0.35 → 1.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/data/.rag-cache.json +1 -0
  2. package/dist/data/skills/_exploit_overrides.json +16 -0
  3. package/dist/data/skills/advanced-agent-cloud/index.md +94 -0
  4. package/dist/data/skills/advanced-agent-cloud/patterns.md +46 -0
  5. package/dist/data/skills/advanced-agent-cloud/skill.json +38 -0
  6. package/dist/data/skills/app-logic/index.md +69 -0
  7. package/dist/data/skills/app-logic/patterns.md +23 -0
  8. package/dist/data/skills/app-logic/skill.json +24 -0
  9. package/dist/data/skills/auth-keycloak/index.md +69 -0
  10. package/dist/data/skills/auth-keycloak/patterns.md +46 -0
  11. package/dist/data/skills/auth-keycloak/skill.json +51 -0
  12. package/dist/data/skills/browser-agent/index.md +58 -0
  13. package/dist/data/skills/browser-agent/patterns.md +15 -0
  14. package/dist/data/skills/browser-agent/skill.json +24 -0
  15. package/dist/data/skills/cloud-secrets/index.md +66 -0
  16. package/dist/data/skills/cloud-secrets/patterns.md +19 -0
  17. package/dist/data/skills/cloud-secrets/skill.json +28 -0
  18. package/dist/data/skills/csharp-dotnet/index.md +103 -0
  19. package/dist/data/skills/csharp-dotnet/patterns.md +270 -0
  20. package/dist/data/skills/csharp-dotnet/skill.json +27 -0
  21. package/dist/data/skills/desktop-vsto-suite/index.md +202 -0
  22. package/dist/data/skills/desktop-vsto-suite/patterns.md +154 -0
  23. package/dist/data/skills/desktop-vsto-suite/skill.json +26 -0
  24. package/dist/data/skills/devops-security/index.md +64 -0
  25. package/dist/data/skills/devops-security/patterns.md +23 -0
  26. package/dist/data/skills/devops-security/skill.json +42 -0
  27. package/dist/data/skills/domain-access-management/index.md +123 -0
  28. package/dist/data/skills/domain-access-management/patterns.md +58 -0
  29. package/dist/data/skills/domain-access-management/skill.json +36 -0
  30. package/dist/data/skills/domain-data-privacy/index.md +98 -0
  31. package/dist/data/skills/domain-data-privacy/patterns.md +48 -0
  32. package/dist/data/skills/domain-data-privacy/skill.json +36 -0
  33. package/dist/data/skills/domain-input-validation/index.md +210 -0
  34. package/dist/data/skills/domain-input-validation/patterns.md +158 -0
  35. package/dist/data/skills/domain-input-validation/skill.json +24 -0
  36. package/dist/data/skills/domain-platform-hardening/index.md +169 -0
  37. package/dist/data/skills/domain-platform-hardening/patterns.md +96 -0
  38. package/dist/data/skills/domain-platform-hardening/skill.json +27 -0
  39. package/dist/data/skills/ds-ml-security/patterns.md +137 -0
  40. package/dist/data/skills/fastapi-async/index.md +83 -0
  41. package/dist/data/skills/fastapi-async/patterns.md +329 -0
  42. package/dist/data/skills/fastapi-async/skill.json +32 -0
  43. package/dist/data/skills/frontend-react/index.md +26 -0
  44. package/dist/data/skills/frontend-react/patterns.md +226 -0
  45. package/dist/data/skills/frontend-react/skill.json +24 -0
  46. package/dist/data/skills/go-core/index.md +86 -0
  47. package/dist/data/skills/go-core/patterns.md +272 -0
  48. package/dist/data/skills/go-core/skill.json +22 -0
  49. package/dist/data/skills/hft-cpp-security/patterns.md +37 -0
  50. package/dist/data/skills/index.md +73 -0
  51. package/dist/data/skills/infra-k8s-helm/index.md +138 -0
  52. package/dist/data/skills/infra-k8s-helm/patterns.md +279 -0
  53. package/dist/data/skills/infra-k8s-helm/skill.json +41 -0
  54. package/dist/data/skills/integration-security/index.md +73 -0
  55. package/dist/data/skills/integration-security/patterns.md +132 -0
  56. package/dist/data/skills/integration-security/skill.json +30 -0
  57. package/dist/data/skills/java-enterprise/index.md +31 -0
  58. package/dist/data/skills/java-enterprise/patterns.md +816 -0
  59. package/dist/data/skills/java-enterprise/skill.json +26 -0
  60. package/dist/data/skills/java-spring/index.md +65 -0
  61. package/dist/data/skills/java-spring/patterns.md +22 -0
  62. package/dist/data/skills/java-spring/skill.json +23 -0
  63. package/dist/data/skills/license-compliance/index.md +58 -0
  64. package/dist/data/skills/license-compliance/patterns.md +12 -0
  65. package/dist/data/skills/license-compliance/skill.json +28 -0
  66. package/dist/data/skills/mobile-security/patterns.md +42 -0
  67. package/dist/data/skills/nodejs-nestjs/index.md +71 -0
  68. package/dist/data/skills/nodejs-nestjs/patterns.md +288 -0
  69. package/dist/data/skills/nodejs-nestjs/skill.json +24 -0
  70. package/dist/data/skills/observability/index.md +68 -0
  71. package/dist/data/skills/observability/patterns.md +22 -0
  72. package/dist/data/skills/observability/skill.json +26 -0
  73. package/dist/data/skills/php-security/patterns.md +202 -0
  74. package/dist/data/skills/ru-regulatory/index.md +72 -0
  75. package/dist/data/skills/ru-regulatory/patterns.md +28 -0
  76. package/dist/data/skills/ru-regulatory/skill.json +53 -0
  77. package/dist/data/skills/ruby-rails/index.md +65 -0
  78. package/dist/data/skills/ruby-rails/patterns.md +172 -0
  79. package/dist/data/skills/ruby-rails/skill.json +24 -0
  80. package/dist/data/skills/rust-security/patterns.md +152 -0
  81. package/dist/data/trufflehog-config.yaml +407 -0
  82. package/dist/index.js +3766 -372
  83. package/package.json +1 -1
@@ -0,0 +1,73 @@
1
+ # HexVibe Skills Index
2
+
3
+ Central catalog of all security domains under `core/skills/`.
4
+
5
+ | Domain | Path | Rules | Primary Stack | Stack Summary |
6
+ |---|---|---:|---|---|
7
+ | Advanced Agent Cloud | `core/skills/advanced-agent-cloud/` | 44 | Agent/Browser | Agent/Browser:44 |
8
+ | App Logic | `core/skills/app-logic/` | 21 | Application Logic | Application Logic:21 |
9
+ | Auth Keycloak | `core/skills/auth-keycloak/` | 21 | Identity/OIDC (Keycloak 22/24) | Identity/OIDC (Keycloak 22/24):21 |
10
+ | Browser Agent | `core/skills/browser-agent/` | 13 | Browser Automation | Browser Automation:13 |
11
+ | Cloud Secrets | `core/skills/cloud-secrets/` | 17 | Cloud/Secrets | Cloud/Secrets:17 |
12
+ | Csharp Dotnet | `core/skills/csharp-dotnet/` | 58 | .NET/C# | .NET/C#:58 |
13
+ | Desktop Vsto Suite | `core/skills/desktop-vsto-suite/` | 152 | Electron/Desktop/.NET | Electron/Desktop/.NET:152 |
14
+ | Devops Security | `core/skills/devops-security/` | 21 | DevOps/Supply Chain | DevOps/Supply Chain:21 |
15
+ | Domain Access Management | `core/skills/domain-access-management/` | 56 | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists. | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists.:19, Validate data with Zod and sanitize DOM/HTML sinks with DOMPurify before rendering.:14, Cache key по subject+scope+tenant+ttl.:1 |
16
+ | Domain Data Privacy | `core/skills/domain-data-privacy/` | 46 | Validate data with Zod and sanitize DOM/HTML sinks with DOMPurify before rendering. | Validate data with Zod and sanitize DOM/HTML sinks with DOMPurify before rendering.:19, Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists.:17, Use using/try-finally and safe .NET APIs; enforce strict allowlists for untrusted input.:3 |
17
+ | Domain Input Validation | `core/skills/domain-input-validation/` | 156 | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists. | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists.:75, Validate data with Zod and sanitize DOM/HTML sinks with DOMPurify before rendering.:66, Use using/try-finally and safe .NET APIs; enforce strict allowlists for untrusted input.:4 |
18
+ | Domain Platform Hardening | `core/skills/domain-platform-hardening/` | 94 | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists. | Use strict Pydantic BaseModel schemas for input/output, including response_model and field allowlists.:36, Validate data with Zod and sanitize DOM/HTML sinks with DOMPurify before rendering.:20, Use using/try-finally and safe .NET APIs; enforce strict allowlists for untrusted input.:8 |
19
+ | Frontend React | `core/skills/frontend-react/` | 50 | TypeScript/React | TypeScript/React:50 |
20
+ | Fastapi Async | `core/skills/fastapi-async/` | 35 | Python/FastAPI | Python/FastAPI:35 |
21
+ | Go Core | `core/skills/go-core/` | 60 | Go 1.21/1.22 | Go 1.21/1.22:60 |
22
+ | Infra K8S Helm | `core/skills/infra-k8s-helm/` | 90 | Kubernetes/Infra | Kubernetes/Infra:90 |
23
+ | Integration Security | `core/skills/integration-security/` | 30 | Integration/API | Integration/API:30 |
24
+ | Java Spring | `core/skills/java-spring/` | 20 | Java/Spring | Java/Spring:20 |
25
+ | License Compliance | `core/skills/license-compliance/` | 10 | Compliance/License | Compliance/License:10 |
26
+ | Nodejs Nestjs | `core/skills/nodejs-nestjs/` | 26 | Node.js 18/20/22 + NestJS | Node.js 18/20/22 + NestJS:26 |
27
+ | Observability | `core/skills/observability/` | 20 | Observability | Observability:20 |
28
+ | Ru Regulatory | `core/skills/ru-regulatory/` | 26 | Compliance/Regulatory | Compliance/Regulatory:26 |
29
+ | Ruby Rails | `core/skills/ruby-rails/` | 20 | Ruby/Rails | Ruby/Rails:20 |
30
+
31
+ **Total unique rules:** 1000
32
+ **Total rows across domains:** 1016
33
+
34
+ ## Standards coverage (compliance layer)
35
+
36
+ Aggregated from `CWE-*` tokens in `patterns.md` via `scripts/compliance_layer.py` (OWASP Top 10 **2021** categories; representative MITRE ATT&CK **Enterprise** techniques; NIST SSDF PO fields are proxy counts).
37
+
38
+ | Standard | Category | Patterns (rules tagged) | Status |
39
+ |---|---|---:|---|
40
+ | OWASP Top 10 (2021) | A01 | 15 | Covered |
41
+ | OWASP Top 10 (2021) | A02 | 16 | Covered |
42
+ | OWASP Top 10 (2021) | A03 | 106 | Covered |
43
+ | OWASP Top 10 (2021) | A04 | 434 | Covered |
44
+ | OWASP Top 10 (2021) | A05 | 194 | Covered |
45
+ | OWASP Top 10 (2021) | A06 | 11 | Covered |
46
+ | OWASP Top 10 (2021) | A07 | 95 | Covered |
47
+ | OWASP Top 10 (2021) | A08 | 24 | Covered |
48
+ | OWASP Top 10 (2021) | A09 | 33 | Covered |
49
+ | OWASP Top 10 (2021) | A10 | 73 | Covered |
50
+ | MITRE ATT&CK (Enterprise) | T1005 | 26 | Mapped |
51
+ | MITRE ATT&CK (Enterprise) | T1055 | 10 | Mapped |
52
+ | MITRE ATT&CK (Enterprise) | T1059 | 79 | Mapped |
53
+ | MITRE ATT&CK (Enterprise) | T1059.004 | 33 | Mapped |
54
+ | MITRE ATT&CK (Enterprise) | T1059.007 | 20 | Mapped |
55
+ | MITRE ATT&CK (Enterprise) | T1078 | 84 | Mapped |
56
+ | MITRE ATT&CK (Enterprise) | T1083 | 10 | Mapped |
57
+ | MITRE ATT&CK (Enterprise) | T1098 | 5 | Mapped |
58
+ | MITRE ATT&CK (Enterprise) | T1110 | 3 | Mapped |
59
+ | MITRE ATT&CK (Enterprise) | T1189 | 13 | Mapped |
60
+ | MITRE ATT&CK (Enterprise) | T1190 | 701 | Mapped |
61
+ | MITRE ATT&CK (Enterprise) | T1195 | 21 | Mapped |
62
+ | MITRE ATT&CK (Enterprise) | T1195.001 | 10 | Mapped |
63
+ | MITRE ATT&CK (Enterprise) | T1204 | 24 | Mapped |
64
+ | MITRE ATT&CK (Enterprise) | T1499 | 10 | Mapped |
65
+ | MITRE ATT&CK (Enterprise) | T1548 | 3 | Mapped |
66
+ | MITRE ATT&CK (Enterprise) | T1550 | 5 | Mapped |
67
+ | MITRE ATT&CK (Enterprise) | T1552 | 21 | Mapped |
68
+ | MITRE ATT&CK (Enterprise) | T1556 | 3 | Mapped |
69
+ | MITRE ATT&CK (Enterprise) | T1562 | 23 | Mapped |
70
+ | NIST SSDF (proxy) | PO.1 | 1000 | Indicative |
71
+ | NIST SSDF (proxy) | PO.3 | 35 | Indicative |
72
+ | **HexVibe rules** | Total IDs in matrix | 1000 | OK |
73
+ | **Compliance tags** | Rules with OWASP+MITRE tags | 1000 | See `rule-compliance-map.json` |
@@ -0,0 +1,138 @@
1
+ # Infra / Kubernetes / Helm / Docker
2
+
3
+ ## Stack overview
4
+
5
+ **Kubernetes** manifests, **Helm** values, **Docker** images, and **NGINX** hardening. Metrics use the **`INF-*`** namespace (including dotted IDs).
6
+
7
+ ## Top threats
8
+
9
+ - Privileged containers, weak TLS, and bad defaults in images (`INF-4.*`, `INF-5.*`, `INF-010`–`INF-014`).
10
+ - NGINX and ingress misconfiguration (`INF-5.3.*`, `INF-5.5.*`, `INF-5.6.*`).
11
+
12
+ ## Pattern catalog
13
+
14
+ Complete Anti-Pattern / Safe-Pattern definitions live in [`patterns.md`](patterns.md). The table below is a **table of contents** by metric ID.
15
+
16
+ | ID | Metric | Stack |
17
+ |---|---|---|
18
+ | `INF-4.1` | Dockerfile без выделенного непривилегированного пользователя | `FROM python:3.11` `WORKDIR /app` `RUN groupadd -r app && useradd -r -g app app` `COPY . /app` `RUN chown -R app:app /app` `USER app` `CMD ["python","main.py"]` |
19
+ | `INF-5.10` | Нет ограничений памяти и CPU для контейнера | `services:` ` api:` ` image: example/api:1.0.0` ` mem_limit: "512m"` ` cpu_shares: 512` |
20
+ | `INF-5.2.1` | Привилегированный контейнер используется | `apiVersion: v1` `kind: Pod` `metadata:` ` name: restricted-pod` `spec:` ` containers:` ` - name: app` ` image: nginx:1.27` ` securityContext:` ` privileged: false` |
21
+ | `INF-5.2.4` | `allowPrivilegeEscalation` не запрещен | `apiVersion: apps/v1` `kind: Deployment` `metadata:` ` name: ape-off` `spec:` ` template:` ` spec:` ` containers:` ` - name: app` ` image: example/app:1.0.0` ` securityContext:` ` allowPrivilegeEscalation: false` |
22
+ | `INF-5.2.5` | Контейнер запускается с root GID | `apiVersion: v1` `kind: Pod` `metadata:` ` name: non-root-gid` `spec:` ` containers:` ` - name: app` ` image: example/app:1.0.0` ` securityContext:` ` runAsNonRoot: true` ` runAsGroup: 10001` |
23
+ | `INF-5.3.1` | NetworkPolicies не определены | `apiVersion: networking.k8s.io/v1` `kind: NetworkPolicy` `metadata:` ` name: app-default-deny` ` namespace: default` `spec:` ` podSelector:` ` matchLabels:` ` app: app` ` policyTypes:` ` - Ingress` ` - Egress` ` ingress: []` ` egress: []` |
24
+ | `INF-2.5.1` | NGINX раскрывает версию (`server_tokens on`) | `server {` ` listen 80;` ` server_tokens off; # CIS: скрыть версию NGINX` `}` |
25
+ | `INF-5.3.2` | NGINX без Content-Security-Policy | `server {` ` listen 443 ssl;` ` add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self'; object-src 'none'" always; # CIS: CSP обязателен` ` location / { proxy_pass http://app; }` `}` |
26
+ | `INF-5.3.1-NGX` | NGINX без X-Frame-Options | `server {` ` listen 443 ssl;` ` add_header X-Frame-Options "DENY" always; # CIS: разрешено DENY или SAMEORIGIN` ` location / { proxy_pass http://app; }` `}` |
27
+ | `INF-1.2.1` | API Server допускает anonymous auth | `apiVersion: v1` `kind: Pod` `metadata:` ` name: kube-apiserver` `spec:` ` containers:` ` - name: kube-apiserver` ` command:` ` - kube-apiserver` ` - --anonymous-auth=false # CIS: запрет неаутентифицированного доступа` |
28
+ | `INF-1.2.6` | API Server без admission-control config файла | `apiVersion: v1` `kind: Pod` `metadata:` ` name: kube-apiserver` `spec:` ` containers:` ` - name: kube-apiserver` ` command:` ` - kube-apiserver` ` - --admission-control-config-file=/etc/kubernetes/admission-control.yaml # CIS: явно задать политику admission` |
29
+ | `INF-5.1.1` | Избыточное использование `cluster-admin` | `apiVersion: rbac.authorization.k8s.io/v1` `kind: Role` `metadata:` ` name: app-read-only` ` namespace: app` `rules:` `- apiGroups: [""]` ` resources: ["pods","services"]` ` verbs: ["get","list","watch"] # CIS: минимум привилегий` `---` `apiVersion: rbac.authorization.k8s.io/v1` `kind: RoleBinding` `metadata:` ` name: app-read-only-binding` ` namespace: app` `subjects:` `- kind: ServiceAccount` ` name: app-sa` ` namespace: app` `roleRef:` ` kind: Role` ` name: app-read-only` ` apiGroup: rbac.authorization.k8s.io` |
30
+ | `INF-5.6.2` | Pod без seccomp профиля | `apiVersion: v1` `kind: Pod` `metadata:` ` name: with-seccomp` `spec:` ` containers:` ` - name: app` ` image: nginx:1.27` ` securityContext:` ` seccompProfile:` ` type: RuntimeDefault # CIS: docker/default или runtime/default` |
31
+ | `INF-1.2.33` | Шифрование секретов в etcd не включено | `apiVersion: v1` `kind: Pod` `metadata:` ` name: kube-apiserver` `spec:` ` containers:` ` - name: kube-apiserver` ` command:` ` - kube-apiserver` ` - --encryption-provider-config=/etc/kubernetes/encryption-provider.yaml # CIS: encryption at rest for secrets` |
32
+ | `INF-4.4` | Dockerfile содержит секреты в `ENV`/`LABEL` | `FROM python:3.11` `ENV DB_PASSWORD_FILE=/run/secrets/db_password` `LABEL security.secrets=\"external-secret-store\" # no plaintext secrets` |
33
+ | `INF-5.25` | Монтирование `/var/run/docker.sock` в контейнер | `apiVersion: v1` `kind: Pod` `metadata:` ` name: no-docker-sock` `spec:` ` containers:` ` - name: app` ` image: alpine:3.20` ` volumeMounts:` ` - name: app-tmp` ` mountPath: /tmp` ` volumes:` ` - name: app-tmp` ` emptyDir: {}` |
34
+ | `INF-5.1.2-TLS` | Разрешены TLS 1.0/1.1 в NGINX | `server {` ` listen 443 ssl;` ` ssl_protocols TLSv1.2 TLSv1.3; # CIS: disable legacy TLS` `}` |
35
+ | `INF-5.5.1` | Не ограничены HTTP-методы | `location /api/ {` ` limit_except GET POST HEAD {` ` deny all; # CIS: allow only approved methods` ` }` ` proxy_pass http://backend;` `}` |
36
+ | `INF-010` | Hardcoded Credentials: захардкоженные пароли и токены в коде/манифестах | `services:` ` db:` ` image: postgres:16` ` environment:` ` POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password` ` API_TOKEN_FILE: /run/secrets/api_token` `secrets:` ` postgres_password:` ` file: ./secrets/postgres_password` ` api_token:` ` file: ./secrets/api_token` |
37
+ | `INF-011` | Committed Private Keys: приватные ключи в репозитории | `tls.crt` `tls.key` `# secrets are provisioned at deploy time via external secret manager` `apiVersion: external-secrets.io/v1beta1` `kind: ExternalSecret` `metadata:` ` name: app-tls` `spec:` ` secretStoreRef:` ` name: vault-store` ` kind: ClusterSecretStore` ` target:` ` name: app-tls` ` data:` ` - secretKey: tls.key` ` remoteRef:` ` key: kv/prod/app/tls_key` |
38
+ | `INF-012` | Insecure .gitignore: секретные конфиги не исключены из Git | `# .gitignore` `.env` `.env.*` `secrets/` `*.pem` `*.key` `*credentials*.json` `!.env.example` |
39
+ | `INF-013` | Mutable Image Tags: использование `:latest` без digest pinning | `apiVersion: apps/v1` `kind: Deployment` `spec:` ` template:` ` spec:` ` containers:` ` - name: api` ` ...` ` image: org/api@sha256:3b5f...` |
40
+ | `INF-014` | Auto-mounted ServiceAccount Token: токен пода доступен без необходимости | `apiVersion: v1` `kind: Pod` `metadata:` ` name: app-pod` `spec:` ` automountServiceAccountToken: false` ` ...` ` containers:` ` - name: app` ` image: org/app:1.0.0` |
41
+ | `K8S-010` | Missing capabilities drop (`ALL`) | `securityContext:` ` allowPrivilegeEscalation: false` ` capabilities:` ` drop: ["ALL"]` |
42
+ | `K8S-011` | Host networking enabled | `spec:` ` hostNetwork: false` |
43
+ | `K8S-012` | Host PID namespace enabled | `spec:` ` hostPID: false` |
44
+ | `K8S-013` | Host IPC namespace enabled | `spec:` ` hostIPC: false` |
45
+ | `K8S-014` | Missing readOnlyRootFilesystem | `securityContext:` ` readOnlyRootFilesystem: true` |
46
+ | `K8S-015` | runAsNonRoot not enforced | `securityContext:` ` runAsNonRoot: true` |
47
+ | `K8S-016` | AppArmor profile not set | `metadata:` ` annotations:` ` container.apparmor.security.beta.kubernetes.io/app: runtime/default` |
48
+ | `K8S-017` | Seccomp profile Unconfined | `seccompProfile:` ` type: RuntimeDefault` |
49
+ | `K8S-018` | No liveness probe | `containers:` `- name: api` ` livenessProbe:` ` httpGet:` ` path: /healthz` |
50
+ | `K8S-019` | No readiness probe | `containers:` `- name: api` ` readinessProbe:` ` httpGet:` ` path: /ready` |
51
+ | `K8S-020` | No resource limits | `resources:` ` limits:` ` cpu: "500m"` ` memory: "512Mi"` |
52
+ | `K8S-021` | NetworkPolicy absent for namespace | `kind: NetworkPolicy` `metadata:` ` namespace: prod` `spec:` ` policyTypes: ["Ingress","Egress"]` |
53
+ | `K8S-022` | Service of type NodePort exposed by default | `kind: Service` `spec:` ` type: ClusterIP` |
54
+ | `K8S-023` | Wildcard RBAC verbs/resources | `verbs: ["get","list"]` `resources: ["pods"]` |
55
+ | `K8S-024` | automountServiceAccountToken enabled | `automountServiceAccountToken: false` |
56
+ | `K8S-025` | Latest image tag in workload | `image: org/api@sha256:abcd...` |
57
+ | `DOCK-010` | Container runs as root | `RUN adduser -D appuser` `USER appuser` |
58
+ | `DOCK-011` | Missing non-root USER in final stage | `FROM alpine:3.20` `USER 10001` `CMD ["app"]` |
59
+ | `DOCK-012` | Writable root filesystem by default | `docker run --read-only --tmpfs /tmp app@sha256:...` |
60
+ | `DOCK-013` | Base image uses latest tag | `FROM node:20.11.1@sha256:...` |
61
+ | `DOCK-014` | ADD used for remote URL | `COPY app.tar.gz /opt/` |
62
+ | `DOCK-015` | Package manager cache not cleaned | `RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*` |
63
+ | `DOCK-016` | Sensitive values in ENV/ARG | `ARG API_TOKEN` `# inject via runtime secrets` |
64
+ | `DOCK-017` | No HEALTHCHECK instruction | `Container Reliability` |
65
+ | `DOCK-018` | Privileged container run flags | `docker run --cap-drop ALL --security-opt no-new-privileges app:1.0` |
66
+ | `DOCK-019` | Docker socket mounted into container | `# do not mount docker.sock` |
67
+ | `DOCK-020` | No seccomp profile at runtime | `docker run --security-opt seccomp=default.json app:1.0` |
68
+ | `NGX-001` | HSTS header missing | `add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;` |
69
+ | `NGX-002` | Content-Security-Policy missing | `add_header Content-Security-Policy "default-src 'self'" always;` |
70
+ | `NGX-003` | X-Content-Type-Options missing | `add_header X-Content-Type-Options "nosniff" always;` |
71
+ | `NGX-004` | X-Frame-Options missing | `add_header X-Frame-Options "DENY" always;` |
72
+ | `NGX-005` | Weak TLS protocols enabled | `ssl_protocols TLSv1.2 TLSv1.3;` |
73
+ | `NGX-006` | TLS 1.3 not enforced for strict profile | `ssl_protocols TLSv1.3;` |
74
+ | `NGX-007` | No request rate limiting | `limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;` |
75
+ | `NGX-008` | Client body size unlimited | `client_max_body_size 10m;` |
76
+ | `NGX-009` | Proxy timeouts missing | `proxy_connect_timeout 5s; proxy_read_timeout 30s;` |
77
+ | `NGX-010` | server_tokens enabled | `server_tokens off;` |
78
+ | `SQD-001` | Squid allows all clients | `http_access deny all` `http_access allow localnet` |
79
+ | `SQD-002` | Squid cache_peer uses plaintext HTTP | `cache_peer upstream.example parent 3129 0 no-query tls` |
80
+ | `SQD-003` | ssl_bump without certificate validation policy | `sslproxy_cert_error deny all` |
81
+ | `SQD-004` | Weak ACL for CONNECT methods | `acl SSL_ports port 443` |
82
+ | `SQD-005` | No request rate/connection controls | `maxconn 100` |
83
+ | `SQD-006` | Access logs disabled | `access_log stdio:/var/log/squid/access.log` |
84
+ | `SQD-007` | Unsafe refresh_pattern wildcard | `Cache control security` |
85
+ | `SQD-008` | DNS over insecure resolver | `dns_nameservers 10.0.0.53` |
86
+ | `SQD-009` | Proxy auth not required for sensitive egress | `auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd` |
87
+ | `SQD-010` | No domain allowlist on egress | `acl allowed_domains dstdomain .corp.local` `http_access allow allowed_domains` |
88
+ | `SQD-011` | Unsafe forwarded_for policy | `forwarded_for transparent` |
89
+ | `SQD-012` | Insecure cache_dir permissions | `cache_effective_user squid` `cache_effective_group squid` |
90
+ | `SQD-013` | No denylist for metadata endpoints | `acl cloud_meta dst 169.254.169.254/32` `http_access deny cloud_meta` |
91
+ | `SQD-014` | Squid final deny rule missing / overly broad localnet ACL | Завершать ACL цепочку `http_access deny all` и ограничивать `localnet` только доверенными CIDR-сетями. |
92
+ | `NGX-011` | Nginx request limiting zone missing (`limit_req_zone`) | Добавить `limit_req_zone` с разумным rate/burst и применять `limit_req` на чувствительных location. |
93
+ | `NGX-012` | Nginx version disclosure via missing `server_tokens off` | Отключить `server_tokens`, скрывать версию веб-сервера и минимизировать fingerprinting surface. |
94
+ | `DOCK-021` | Docker base image uses mutable `latest` tag (`FROM ...:latest`) | Пиновать base image на конкретную версию и digest (`FROM python:3.12.3@sha256:...`) для воспроизводимости и supply-chain контроля. |
95
+ | `DOCK-022` | Unpinned `apt-get install` packages in Dockerfile | Фиксировать версии пакетов (`curl=... openssl=...`), использовать `--no-install-recommends` и очищать apt cache. |
96
+ | `INF-015` | Unintended proxy path allows access to internal K8s endpoints (CWE-441) | Блокировать proxy к internal ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.169.254`) и использовать strict upstream allowlist. |
97
+ | `INF-016` | Helm chart defaults privileged pod/container security context (CWE-1188) | Дефолтно выставлять безопасные значения (`privileged: false`, `allowPrivilegeEscalation: false`, `runAsNonRoot: true`). |
98
+ | `INF-017` | Helm chart default enables host namespace sharing (CWE-1188) | По умолчанию отключать host namespaces и разрешать их только explicit opt-in с security review. |
99
+ | `INF-018` | Helm default grants broad capabilities without drop-all baseline (CWE-1188) | В chart defaults задавать `drop: ["ALL"]` и точечно добавлять только необходимые capabilities. |
100
+ | `NGX-013` | Nginx forward proxy behavior enables unintended internal routing (CWE-441) | Запретить dynamic upstream от пользовательских заголовков, фиксировать upstreams и блокировать internal dns zones/cluster domains. |
101
+ | `SQD-015` | Squid ACL permits proxying to Kubernetes control-plane/internal services (CWE-441) | Добавить explicit deny ACL для `*.svc`, control-plane IPs и metadata endpoints перед allow rules. |
102
+ | `K8S-026` | Helm values default `automountServiceAccountToken: true` for all workloads (CWE-1188) | Устанавливать default `false` и включать токен только для конкретных сервисов, где это необходимо. |
103
+ | `DOCK-023` | Docker: `docker load` образа без проверки подписи Cosign (CWE-347) | Подпись артефакта в registry; SBOM + verify в pipeline. |
104
+ | `DOCK-024` | Dockerfile: `FROM` без проверки digest при pull в CI (CWE-347) | `FROM repo/img@sha256:...` + verify attestation. |
105
+ | `DOCK-025` | Docker Compose pull без trust policy (CWE-347) | Подписанные образы и политика deploy only if verified. |
106
+ | `K8S-027` | Helm: `helm install` без `--verify` provenance (CWE-347) | Helm provenance + GPG/cosign для chart packages. |
107
+ | `K8S-028` | Helm: `values.yaml` с `image: tag` без digest и без policy (CWE-347) | OCI artifact signing + Kyborio/OPA policy. |
108
+
109
+ ## Verification
110
+
111
+ **Verification:** Check the gold testbed file(s) below for `Vulnerable: <ID>` markers (static Semgrep + `detection-matrix.md` ground truth).
112
+
113
+ - [`gold-standard-testbed/infra_vulnerable.yaml`](../gold-standard-testbed/infra_vulnerable.yaml)
114
+ - [`gold-standard-testbed/Dockerfile`](../gold-standard-testbed/Dockerfile)
115
+ - [`gold-standard-testbed/nginx.conf`](../gold-standard-testbed/nginx.conf)
116
+
117
+ **Optional HTTP integration tests** (pytest + httpx; require a running API, `HEXVIBE_TARGET_URL`): [`gold-standard-testbed/integration/verify_infra_k8s_helm_poc.py`](../gold-standard-testbed/integration/verify_infra_k8s_helm_poc.py). See [`gold-standard-testbed/integration/README.md`](../gold-standard-testbed/integration/README.md).
118
+
119
+ After changing [`patterns.md`](patterns.md), run from the repo root:
120
+
121
+ ```bash
122
+ python scripts/sync_semgrep.py
123
+ ```
124
+
125
+ ## Workflow: Recon → Scan → Verify
126
+
127
+ ### 1) Recon
128
+ - Map entrypoints, data flows, and trust boundaries for this stack.
129
+ - Identify which metrics in [`patterns.md`](patterns.md) apply to the code under review.
130
+
131
+ ### 2) Scan
132
+ - Run Semgrep with `semgrep-rules/<skill>.yaml` (generated) and correlate with Anti-Patterns.
133
+ - Eliminate findings that cannot bind to a metric row.
134
+
135
+ ### 3) Verify
136
+ - Confirm markers or scanner hits for touched IDs in the gold testbed when adding metrics.
137
+ - Emit findings as `Vulnerable: <PREFIX>-<NNN>` in written reviews.
138
+