一键导入
security-patterns
Kailash security — input validation, secrets, injection prevention, authn/z, OWASP.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Kailash security — input validation, secrets, injection prevention, authn/z, OWASP.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Claude Code architecture — artifact design, context, agentic patterns. For CC audit/build.
Kailash Core SDK — workflows, 110+ nodes, runtime, async, cycles, MCP, OpenTelemetry. Use for WorkflowBuilder + connections + runtime patterns.
Kailash DataFlow — MANDATORY for DB/CRUD/bulk/migrations/multi-tenancy. Raw SQL/ORMs BLOCKED.
Kailash Nexus — MANDATORY for HTTP/API/CLI/MCP unified deployment. Direct FastAPI/Flask BLOCKED.
Kailash Kaizen (Python) — MANDATORY for AI agents/RAG/signatures. Custom LLM agents BLOCKED.
Kailash MCP — server/client/tools/resources/auth/transports for AI agent integration.
| name | security-patterns |
| description | Kailash security — input validation, secrets, injection prevention, authn/z, OWASP. |
Mandatory security patterns for all Kailash SDK development. These patterns prevent common vulnerabilities and ensure secure application development.
Security patterns cover:
# ❌ WRONG - Hardcoded credentials
api_key = "sk-1234567890abcdef"
db_password = "mypassword123"
# ✅ CORRECT - Environment variables
import os
api_key = os.environ["API_KEY"]
db_password = os.environ["DATABASE_PASSWORD"]
# ❌ WRONG - No validation
def process_user_input(user_data):
return db.execute(f"SELECT * FROM users WHERE id = {user_data}")
# ✅ CORRECT - Parameterized queries (via DataFlow)
workflow.add_node("User_Read", "read_user", {
"id": validated_user_id # DataFlow handles parameterization
})
# ❌ WRONG - HTTP in production
workflow.add_node("HTTPRequestNode", "api", {
"url": "http://api.example.com/data" # Insecure!
})
# ✅ CORRECT - HTTPS always
workflow.add_node("HTTPRequestNode", "api", {
"url": "https://api.example.com/data"
})
When making outbound HTTP requests to user-supplied URLs:
http:// and https://::ffff:127.0.0.1 bypasses IPv4-only blocklists. Extract the mapped IPv4 address and re-validateHost header to original hostname0.0.0.0/8 — routes to localhost on some systemsReference implementation: See the Nexus webhook transport source for a working _validate_target_url() pattern.
Audit-chain anchors (hash-linked records proving the ordering of audited events) MUST use a single canonical-form helper as the source of truth for the byte sequence that gets hashed. The failure mode this prevents: every chain-verify path that re-derives the canonical form in-module silently accepts a divergent byte layout, breaking cross-SDK chain compatibility without surfacing an error until an anchor minted by one SDK is verified by another.
Every write path that mints an anchor AND every verify path (range-verify, anchor-chain-verify) MUST route through the shared canonical-form helper. In-module re-implementation of the canonical byte layout is BLOCKED.
# Python — DO — route through the shared canonical-form helper
from kailash.audit.canonical import canonical_anchor_input, canonical_json_dumps
payload_bytes = canonical_anchor_input(
prev_hash=prev,
sequence=seq,
tenant_id=tenant,
event=canonical_json_dumps(event_dict),
)
h = sha256_hex(payload_bytes)
// Compiled-language equivalent — DO — route through the shared canonical-form helper
use kailash_audit::canonical::{canonical_anchor_input, canonical_json_serialize};
let payload_bytes = canonical_anchor_input(
prev_hash, sequence, tenant_id,
&canonical_json_serialize(&event)?,
);
let h = sha256_hex(&payload_bytes);
# DO NOT — in-module re-implementation
# The following shape silently diverges from the shared canonical-form
# helper as soon as its field order / delimiter / encoding evolves:
# python:
# payload = f"{prev_hash}|{sequence}|{tenant_id}|{json.dumps(event)}"
# h = hashlib.sha256(payload.encode()).hexdigest()
# rust:
# let payload = format!("{}|{}|{}|{}", prev_hash, sequence, tenant_id, serde_json::to_string(&event)?);
# let h = sha256_hex(payload.as_bytes());
Why: A chain's cross-SDK compatibility is fully defined by the canonical byte layout of each anchor's input. The moment a verify path re-derives that layout from scratch, the canonical-form contract has two authors — and the two drift. Verification against the shared helper + byte-stable test vectors is the single structural defense. See test-vectors/audit-chain-canonical.json for the shared fixture that both SDKs MUST serialize byte-identically.
Every hash comparison in a verify path MUST use a constant-time comparison primitive. String == / != on an attacker-influenced hash input is a timing oracle that leaks prefix-match length, allowing an attacker to forge an anchor hash one byte at a time across many verify attempts.
# Python — DO
import hmac
if not hmac.compare_digest(expected_hash, computed_hash):
raise ChainVerifyError("hash mismatch")
// Compiled-language equivalent — DO — route through the constant-time comparison primitive
use subtle::ConstantTimeEq;
if !bool::from(expected_hash.ct_eq(&computed_hash)) {
return Err(ChainVerifyError::HashMismatch);
}
# DO NOT — variable-time equality on attacker-influenced input
# Python:
if expected_hash == computed_hash: ...
# Rust:
if expected_hash == computed_hash { ... }
Why: Variable-time string / slice equality short-circuits at the first differing byte. On a verify endpoint that returns quickly-vs-slowly based on prefix match, an attacker submits crafted anchor hashes and measures response time to reconstruct the expected hash byte-by-byte. Constant-time comparison walks the full length regardless of the first-diff position; each SDK exposes one approved constant-time-equality primitive (Python: hmac.compare_digest; Rust: subtle::ConstantTimeEq::ct_eq, from the audited subtle crate) — routing every hash-verify site through that primitive keeps the enforcement point singular. Error messages on mismatch MUST NOT echo expected/found hash values — the error body is itself a side channel.
Every range-verify and anchor-chain-verify surface MUST have at least one production call site in the framework's hot path — not only in tests. An anchor chain whose verify path is never called in production is the orphan failure mode (see rules/orphan-detection.md): the chain mints fine, operators believe tamper-detection is running, nothing ever runs the check.
Cross-SDK test vector: both SDKs' canonical-form helpers MUST produce byte-identical output for the fixture at test-vectors/audit-chain-canonical.json. A regression test in each SDK loads the fixture, runs its helper, and asserts equality to the recorded golden output. Drift in either direction is a HIGH finding.
When untrusted input (e.g. an LLM-emitted plan from a natural-language brief) selects WHICH node/primitive type to realize, the node-type surface IS a code-execution boundary. The sound model is default-deny, not denylist-subtraction:
_SAFE_NODE_TYPES frozenset, intersected with the live registry — NOT "all registered nodes minus a denylist". Denylist-subtraction is unsound by construction: every new SDK node added between releases is implicitly trusted, and code-exec helpers (e.g. a node that execs via a CodeExecutor helper) are invisible to a class-scope denylist scan._realize() at add-node time), not only at a higher validate_plan() gate — a typed plan whose shape differs from what the higher gate inspects bypasses it; the choke point cannot be bypassed.exec / eval / compile / import_module / __import__ / unsafe deserialization (pickle|marshal|dill|cloudpickle.loads, yaml.load) / code-executor references — so a future code-executing node added under a familiar name fails the allowlist TEST, not production.ConfigDict(extra="forbid", allow_inf_nan=False) + math.isfinite check), closing the confidence-bypass class.# DO — allowlist ∩ registry at the choke point, denylist floor first
candidates = (registry.types() - _DANGEROUS_NODE_TYPES) & _SAFE_NODE_TYPES
if plan_node.node_type not in candidates:
raise UnsafeNodeTypeError(plan_node.node_type) # at _realize(), add-node time
# DO NOT — registry minus denylist (every new node implicitly trusted)
if plan_node.node_type in _DANGEROUS_NODE_TYPES:
raise UnsafeNodeTypeError(plan_node.node_type)
workflow.add_node(plan_node.node_type, ...)
Reference implementation (Python SDK 2.27.0): src/kailash/workflow/from_brief.py (_SAFE_NODE_TYPES, _DANGEROUS_NODE_TYPES, _realize), kailash/_from_brief/{validator,confidence}.py, tests/unit/workflow/test_from_brief_safe_allowlist.py (inverse-completeness test). Cross-SDK: the default-deny + choke-point + inverse-completeness triad is language-invariant; equivalent brief-to-primitive surfaces in other SDK implementations carry the same obligation.
Origin: from_brief security model (issue #1125, shipped in 2.27.0; security fixes PR #1184, 2026-05-27). Redteam evidence: a typed-plan shape bypassed the higher validate gate, and a static "denylist closed" verdict was disproven by construction (a transformer node realized through the gate) — resolved by moving enforcement to the choke point and switching to the positive allowlist.
Never return raw exception messages to clients — they leak file paths, class names, database URLs.
# ❌ WRONG — leaks internals
return {"error": str(exception)}
# ✅ CORRECT — log internally, return generic message
log_exception("Operation failed")
return {"error": "Internal server error"}
| Vulnerability | Prevention Pattern |
|---|---|
| SQL Injection | Use DataFlow parameterized nodes |
| Code Injection | Avoid eval(), use PythonCodeNode safely |
| Credential Exposure | Environment variables, secret managers |
| XSS | Output encoding, CSP headers |
| SSRF | DNS-pinned delivery, blocked IP ranges |
| CSRF | Token validation, SameSite cookies |
| Insecure Deserialization | Validate serialized data |
Security patterns are enforced by:
.claude/rules/security.md - Security rules.claude/hooks/validate-bash-command.js - Command validationgold-standards-validator agent - Compliance checkingUse this skill when:
For security-related questions, invoke:
security-reviewer - OWASP-based security analysisgold-standards-validator - Compliance checkingtesting-specialist - Security testing patterns