# Oc Security Audit

> Pre-launch security audit for web apps. Runs OWASP checks via shell scripts, then AI analyzes findings. Covers rate limiting, hosting bypass, data exposure, headers, session security, AI risks. Complements /security-review.

- Skill: `miclivne/oc-security-audit` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add miclivne/oc-security-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/miclivne/oc-security-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: miclivne (https://skillmd.com/u/miclivne)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/miclivne/oc-security-audit

---


You are running the OC Security Audit — a pre-launch security check for web applications.

Before each step, print a short status line so the user knows what's happening. Use this format:

**`[Step N/6]` Description — brief detail**

## Step 1: Discover

Print: **`[Step 1/6]` Detecting your stack — framework, ORM, auth, routes, domain...**

Run the discovery script:

```bash
bash ${CLAUDE_SKILL_DIR}/scripts/discover.sh
```

Extract from the output:
- `PROFILE`, `SRC_ROOT`, `PROJECT_ROOT`, `DOMAIN`, `HOSTING`, `FRAMEWORK`, `ORM`
- All `ROUTE:` lines (route inventory)
- All feature flags: `FILE_UPLOADS`, `AI_SDK`, `PAYMENTS`, `WEBSOCKETS` (format: `KEY: value`)

After discovery completes, print: **`[Step 1/6]` Done — detected {FRAMEWORK} + {ORM}, {ROUTE_COUNT} routes, domain: {DOMAIN}**

If `DOMAIN` is `unknown`, ask the user: "What is your production domain? (e.g. myapp.com)"
If `PROFILE` is `unsupported`, tell the user that only stack-independent checks will run.

## Step 2: Select tests

If `PROFILE` is `unsupported`, skip reading the profile file. Instead print:

**`[Step 2/6]` Profile: unsupported — only stack-independent checks will run**
✅ Will check: security headers, TLS, exposed files, DNS, npm audit, secrets, Docker config
⚠️ Won't check: auth per route, rate limiting, code injection escape hatches, session config, LLM judgments
ℹ️ Want full coverage? Open an issue to request your stack: https://github.com/miclivne/oc-security-audit/issues

Then skip Step 4 (LLM judgment calls) — there is no profile to read judgment calls from.

If `PROFILE` is NOT `unsupported`, proceed normally:

Print: **`[Step 2/6]` Selecting tests for {PROFILE} profile...**

Read `profiles/{PROFILE}.md` and count the decisions:
- Count rows with `RUN (script)` + `RUN (escape-hatch)` + `RUN (conditional)` → these will execute
- Count rows with `RUN (llm)` → these are LLM judgment calls
- Count rows with `SKIP` → not applicable to this stack
- Count rows with `DEFER` → need deeper code review

Print the selection summary:

**`[Step 2/6]` Profile has {TOTAL} OWASP test cases:**
- **{RUN_SCRIPT} test types selected** (automated script checks — some test multiple targets, e.g., rate limiting checks each route)
- **{RUN_LLM} judgment calls** (LLM reads code to assess)
- **{SKIP} skipped** (not applicable — e.g., OAuth-only means no password tests)
- **{DEFER} deferred** (need deeper code analysis — run `/security-review`)

## Step 3: Scan

Print: **`[Step 3/6]` Running {RUN_SCRIPT} security checks — headers, auth, rate limiting, secrets, DNS...**

Extract feature flags from discovery output, then run scan.sh with ALL values.

```bash
OC_FILE_UPLOADS=$(echo "$DISCOVERY" | grep "^FILE_UPLOADS:" | awk '{print $2}')
OC_AI_SDK=$(echo "$DISCOVERY" | grep "^AI_SDK:" | awk '{print $2}')
OC_PAYMENTS=$(echo "$DISCOVERY" | grep "^PAYMENTS:" | awk '{print $2}')
OC_WEBSOCKETS=$(echo "$DISCOVERY" | grep "^WEBSOCKETS:" | awk '{print $2}')
```

Then invoke (use `$HOME`, NOT `~` — tilde is not expanded in subshells):

```bash
OC_PROFILE={profile} OC_SRC_ROOT={src_root} OC_PROJECT_ROOT={project_root} OC_DOMAIN={domain} OC_HOSTING={hosting} OC_FRAMEWORK={framework} OC_ORM={orm} OC_FILE_UPLOADS=$OC_FILE_UPLOADS OC_AI_SDK=$OC_AI_SDK OC_PAYMENTS=$OC_PAYMENTS OC_WEBSOCKETS=$OC_WEBSOCKETS bash ${CLAUDE_SKILL_DIR}/scripts/scan.sh
```

After scan completes, print: **`[Step 3/6]` Done — {TOTAL} individual checks run across {RUN_SCRIPT} test types ({PASS} pass, {WARN} warn, {FAIL} fail)**

## Step 4: Analyze

If `PROFILE` is `unsupported`, skip this step entirely. Print:
**`[Step 4/6]` Skipped — no profile-specific judgment calls for unsupported stacks**

Otherwise:

Print: **`[Step 4/6]` Reading code for judgment calls — IDOR, privilege escalation, data exposure...**

Read `profiles/{PROFILE}.md`, section `## LLM judgment calls`.
For each JUDGMENT-N: read ONLY the files listed, answer ONLY the questions asked. Do not explore broadly.

Do NOT print the judgment results here — they go into the report (PASS results in "What's secure", WARN results as issue blocks in "What needs attention"). Just print the step completion:

After analysis, print: **`[Step 4/6]` Done — {N} judgment calls completed**

## Step 5: Report

Print: **`[Step 5/6]` Writing the report...**

Read `templates/report.md` for the full report structure and instructions.
Key rules:
- Present report directly in conversation, NOT to a file
- Lead with the positive — "What's secure" comes first
- Group related findings into single issues (e.g., 9 rate limiting WARNs = 1 issue)
- Issues are grouped under their category — the user reads: category → issues → details
- Each issue uses the 7-section format from `templates/issue-format.md`
- "What could go wrong when fixing" is the most important section — must name a specific risk

## Step 6: Close

Print: **`[Step 6/6]` Wrapping up...**

1. Remind: "For deep code vulnerability analysis, also run `/security-review`."
2. Ask if the user wants the report saved to a file.

