feat(recon): add kubeflow pipelines and metaflow exposure modules (#290)

detect an anonymously reachable kubeflow pipelines apiserver, whose
same api accepts pipeline run submission with an attacker-supplied
workflow manifest (arbitrary container execution), and a metaflow
metadata service leaking flow and owner enumeration. match distinctive
snake_case json keys with status 200, fail closed on empty instances
to avoid the bare-substring false-positive class.
This commit is contained in:
Tigah
2026-07-22 12:46:15 -07:00
committed by GitHub
parent b4fae85847
commit c24617d16c
3 changed files with 195 additions and 0 deletions
@@ -0,0 +1,37 @@
# Kubeflow Pipelines API Exposure Detection Module
id: kubeflow-pipelines-exposure
info:
name: Kubeflow Pipelines API Exposure
author: sif
severity: high
description: Detects a Kubeflow Pipelines api server reachable without going through the istio/dex auth proxy, listing registered pipelines over its rest api; the same api accepts pipeline run submission, which executes arbitrary containers on the backing cluster
tags: [kubeflow, mlops, pipelines, kubernetes, data-orchestration, rce, exposure, unauth, recon]
type: http
http:
method: GET
paths:
- "{{BaseURL}}/apis/v1beta1/pipelines"
matchers:
- type: word
part: body
words:
- "\"pipelines\""
- "\"total_size\""
- "\"next_page_token\""
condition: and
- type: status
status:
- 200
extractors:
- type: regex
name: kubeflow_pipeline_count
part: body
regex:
- '"total_size"\s*:\s*([0-9]+)'
group: 1
@@ -0,0 +1,37 @@
# Metaflow Metadata Service Exposure Detection Module
id: metaflow-metadata-exposure
info:
name: Metaflow Metadata Service Exposure
author: sif
severity: medium
description: Detects a Metaflow metadata service reachable without auth, disclosing every registered flow's name, owner and creation time over its rest api
tags: [metaflow, mlops, data-orchestration, pipeline, api, exposure, unauth, recon]
type: http
http:
method: GET
paths:
- "{{BaseURL}}/flows"
matchers:
- type: word
part: body
words:
- "\"flow_id\""
- "\"user_name\""
- "\"ts_epoch\""
condition: and
- type: status
status:
- 200
extractors:
- type: regex
name: metaflow_flow_id
part: body
regex:
- '"flow_id"\s*:\s*"([^"]+)"'
group: 1