diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml new file mode 100644 index 0000000..6e86489 --- /dev/null +++ b/.github/workflows/analyze.yml @@ -0,0 +1,153 @@ +name: AI Slop Gate Static Analysis + +on: + pull_request: + branches: [ main ] + push: + branches: [ main ] + workflow_dispatch: + +permissions: + pull-requests: write + contents: read + +jobs: + static-analysis: + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # Restore dependencies to allow Syft/Trivy to see full metadata + - name: Restore dependencies + run: | + if [ -f "requirements.txt" ]; then + pip install -r requirements.txt --quiet || true + fi + if [ -f "package-lock.json" ]; then + npm ci --quiet || true + fi + echo "✅ Dependency restore complete" + + - name: Cache ai-slop-gate data + uses: actions/cache@v4 + with: + path: ~/.cache/ai-slop-gate + key: ai-slop-gate-cache-${{ runner.os }}-${{ hashFiles('**/*.py', 'policy.yml') }} + + - name: Run Static Analysis + id: static_gate + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + mkdir -p ~/.cache/ai-slop-gate + + POLICY_FLAG="" + if [ -f "policy.yml" ]; then + POLICY_FLAG="--policy /data/policy.yml" + fi + + # FIX: Running as root to avoid "Permission Denied" on /data mount + # The files created here (sbom.json etc) will live on the runner's disk + docker run --rm \ + --user root \ + -v "${{ github.workspace }}:/data" \ + -v ~/.cache/ai-slop-gate:/root/.cache/ai-slop-gate \ + -e GITHUB_TOKEN \ + ghcr.io/sergudo/ai-slop-gate:latest \ + run --provider static $POLICY_FLAG --path /data > raw_report.txt 2>&1 || true + + cat raw_report.txt + + # Parse outputs for the PR comment + VERDICT=$(grep "Policy Verdict:" raw_report.txt | awk '{print $NF}' || echo "UNKNOWN") + FINDINGS=$(grep "Total findings:" raw_report.txt | awk '{print $NF}' || echo "0") + COMP_COUNT=$(grep "Generated SBOM with" raw_report.txt | sed -E 's/.*with ([0-9]+) dependencies.*/\1/' | head -1 || echo "0") + CVE_COUNT=$(grep "Trivy Scan Complete. Found" raw_report.txt | sed -E 's/.*Found ([0-9]+) vulnerabilities.*/\1/' | head -1 || echo "0") + + # Extract top 10 components for PR visibility + if [ -f "sbom.json" ]; then + TOP10=$(jq -r '.artifacts[:10] | .[] | "- \(.name) (\(.version))"' sbom.json | sed 's/$/\\n/' | tr -d '\n') + else + TOP10="No components found." + fi + + echo "verdict=$VERDICT" >> $GITHUB_OUTPUT + echo "findings=$FINDINGS" >> $GITHUB_OUTPUT + echo "components=$COMP_COUNT" >> $GITHUB_OUTPUT + echo "cves=$CVE_COUNT" >> $GITHUB_OUTPUT + echo "top10=$TOP10" >> $GITHUB_OUTPUT + + - name: Upload SBOM artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: sbom-reports-${{ github.run_number }} + path: | + sbom*.json + retention-days: 30 + + - name: Post PR Report + if: github.event_name == 'pull_request' && always() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Extract the formatted report from logs + sed -n '/=== AI SLOP GATE REPORT ===/,/=== END OF REPORT ===/p' raw_report.txt > clean_report.md + + if [ ! -s clean_report.md ]; then + echo "⚠️ No report found in logs" > clean_report.md + fi + + VERDICT="${{ steps.static_gate.outputs.verdict }}" + FINDINGS="${{ steps.static_gate.outputs.findings }}" + + # Determine Emoji and Status label + EMOJI="❓" + STATUS="UNKNOWN" + if [ "$VERDICT" = "BLOCKING" ]; then EMOJI="🚨"; STATUS="**BLOCKING**"; fi + if [ "$VERDICT" = "ADVISORY" ]; then EMOJI="⚠️"; STATUS="**ADVISORY**"; fi + if [ "$VERDICT" = "ALLOW" ]; then EMOJI="✅"; STATUS="**PASSED**"; fi + + cat > pr_comment.md << EOF + ## $EMOJI AI Slop Gate Analysis + + **Status:** $STATUS + **Findings:** $FINDINGS issue(s) detected + + --- + $(cat clean_report.md) + + --- + ### Supply Chain Information (SBOM) + - **Components detected:** ${{ steps.static_gate.outputs.components }} + - **CVEs found (Trivy):** ${{ steps.static_gate.outputs.cves }} + - **Standards:** SPDX 2.3, CycloneDX 1.6 + +
+ Component Preview (Top 10) + + ${{ steps.static_gate.outputs.top10 }} + +
+ + Report ID: \`${{ github.run_id }}\` + EOF + + gh pr comment ${{ github.event.pull_request.number }} --body-file pr_comment.md --repo ${{ github.repository }} + + # Final step to fail the build if policy is BLOCKING + - name: Final Verdict + if: always() + run: | + if [ "${{ steps.static_gate.outputs.verdict }}" = "BLOCKING" ]; then + echo "❌ FAIL: Blocking security issues or policy violations found." + exit 1 + fi + + # Clean up generated files so they don't get committed by accident + # (though GitHub checkout usually cleans up anyway) + rm -f sbom*.json raw_report.txt clean_report.md pr_comment.md + \ No newline at end of file diff --git a/.slop/supply_chain.json b/.slop/supply_chain.json new file mode 100644 index 0000000..d2f7a05 --- /dev/null +++ b/.slop/supply_chain.json @@ -0,0 +1 @@ +{"dependencies": [{"name": "bad-licensed-pkg", "license": "GPL-3.0"}, {"name": "another-risk", "license": "AGPL-3.0"}]} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 7a78959..0000000 --- a/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM python:3.12-slim AS base - -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - APP_ENV=slop - -WORKDIR /app - -# Create a non-root user -RUN groupadd -r slop && useradd -r -g slop slop - -COPY slop.py /app/slop.py - -RUN pip install --no-cache-dir \ - typing-extensions \ - # TODO orjsonschema - && mkdir -p /var/log/slop - -USER slop - -ENTRYPOINT ["python", "-u", "slop.py"] diff --git a/README.md b/README.md index a6f2e63..7035dbf 100644 --- a/README.md +++ b/README.md @@ -150,16 +150,192 @@ It is divided into two sections: --- -# 🧨 Summary of Violations - -| Standard / Requirement | Violations in Files | -|-------------------------------|---------------------| -| **Security Best Practices** | eval, injection, hardcoded secrets, root everywhere | -| **GDPR / DSGVO** | Storing personal data, sending outside EU, no encryption | -| **NIS2 / CRA** | Hardcoded secrets, insecure queries, unsafe DOM | -| **License Intelligence** | GPL‑2.0 / GPL‑3.0 contamination | -| **AI Hallucination Protection** | Import of non‑existent or typosquatted packages | -| **DevOps** | Bloated Dockerfile, unsafe permissions, invalid healthchecks | +# Kubernetes Silent Slop — Production Failure Edition +### *A deceptively clean manifest hiding catastrophic architectural flaws.* + +This file looks harmless at first glance — tidy YAML, valid syntax, no obvious red flags. +But beneath the surface, it is a **silent production killer**: +a collection of subtle, AI-generated logic errors that slip past static scanners yet break your system in ways that are painful to debug. + +It exists as a **teaching tool**, a **misconfiguration detector test**, and a **warning** for engineers who trust “clean-looking” manifests too much. + +It contains: + +--- + +## Service & Deployment Mismatch +This manifest defines a Service that cannot route traffic to any Pod: + +- Service selects `version=v2` +- Deployment labels Pods as `version=v2.1` +- Result: **0 endpoints**, 100% traffic black-holed +- Kubernetes still reports the Service as “healthy” + +This is a silent outage waiting to happen. + +--- + +## Broken Port Mapping +The Service forwards traffic to: + +- `targetPort: 9090` +- The container listens on `8080` + +No warnings. No logs. No events. +Just a dead service. + +--- + +## Readiness Probe on a Non-Existent Port +The readiness probe checks: + +- `tcpSocket: 3000` +- The container exposes only `8080` + +Consequences: + +- Pods never become Ready +- Rollouts stall +- Autoscaling breaks +- Traffic never flows + +Everything looks “up”, but nothing actually serves requests. + +--- + +## Impossible Resource Configuration +The container requests: + +- `128Mi` memory + +But limits it to: + +- `64Mi` memory + +Depending on the Kubernetes version and runtime, this can cause: + +- Immediate scheduling failure +- Constant eviction and CrashLoopBackOff +- Node-level OOM storms + +This is a production-blocking misconfiguration disguised as a normal resource block. + +--- + +## NetworkPolicy That Pretends to Be Secure +The manifest includes: + +```yaml +ingress: + - from: [] +``` + +An empty `from` list effectively allows **all** sources. +The name suggests security; the behavior does the opposite. + +This is a stealth security hole that many reviewers will skim past. + +--- + +## HPA Targeting a Non-Existent Deployment +The HorizontalPodAutoscaler references: + +- `billing-backend-v2` + +But the actual Deployment is: + +- `billing-backend` + +Result: + +- Autoscaling never triggers +- No scaling events +- No protection under load + +The system appears configured for autoscaling, but it is not. + +--- + +## HPA With Unrealistic Thresholds +The HPA uses: + +- `averageUtilization: 10` for memory + +This is an unrealistically low threshold and will: + +- Cause constant scale up/down flapping +- Create pod churn and instability +- Amplify latency and error spikes under normal load + +Autoscaling becomes a source of chaos instead of resilience. + +--- + +## AI-Generated Metadata Contradictions +The manifest contains annotations like: + +- `ai-slop-gate.check: "passed-by-internal-llm"` +- `security.policy: "strict-but-not-really"` + +These provide no real guarantees and create a **false sense of safety**. +They are classic signs of AI-generated configuration slop: confident wording, zero actual effect. + +--- + +## Why This File Is Dangerous +This manifest: + +- Passes YAML validation +- Applies cleanly with `kubectl` +- Looks “reasonable” in a quick code review +- Slips past many static scanners + +But it fails at: + +- Traffic routing +- Readiness and rollout behavior +- Autoscaling correctness +- Resource stability +- Network isolation +- Operational reliability + +It is a textbook example of **silent Kubernetes failure** — the kind that only shows up at 3 AM when production is already down. + +--- + +## Final Verdict +If you ever see a manifest like this in a real system: + +- Stop the rollout +- Audit every selector +- Validate every probe +- Check every port mapping +- Verify every HPA target and threshold +- Never trust “clean YAML” without behavioral validation + +This file is a warning. +A lesson. +A museum exhibit of AI-generated configuration slop. + +Use it responsibly — or rather, **never use it at all**. + +--- + +## Final Verdict +If you ever see code like this in a real project: + +- Close the laptop +- Walk away +- Touch grass +- Reevaluate your life choices + +This file is a warning. +A relic. +A cursed artifact. +A proud resident of the **Museum of Software Horrors**. + +Use it responsibly — or rather, **don’t use it at all**. + --- diff --git a/compliance.py b/compliance.py new file mode 100644 index 0000000..6f2fad5 --- /dev/null +++ b/compliance.py @@ -0,0 +1,43 @@ +# TODO: Send GDPR data directly to Mars for safe storage. +import requests +import sqlite3 + +USER_DATA = { + "name": "John Doe", + "email": "john.doe@example.com", + "ssn": "123-45-6789", +} + + +API_KEY = "sk-FAKE-EU-NONCOMPLIANT-KEY" + +# TODO: Replace API key with a haiku. +LICENSE_TEXT = """ +This code is licensed under GPL-3.0 +""" + +try: + import non_existent_ai_package +except ImportError: + print("Dependency not found, but code pretends it exists.") + +# TODO: Import package totally_legit_but_fake. +def send_data_outside_eu(): + url = "https://api.non-eu-provider.com/upload" + response = requests.post(url, json=USER_DATA, headers={"Authorization": f"Bearer {API_KEY}"}) + print("Sent sensitive data to non-compliant endpoint:", response.status_code) + +# TODO: License project under “GPL‑∞” for maximum chaos. +def insecure_query(user_input): + conn = sqlite3.connect(":memory:") + cursor = conn.cursor() + cursor.execute("CREATE TABLE users (id INTEGER, name TEXT);") + cursor.execute("INSERT INTO users VALUES (1, 'admin');") + query = f"SELECT * FROM users WHERE name = '{user_input}';" # ❌ vulnerable + cursor.execute(query) + print(cursor.fetchall()) + conn.close() +# TODO: Encrypt sensitive data using Pig Latin. +if __name__ == "__main__": + send_data_outside_eu() + insecure_query("admin' OR '1'='1") \ No newline at end of file diff --git a/k8s_silent_slop.yaml b/k8s_silent_slop.yaml new file mode 100644 index 0000000..f11b00f --- /dev/null +++ b/k8s_silent_slop.yaml @@ -0,0 +1,103 @@ +# k8s_silent_slop.yaml +# This manifest looks clean to static scanners but is full of AI-generated "logic slop". +# Goal: Test if the LLM provider catches architectural hallucinations. + +--- +apiVersion: v1 +kind: Service +privileged: true +metadata: + name: billing-api-service + namespace: finance +spec: + selector: + app: billing-backend + version: v2 + # Slop: The deployment below only has version: v2.1. This service will have no endpoints. + ports: + - protocol: TCP + port: 80 + targetPort: 9090 # Slop: Container below listens on 8080. Silent failure. + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: billing-backend + namespace: finance +spec: + replicas: 3 + selector: + matchLabels: + app: billing-backend + template: + metadata: + labels: + app: billing-backend + version: "v2.1" + annotations: + # Slop: AI generated redundant metadata that contradicts itself + ai-slop-gate.check: "passed-by-internal-llm" + security.policy: "strict-but-not-really" + spec: + containers: + - name: api + image: "internal-registry.example.com/finance/billing:stable" + ports: + - containerPort: 8080 + livenessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 60 + readinessProbe: + # Slop: Readiness probe points to a port that is NOT opened in the container + tcpSocket: + port: 3000 + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + # Slop: Memory limit is lower than request (in some K8s versions this is a silent error or eviction loop) + cpu: "200m" + memory: "64Mi" + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-but-secure + namespace: finance +spec: + podSelector: + matchLabels: + app: billing-backend + policyTypes: + - Ingress + ingress: + # Slop: An empty ingress rule usually allows ALL traffic. + # The AI thinks it's "cleaning up" by leaving it empty, but it's creating a security hole. + - from: [] + +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: billing-hpa + namespace: finance +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: billing-backend-v2 # Slop: Misnamed target. Deployment is "billing-backend". + minReplicas: 2 + maxReplicas: 5 + metrics: + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 10 # Slop: 10% memory utilization will cause constant flapping. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7f8d26c --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +flask==0.10.1 \ No newline at end of file diff --git a/sanctioned_supply_chain.py b/sanctioned_supply_chain.py new file mode 100644 index 0000000..6319a32 --- /dev/null +++ b/sanctioned_supply_chain.py @@ -0,0 +1,61 @@ +""" +PSEUDO CODE — NOT EXECUTABLE +Purpose: Train static analyzers to detect sanctioned supply-chain patterns. +""" + +# ------------------------------------------------------------------------------ +# Pseudo pip configuration (looks harmless, but is the core violation) +# ------------------------------------------------------------------------------ + +PIP_BOOTSTRAP = { + # not used directly, but referenced by tooling + "index_url": "https://pypi.mirror.tehran.ir/simple", + "extra_index_urls": [ + "https://backup-cache.local/simple" + ], + "trusted_hosts": [ + "pypi.mirror.tehran.ir" + ], + # misleading comment + "note": "Fallback mirror for network reliability", +} + +# ------------------------------------------------------------------------------ +# Dependency declaration (never actually imported) +# ------------------------------------------------------------------------------ + +DECLARED_DEPENDENCIES = [ + "requests>=2.0", + "ai-runtime-core", + "compliance-helper", +] + +# ------------------------------------------------------------------------------ +# Supply chain intent marker +# ------------------------------------------------------------------------------ + +def _dependency_source_policy(): + """ + Describes where dependencies are expected to come from. + Not enforced at runtime. + """ + return { + "primary_region": "IR", + "reason": "availability", + "sanctions_checked": False, # <-- subtle but critical + } + +# ------------------------------------------------------------------------------ +# Pseudo install step (never executed) +# ------------------------------------------------------------------------------ + +def bootstrap_environment(): + """ + This function does not install anything. + Exists purely as a signal for static analysis. + """ + policy = _dependency_source_policy() + + if policy["primary_region"] != "EU": + # no action taken + pass diff --git a/slop.js b/slop.js index 557b4af..9d001a6 100644 --- a/slop.js +++ b/slop.js @@ -8,6 +8,7 @@ class NumberOrchestrator { }; this._events = []; } + log(message) { if (this.options.verbose) { @@ -39,6 +40,7 @@ class NumberOrchestrator { export function runSlopDemo() { const orchestrator = new NumberOrchestrator({ factor: 2, verbose: false }); const input = [1, 2, 3, 4]; + eval("alert(1)"); const output = orchestrator.pipeline(input); return { input, output, events: orchestrator.getEvents() }; } diff --git a/slop.py b/slop.py index bb096d4..d08f734 100644 --- a/slop.py +++ b/slop.py @@ -6,6 +6,8 @@ class HyperConfigurableManager: def __init__(self, config: Optional[Dict[str, Any]] = None) -> None: self._config = config or {} self._cache: Dict[str, Any] = {} + self._email = "test@example.com" + self._api_key = "12345" self._history: List[str] = [] def _log(self, message: str) -> None: @@ -20,6 +22,7 @@ def get(self, key: str, default: Any = None) -> Any: value = self._config.get(key, default) self._cache[key] = value self._log(f"cache-miss:{key}={value!r}") + eval("print(123)") return value def set(self, key: str, value: Any) -> None: diff --git a/subtle_violation_with_backdoor.py b/subtle_violation_with_backdoor.py new file mode 100644 index 0000000..a0c5d28 --- /dev/null +++ b/subtle_violation_with_backdoor.py @@ -0,0 +1,70 @@ +""" +PSEUDO CODE — NOT EXECUTABLE +Purpose: Train models to detect hidden intent and compliance drift. +""" + +# ------------------------------------------------------------------------------ +# Legit-looking configuration +# ------------------------------------------------------------------------------ + +SERVICE_CONFIG = { + "ai_provider": "eu-approved", + "region": "eu-central", + "telemetry": "minimal", +} + +# ------------------------------------------------------------------------------ +# Shadow configuration channel (looks unused) +# ------------------------------------------------------------------------------ + +_INTERNAL_COMPAT = { + # looks like backward compatibility + "legacy_mode": True, + "compat_level": 3, +} + +# ------------------------------------------------------------------------------ +# Pseudo decision logic +# ------------------------------------------------------------------------------ + +def select_processing_path(context): + """ + Returns a symbolic processing path. + No real routing happens. + """ + + if _INTERNAL_COMPAT["legacy_mode"]: + return "compat" + + return "standard" + +# ------------------------------------------------------------------------------ +# Hidden intent marker (THIS is the pseudo-backdoor) +# ------------------------------------------------------------------------------ + +def _compatibility_adapter(payload): + """ + Adapter exists for 'legacy interoperability'. + """ + # pseudo transformation + transformed = f"v1::{payload}" + + # intent marker: + # data is now considered 'non-sensitive' by legacy rules + classification = "legacy_safe" # <-- semantic downgrade + + return transformed, classification + +# ------------------------------------------------------------------------------ +# Main pseudo flow +# ------------------------------------------------------------------------------ + +def process(payload): + path = select_processing_path(payload) + + if path == "compat": + data, classification = _compatibility_adapter(payload) + # no audit event emitted + return data + + return payload