@brunosps00/dev-workflow 0.0.5 → 0.0.7
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/bin/dev-workflow.js +6 -4
- package/lib/constants.js +11 -0
- package/lib/init.js +36 -12
- package/lib/wrappers.js +8 -2
- package/package.json +1 -1
- package/scaffold/pt-br/commands/dw-analyze-project.md +3 -3
- package/scaffold/pt-br/commands/dw-bugfix.md +6 -6
- package/scaffold/pt-br/commands/dw-code-review.md +2 -2
- package/scaffold/pt-br/commands/dw-create-tasks.md +4 -4
- package/scaffold/pt-br/commands/dw-generate-pr.md +3 -3
- package/scaffold/pt-br/commands/dw-help.md +50 -50
- package/scaffold/pt-br/commands/dw-review-implementation.md +3 -3
- package/scaffold/pt-br/commands/dw-run-plan.md +8 -8
- package/scaffold/pt-br/commands/dw-run-task.md +3 -3
- package/scaffold/pt-br/templates/tasks-template.md +2 -2
- package/scaffold/skills/agent-browser/SKILL.md +750 -0
- package/scaffold/skills/agent-browser/references/authentication.md +303 -0
- package/scaffold/skills/agent-browser/references/commands.md +295 -0
- package/scaffold/skills/agent-browser/references/profiling.md +120 -0
- package/scaffold/skills/agent-browser/references/proxy-support.md +194 -0
- package/scaffold/skills/agent-browser/references/session-management.md +193 -0
- package/scaffold/skills/agent-browser/references/snapshot-refs.md +219 -0
- package/scaffold/skills/agent-browser/references/video-recording.md +173 -0
- package/scaffold/skills/agent-browser/templates/authenticated-session.sh +105 -0
- package/scaffold/skills/agent-browser/templates/capture-workflow.sh +69 -0
- package/scaffold/skills/agent-browser/templates/form-automation.sh +62 -0
- package/scaffold/skills/humanizer/README.md +143 -0
- package/scaffold/skills/humanizer/SKILL.md +488 -0
- package/scaffold/skills/humanizer/WARP.md +53 -0
- package/scaffold/skills/remotion-best-practices/SKILL.md +61 -0
- package/scaffold/skills/remotion-best-practices/rules/3d.md +86 -0
- package/scaffold/skills/remotion-best-practices/rules/animations.md +27 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +103 -0
- package/scaffold/skills/remotion-best-practices/rules/assets.md +78 -0
- package/scaffold/skills/remotion-best-practices/rules/audio-visualization.md +198 -0
- package/scaffold/skills/remotion-best-practices/rules/audio.md +169 -0
- package/scaffold/skills/remotion-best-practices/rules/calculate-metadata.md +134 -0
- package/scaffold/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/scaffold/skills/remotion-best-practices/rules/charts.md +120 -0
- package/scaffold/skills/remotion-best-practices/rules/compositions.md +154 -0
- package/scaffold/skills/remotion-best-practices/rules/display-captions.md +184 -0
- package/scaffold/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/scaffold/skills/remotion-best-practices/rules/ffmpeg.md +38 -0
- package/scaffold/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/scaffold/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/scaffold/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/scaffold/skills/remotion-best-practices/rules/get-video-duration.md +60 -0
- package/scaffold/skills/remotion-best-practices/rules/gifs.md +141 -0
- package/scaffold/skills/remotion-best-practices/rules/images.md +134 -0
- package/scaffold/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
- package/scaffold/skills/remotion-best-practices/rules/light-leaks.md +73 -0
- package/scaffold/skills/remotion-best-practices/rules/lottie.md +70 -0
- package/scaffold/skills/remotion-best-practices/rules/maps.md +412 -0
- package/scaffold/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/scaffold/skills/remotion-best-practices/rules/measuring-text.md +140 -0
- package/scaffold/skills/remotion-best-practices/rules/parameters.md +109 -0
- package/scaffold/skills/remotion-best-practices/rules/sequencing.md +118 -0
- package/scaffold/skills/remotion-best-practices/rules/sfx.md +26 -0
- package/scaffold/skills/remotion-best-practices/rules/subtitles.md +36 -0
- package/scaffold/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/scaffold/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/scaffold/skills/remotion-best-practices/rules/timing.md +179 -0
- package/scaffold/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
- package/scaffold/skills/remotion-best-practices/rules/transitions.md +197 -0
- package/scaffold/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/scaffold/skills/remotion-best-practices/rules/trimming.md +51 -0
- package/scaffold/skills/remotion-best-practices/rules/videos.md +171 -0
- package/scaffold/skills/remotion-best-practices/rules/voiceover.md +99 -0
- package/scaffold/skills/security-review/LICENSE +22 -0
- package/scaffold/skills/security-review/SKILL.md +312 -0
- package/scaffold/skills/security-review/infrastructure/docker.md +432 -0
- package/scaffold/skills/security-review/languages/javascript.md +388 -0
- package/scaffold/skills/security-review/languages/python.md +363 -0
- package/scaffold/skills/security-review/references/api-security.md +519 -0
- package/scaffold/skills/security-review/references/authentication.md +353 -0
- package/scaffold/skills/security-review/references/authorization.md +372 -0
- package/scaffold/skills/security-review/references/business-logic.md +443 -0
- package/scaffold/skills/security-review/references/cryptography.md +329 -0
- package/scaffold/skills/security-review/references/csrf.md +398 -0
- package/scaffold/skills/security-review/references/data-protection.md +378 -0
- package/scaffold/skills/security-review/references/deserialization.md +410 -0
- package/scaffold/skills/security-review/references/error-handling.md +436 -0
- package/scaffold/skills/security-review/references/file-security.md +457 -0
- package/scaffold/skills/security-review/references/injection.md +259 -0
- package/scaffold/skills/security-review/references/logging.md +433 -0
- package/scaffold/skills/security-review/references/misconfiguration.md +435 -0
- package/scaffold/skills/security-review/references/modern-threats.md +475 -0
- package/scaffold/skills/security-review/references/ssrf.md +415 -0
- package/scaffold/skills/security-review/references/supply-chain.md +405 -0
- package/scaffold/skills/security-review/references/xss.md +336 -0
- package/scaffold/skills/vercel-react-best-practices/AGENTS.md +3648 -0
- package/scaffold/skills/vercel-react-best-practices/README.md +123 -0
- package/scaffold/skills/vercel-react-best-practices/SKILL.md +146 -0
- package/scaffold/skills/vercel-react-best-practices/rules/_sections.md +46 -0
- package/scaffold/skills/vercel-react-best-practices/rules/_template.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/scaffold/skills/webapp-testing/SKILL.md +133 -0
- package/scaffold/skills/webapp-testing/assets/test-helper.js +56 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Cross-Site Scripting (XSS) Prevention Reference
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
XSS occurs when applications include untrusted data in web pages without proper validation or escaping. Attackers can execute scripts in victims' browsers to hijack sessions, deface websites, or redirect users to malicious sites.
|
|
6
|
+
|
|
7
|
+
## XSS Types
|
|
8
|
+
|
|
9
|
+
| Type | Description | Example |
|
|
10
|
+
|------|-------------|---------|
|
|
11
|
+
| **Reflected** | Malicious script from current HTTP request | URL parameter rendered in response |
|
|
12
|
+
| **Stored** | Malicious script stored in target server | Comment field saved and displayed |
|
|
13
|
+
| **DOM-based** | Vulnerability in client-side code | JavaScript reads URL and writes to DOM |
|
|
14
|
+
|
|
15
|
+
## Output Encoding by Context
|
|
16
|
+
|
|
17
|
+
### HTML Body Context
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
// VULNERABLE: innerHTML with user data
|
|
21
|
+
element.innerHTML = userInput;
|
|
22
|
+
|
|
23
|
+
// SAFE: Use textContent
|
|
24
|
+
element.textContent = userInput;
|
|
25
|
+
|
|
26
|
+
// SAFE: Use createTextNode
|
|
27
|
+
document.createTextNode(userInput);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**HTML Entity Encoding**
|
|
31
|
+
| Character | Encoding |
|
|
32
|
+
|-----------|----------|
|
|
33
|
+
| `<` | `<` |
|
|
34
|
+
| `>` | `>` |
|
|
35
|
+
| `&` | `&` |
|
|
36
|
+
| `"` | `"` |
|
|
37
|
+
| `'` | `'` |
|
|
38
|
+
|
|
39
|
+
### HTML Attribute Context
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<!-- VULNERABLE: Unquoted attribute -->
|
|
43
|
+
<input value=${userInput}>
|
|
44
|
+
|
|
45
|
+
<!-- VULNERABLE: Event handler with user data -->
|
|
46
|
+
<button onclick="doSomething('${userInput}')">
|
|
47
|
+
|
|
48
|
+
<!-- SAFE: Quoted attribute with encoding -->
|
|
49
|
+
<input value="${htmlEncode(userInput)}">
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Rules:**
|
|
53
|
+
- Always quote attribute values
|
|
54
|
+
- Never place user input in event handlers (`onclick`, `onerror`, etc.)
|
|
55
|
+
- Use `setAttribute()` which auto-encodes
|
|
56
|
+
|
|
57
|
+
### JavaScript Context
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
// VULNERABLE: eval with user input
|
|
61
|
+
eval(userInput);
|
|
62
|
+
|
|
63
|
+
// VULNERABLE: setTimeout with string
|
|
64
|
+
setTimeout("doSomething('" + userInput + "')", 1000);
|
|
65
|
+
|
|
66
|
+
// VULNERABLE: Function constructor
|
|
67
|
+
new Function("return " + userInput)();
|
|
68
|
+
|
|
69
|
+
// SAFE: JSON encoding for data
|
|
70
|
+
const data = JSON.parse(jsonString);
|
|
71
|
+
|
|
72
|
+
// SAFE: setTimeout with function
|
|
73
|
+
setTimeout(() => doSomething(userInput), 1000);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Safe JavaScript Locations** (with proper encoding):
|
|
77
|
+
- Inside quoted string values only
|
|
78
|
+
- Never directly in script blocks
|
|
79
|
+
|
|
80
|
+
### URL Context
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// VULNERABLE: User input in href
|
|
84
|
+
element.href = userInput;
|
|
85
|
+
|
|
86
|
+
// VULNERABLE: javascript: URL scheme
|
|
87
|
+
<a href="javascript:${userInput}">
|
|
88
|
+
|
|
89
|
+
// SAFE: Validate URL scheme
|
|
90
|
+
const url = new URL(userInput);
|
|
91
|
+
if (url.protocol === 'https:' || url.protocol === 'http:') {
|
|
92
|
+
element.href = url.toString();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// SAFE: Encode URL parameters
|
|
96
|
+
const encoded = encodeURIComponent(userInput);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### CSS Context
|
|
100
|
+
|
|
101
|
+
```css
|
|
102
|
+
/* VULNERABLE: User input in style */
|
|
103
|
+
.element { background: url(${userInput}); }
|
|
104
|
+
|
|
105
|
+
/* VULNERABLE: Expression in CSS */
|
|
106
|
+
.element { behavior: expression(${userInput}); }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Rules:**
|
|
110
|
+
- Place user data only in CSS property values
|
|
111
|
+
- Never allow user input in selectors or URLs
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Safe DOM Sinks
|
|
116
|
+
|
|
117
|
+
**Use These:**
|
|
118
|
+
```javascript
|
|
119
|
+
elem.textContent = variable;
|
|
120
|
+
elem.insertAdjacentText('beforeend', variable);
|
|
121
|
+
elem.className = variable; // for class names
|
|
122
|
+
elem.setAttribute('data-value', variable);
|
|
123
|
+
formField.value = variable;
|
|
124
|
+
document.createTextNode(variable);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Avoid These:**
|
|
128
|
+
```javascript
|
|
129
|
+
elem.innerHTML = variable; // XSS
|
|
130
|
+
elem.outerHTML = variable; // XSS
|
|
131
|
+
document.write(variable); // XSS
|
|
132
|
+
document.writeln(variable); // XSS
|
|
133
|
+
eval(variable); // Code execution
|
|
134
|
+
setTimeout(variable); // If string argument
|
|
135
|
+
setInterval(variable); // If string argument
|
|
136
|
+
new Function(variable); // Code execution
|
|
137
|
+
elem.insertAdjacentHTML(); // XSS
|
|
138
|
+
elem.onevent = variable; // Event handler
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Framework-Specific Considerations
|
|
144
|
+
|
|
145
|
+
### React
|
|
146
|
+
|
|
147
|
+
```jsx
|
|
148
|
+
// SAFE: Auto-escaped by default
|
|
149
|
+
<div>{userInput}</div>
|
|
150
|
+
|
|
151
|
+
// VULNERABLE: dangerouslySetInnerHTML
|
|
152
|
+
<div dangerouslySetInnerHTML={{__html: userInput}} />
|
|
153
|
+
|
|
154
|
+
// SAFE: Sanitize before using dangerouslySetInnerHTML
|
|
155
|
+
import DOMPurify from 'dompurify';
|
|
156
|
+
<div dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(userInput)}} />
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Angular
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
// SAFE: Auto-escaped by default
|
|
163
|
+
<div>{{ userInput }}</div>
|
|
164
|
+
|
|
165
|
+
// VULNERABLE: bypassSecurityTrust*
|
|
166
|
+
this.sanitizer.bypassSecurityTrustHtml(userInput);
|
|
167
|
+
|
|
168
|
+
// Use bypassSecurityTrust* only with sanitized input
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Vue
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<!-- SAFE: Auto-escaped -->
|
|
175
|
+
<div>{{ userInput }}</div>
|
|
176
|
+
|
|
177
|
+
<!-- VULNERABLE: v-html directive -->
|
|
178
|
+
<div v-html="userInput"></div>
|
|
179
|
+
|
|
180
|
+
<!-- SAFE: Sanitize first -->
|
|
181
|
+
<div v-html="sanitizedInput"></div>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Django/Jinja2
|
|
185
|
+
|
|
186
|
+
```django
|
|
187
|
+
<!-- SAFE: Auto-escaped by default -->
|
|
188
|
+
{{ user_input }}
|
|
189
|
+
|
|
190
|
+
<!-- VULNERABLE: |safe filter -->
|
|
191
|
+
{{ user_input|safe }}
|
|
192
|
+
|
|
193
|
+
<!-- VULNERABLE: {% autoescape off %} -->
|
|
194
|
+
{% autoescape off %}
|
|
195
|
+
{{ user_input }}
|
|
196
|
+
{% endautoescape %}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## HTML Sanitization
|
|
202
|
+
|
|
203
|
+
When users must submit HTML (rich text editors), use a sanitization library.
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
// Recommended: DOMPurify
|
|
207
|
+
import DOMPurify from 'dompurify';
|
|
208
|
+
|
|
209
|
+
const clean = DOMPurify.sanitize(dirty);
|
|
210
|
+
|
|
211
|
+
// With configuration
|
|
212
|
+
const clean = DOMPurify.sanitize(dirty, {
|
|
213
|
+
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
|
|
214
|
+
ALLOWED_ATTR: ['href']
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Key Points:**
|
|
219
|
+
- Keep sanitization libraries updated
|
|
220
|
+
- Configure allowed tags/attributes based on needs
|
|
221
|
+
- Sanitize on output, not just input
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Content Security Policy (CSP)
|
|
226
|
+
|
|
227
|
+
CSP provides defense-in-depth but should not be the primary XSS defense.
|
|
228
|
+
|
|
229
|
+
### Strict CSP (Recommended)
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Content-Security-Policy:
|
|
233
|
+
default-src 'self';
|
|
234
|
+
script-src 'nonce-{RANDOM}' 'strict-dynamic';
|
|
235
|
+
object-src 'none';
|
|
236
|
+
base-uri 'none';
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Nonce-Based Approach
|
|
240
|
+
|
|
241
|
+
```html
|
|
242
|
+
<!-- Server generates unique nonce per request -->
|
|
243
|
+
<script nonce="r4nd0m123">
|
|
244
|
+
// Allowed script
|
|
245
|
+
</script>
|
|
246
|
+
|
|
247
|
+
<script>
|
|
248
|
+
// Blocked - no nonce
|
|
249
|
+
</script>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Hash-Based Approach
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
Content-Security-Policy: script-src 'sha256-base64hash...'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## DOM-based XSS Prevention
|
|
261
|
+
|
|
262
|
+
### Dangerous Sources
|
|
263
|
+
|
|
264
|
+
```javascript
|
|
265
|
+
// Attacker-controllable sources
|
|
266
|
+
location.hash
|
|
267
|
+
location.search
|
|
268
|
+
document.referrer
|
|
269
|
+
window.name
|
|
270
|
+
postMessage data
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Prevention
|
|
274
|
+
|
|
275
|
+
```javascript
|
|
276
|
+
// VULNERABLE: Direct use of source in sink
|
|
277
|
+
element.innerHTML = location.hash.slice(1);
|
|
278
|
+
|
|
279
|
+
// SAFE: Validate and encode
|
|
280
|
+
const hash = location.hash.slice(1);
|
|
281
|
+
if (/^[a-zA-Z0-9-]+$/.test(hash)) {
|
|
282
|
+
element.textContent = hash;
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Key Grep Patterns for Detection
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Dangerous DOM sinks
|
|
292
|
+
grep -rn "innerHTML\|outerHTML\|document\.write" --include="*.js" --include="*.jsx"
|
|
293
|
+
grep -rn "dangerouslySetInnerHTML" --include="*.jsx" --include="*.tsx"
|
|
294
|
+
grep -rn "v-html" --include="*.vue"
|
|
295
|
+
grep -rn "\|safe\|autoescape off" --include="*.html" --include="*.jinja"
|
|
296
|
+
|
|
297
|
+
# Dangerous JavaScript
|
|
298
|
+
grep -rn "eval(\|Function(\|setTimeout.*string\|setInterval.*string" --include="*.js"
|
|
299
|
+
|
|
300
|
+
# Framework bypasses
|
|
301
|
+
grep -rn "bypassSecurityTrust" --include="*.ts"
|
|
302
|
+
grep -rn "mark_safe\|SafeString" --include="*.py"
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Testing Payloads
|
|
308
|
+
|
|
309
|
+
**Basic:**
|
|
310
|
+
```
|
|
311
|
+
<script>alert('XSS')</script>
|
|
312
|
+
<img src=x onerror=alert('XSS')>
|
|
313
|
+
<svg onload=alert('XSS')>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Attribute Escape:**
|
|
317
|
+
```
|
|
318
|
+
" onmouseover="alert('XSS')
|
|
319
|
+
' onclick='alert("XSS")
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**JavaScript Context:**
|
|
323
|
+
```
|
|
324
|
+
';alert('XSS')//
|
|
325
|
+
\';alert(\'XSS\')//
|
|
326
|
+
</script><script>alert('XSS')</script>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## References
|
|
332
|
+
|
|
333
|
+
- [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)
|
|
334
|
+
- [OWASP DOM-based XSS Prevention](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html)
|
|
335
|
+
- [OWASP CSP Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
|
|
336
|
+
- [CWE-79: Cross-site Scripting](https://cwe.mitre.org/data/definitions/79.html)
|