Best for
- Writing authentication / authorization code (→ references/auth-modern.md)
- Handling user input or external data
- Implementing cryptography or password storage (→ references/crypto-modern.md)
JotJunior/cstk/plugins/cstk/skills/owasp-security/SKILL.md
Security review: OWASP Top 10:2025, ASVS 5.0, Agentic AI 2026, LLM Top 10, API/CICD, NIST 800-63B-4, WebAuthn, OAuth 2.1, FAPI 2.0, post-quantum. Triggers: "security review", "OWASP", "vulnerability check", "auth code", "threat model", "MCP security". Skip for general code review.
Decision brief
Apply these security standards when writing or reviewing code.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/JotJunior/cstk --skill "plugins/cstk/skills/owasp-security"Inspect the Agent Skill "owasp-security" from https://github.com/JotJunior/cstk/blob/d1b28a511642ec12e088ed01df11d8ee9eb8bc05/plugins/cstk/skills/owasp-security/SKILL.md at commit d1b28a511642ec12e088ed01df11d8ee9eb8bc05. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
When reviewing code, check for these issues:
This file is the operational entry point — quick checklists and code patterns. For deep coverage of any topic below, open the matching file in references/:
Review the “Quick Reference: OWASP Top 10:2025” section in the pinned source before continuing.
[ ] All user input validated server-side
Deep dive: references/auth-modern.md
Permission review
The documentation asks the agent to read local files, directories, or repositories.
This file is the **operational entry point** — quick checklists and code patterns. For deep coverage of any topic below, open the matching file in [`references/`](./references/):The documentation includes network, browsing, or remote request actions.
factory.setFeature("http://xml.org/sax/features/external-general-entities", false)The documentation asks the agent to read local files, directories, or repositories.
open(FILE, $user_file);Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 22 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Apply these security standards when writing or reviewing code.
Scope & limits. This skill is a checklist-guided review assistant over the standards below — useful for sweeping a diff or PR and surfacing high-signal findings. It is not, and does not replace, a formal audit, pentest, or certification: the breadth of the catalog (10+ frameworks) means checklist coverage, not exhaustive verification. Use it to raise the security floor and to prioritize; treat findings as starting points, not verdicts.
This file is the operational entry point — quick checklists and code patterns. For deep coverage of any topic below, open the matching file in references/:
| Topic | File |
|---|---|
| LLM Top 10:2025 + Agentic 2026 deep dive + MCP security + modern prompt injection + MAESTRO | references/llm-agentic.md |
| OWASP API Security Top 10:2023 + OWASP CI/CD Top 10 (PPE, OIDC federation, signing) | references/api-cicd.md |
| NIST SP 800-63B-4 + WebAuthn/Passkeys + OAuth 2.1 + FAPI 2.0 | references/auth-modern.md |
| Post-quantum crypto (FIPS 203/204/205) + crypto agility + 2026 secrets management | references/crypto-modern.md |
| CWE Top 25:2025 + Mobile Top 10:2024 + Kubernetes/Docker Top 10 + EU AI Act mapping | references/extras.md |
The full historical reference document with deeper background on Top 10:2025, ASVS 5.0, and Agentic 2026 is in OWASP-2025-2026-Report.md.
| # | Vulnerability | Key Prevention |
|---|---|---|
| A01 | Broken Access Control | Deny by default, enforce server-side, verify ownership |
| A02 | Security Misconfiguration | Harden configs, disable defaults, minimize features |
| A03 | Supply Chain Failures | Lock versions, verify integrity, audit dependencies |
| A04 | Cryptographic Failures | TLS 1.2+, AES-256-GCM, Argon2/bcrypt for passwords |
| A05 | Injection | Parameterized queries, input validation, safe APIs |
| A06 | Insecure Design | Threat model, rate limit, design security controls |
| A07 | Auth Failures | MFA, check breached passwords, secure sessions |
| A08 | Integrity Failures | Sign packages, SRI for CDN, safe serialization |
| A09 | Logging Failures | Log security events, structured format, alerting |
| A10 | Exception Handling | Fail-closed, hide internals, log with context |
When reviewing code, check for these issues:
Deep dive: references/auth-modern.md
Deep dive: references/crypto-modern.md
# UNSAFE
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# SAFE
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# UNSAFE
os.system(f"convert {filename} output.png")
# SAFE
subprocess.run(["convert", filename, "output.png"], shell=False)
# UNSAFE
hashlib.md5(password.encode()).hexdigest()
# SAFE
from argon2 import PasswordHasher
PasswordHasher().hash(password)
# UNSAFE - No authorization check
@app.route('/api/user/<user_id>')
def get_user(user_id):
return db.get_user(user_id)
# SAFE - Authorization enforced
@app.route('/api/user/<user_id>')
@login_required
def get_user(user_id):
if current_user.id != user_id and not current_user.is_admin:
abort(403)
return db.get_user(user_id)
# UNSAFE - Exposes internals
@app.errorhandler(Exception)
def handle_error(e):
return str(e), 500
# SAFE - Fail-closed, log context
@app.errorhandler(Exception)
def handle_error(e):
error_id = uuid.uuid4()
logger.exception(f"Error {error_id}: {e}")
return {"error": "An error occurred", "id": str(error_id)}, 500
# UNSAFE - Fail-open
def check_permission(user, resource):
try:
return auth_service.check(user, resource)
except Exception:
return True # DANGEROUS!
# SAFE - Fail-closed
def check_permission(user, resource):
try:
return auth_service.check(user, resource)
except Exception as e:
logger.error(f"Auth check failed: {e}")
return False # Deny on error
Two complementary OWASP lists apply when building AI-powered systems:
OWASP Top 10 for LLM Applications 2025 — model-boundary risks:
| ID | Risk | One-line |
|---|---|---|
| LLM01 | Prompt Injection | Direct or indirect (via tool output / RAG / docs) |
| LLM02 | Sensitive Info Disclosure | PII / secrets leaked via outputs |
| LLM03 | Supply Chain | Compromised models, fine-tunes, LoRA adapters |
| LLM04 | Data / Model Poisoning | Training-data tampering, backdoors |
| LLM05 | Improper Output Handling | Downstream systems trust LLM output unchecked |
| LLM06 | Excessive Agency | Too much functionality / permission / autonomy |
| LLM07 | System Prompt Leakage | System prompts treated as secrets, but extractable |
| LLM08 | Vector / Embedding Weaknesses | RAG poisoning, embedding inversion, cross-tenant leak |
| LLM09 | Misinformation | Hallucinations propagated as fact |
| LLM10 | Unbounded Consumption | Token / resource / cost exhaustion |
OWASP Top 10 for Agentic Applications 2026 — system-level risks:
| ID | Risk | Mitigation |
|---|---|---|
| ASI01 | Goal Hijack | Boundaries, output schemas, behavior monitoring |
| ASI02 | Tool Misuse | Least privilege, schemas on I/O, audit |
| ASI03 | Privilege Abuse | Short-lived scoped tokens, delegated identity |
| ASI04 | Supply Chain | Sign packages, sandbox MCP servers, allowlist |
| ASI05 | Code Execution | Sandbox, static analysis, human approval |
| ASI06 | Memory Poisoning | Validate at ingest + retrieve, trust segmentation |
| ASI07 | Inter-Agent Comms | Authenticate, encrypt, message integrity |
| ASI08 | Cascading Failures | Circuit breakers, degradation, isolation |
| ASI09 | Trust Exploitation | Label AI content, verification steps |
| ASI10 | Rogue Agents | Behavior baseline, kill switch, anomaly alerts |
fetch → write_file → send_email) where no single call looks malicious. Model trajectories, not just calls.Deep dive: references/llm-agentic.md
ASVS 5.0 has 17 categories (V1-V17). V15 OAuth/OIDC, V16 Self-Contained Tokens, V17 WebSockets are new in 5.0.
When the review focuses on APIs or build/deploy pipelines, the general Top 10 isn't enough. Use the dedicated lists:
OWASP API Security Top 10:2023 (still current in 2026):
OWASP CI/CD Top 10:
Deep dive: references/api-cicd.md
Top 5 most-exploited weaknesses observed in CVEs over 24 months:
Use to prioritize SAST rules and developer training. Full list + OWASP mapping: references/extras.md
Important: The examples below are illustrative starting points, not exhaustive. When reviewing code, think like a senior security researcher: consider the language's memory model, type system, standard library pitfalls, ecosystem-specific attack vectors, and historical CVE patterns. Each language has deeper quirks beyond what's listed here.
Different languages have unique security pitfalls. Here are the top 20 languages with key security considerations. Go deeper for the specific language you're working in:
Main Risks: Prototype pollution, XSS, eval injection
// UNSAFE: Prototype pollution
Object.assign(target, userInput)
// SAFE: Use null prototype or validate keys
Object.assign(Object.create(null), validated)
// UNSAFE: eval injection
eval(userCode)
// SAFE: Never use eval with user input
Watch for: eval(), innerHTML, document.write(), prototype chain manipulation, __proto__
Main Risks: Pickle deserialization, format string injection, shell injection
# UNSAFE: Pickle RCE
pickle.loads(user_data)
# SAFE: Use JSON or validate source
json.loads(user_data)
# UNSAFE: Format string injection
query = "SELECT * FROM users WHERE name = '%s'" % user_input
# SAFE: Parameterized
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
Watch for: pickle, eval(), exec(), os.system(), subprocess with shell=True
Main Risks: Deserialization RCE, XXE, JNDI injection
// UNSAFE: Arbitrary deserialization
ObjectInputStream ois = new ObjectInputStream(userStream);
Object obj = ois.readObject();
// SAFE: Use allowlist or JSON
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, SafeClass.class);
Watch for: ObjectInputStream, Runtime.exec(), XML parsers without XXE protection, JNDI lookups
Main Risks: Deserialization, SQL injection, path traversal
// UNSAFE: BinaryFormatter RCE
BinaryFormatter bf = new BinaryFormatter();
object obj = bf.Deserialize(stream);
// SAFE: Use System.Text.Json
var obj = JsonSerializer.Deserialize<SafeType>(json);
Watch for: BinaryFormatter, JavaScriptSerializer, TypeNameHandling.All, raw SQL strings
Main Risks: Type juggling, file inclusion, object injection
// UNSAFE: Type juggling in auth
if ($password == $stored_hash) { ... }
// SAFE: Use strict comparison
if (hash_equals($stored_hash, $password)) { ... }
// UNSAFE: File inclusion
include($_GET['page'] . '.php');
// SAFE: Allowlist pages
$allowed = ['home', 'about']; include(in_array($page, $allowed) ? "$page.php" : 'home.php');
Watch for: == vs ===, include/require, unserialize(), preg_replace with /e, extract()
Main Risks: Race conditions, template injection, slice bounds
// UNSAFE: Race condition
go func() { counter++ }()
// SAFE: Use sync primitives
atomic.AddInt64(&counter, 1)
// UNSAFE: Template injection
template.HTML(userInput)
// SAFE: Let template escape
{{.UserInput}}
Watch for: Goroutine data races, template.HTML(), unsafe package, unchecked slice access
Main Risks: Mass assignment, YAML deserialization, regex DoS
# UNSAFE: Mass assignment
User.new(params[:user])
# SAFE: Strong parameters
User.new(params.require(:user).permit(:name, :email))
# UNSAFE: YAML RCE
YAML.load(user_input)
# SAFE: Use safe_load
YAML.safe_load(user_input)
Watch for: YAML.load, Marshal.load, eval, send with user input, .permit!
Main Risks: Unsafe blocks, FFI boundary issues, integer overflow in release
// CAUTION: Unsafe bypasses safety
unsafe { ptr::read(user_ptr) }
// CAUTION: Release integer overflow
let x: u8 = 255;
let y = x + 1; // Wraps to 0 in release!
// SAFE: Use checked arithmetic
let y = x.checked_add(1).unwrap_or(255);
Watch for: unsafe blocks, FFI calls, integer overflow in release builds, .unwrap() on untrusted input
Main Risks: Force unwrapping crashes, Objective-C interop
// UNSAFE: Force unwrap on untrusted data
let value = jsonDict["key"]!
// SAFE: Safe unwrapping
guard let value = jsonDict["key"] else { return }
// UNSAFE: Format string
String(format: userInput, args)
// SAFE: Don't use user input as format
Watch for: force unwrap (!), try!, ObjC bridging, NSSecureCoding misuse
Main Risks: Null safety bypass, Java interop, serialization
// UNSAFE: Platform type from Java
val len = javaString.length // NPE if null
// SAFE: Explicit null check
val len = javaString?.length ?: 0
// UNSAFE: Reflection
clazz.getDeclaredMethod(userInput)
// SAFE: Allowlist methods
Watch for: Java interop nulls (! operator), reflection, serialization, platform types
Main Risks: Buffer overflow, use-after-free, format string
// UNSAFE: Buffer overflow
char buf[10]; strcpy(buf, userInput);
// SAFE: Bounds checking
strncpy(buf, userInput, sizeof(buf) - 1);
// UNSAFE: Format string
printf(userInput);
// SAFE: Always use format specifier
printf("%s", userInput);
Watch for: strcpy, sprintf, gets, pointer arithmetic, manual memory management, integer overflow
Main Risks: XML external entities, serialization, pattern matching exhaustiveness
// UNSAFE: XXE
val xml = XML.loadString(userInput)
// SAFE: Disable external entities
val factory = SAXParserFactory.newInstance()
factory.setFeature("http://xml.org/sax/features/external-general-entities", false)
Watch for: Java interop issues, XML parsing, Serializable, exhaustive pattern matching
Main Risks: Code injection, file path manipulation
# UNSAFE: eval injection
eval(parse(text = user_input))
# SAFE: Never parse user input as code
# UNSAFE: Path traversal
read.csv(paste0("data/", user_file))
# SAFE: Validate filename
if (grepl("^[a-zA-Z0-9]+\\.csv$", user_file)) read.csv(...)
Watch for: eval(), parse(), source(), system(), file path manipulation
Main Risks: Regex injection, open() injection, taint mode bypass
# UNSAFE: Regex DoS
$input =~ /$user_pattern/;
# SAFE: Use quotemeta
$input =~ /\Q$user_pattern\E/;
# UNSAFE: open() command injection
open(FILE, $user_file);
# SAFE: Three-argument open
open(my $fh, '<', $user_file);
Watch for: Two-arg open(), regex from user input, backticks, eval, disabled taint mode
Main Risks: Command injection, word splitting, globbing
# UNSAFE: Unquoted variables
rm $user_file
# SAFE: Always quote
rm "$user_file"
# UNSAFE: eval
eval "$user_command"
# SAFE: Never eval user input
Watch for: Unquoted variables, eval, backticks, $(...) with user input, missing set -euo pipefail
Main Risks: Sandbox escape, loadstring injection
-- UNSAFE: Code injection
loadstring(user_code)()
-- SAFE: Use sandboxed environment with restricted functions
Watch for: loadstring, loadfile, dofile, os.execute, io library, debug library
Main Risks: Atom exhaustion, code injection, ETS access
# UNSAFE: Atom exhaustion DoS
String.to_atom(user_input)
# SAFE: Use existing atoms only
String.to_existing_atom(user_input)
# UNSAFE: Code injection
Code.eval_string(user_input)
# SAFE: Never eval user input
Watch for: String.to_atom, Code.eval_string, :erlang.binary_to_term, ETS public tables
Main Risks: Platform channel injection, insecure storage
// UNSAFE: Storing secrets in SharedPreferences
prefs.setString('auth_token', token);
// SAFE: Use flutter_secure_storage
secureStorage.write(key: 'auth_token', value: token);
Watch for: Platform channel data, dart:mirrors, Function.apply, insecure local storage
Main Risks: Command injection, execution policy bypass
# UNSAFE: Injection
Invoke-Expression $userInput
# SAFE: Avoid Invoke-Expression with user data
# UNSAFE: Unvalidated path
Get-Content $userPath
# SAFE: Validate path is within allowed directory
Watch for: Invoke-Expression, & $userVar, Start-Process with user args, -ExecutionPolicy Bypass
Main Risks: Injection, privilege escalation, data exfiltration
-- UNSAFE: String concatenation
"SELECT * FROM users WHERE id = " + userId
-- SAFE: Parameterized query (language-specific)
-- Use prepared statements in ALL cases
Watch for: Dynamic SQL, EXECUTE IMMEDIATE, stored procedures with dynamic queries, privilege grants
When reviewing any language, think like a senior security researcher:
For any language not listed: Research its specific CWE patterns, CVE history, and known footguns. The examples above are entry points, not complete coverage.
The most common false positive: flagging a route handler as "no auth check" when auth is enforced globally in middleware (Next.js middleware.ts, Express app.use, Chi middleware stack, FastAPI dependencies). Read the middleware config before reporting.
return True in the except branch of a permission check is the most critical vulnerability pattern you will see. Auth failure must deny, not grant. This is not a style preference.
Every language has deeper quirks than what is listed (memory model, type system, serialization traps, FFI boundaries, historic CVEs in std lib). For any language you review, apply the deep analysis mindset — do not stop at the top-line examples.
Top 10:2025 reordered and added categories (Supply Chain moved up; Exception Handling is now A10). Citing 2021 rankings gives stale advice. Same applies to ASVS (5.0 is current).
Client-side validation is UX, not security. Every reference to "validated input" in the checklist assumes server-side enforcement. If code only validates in the browser, it is unvalidated.
Prompt injection (ASI01), tool misuse (ASI02), memory poisoning (ASI06) are actively exploited in 2026. When reviewing agent code, apply the ASI checklist — do not treat it as forward-looking only. Indirect prompt injection (via fetched web pages / docs / tool output) is the dominant vector — it bypasses input-sanitization mindsets built for user-typed prompts.
NIST SP 800-63B-4 (final 31-Jul-2025) says passwords SHALL NOT be required to rotate on a schedule. Rotate only on evidence of compromise. Also: no composition rules ("must have a digit"), no password hints, no knowledge-based recovery. If you see "change your password every 90 days" in a fresh design, flag it.
When recommending "add MFA", first ask whether passkeys (WebAuthn) fit. Passkeys are phishing-resistant and AAL2 by themselves (with userVerification). Password + TOTP is still relayable via reverse-proxy phishing kits — it's better than nothing, but not the default recommendation for new builds anymore.
MCP authorization spec (Jun-2025) is not optional theory. Tokens must carry resource indicators (RFC 8707) scoped to the specific MCP server, and DPoP sender-constraining prevents stolen-token replay. "Confused deputy" attacks in MCP proxies are the canonical failure mode.
Harvest-now-decrypt-later means anything encrypted today with RSA / ECDH and stored by an adversary is at risk once a sufficient quantum computer arrives (~2030-2035 mainstream estimate). For new systems handling secrets that must remain confidential past 2035, plan crypto-agility now; for systems already in production, inventory and prioritize. FIPS 203/204/205 are the standards.
A real agent application has BOTH model-boundary risks (LLM Top 10 — prompt injection, output handling, system prompt leakage, RAG poisoning) AND system-level risks (Agentic — tool misuse, privilege abuse, cascading failures). Applying only one list leaves the other surface unreviewed.
Use this skill when:
references/auth-modern.md)references/crypto-modern.md)references/api-cicd.md)references/llm-agentic.md)references/api-cicd.md)references/extras.md)references/extras.md)references/crypto-modern.md)Frequently asked questions
Apply these security standards when writing or reviewing code.
The source record exposes this install command: npx skills add https://github.com/JotJunior/cstk --skill "plugins/cstk/skills/owasp-security". Inspect the command and pinned source before running it.
Static rules flagged read-files, network in the source; the page lists the matching lines and excerpts.
Alternatives
aAAaqwq/AGI-Super-Team
Conduct context-driven code reviews focusing on quality, testability, and maintainability. Use when reviewing code, providing feedback, or establishing review practices.
magnus919/agent-skills
Use this skill to reverse-engineer an existing software system, map its architecture, data flow, privacy posture, coupling, quality characteristics, and feature surface, then produce an evidence-grounded clean-room design document, PRD, or migration plan under new constraints. Use for codebase archaeology, implicit contract extraction, architecture health assessment, or decomposition-readiness analysis. Do not use for greenfield architecture design, direct code review, bug hunting, security audi
alirezarezvani/claude-skills
Adversarial code review that breaks the self-review monoculture. Use when you want a genuinely critical review of recent changes, before merging a PR, or when you suspect Claude is being too agreeable about code quality. Forces perspective shifts through hostile reviewer personas that catch blind spots the author's mental model shares with the reviewer.
Playa-0v0/Cyrene-Agent
Conducts multi-axis code review. Use before merging any change. Use when reviewing code written by yourself, another agent, or a human. Use when you need to assess code quality across multiple dimensions before it enters the main branch.