@pilllesss/yorn 1.0.182 → 1.0.183

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.

Potentially problematic release.


This version of @pilllesss/yorn might be problematic. Click here for more details.

Files changed (45) hide show
  1. package/README.md +1 -1
  2. package/dist/providers/data/.manifest.json +1 -1
  3. package/dist/skills/code-review/LICENSE +21 -0
  4. package/dist/skills/code-review/SKILL.md +233 -0
  5. package/dist/skills/code-review/assets/pr-review-template.md +137 -0
  6. package/dist/skills/code-review/assets/review-checklist.md +123 -0
  7. package/dist/skills/code-review/reference/angular.md +768 -0
  8. package/dist/skills/code-review/reference/architecture-review-guide.md +472 -0
  9. package/dist/skills/code-review/reference/c.md +890 -0
  10. package/dist/skills/code-review/reference/code-quality-universal.md +488 -0
  11. package/dist/skills/code-review/reference/code-review-best-practices.md +136 -0
  12. package/dist/skills/code-review/reference/common-bugs-checklist.md +302 -0
  13. package/dist/skills/code-review/reference/cpp.md +893 -0
  14. package/dist/skills/code-review/reference/cross-cutting/async-concurrency-patterns.md +515 -0
  15. package/dist/skills/code-review/reference/cross-cutting/error-handling-principles.md +492 -0
  16. package/dist/skills/code-review/reference/cross-cutting/n-plus-one-queries.md +309 -0
  17. package/dist/skills/code-review/reference/cross-cutting/sql-injection-prevention.md +308 -0
  18. package/dist/skills/code-review/reference/cross-cutting/xss-prevention.md +264 -0
  19. package/dist/skills/code-review/reference/csharp.md +525 -0
  20. package/dist/skills/code-review/reference/css-less-sass.md +661 -0
  21. package/dist/skills/code-review/reference/dart.md +670 -0
  22. package/dist/skills/code-review/reference/django.md +985 -0
  23. package/dist/skills/code-review/reference/fastapi.md +580 -0
  24. package/dist/skills/code-review/reference/go.md +993 -0
  25. package/dist/skills/code-review/reference/java.md +409 -0
  26. package/dist/skills/code-review/reference/java8.md +586 -0
  27. package/dist/skills/code-review/reference/kotlin.md +1018 -0
  28. package/dist/skills/code-review/reference/nestjs.md +593 -0
  29. package/dist/skills/code-review/reference/performance-review-guide.md +816 -0
  30. package/dist/skills/code-review/reference/php.md +684 -0
  31. package/dist/skills/code-review/reference/python.md +1073 -0
  32. package/dist/skills/code-review/reference/qt.md +757 -0
  33. package/dist/skills/code-review/reference/react.md +871 -0
  34. package/dist/skills/code-review/reference/ruby.md +964 -0
  35. package/dist/skills/code-review/reference/rust.md +846 -0
  36. package/dist/skills/code-review/reference/security-review-guide.md +494 -0
  37. package/dist/skills/code-review/reference/svelte.md +1064 -0
  38. package/dist/skills/code-review/reference/swift.md +936 -0
  39. package/dist/skills/code-review/reference/typescript.md +1016 -0
  40. package/dist/skills/code-review/reference/vue.md +924 -0
  41. package/dist/skills/code-review/reference/zig.md +440 -0
  42. package/dist/skills/code-review/scripts/pr-analyzer.py +435 -0
  43. package/dist/skills/code-review/scripts/test_pr_analyzer.py +380 -0
  44. package/dist/yorn.cjs +628 -628
  45. package/package.json +2 -2
@@ -0,0 +1,494 @@
1
+ # Security Review Guide
2
+
3
+ Security-focused code review checklist based on OWASP Top 10 and best practices.
4
+
5
+ ## Authentication & Authorization
6
+
7
+ ### Authentication
8
+ - [ ] Passwords hashed with strong algorithm (bcrypt, argon2)
9
+ - [ ] Password complexity requirements enforced
10
+ - [ ] Account lockout after failed attempts
11
+ - [ ] Secure password reset flow
12
+ - [ ] Multi-factor authentication for sensitive operations
13
+ - [ ] Session tokens are cryptographically random
14
+ - [ ] Session timeout implemented
15
+
16
+ ### Authorization
17
+ - [ ] Authorization checks on every request
18
+ - [ ] Principle of least privilege applied
19
+ - [ ] Role-based access control (RBAC) properly implemented
20
+ - [ ] No privilege escalation paths
21
+ - [ ] Direct object reference checks (IDOR prevention)
22
+ - [ ] API endpoints protected appropriately
23
+
24
+ ### JWT Security
25
+ ```typescript
26
+ // ❌ Insecure JWT configuration
27
+ jwt.sign(payload, 'weak-secret');
28
+
29
+ // ✅ Secure JWT configuration
30
+ jwt.sign(payload, process.env.JWT_SECRET, {
31
+ algorithm: 'RS256',
32
+ expiresIn: '15m',
33
+ issuer: 'your-app',
34
+ audience: 'your-api'
35
+ });
36
+
37
+ // ❌ Not verifying JWT properly
38
+ const decoded = jwt.decode(token); // No signature verification!
39
+
40
+ // ✅ Verify signature and claims
41
+ const decoded = jwt.verify(token, publicKey, {
42
+ algorithms: ['RS256'],
43
+ issuer: 'your-app',
44
+ audience: 'your-api'
45
+ });
46
+ ```
47
+
48
+ ## Input Validation
49
+
50
+ ### SQL Injection Prevention
51
+
52
+ **The #1 rule**: Always use parameterized queries. Never concatenate user input into SQL strings.
53
+
54
+ Every major language and framework has a parameterized query mechanism:
55
+ - Python: `cursor.execute("SELECT ...", params)` / ORM filter methods
56
+ - Java: `PreparedStatement` / JPA `@Query` with `@Param`
57
+ - Go: `db.Query("SELECT ...", args...)`
58
+ - Node.js: `client.query("SELECT ...", [args])` / Prisma ORM
59
+ - PHP: PDO prepared statements / Laravel Eloquent
60
+ - C#: ADO.NET `SqlParameter` / Dapper / EF Core LINQ
61
+
62
+ > **See [SQL Injection Prevention Guide](cross-cutting/sql-injection-prevention.md) for complete cross-language examples, ORM unsafe patterns, dynamic identifier handling, and detection tools.**
63
+
64
+ ### XSS Prevention
65
+
66
+ **The #1 rule**: Rely on framework auto-escaping. Audit every escape hatch.
67
+
68
+ Every major framework auto-escapes by default:
69
+ - React: JSX auto-escapes. Audit `dangerouslySetInnerHTML`.
70
+ - Vue: `{{ }}` auto-escapes. Audit `v-html`.
71
+ - Angular: Interpolation auto-escapes. Audit `bypassSecurityTrustHtml`.
72
+ - Svelte: `{ }` auto-escapes. Audit `{@html}`.
73
+ - Django: Templates auto-escape. Audit `mark_safe`.
74
+
75
+ For defense-in-depth, configure Content Security Policy (CSP) with nonce-based `script-src`.
76
+
77
+ > **See [XSS Prevention Guide](cross-cutting/xss-prevention.md) for complete cross-framework examples, CSP configuration, input validation vs output encoding, and detection tools.**
78
+
79
+ ### CSRF Prevention
80
+
81
+ **CSRF Token Implementation**
82
+ ```typescript
83
+ // ✅ Server: generate and validate CSRF token
84
+ import crypto from 'node:crypto';
85
+
86
+ function generateCsrfToken(): string {
87
+ return crypto.randomBytes(32).toString('hex');
88
+ }
89
+
90
+ // Middleware: validate token on state-changing requests
91
+ app.post('/api/data', (req, res) => {
92
+ const token = req.headers['x-csrf-token'];
93
+ const sessionToken = req.session.csrfToken;
94
+ if (!token || token !== sessionToken) {
95
+ return res.status(403).json({ error: 'Invalid CSRF token' });
96
+ }
97
+ // ...handle request
98
+ });
99
+ ```
100
+
101
+ **Python (Django)**
102
+ ```python
103
+ # ✅ Django: built-in CSRF protection
104
+ # settings.py
105
+ MIDDLEWARE = [
106
+ 'django.middleware.csrf.CsrfViewMiddleware', # 默认启用
107
+ ]
108
+
109
+ # templates: include CSRF token
110
+ # <form method="post">
111
+ # {% csrf_token %}
112
+ # </form>
113
+
114
+ # ❌ Disabling CSRF on a view
115
+ @csrf_exempt # 除非绝对必要,否则不使用
116
+ def my_view(request):
117
+ ...
118
+ ```
119
+
120
+ **Java (Spring Boot)**
121
+ ```java
122
+ // ✅ Spring Security: CSRF enabled by default
123
+ @Configuration
124
+ @EnableWebSecurity
125
+ public class SecurityConfig {
126
+ @Bean
127
+ public SecurityFilterChain filterChain(HttpSecurity http) {
128
+ http.csrf(csrf -> csrf
129
+ .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
130
+ );
131
+ return http.build();
132
+ }
133
+ }
134
+ ```
135
+
136
+ **SameSite Cookie**
137
+ ```typescript
138
+ // ✅ Set SameSite cookie as additional defense
139
+ res.cookie('session', sessionId, {
140
+ httpOnly: true,
141
+ secure: true,
142
+ sameSite: 'strict', // 或 'lax' 用于允许导航 GET 请求
143
+ maxAge: 3600000,
144
+ });
145
+ ```
146
+
147
+ ### SSRF Prevention
148
+
149
+ ```python
150
+ # ❌ Vulnerable: user-controlled URL
151
+ import requests
152
+ url = request.GET.get('url')
153
+ response = requests.get(url)
154
+
155
+ # ✅ Validate URL against whitelist
156
+ ALLOWED_HOSTS = ['api.example.com', 'cdn.example.com']
157
+
158
+ def is_safe_url(url: str) -> bool:
159
+ from urllib.parse import urlparse
160
+ parsed = urlparse(url)
161
+ return parsed.hostname in ALLOWED_HOSTS
162
+
163
+ if is_safe_url(url):
164
+ response = requests.get(url)
165
+ ```
166
+
167
+ ```typescript
168
+ // ❌ Vulnerable: fetching arbitrary URLs
169
+ const url = req.query.url;
170
+ const response = await fetch(url);
171
+
172
+ // ✅ Validate URL before fetching
173
+ const ALLOWED_DOMAINS = ['api.internal.com'];
174
+
175
+ function isSafeUrl(url: string): boolean {
176
+ try {
177
+ const parsed = new URL(url);
178
+ // Block internal IPs
179
+ if (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1') {
180
+ return false;
181
+ }
182
+ if (parsed.hostname.match(/^10\.|^172\.(1[6-9]|2\d|3[01])\.|^192\.168\./)) {
183
+ return false; // Block private IP ranges
184
+ }
185
+ return ALLOWED_DOMAINS.includes(parsed.hostname);
186
+ } catch {
187
+ return false;
188
+ }
189
+ }
190
+ ```
191
+
192
+ ```go
193
+ // ✅ Go: validate URL before making requests
194
+ import "net/url"
195
+
196
+ func isSafeURL(rawURL string) bool {
197
+ u, err := url.Parse(rawURL)
198
+ if err != nil {
199
+ return false
200
+ }
201
+ // Block internal IPs
202
+ if u.Hostname() == "localhost" || u.Hostname() == "127.0.0.1" {
203
+ return false
204
+ }
205
+ // Only allow HTTPS
206
+ if u.Scheme != "https" {
207
+ return false
208
+ }
209
+ return true
210
+ }
211
+ ```
212
+
213
+ ### IDOR(不安全直接对象引用)
214
+
215
+ ```python
216
+ # ❌ Vulnerable: no ownership check
217
+ def get_order(request, order_id):
218
+ order = Order.objects.get(id=order_id) # 任何用户可查看任何订单
219
+ return JsonResponse(order.to_dict())
220
+
221
+ # ✅ Check ownership before returning
222
+ def get_order(request, order_id):
223
+ order = Order.objects.filter(id=order_id, user=request.user).first()
224
+ if not order:
225
+ return JsonResponse({'error': 'Not found'}, status=404)
226
+ return JsonResponse(order.to_dict())
227
+ ```
228
+
229
+ ```typescript
230
+ // ❌ Vulnerable: no authorization check
231
+ app.get('/api/orders/:id', async (req, res) => {
232
+ const order = await db.order.findUnique({
233
+ where: { id: Number(req.params.id) }
234
+ });
235
+ res.json(order);
236
+ });
237
+
238
+ // ✅ Include user context in query
239
+ app.get('/api/orders/:id', async (req, res) => {
240
+ const order = await db.order.findFirst({
241
+ where: {
242
+ id: Number(req.params.id),
243
+ userId: req.user.id, // Scope to current user
244
+ }
245
+ });
246
+ if (!order) return res.status(404).json({ error: 'Not found' });
247
+ res.json(order);
248
+ });
249
+ ```
250
+
251
+ ```java
252
+ // ✅ Spring Security: method-level authorization
253
+ @GetMapping("/api/orders/{id}")
254
+ @PreAuthorize("@orderService.isOwner(#id, authentication.principal.id)")
255
+ public Order getOrder(@PathVariable Long id) {
256
+ return orderService.findById(id);
257
+ }
258
+ ```
259
+
260
+ **UUID vs 自增 ID**
261
+ ```typescript
262
+ // ❌ 自增 ID 可被枚举
263
+ // GET /api/users/1, /api/users/2, /api/users/3 ...
264
+
265
+ // ✅ UUID 不可预测
266
+ // GET /api/users/550e8400-e29b-41d4-a716-446655440000
267
+
268
+ // ⚠️ UUID 只是防止枚举,不是权限控制
269
+ // 仍然需要验证当前用户是否有权访问该资源
270
+ ```
271
+
272
+ ### Command Injection Prevention
273
+
274
+ **Python**
275
+ ```python
276
+ # ❌ Vulnerable: shell=True
277
+ import subprocess
278
+ subprocess.run(f"convert {filename} output.png", shell=True)
279
+
280
+ # ✅ Use list arguments without shell
281
+ subprocess.run(['convert', filename, 'output.png'], check=True)
282
+
283
+ # ✅ Validate and sanitize input
284
+ import shlex
285
+ safe_filename = shlex.quote(filename)
286
+ ```
287
+
288
+ **Node.js**
289
+ ```typescript
290
+ // ❌ Vulnerable: exec with string interpolation
291
+ import { exec } from 'node:child_process';
292
+ exec(`convert ${filename} output.png`);
293
+
294
+ // ✅ Use execFile with array arguments
295
+ import { execFile } from 'node:child_process';
296
+ execFile('convert', [filename, 'output.png'], (error, stdout) => {
297
+ if (error) throw error;
298
+ });
299
+
300
+ // ❌ Never pass user input to shell
301
+ exec(`echo ${userInput}`); // userInput = "; rm -rf /"
302
+
303
+ // ✅ Sanitize or use non-shell alternatives
304
+ import { writeFile } from 'node:fs/promises';
305
+ await writeFile('output.txt', userInput); // No shell involved
306
+ ```
307
+
308
+ **Go**
309
+ ```go
310
+ // ❌ Vulnerable: shell command with user input
311
+ cmd := exec.Command("sh", "-c", "echo " + userInput)
312
+
313
+ // ✅ Use exec.Command with separate arguments
314
+ cmd := exec.Command("echo", userInput)
315
+
316
+ // ❌ Passing user input to shell
317
+ out, _ := exec.Command("bash", "-c", "cat "+filename).Output()
318
+
319
+ // ✅ Read file directly without shell
320
+ data, err := os.ReadFile(filename)
321
+ ```
322
+
323
+ **Java**
324
+ ```java
325
+ // ❌ Vulnerable: Runtime.exec with string concatenation
326
+ Runtime.getRuntime().exec("convert " + filename + " output.png");
327
+
328
+ // ✅ Use ProcessBuilder with separate arguments
329
+ ProcessBuilder pb = new ProcessBuilder("convert", filename, "output.png");
330
+ Process process = pb.start();
331
+
332
+ // ❌ Dangerous: passing user input to shell
333
+ Runtime.getRuntime().exec(new String[]{"sh", "-c", "echo " + userInput});
334
+ ```
335
+
336
+ ## Data Protection
337
+
338
+ ### Sensitive Data Handling
339
+ - [ ] No secrets in source code
340
+ - [ ] Secrets stored in environment variables or secret manager
341
+ - [ ] Sensitive data encrypted at rest
342
+ - [ ] Sensitive data encrypted in transit (HTTPS)
343
+ - [ ] PII handled according to regulations (GDPR, etc.)
344
+ - [ ] Sensitive data not logged
345
+ - [ ] Secure data deletion when required
346
+
347
+ ### Configuration Security
348
+ ```yaml
349
+ # ❌ Secrets in config files
350
+ database:
351
+ password: "super-secret-password"
352
+
353
+ # ✅ Reference environment variables
354
+ database:
355
+ password: ${DATABASE_PASSWORD}
356
+ ```
357
+
358
+ ### Error Messages
359
+ ```typescript
360
+ // ❌ Leaking sensitive information
361
+ catch (error) {
362
+ return res.status(500).json({
363
+ error: error.stack, // Exposes internal details
364
+ query: sqlQuery // Exposes database structure
365
+ });
366
+ }
367
+
368
+ // ✅ Generic error messages
369
+ catch (error) {
370
+ logger.error('Database error', { error, userId }); // Log internally
371
+ return res.status(500).json({
372
+ error: 'An unexpected error occurred'
373
+ });
374
+ }
375
+ ```
376
+
377
+ ## API Security
378
+
379
+ ### Rate Limiting
380
+ - [ ] Rate limiting on all public endpoints
381
+ - [ ] Stricter limits on authentication endpoints
382
+ - [ ] Per-user and per-IP limits
383
+ - [ ] Graceful handling when limits exceeded
384
+
385
+ ### CORS Configuration
386
+ ```typescript
387
+ // ❌ Overly permissive CORS
388
+ app.use(cors({ origin: '*' }));
389
+
390
+ // ✅ Restrictive CORS
391
+ app.use(cors({
392
+ origin: ['https://your-app.com'],
393
+ methods: ['GET', 'POST'],
394
+ credentials: true
395
+ }));
396
+ ```
397
+
398
+ ### HTTP Headers
399
+ ```typescript
400
+ // Security headers to set
401
+ app.use(helmet({
402
+ contentSecurityPolicy: {
403
+ directives: {
404
+ defaultSrc: ["'self'"],
405
+ scriptSrc: ["'self'"],
406
+ styleSrc: ["'self'", "'unsafe-inline'"],
407
+ }
408
+ },
409
+ hsts: { maxAge: 31536000, includeSubDomains: true },
410
+ noSniff: true,
411
+ xssFilter: true,
412
+ frameguard: { action: 'deny' }
413
+ }));
414
+ ```
415
+
416
+ ## Cryptography
417
+
418
+ ### Secure Practices
419
+ - [ ] Using well-established algorithms (AES-256, RSA-2048+)
420
+ - [ ] Not implementing custom cryptography
421
+ - [ ] Using cryptographically secure random number generation
422
+ - [ ] Proper key management and rotation
423
+ - [ ] Secure key storage (HSM, KMS)
424
+
425
+ ### Common Mistakes
426
+ ```typescript
427
+ // ❌ Weak random generation
428
+ const token = Math.random().toString(36);
429
+
430
+ // ✅ Cryptographically secure random
431
+ const crypto = require('crypto');
432
+ const token = crypto.randomBytes(32).toString('hex');
433
+
434
+ // ❌ MD5/SHA1 for passwords
435
+ const hash = crypto.createHash('md5').update(password).digest('hex');
436
+
437
+ // ✅ Use bcrypt or argon2
438
+ const bcrypt = require('bcrypt');
439
+ const hash = await bcrypt.hash(password, 12);
440
+ ```
441
+
442
+ ## Dependency Security
443
+
444
+ ### Checklist
445
+ - [ ] Dependencies from trusted sources only
446
+ - [ ] No known vulnerabilities (npm audit, cargo audit)
447
+ - [ ] Dependencies kept up to date
448
+ - [ ] Lock files committed (package-lock.json, Cargo.lock)
449
+ - [ ] Minimal dependency usage
450
+ - [ ] License compliance verified
451
+
452
+ ### Audit Commands
453
+ ```bash
454
+ # Node.js
455
+ npm audit
456
+ npm audit fix
457
+
458
+ # Python
459
+ pip-audit
460
+ safety check
461
+
462
+ # Rust
463
+ cargo audit
464
+
465
+ # General
466
+ snyk test
467
+ ```
468
+
469
+ ## Logging & Monitoring
470
+
471
+ ### Secure Logging
472
+ - [ ] No sensitive data in logs (passwords, tokens, PII)
473
+ - [ ] Logs protected from tampering
474
+ - [ ] Appropriate log retention
475
+ - [ ] Security events logged (login attempts, permission changes)
476
+ - [ ] Log injection prevented
477
+
478
+ ```typescript
479
+ // ❌ Logging sensitive data
480
+ logger.info(`User login: ${email}, password: ${password}`);
481
+
482
+ // ✅ Safe logging
483
+ logger.info('User login attempt', { email, success: true });
484
+ ```
485
+
486
+ ## Security Review Severity Levels
487
+
488
+ | Severity | Description | Action |
489
+ |----------|-------------|--------|
490
+ | **Critical** | Immediate exploitation possible, data breach risk | Block merge, fix immediately |
491
+ | **High** | Significant vulnerability, requires specific conditions | Block merge, fix before release |
492
+ | **Medium** | Moderate risk, defense in depth concern | Should fix, can merge with tracking |
493
+ | **Low** | Minor issue, best practice violation | Nice to fix, non-blocking |
494
+ | **Info** | Suggestion for improvement | Optional enhancement |