10 KiB
10 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13-osint_package_registries_container_iac | 03 | execute | 1 |
|
true |
|
|
Purpose: Enables KeyHunter to scan container images, Kubernetes configs, Terraform modules, and Helm charts for leaked API keys embedded in infrastructure definitions. Output: 4 source files + 4 test files in pkg/recon/sources/
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @pkg/recon/source.go @pkg/recon/sources/httpclient.go @pkg/recon/sources/queries.go @pkg/recon/sources/replit.go (pattern reference) @pkg/recon/sources/shodan.go (pattern reference — search API source) @pkg/recon/sources/replit_test.go (test pattern reference) From pkg/recon/source.go: ```go type ReconSource interface { Name() string RateLimit() rate.Limit Burst() int RespectsRobots() bool Enabled(cfg Config) bool Sweep(ctx context.Context, query string, out chan<- Finding) error } ```From pkg/recon/sources/httpclient.go:
func NewClient() *Client
func (c *Client) Do(ctx context.Context, req *http.Request) (*http.Response, error)
From pkg/recon/sources/queries.go:
func BuildQueries(reg *providers.Registry, source string) []string
KubernetesSource (kubernetes.go):
- Struct:
KubernetesSourcewithBaseURL,Registry,Limiters,Client - Compile-time assertion:
var _ recon.ReconSource = (*KubernetesSource)(nil) - Name() returns "k8s"
- RateLimit() returns rate.Every(3 * time.Second)
- Burst() returns 1
- RespectsRobots() returns true (searches public web for exposed K8s dashboards/configs)
- Enabled() always true
- BaseURL defaults to "https://search.censys.io" — uses Censys-style search for exposed K8s dashboards
- ALTERNATIVE simpler approach: Search GitHub for exposed Kubernetes manifests containing secrets.
Use BaseURL "https://api.github.com" and search for
kind: SecretorapiVersion: v1 kind: ConfigMapwith provider keywords. BUT this duplicates GitHubSource. - BEST approach: Use a dedicated search via pkg.go.dev-style HTML scraping but for Kubernetes YAML files on public artifact hubs. Actually, the simplest approach that aligns with RECON-INFRA-02 ("discovers publicly exposed Kubernetes dashboards and scans publicly readable Secret/ConfigMap objects"): Use Shodan/Censys-style dork queries. But those sources already exist.
- FINAL approach: KubernetesSource searches Artifact Hub (artifacthub.io) for Kubernetes manifests/operators that may embed secrets. ArtifactHub has a JSON API.
GET
{BaseURL}/api/v1/packages/search?ts_query_web={keyword}&kind=0&limit=20(kind=0 = Helm charts, but also covers operators) Actually, use kind=6 for "Kube Operator" or leave blank for all kinds. BaseURL defaults to "https://artifacthub.io" Parse JSON:{"packages": [{"name": "...", "normalized_name": "...", "repository": {"name": "...", "url": "..."}}]}Emit Finding: Source="https://artifacthub.io/packages/{repository.kind}/{repository.name}/{package.name}", SourceType="recon:k8s"
Tests — httptest pattern:
- dockerhub_test.go: httptest serving canned Docker Hub search JSON. Verify findings have correct SourceType and Source URL format.
- kubernetes_test.go: httptest serving canned Artifact Hub search JSON. Standard test categories. cd /home/salva/Documents/apikey && go test ./pkg/recon/sources/ -run "TestDockerHub|TestKubernetes" -v -count=1 DockerHubSource and KubernetesSource pass all tests: Docker Hub search returns repo findings, K8s source finds Artifact Hub packages
HelmSource (helm.go):
- Struct:
HelmSourcewithBaseURL,Registry,Limiters,Client - Compile-time assertion:
var _ recon.ReconSource = (*HelmSource)(nil) - Name() returns "helm"
- RateLimit() returns rate.Every(2 * time.Second)
- Burst() returns 2
- RespectsRobots() returns false (JSON API)
- Enabled() always true
- BaseURL defaults to "https://artifacthub.io"
- Sweep() logic:
- BuildQueries(s.Registry, "helm")
- For each keyword, GET
{BaseURL}/api/v1/packages/search?ts_query_web={keyword}&kind=0&limit=20(kind=0 = Helm charts) - Parse JSON:
{"packages": [{"package_id": "...", "name": "...", "normalized_name": "...", "repository": {"name": "...", "kind": 0}}]} - Define response structs:
artifactHubSearchResponse,artifactHubPackage,artifactHubRepo - Emit Finding per package: Source="https://artifacthub.io/packages/helm/{repo.name}/{package.name}", SourceType="recon:helm"
- Note: HelmSource and KubernetesSource both use Artifact Hub but with different
kindparameters and different SourceType tags. Keep them separate — different concerns.
Tests — httptest pattern:
- terraform_test.go: httptest serving canned Terraform registry JSON. Verify module URL construction from namespace/name/provider.
- helm_test.go: httptest serving canned Artifact Hub JSON for Helm charts. Standard test categories. cd /home/salva/Documents/apikey && go test ./pkg/recon/sources/ -run "TestTerraform|TestHelm" -v -count=1 TerraformSource and HelmSource pass all tests. Terraform constructs correct module URLs. Helm extracts Artifact Hub packages correctly.
<success_criteria>
- 4 new source files implement recon.ReconSource interface
- 4 test files use httptest with canned fixtures
- All tests pass
- No compilation errors across the package </success_criteria>