@qball-inc/the-bulwark 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +43 -0
- package/agents/bulwark-fix-validator.md +633 -0
- package/agents/bulwark-implementer.md +391 -0
- package/agents/bulwark-issue-analyzer.md +308 -0
- package/agents/bulwark-standards-reviewer.md +221 -0
- package/agents/plan-creation-architect.md +323 -0
- package/agents/plan-creation-eng-lead.md +352 -0
- package/agents/plan-creation-po.md +300 -0
- package/agents/plan-creation-qa-critic.md +334 -0
- package/agents/product-ideation-competitive-analyzer.md +298 -0
- package/agents/product-ideation-idea-validator.md +268 -0
- package/agents/product-ideation-market-researcher.md +292 -0
- package/agents/product-ideation-pattern-documenter.md +308 -0
- package/agents/product-ideation-segment-analyzer.md +303 -0
- package/agents/product-ideation-strategist.md +259 -0
- package/agents/statusline-setup.md +97 -0
- package/hooks/hooks.json +59 -0
- package/package.json +45 -0
- package/scripts/hooks/cleanup-stale.sh +13 -0
- package/scripts/hooks/enforce-quality.sh +166 -0
- package/scripts/hooks/implementer-quality.sh +256 -0
- package/scripts/hooks/inject-protocol.sh +52 -0
- package/scripts/hooks/suggest-pipeline.sh +175 -0
- package/scripts/hooks/track-pipeline-start.sh +37 -0
- package/scripts/hooks/track-pipeline-stop.sh +52 -0
- package/scripts/init-rules.sh +35 -0
- package/scripts/init.sh +151 -0
- package/skills/anthropic-validator/SKILL.md +607 -0
- package/skills/anthropic-validator/references/agents-checklist.md +131 -0
- package/skills/anthropic-validator/references/commands-checklist.md +102 -0
- package/skills/anthropic-validator/references/hooks-checklist.md +151 -0
- package/skills/anthropic-validator/references/mcp-checklist.md +136 -0
- package/skills/anthropic-validator/references/plugins-checklist.md +148 -0
- package/skills/anthropic-validator/references/skills-checklist.md +85 -0
- package/skills/assertion-patterns/SKILL.md +296 -0
- package/skills/bug-magnet-data/SKILL.md +284 -0
- package/skills/bug-magnet-data/context/cli-args.md +91 -0
- package/skills/bug-magnet-data/context/db-query.md +104 -0
- package/skills/bug-magnet-data/context/file-contents.md +103 -0
- package/skills/bug-magnet-data/context/http-body.md +91 -0
- package/skills/bug-magnet-data/context/process-spawn.md +123 -0
- package/skills/bug-magnet-data/data/booleans/boundaries.yaml +143 -0
- package/skills/bug-magnet-data/data/collections/arrays.yaml +114 -0
- package/skills/bug-magnet-data/data/collections/objects.yaml +123 -0
- package/skills/bug-magnet-data/data/concurrency/race-conditions.yaml +118 -0
- package/skills/bug-magnet-data/data/concurrency/state-machines.yaml +115 -0
- package/skills/bug-magnet-data/data/dates/boundaries.yaml +137 -0
- package/skills/bug-magnet-data/data/dates/invalid.yaml +132 -0
- package/skills/bug-magnet-data/data/dates/timezone.yaml +118 -0
- package/skills/bug-magnet-data/data/encoding/charset.yaml +79 -0
- package/skills/bug-magnet-data/data/encoding/normalization.yaml +105 -0
- package/skills/bug-magnet-data/data/formats/email.yaml +154 -0
- package/skills/bug-magnet-data/data/formats/json.yaml +187 -0
- package/skills/bug-magnet-data/data/formats/url.yaml +165 -0
- package/skills/bug-magnet-data/data/language-specific/javascript.yaml +182 -0
- package/skills/bug-magnet-data/data/language-specific/python.yaml +174 -0
- package/skills/bug-magnet-data/data/language-specific/rust.yaml +148 -0
- package/skills/bug-magnet-data/data/numbers/boundaries.yaml +161 -0
- package/skills/bug-magnet-data/data/numbers/precision.yaml +89 -0
- package/skills/bug-magnet-data/data/numbers/special.yaml +69 -0
- package/skills/bug-magnet-data/data/strings/boundaries.yaml +109 -0
- package/skills/bug-magnet-data/data/strings/injection.yaml +208 -0
- package/skills/bug-magnet-data/data/strings/special-chars.yaml +190 -0
- package/skills/bug-magnet-data/data/strings/unicode.yaml +139 -0
- package/skills/bug-magnet-data/references/external-lists.md +115 -0
- package/skills/bulwark-brainstorm/SKILL.md +563 -0
- package/skills/bulwark-brainstorm/references/at-teammate-prompts.md +60 -0
- package/skills/bulwark-brainstorm/references/role-critical-analyst.md +78 -0
- package/skills/bulwark-brainstorm/references/role-development-lead.md +66 -0
- package/skills/bulwark-brainstorm/references/role-product-delivery-lead.md +79 -0
- package/skills/bulwark-brainstorm/references/role-product-manager.md +62 -0
- package/skills/bulwark-brainstorm/references/role-project-sme.md +59 -0
- package/skills/bulwark-brainstorm/references/role-technical-architect.md +66 -0
- package/skills/bulwark-research/SKILL.md +298 -0
- package/skills/bulwark-research/references/viewpoint-contrarian.md +63 -0
- package/skills/bulwark-research/references/viewpoint-direct-investigation.md +62 -0
- package/skills/bulwark-research/references/viewpoint-first-principles.md +65 -0
- package/skills/bulwark-research/references/viewpoint-practitioner.md +62 -0
- package/skills/bulwark-research/references/viewpoint-prior-art.md +66 -0
- package/skills/bulwark-scaffold/SKILL.md +330 -0
- package/skills/bulwark-statusline/SKILL.md +161 -0
- package/skills/bulwark-statusline/scripts/statusline.sh +144 -0
- package/skills/bulwark-verify/SKILL.md +519 -0
- package/skills/code-review/SKILL.md +428 -0
- package/skills/code-review/examples/anti-patterns/linting.ts +181 -0
- package/skills/code-review/examples/anti-patterns/security.ts +91 -0
- package/skills/code-review/examples/anti-patterns/standards.ts +195 -0
- package/skills/code-review/examples/anti-patterns/type-safety.ts +108 -0
- package/skills/code-review/examples/recommended/linting.ts +195 -0
- package/skills/code-review/examples/recommended/security.ts +154 -0
- package/skills/code-review/examples/recommended/standards.ts +231 -0
- package/skills/code-review/examples/recommended/type-safety.ts +181 -0
- package/skills/code-review/frameworks/angular.md +218 -0
- package/skills/code-review/frameworks/django.md +235 -0
- package/skills/code-review/frameworks/express.md +207 -0
- package/skills/code-review/frameworks/flask.md +298 -0
- package/skills/code-review/frameworks/generic.md +146 -0
- package/skills/code-review/frameworks/react.md +152 -0
- package/skills/code-review/frameworks/vue.md +244 -0
- package/skills/code-review/references/linting-patterns.md +221 -0
- package/skills/code-review/references/security-patterns.md +125 -0
- package/skills/code-review/references/standards-patterns.md +246 -0
- package/skills/code-review/references/type-safety-patterns.md +130 -0
- package/skills/component-patterns/SKILL.md +131 -0
- package/skills/component-patterns/references/pattern-cli-command.md +118 -0
- package/skills/component-patterns/references/pattern-database.md +166 -0
- package/skills/component-patterns/references/pattern-external-api.md +139 -0
- package/skills/component-patterns/references/pattern-file-parser.md +168 -0
- package/skills/component-patterns/references/pattern-http-server.md +162 -0
- package/skills/component-patterns/references/pattern-process-spawner.md +133 -0
- package/skills/continuous-feedback/SKILL.md +327 -0
- package/skills/continuous-feedback/references/collect-instructions.md +81 -0
- package/skills/continuous-feedback/references/specialize-code-review.md +82 -0
- package/skills/continuous-feedback/references/specialize-general.md +98 -0
- package/skills/continuous-feedback/references/specialize-test-audit.md +81 -0
- package/skills/create-skill/SKILL.md +359 -0
- package/skills/create-skill/references/agent-conventions.md +194 -0
- package/skills/create-skill/references/agent-template.md +195 -0
- package/skills/create-skill/references/content-guidance.md +291 -0
- package/skills/create-skill/references/decision-framework.md +124 -0
- package/skills/create-skill/references/template-pipeline.md +217 -0
- package/skills/create-skill/references/template-reference-heavy.md +111 -0
- package/skills/create-skill/references/template-research.md +210 -0
- package/skills/create-skill/references/template-script-driven.md +172 -0
- package/skills/create-skill/references/template-simple.md +80 -0
- package/skills/create-subagent/SKILL.md +353 -0
- package/skills/create-subagent/references/agent-conventions.md +268 -0
- package/skills/create-subagent/references/content-guidance.md +232 -0
- package/skills/create-subagent/references/decision-framework.md +134 -0
- package/skills/create-subagent/references/template-single-agent.md +192 -0
- package/skills/fix-bug/SKILL.md +241 -0
- package/skills/governance-protocol/SKILL.md +116 -0
- package/skills/init/SKILL.md +341 -0
- package/skills/issue-debugging/SKILL.md +385 -0
- package/skills/issue-debugging/references/anti-patterns.md +245 -0
- package/skills/issue-debugging/references/debug-report-schema.md +227 -0
- package/skills/mock-detection/SKILL.md +511 -0
- package/skills/mock-detection/references/false-positive-prevention.md +402 -0
- package/skills/mock-detection/references/stub-patterns.md +236 -0
- package/skills/pipeline-templates/SKILL.md +215 -0
- package/skills/pipeline-templates/references/code-change-workflow.md +277 -0
- package/skills/pipeline-templates/references/code-review.md +336 -0
- package/skills/pipeline-templates/references/fix-validation.md +421 -0
- package/skills/pipeline-templates/references/new-feature.md +335 -0
- package/skills/pipeline-templates/references/research-brainstorm.md +161 -0
- package/skills/pipeline-templates/references/research-planning.md +257 -0
- package/skills/pipeline-templates/references/test-audit.md +389 -0
- package/skills/pipeline-templates/references/test-execution-fix.md +238 -0
- package/skills/plan-creation/SKILL.md +497 -0
- package/skills/product-ideation/SKILL.md +372 -0
- package/skills/product-ideation/references/analysis-frameworks.md +161 -0
- package/skills/session-handoff/SKILL.md +139 -0
- package/skills/session-handoff/references/examples.md +223 -0
- package/skills/setup-lsp/SKILL.md +312 -0
- package/skills/setup-lsp/references/server-registry.md +85 -0
- package/skills/setup-lsp/references/troubleshooting.md +135 -0
- package/skills/subagent-output-templating/SKILL.md +415 -0
- package/skills/subagent-output-templating/references/examples.md +440 -0
- package/skills/subagent-prompting/SKILL.md +364 -0
- package/skills/subagent-prompting/references/examples.md +342 -0
- package/skills/test-audit/SKILL.md +531 -0
- package/skills/test-audit/references/known-limitations.md +41 -0
- package/skills/test-audit/references/priority-classification.md +30 -0
- package/skills/test-audit/references/prompts/deep-mode-detection.md +83 -0
- package/skills/test-audit/references/prompts/synthesis.md +57 -0
- package/skills/test-audit/references/rewrite-instructions.md +46 -0
- package/skills/test-audit/references/schemas/audit-output.yaml +100 -0
- package/skills/test-audit/references/schemas/diagnostic-output.yaml +49 -0
- package/skills/test-audit/scripts/data-flow-analyzer.ts +509 -0
- package/skills/test-audit/scripts/integration-mock-detector.ts +462 -0
- package/skills/test-audit/scripts/package.json +20 -0
- package/skills/test-audit/scripts/skip-detector.ts +211 -0
- package/skills/test-audit/scripts/verification-counter.ts +295 -0
- package/skills/test-classification/SKILL.md +310 -0
- package/skills/test-fixture-creation/SKILL.md +295 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Vue Framework Patterns
|
|
2
|
+
|
|
3
|
+
Security and quality patterns specific to Vue.js applications.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Security Patterns
|
|
8
|
+
|
|
9
|
+
### XSS Prevention
|
|
10
|
+
|
|
11
|
+
| Pattern | Risk | Detection |
|
|
12
|
+
|---------|------|-----------|
|
|
13
|
+
| `v-html` directive | High | `v-html="userInput"` |
|
|
14
|
+
| Dynamic component rendering | Medium | `:is="userComponent"` |
|
|
15
|
+
| Template compilation | Critical | `Vue.compile(userTemplate)` |
|
|
16
|
+
|
|
17
|
+
**Safe Pattern:**
|
|
18
|
+
```vue
|
|
19
|
+
<!-- BAD -->
|
|
20
|
+
<div v-html="userComment"></div>
|
|
21
|
+
|
|
22
|
+
<!-- GOOD - Vue escapes by default -->
|
|
23
|
+
<div>{{ userComment }}</div>
|
|
24
|
+
|
|
25
|
+
<!-- If HTML needed, sanitize first -->
|
|
26
|
+
<script setup>
|
|
27
|
+
import DOMPurify from 'dompurify';
|
|
28
|
+
|
|
29
|
+
const sanitizedHtml = computed(() =>
|
|
30
|
+
DOMPurify.sanitize(props.htmlContent)
|
|
31
|
+
);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<div v-html="sanitizedHtml"></div>
|
|
36
|
+
</template>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### URL Safety
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<!-- BAD -->
|
|
43
|
+
<a :href="userUrl">Link</a>
|
|
44
|
+
|
|
45
|
+
<!-- GOOD -->
|
|
46
|
+
<script setup>
|
|
47
|
+
const safeUrl = computed(() => {
|
|
48
|
+
try {
|
|
49
|
+
const url = new URL(props.userUrl);
|
|
50
|
+
if (['http:', 'https:'].includes(url.protocol)) {
|
|
51
|
+
return props.userUrl;
|
|
52
|
+
}
|
|
53
|
+
} catch {}
|
|
54
|
+
return '#';
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<template>
|
|
59
|
+
<a :href="safeUrl">Link</a>
|
|
60
|
+
</template>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Dynamic Components
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<!-- BAD - User can inject any component -->
|
|
67
|
+
<component :is="userSelectedComponent" />
|
|
68
|
+
|
|
69
|
+
<!-- GOOD - Allowlist of components -->
|
|
70
|
+
<script setup>
|
|
71
|
+
const allowedComponents = {
|
|
72
|
+
'profile': ProfileComponent,
|
|
73
|
+
'settings': SettingsComponent
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const safeComponent = computed(() =>
|
|
77
|
+
allowedComponents[props.componentName] || DefaultComponent
|
|
78
|
+
);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<component :is="safeComponent" />
|
|
83
|
+
</template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Type Safety Patterns
|
|
89
|
+
|
|
90
|
+
### Props Typing (Vue 3 + TypeScript)
|
|
91
|
+
|
|
92
|
+
```vue
|
|
93
|
+
<!-- BAD -->
|
|
94
|
+
<script setup>
|
|
95
|
+
const props = defineProps(['title', 'count']);
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<!-- GOOD -->
|
|
99
|
+
<script setup lang="ts">
|
|
100
|
+
interface Props {
|
|
101
|
+
title: string;
|
|
102
|
+
count: number;
|
|
103
|
+
optional?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const props = defineProps<Props>();
|
|
107
|
+
</script>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Emits Typing
|
|
111
|
+
|
|
112
|
+
```vue
|
|
113
|
+
<!-- BAD -->
|
|
114
|
+
<script setup>
|
|
115
|
+
const emit = defineEmits(['update', 'delete']);
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<!-- GOOD -->
|
|
119
|
+
<script setup lang="ts">
|
|
120
|
+
interface Emits {
|
|
121
|
+
(e: 'update', value: string): void;
|
|
122
|
+
(e: 'delete', id: number): void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const emit = defineEmits<Emits>();
|
|
126
|
+
</script>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Ref Typing
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// BAD
|
|
133
|
+
const count = ref(0); // Ref<number> inferred but not explicit
|
|
134
|
+
const user = ref(null); // Ref<null>
|
|
135
|
+
|
|
136
|
+
// GOOD
|
|
137
|
+
const count = ref<number>(0);
|
|
138
|
+
const user = ref<User | null>(null);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Composable Return Types
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// BAD
|
|
145
|
+
function useUser() {
|
|
146
|
+
const user = ref(null);
|
|
147
|
+
return { user };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// GOOD
|
|
151
|
+
interface UseUserReturn {
|
|
152
|
+
user: Ref<User | null>;
|
|
153
|
+
loading: Ref<boolean>;
|
|
154
|
+
error: Ref<string | null>;
|
|
155
|
+
fetchUser: (id: string) => Promise<void>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function useUser(): UseUserReturn {
|
|
159
|
+
const user = ref<User | null>(null);
|
|
160
|
+
const loading = ref(false);
|
|
161
|
+
const error = ref<string | null>(null);
|
|
162
|
+
|
|
163
|
+
async function fetchUser(id: string) {
|
|
164
|
+
// ...
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return { user, loading, error, fetchUser };
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Linting Patterns
|
|
174
|
+
|
|
175
|
+
### Component Size
|
|
176
|
+
|
|
177
|
+
| Metric | Threshold | Action |
|
|
178
|
+
|--------|-----------|--------|
|
|
179
|
+
| Template lines | >100 | Extract child components |
|
|
180
|
+
| Script lines | >200 | Extract composables |
|
|
181
|
+
| Props count | >7 | Consider refactoring |
|
|
182
|
+
|
|
183
|
+
### Reactivity
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// BAD - Reactivity lost
|
|
187
|
+
const { user } = toRefs(props);
|
|
188
|
+
const name = user.value.name; // Not reactive
|
|
189
|
+
|
|
190
|
+
// GOOD
|
|
191
|
+
const { user } = toRefs(props);
|
|
192
|
+
const name = computed(() => user.value.name);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Memory Management
|
|
196
|
+
|
|
197
|
+
```vue
|
|
198
|
+
<script setup>
|
|
199
|
+
import { onUnmounted } from 'vue';
|
|
200
|
+
|
|
201
|
+
// Clean up subscriptions
|
|
202
|
+
const unsubscribe = store.subscribe((mutation) => {});
|
|
203
|
+
onUnmounted(() => unsubscribe());
|
|
204
|
+
|
|
205
|
+
// Clean up intervals/timeouts
|
|
206
|
+
const interval = setInterval(() => {}, 1000);
|
|
207
|
+
onUnmounted(() => clearInterval(interval));
|
|
208
|
+
</script>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Coding Standards
|
|
214
|
+
|
|
215
|
+
### Naming Conventions
|
|
216
|
+
|
|
217
|
+
| Element | Convention | Example |
|
|
218
|
+
|---------|------------|---------|
|
|
219
|
+
| Component | PascalCase | `UserProfile.vue` |
|
|
220
|
+
| Composable | camelCase with `use` prefix | `useUserProfile` |
|
|
221
|
+
| Props | camelCase | `userName` |
|
|
222
|
+
| Events | kebab-case | `@update-user` |
|
|
223
|
+
|
|
224
|
+
### File Organization
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
components/
|
|
228
|
+
UserProfile/
|
|
229
|
+
UserProfile.vue
|
|
230
|
+
UserProfileHeader.vue
|
|
231
|
+
UserProfileStats.vue
|
|
232
|
+
composables/
|
|
233
|
+
useUser.ts
|
|
234
|
+
useAuth.ts
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## What to Skip
|
|
240
|
+
|
|
241
|
+
- Vite/Vue CLI configuration
|
|
242
|
+
- Pinia/Vuex store boilerplate
|
|
243
|
+
- Router configuration
|
|
244
|
+
- Test utility setup
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Linting Patterns Reference
|
|
2
|
+
|
|
3
|
+
Patterns for the Linting section of code-review skill.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Complexity Patterns
|
|
8
|
+
|
|
9
|
+
### Cyclomatic Complexity
|
|
10
|
+
|
|
11
|
+
| Level | Threshold | Severity | Guidance |
|
|
12
|
+
|-------|-----------|----------|----------|
|
|
13
|
+
| Low | 1-10 | OK | Simple, testable |
|
|
14
|
+
| Moderate | 11-20 | Suggestion | Consider refactoring |
|
|
15
|
+
| High | 21-50 | Important | Should refactor |
|
|
16
|
+
| Very High | 50+ | Important | Must refactor |
|
|
17
|
+
|
|
18
|
+
**Detection:**
|
|
19
|
+
- Count decision points: if, else, case, &&, ||, ?:, catch
|
|
20
|
+
- Each decision point adds 1 to complexity
|
|
21
|
+
- Nested conditions multiply cognitive load
|
|
22
|
+
|
|
23
|
+
### Nesting Depth
|
|
24
|
+
|
|
25
|
+
| Level | Threshold | Severity |
|
|
26
|
+
|-------|-----------|----------|
|
|
27
|
+
| Acceptable | 1-3 levels | OK |
|
|
28
|
+
| Warning | 4 levels | Suggestion |
|
|
29
|
+
| Problem | 5+ levels | Important |
|
|
30
|
+
|
|
31
|
+
**Detection:**
|
|
32
|
+
```typescript
|
|
33
|
+
// 5 levels of nesting - IMPORTANT
|
|
34
|
+
if (a) {
|
|
35
|
+
if (b) {
|
|
36
|
+
for (const x of items) {
|
|
37
|
+
if (x.valid) {
|
|
38
|
+
try {
|
|
39
|
+
// deeply nested logic
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Remediation:**
|
|
48
|
+
- Early returns to flatten conditionals
|
|
49
|
+
- Extract to helper functions
|
|
50
|
+
- Use guard clauses
|
|
51
|
+
|
|
52
|
+
### Function Length
|
|
53
|
+
|
|
54
|
+
| Lines | Severity | Guidance |
|
|
55
|
+
|-------|----------|----------|
|
|
56
|
+
| <25 | OK | Ideal |
|
|
57
|
+
| 25-50 | Suggestion | Consider splitting |
|
|
58
|
+
| 50-100 | Important | Should split |
|
|
59
|
+
| 100+ | Important | Must split |
|
|
60
|
+
|
|
61
|
+
**Exceptions:**
|
|
62
|
+
- Configuration objects/arrays (long but simple)
|
|
63
|
+
- Generated code
|
|
64
|
+
- Test setup with many assertions
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Naming Patterns
|
|
69
|
+
|
|
70
|
+
### Generic Names (Avoid)
|
|
71
|
+
|
|
72
|
+
| Pattern | Example | Problem |
|
|
73
|
+
|---------|---------|---------|
|
|
74
|
+
| Single letter | `d`, `x`, `t` | No semantic meaning |
|
|
75
|
+
| Generic nouns | `data`, `info`, `temp`, `result` | Doesn't describe content |
|
|
76
|
+
| Type-as-name | `string`, `array`, `object` | Redundant with type system |
|
|
77
|
+
| Abbreviated | `usr`, `cfg`, `mgr` | Reduces readability |
|
|
78
|
+
|
|
79
|
+
**Exceptions:**
|
|
80
|
+
- Loop indices: `i`, `j`, `k` are acceptable
|
|
81
|
+
- Lambda parameters: `x => x * 2` for simple transforms
|
|
82
|
+
- Coordinates: `x`, `y`, `z` for geometry
|
|
83
|
+
|
|
84
|
+
### Misleading Names
|
|
85
|
+
|
|
86
|
+
| Pattern | Example | Problem |
|
|
87
|
+
|---------|---------|---------|
|
|
88
|
+
| Wrong plurality | `user` for array, `users` for single | Confuses data shape |
|
|
89
|
+
| Wrong type hint | `isValid` returning non-boolean | Breaks expectations |
|
|
90
|
+
| Outdated name | `tempFix` that's been permanent | Misleading history |
|
|
91
|
+
| Wrong scope | `globalUser` that's local | Suggests wrong lifetime |
|
|
92
|
+
|
|
93
|
+
### Good Naming
|
|
94
|
+
|
|
95
|
+
| Context | Pattern | Example |
|
|
96
|
+
|---------|---------|---------|
|
|
97
|
+
| Boolean | `is`, `has`, `can`, `should` prefix | `isActive`, `hasPermission` |
|
|
98
|
+
| Function | Verb phrase | `calculateTotal`, `fetchUser` |
|
|
99
|
+
| Handler | `handle` or `on` prefix | `handleClick`, `onSubmit` |
|
|
100
|
+
| Collection | Plural noun | `users`, `orderItems` |
|
|
101
|
+
| Singular | Singular noun | `user`, `currentOrder` |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Structure Patterns
|
|
106
|
+
|
|
107
|
+
### God Function
|
|
108
|
+
|
|
109
|
+
A function that does too many things.
|
|
110
|
+
|
|
111
|
+
**Indicators:**
|
|
112
|
+
- Multiple unrelated operations
|
|
113
|
+
- Comments separating "phases"
|
|
114
|
+
- Many parameters (>5)
|
|
115
|
+
- Mixed abstraction levels
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
```typescript
|
|
119
|
+
// GOD FUNCTION - does validation, transformation, persistence, notification
|
|
120
|
+
async function processOrder(order: Order) {
|
|
121
|
+
// Validate
|
|
122
|
+
if (!order.items.length) throw new Error('Empty order');
|
|
123
|
+
if (!order.customer) throw new Error('No customer');
|
|
124
|
+
|
|
125
|
+
// Calculate totals
|
|
126
|
+
const subtotal = order.items.reduce((sum, i) => sum + i.price, 0);
|
|
127
|
+
const tax = subtotal * 0.1;
|
|
128
|
+
const total = subtotal + tax;
|
|
129
|
+
|
|
130
|
+
// Save to database
|
|
131
|
+
await db.orders.insert({ ...order, total });
|
|
132
|
+
|
|
133
|
+
// Send notifications
|
|
134
|
+
await email.send(order.customer.email, 'Order confirmed');
|
|
135
|
+
await slack.notify('#orders', `New order: ${order.id}`);
|
|
136
|
+
|
|
137
|
+
return { success: true };
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Remediation:** Extract to `validateOrder`, `calculateTotals`, `saveOrder`, `notifyOrder`.
|
|
142
|
+
|
|
143
|
+
### Mixed Concerns
|
|
144
|
+
|
|
145
|
+
| Pattern | Example | Problem |
|
|
146
|
+
|---------|---------|---------|
|
|
147
|
+
| UI logic in data layer | Formatting in repository | Coupling |
|
|
148
|
+
| Business logic in controller | Validation in route handler | Testability |
|
|
149
|
+
| Side effects in pure function | Logging in calculator | Unpredictability |
|
|
150
|
+
|
|
151
|
+
### Duplicate Code
|
|
152
|
+
|
|
153
|
+
**Detection:**
|
|
154
|
+
- Near-identical blocks (>10 lines)
|
|
155
|
+
- Copy-paste with minor modifications
|
|
156
|
+
- Same pattern repeated 3+ times
|
|
157
|
+
|
|
158
|
+
**Severity:** Suggestion (unless bugs have diverged)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Control Flow
|
|
163
|
+
|
|
164
|
+
### Early Return Missing
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// BEFORE: Deep nesting
|
|
168
|
+
function process(user: User) {
|
|
169
|
+
if (user) {
|
|
170
|
+
if (user.active) {
|
|
171
|
+
if (user.verified) {
|
|
172
|
+
return doWork(user);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// AFTER: Guard clauses
|
|
180
|
+
function process(user: User) {
|
|
181
|
+
if (!user) return null;
|
|
182
|
+
if (!user.active) return null;
|
|
183
|
+
if (!user.verified) return null;
|
|
184
|
+
return doWork(user);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Complex Conditionals
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// BEFORE: Hard to understand
|
|
192
|
+
if (user.role === 'admin' || (user.role === 'manager' && user.department === 'sales') || user.permissions.includes('override')) {
|
|
193
|
+
// ...
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// AFTER: Named condition
|
|
197
|
+
const canAccess = isAdmin(user) || isSalesManager(user) || hasOverride(user);
|
|
198
|
+
if (canAccess) {
|
|
199
|
+
// ...
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Detection Priority
|
|
206
|
+
|
|
207
|
+
1. **Nesting depth**: Visual inspection, count indent levels
|
|
208
|
+
2. **Function length**: Line count
|
|
209
|
+
3. **Generic names**: Pattern matching on common words
|
|
210
|
+
4. **Complex conditionals**: Count operators in single expression
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## False Positive Prevention
|
|
215
|
+
|
|
216
|
+
**Skip these patterns:**
|
|
217
|
+
- Intentionally complex algorithms with explanatory comments
|
|
218
|
+
- Generated code (migrations, schemas)
|
|
219
|
+
- Configuration objects with many properties
|
|
220
|
+
- Test files with verbose setup
|
|
221
|
+
- Legacy code with explicit TODO/FIXME markers
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Security Patterns Reference
|
|
2
|
+
|
|
3
|
+
Patterns for the Security section of code-review skill.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## OWASP Top 10 (2021) Checklist
|
|
8
|
+
|
|
9
|
+
### A01:2021 - Broken Access Control
|
|
10
|
+
|
|
11
|
+
| Pattern | Detection Criteria | Severity |
|
|
12
|
+
|---------|-------------------|----------|
|
|
13
|
+
| Missing authorization check | Route/function accesses resource without verifying user permissions | Critical |
|
|
14
|
+
| IDOR vulnerability | User-supplied ID used directly to fetch resources without ownership check | Critical |
|
|
15
|
+
| Path traversal | User input in file paths without sanitization (`../` patterns) | Critical |
|
|
16
|
+
| CORS misconfiguration | `Access-Control-Allow-Origin: *` with credentials | Important |
|
|
17
|
+
|
|
18
|
+
**Detection Approach:**
|
|
19
|
+
- Look for database queries/file access without preceding auth check
|
|
20
|
+
- Check if user-supplied IDs are validated against session user
|
|
21
|
+
- Verify CORS headers in response configuration
|
|
22
|
+
|
|
23
|
+
### A02:2021 - Cryptographic Failures
|
|
24
|
+
|
|
25
|
+
| Pattern | Detection Criteria | Severity |
|
|
26
|
+
|---------|-------------------|----------|
|
|
27
|
+
| Hardcoded secrets | API keys, passwords, tokens in source code | Critical |
|
|
28
|
+
| Weak hashing | MD5, SHA1 for passwords | Critical |
|
|
29
|
+
| Missing encryption | Sensitive data stored/transmitted in plaintext | Critical |
|
|
30
|
+
| Insecure random | `Math.random()` for security-sensitive operations | Important |
|
|
31
|
+
|
|
32
|
+
**Detection Approach:**
|
|
33
|
+
- Regex for common secret patterns (API_KEY, PASSWORD, SECRET)
|
|
34
|
+
- Check crypto library usage (bcrypt vs md5)
|
|
35
|
+
- Verify TLS usage for sensitive data
|
|
36
|
+
|
|
37
|
+
### A03:2021 - Injection
|
|
38
|
+
|
|
39
|
+
| Pattern | Detection Criteria | Severity |
|
|
40
|
+
|---------|-------------------|----------|
|
|
41
|
+
| SQL injection | String concatenation in SQL queries | Critical |
|
|
42
|
+
| NoSQL injection | User input in MongoDB queries without sanitization | Critical |
|
|
43
|
+
| Command injection | User input in exec/spawn without escaping | Critical |
|
|
44
|
+
| XSS | User input rendered without escaping | Critical |
|
|
45
|
+
| Template injection | User input in template strings | Important |
|
|
46
|
+
|
|
47
|
+
**Detection Approach:**
|
|
48
|
+
- Trace user input (req.query, req.body, req.params) to dangerous sinks
|
|
49
|
+
- Check for parameterized queries vs string concatenation
|
|
50
|
+
- Verify output encoding in templates
|
|
51
|
+
|
|
52
|
+
### A04:2021 - Insecure Design
|
|
53
|
+
|
|
54
|
+
| Pattern | Detection Criteria | Severity |
|
|
55
|
+
|---------|-------------------|----------|
|
|
56
|
+
| Missing rate limiting | Auth endpoints without throttling | Important |
|
|
57
|
+
| No account lockout | Unlimited login attempts | Important |
|
|
58
|
+
| Predictable tokens | Sequential/timestamp-based tokens | Critical |
|
|
59
|
+
|
|
60
|
+
### A05:2021 - Security Misconfiguration
|
|
61
|
+
|
|
62
|
+
| Pattern | Detection Criteria | Severity |
|
|
63
|
+
|---------|-------------------|----------|
|
|
64
|
+
| Debug mode in production | DEBUG=true, verbose error messages | Important |
|
|
65
|
+
| Default credentials | admin/admin, test/test in code | Critical |
|
|
66
|
+
| Unnecessary features | Unused endpoints exposed | Suggestion |
|
|
67
|
+
|
|
68
|
+
### A06:2021 - Vulnerable Components
|
|
69
|
+
|
|
70
|
+
| Pattern | Detection Criteria | Severity |
|
|
71
|
+
|---------|-------------------|----------|
|
|
72
|
+
| Known vulnerable packages | Outdated dependencies with CVEs | Varies |
|
|
73
|
+
| Unmaintained dependencies | No updates in 2+ years | Suggestion |
|
|
74
|
+
|
|
75
|
+
**Note:** Defer to `npm audit` / `pip-audit` for detailed analysis.
|
|
76
|
+
|
|
77
|
+
### A07:2021 - Auth Failures
|
|
78
|
+
|
|
79
|
+
| Pattern | Detection Criteria | Severity |
|
|
80
|
+
|---------|-------------------|----------|
|
|
81
|
+
| Session fixation | Session ID not regenerated after login | Critical |
|
|
82
|
+
| Weak password policy | No length/complexity requirements | Important |
|
|
83
|
+
| Missing MFA | Sensitive operations without 2FA | Suggestion |
|
|
84
|
+
|
|
85
|
+
### A08:2021 - Data Integrity Failures
|
|
86
|
+
|
|
87
|
+
| Pattern | Detection Criteria | Severity |
|
|
88
|
+
|---------|-------------------|----------|
|
|
89
|
+
| Unsigned data | CI/CD pipelines without artifact verification | Important |
|
|
90
|
+
| Insecure deserialization | Deserializing untrusted data | Critical |
|
|
91
|
+
|
|
92
|
+
### A09:2021 - Logging Failures
|
|
93
|
+
|
|
94
|
+
| Pattern | Detection Criteria | Severity |
|
|
95
|
+
|---------|-------------------|----------|
|
|
96
|
+
| Sensitive data in logs | Passwords, tokens logged | Critical |
|
|
97
|
+
| Missing audit logs | No logging for security events | Important |
|
|
98
|
+
| Log injection | User input in log messages without sanitization | Important |
|
|
99
|
+
|
|
100
|
+
### A10:2021 - SSRF
|
|
101
|
+
|
|
102
|
+
| Pattern | Detection Criteria | Severity |
|
|
103
|
+
|---------|-------------------|----------|
|
|
104
|
+
| Unvalidated URL fetch | User-supplied URL in fetch/axios without allowlist | Critical |
|
|
105
|
+
| Internal network access | User-controlled URLs that could access internal services | Critical |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Detection Priority
|
|
110
|
+
|
|
111
|
+
1. **Trace user input**: req.query, req.body, req.params, URL params
|
|
112
|
+
2. **Identify dangerous sinks**: db.query, exec, eval, innerHTML, render
|
|
113
|
+
3. **Check for sanitization**: Between source and sink
|
|
114
|
+
4. **Verify context**: Is this test code? Is there upstream validation?
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## False Positive Prevention
|
|
119
|
+
|
|
120
|
+
**Skip these patterns:**
|
|
121
|
+
- Parameterized queries (even with nearby concatenation)
|
|
122
|
+
- Test fixtures with intentional vulnerabilities
|
|
123
|
+
- Comments containing example code
|
|
124
|
+
- Sanitization applied before dangerous sink
|
|
125
|
+
- Internal-only endpoints with network-level protection
|