@runsec/mcp 1.0.1

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 (40) hide show
  1. package/dist/index.js +578 -0
  2. package/package.json +43 -0
  3. package/src/rules/data/rule-compliance-map.json +43563 -0
  4. package/src/rules/data/semgrep-rules/README-taint-overlays.md +21 -0
  5. package/src/rules/data/semgrep-rules/advanced-agent-cloud.yaml +802 -0
  6. package/src/rules/data/semgrep-rules/app-logic.yaml +445 -0
  7. package/src/rules/data/semgrep-rules/auth-keycloak.yaml +831 -0
  8. package/src/rules/data/semgrep-rules/browser-agent.yaml +260 -0
  9. package/src/rules/data/semgrep-rules/cloud-secrets.yaml +316 -0
  10. package/src/rules/data/semgrep-rules/csharp-dotnet.yaml +4864 -0
  11. package/src/rules/data/semgrep-rules/desktop-electron-pro.yaml +30 -0
  12. package/src/rules/data/semgrep-rules/desktop-vsto-suite.yaml +2759 -0
  13. package/src/rules/data/semgrep-rules/devops-security.yaml +393 -0
  14. package/src/rules/data/semgrep-rules/domain-access-management.yaml +1023 -0
  15. package/src/rules/data/semgrep-rules/domain-data-privacy.yaml +852 -0
  16. package/src/rules/data/semgrep-rules/domain-input-validation.yaml +2894 -0
  17. package/src/rules/data/semgrep-rules/domain-platform-hardening.yaml +1715 -0
  18. package/src/rules/data/semgrep-rules/ds-ml-security.yaml +2431 -0
  19. package/src/rules/data/semgrep-rules/fastapi-async.yaml +5953 -0
  20. package/src/rules/data/semgrep-rules/frontend-react.yaml +4035 -0
  21. package/src/rules/data/semgrep-rules/frontend-security.yaml +200 -0
  22. package/src/rules/data/semgrep-rules/go-core.yaml +4959 -0
  23. package/src/rules/data/semgrep-rules/hft-cpp-security.yaml +631 -0
  24. package/src/rules/data/semgrep-rules/infra-k8s-helm.yaml +4968 -0
  25. package/src/rules/data/semgrep-rules/integration-security.yaml +2362 -0
  26. package/src/rules/data/semgrep-rules/java-enterprise.yaml +14756 -0
  27. package/src/rules/data/semgrep-rules/java-spring.yaml +397 -0
  28. package/src/rules/data/semgrep-rules/license-compliance.yaml +186 -0
  29. package/src/rules/data/semgrep-rules/mobile-flutter.yaml +37 -0
  30. package/src/rules/data/semgrep-rules/mobile-security.yaml +721 -0
  31. package/src/rules/data/semgrep-rules/nodejs-nestjs.yaml +5164 -0
  32. package/src/rules/data/semgrep-rules/nodejs-security.yaml +326 -0
  33. package/src/rules/data/semgrep-rules/observability.yaml +381 -0
  34. package/src/rules/data/semgrep-rules/php-security.yaml +3601 -0
  35. package/src/rules/data/semgrep-rules/python-backend-pro.yaml +30 -0
  36. package/src/rules/data/semgrep-rules/python-django.yaml +181 -0
  37. package/src/rules/data/semgrep-rules/python-security.yaml +284 -0
  38. package/src/rules/data/semgrep-rules/ru-regulatory.yaml +496 -0
  39. package/src/rules/data/semgrep-rules/ruby-rails.yaml +3078 -0
  40. package/src/rules/data/semgrep-rules/rust-security.yaml +2701 -0
@@ -0,0 +1,381 @@
1
+ rules:
2
+ - id: runsec.observability.log-001
3
+ metadata:
4
+ runsec_version: v1.0
5
+ confidence: |-
6
+ 0.9
7
+ exploit_scenario: |-
8
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
9
+ fix_template: |-
10
+ try: await repo.save(event) except Exception: logger.exception("audit-save-failed", extra={"event_type": event.type}) raise
11
+ pattern-either:
12
+ - pattern: |-
13
+ try:
14
+ await repo.save(event)
15
+ except Exception:
16
+ pass
17
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-001\\b'
18
+ message: |-
19
+ RunSec Detection [LOG-001]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V7 Error Handling and Logging
20
+ languages:
21
+ - generic
22
+ severity: WARNING
23
+ - id: runsec.observability.log-002
24
+ metadata:
25
+ runsec_version: v1.0
26
+ confidence: |-
27
+ 0.9
28
+ exploit_scenario: |-
29
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
30
+ fix_template: |-
31
+ trace_id = request.headers.get("x-trace-id") or str(uuid4()) logger.info("request accepted", extra={"trace_id": trace_id, "path": request.url.path}) response.headers["X-Trace-ID"] = trace_id
32
+ pattern-either:
33
+ - pattern: |-
34
+ logger.info("request accepted")
35
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-002\\b'
36
+ message: |-
37
+ RunSec Detection [LOG-002]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V7
38
+ languages:
39
+ - generic
40
+ severity: WARNING
41
+ - id: runsec.observability.log-003
42
+ metadata:
43
+ runsec_version: v1.0
44
+ confidence: |-
45
+ 0.9
46
+ exploit_scenario: |-
47
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
48
+ fix_template: |-
49
+ logger.warning("auth_failed", extra={"trace_id": trace_id, "user": username, "ip": client_ip, "reason": "bad_credentials"})
50
+ pattern-either:
51
+ - pattern: |-
52
+ logger.error(f"login failed for {username}")
53
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-003\\b'
54
+ message: |-
55
+ RunSec Detection [LOG-003]: OWASP API Security Top 10 (2023) API10 Unsafe Consumption of APIs; OWASP ASVS v4.0.3 V7
56
+ languages:
57
+ - generic
58
+ severity: WARNING
59
+ - id: runsec.observability.log-004
60
+ metadata:
61
+ runsec_version: v1.0
62
+ confidence: |-
63
+ 0.9
64
+ exploit_scenario: |-
65
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
66
+ fix_template: |-
67
+ safe = {"username": payload.get("username"), "mfa": payload.get("mfa")} logger.info("auth payload sanitized", extra={"trace_id": trace_id, "payload": safe})
68
+ pattern-either:
69
+ - pattern: |-
70
+ logger.info("auth payload=%s", payload)
71
+ # payload may include password/token
72
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-004\\b'
73
+ message: |-
74
+ RunSec Detection [LOG-004]: OWASP Top 10 (2021) A02 Cryptographic Failures; OWASP Top 10 (2021) A09
75
+ languages:
76
+ - generic
77
+ severity: WARNING
78
+ - id: runsec.observability.log-005
79
+ metadata:
80
+ runsec_version: v1.0
81
+ confidence: |-
82
+ 0.9
83
+ exploit_scenario: |-
84
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
85
+ fix_template: |-
86
+ except Exception: logger.exception("unhandled error", extra={"trace_id": trace_id}) raise HTTPException(status_code=500, detail="internal server error")
87
+ pattern-either:
88
+ - pattern: |-
89
+ except Exception as exc:
90
+ raise HTTPException(status_code=500, detail=traceback.format_exc())
91
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-005\\b'
92
+ message: |-
93
+ RunSec Detection [LOG-005]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP API Security Top 10 (2023) API8 Security Misconfiguration
94
+ languages:
95
+ - generic
96
+ severity: WARNING
97
+ - id: runsec.observability.log-006
98
+ metadata:
99
+ runsec_version: v1.0
100
+ confidence: |-
101
+ 0.9
102
+ exploit_scenario: |-
103
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
104
+ fix_template: |-
105
+ @app.post("/admin/users/{uid}/role") async def set_role(uid: int, role: str, actor=Depends(current_user)): await repo.set_role(uid, role) await audit_log.write({"event": "role_change", "actor_id": actor.id, "target_user_id": uid, "new_role": role, "trace_id": trace_id})
106
+ pattern-either:
107
+ - pattern: |-
108
+ @app.post("/admin/users/{uid}/role")
109
+ async def set_role(uid: int, role: str):
110
+ await repo.set_role(uid, role)
111
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-006\\b'
112
+ message: |-
113
+ RunSec Detection [LOG-006]: OWASP Top 10 (2021) A09; OWASP ASVS v4.0.3 V7 Logging
114
+ languages:
115
+ - generic
116
+ severity: WARNING
117
+ - id: runsec.observability.log-007
118
+ metadata:
119
+ runsec_version: v1.0
120
+ confidence: |-
121
+ 0.9
122
+ exploit_scenario: |-
123
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
124
+ fix_template: |-
125
+ if not auth_ok: await audit_log.write({"event": "auth_failed", "username": username, "ip": client_ip, "trace_id": trace_id}) await risk_counter.bump(f"auth:{username}:{client_ip}") raise HTTPException(status_code=401, detail="invalid credentials")
126
+ pattern-either:
127
+ - pattern: |-
128
+ if not auth_ok:
129
+ raise HTTPException(status_code=401, detail="invalid credentials")
130
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-007\\b'
131
+ message: |-
132
+ RunSec Detection [LOG-007]: OWASP Top 10 (2021) A07 Identification and Authentication Failures; OWASP Top 10 (2021) A09
133
+ languages:
134
+ - generic
135
+ severity: WARNING
136
+ - id: runsec.observability.log-008
137
+ metadata:
138
+ runsec_version: v1.0
139
+ confidence: |-
140
+ 0.9
141
+ exploit_scenario: |-
142
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
143
+ fix_template: |-
144
+ @app.middleware("http") async def m(request: Request, call_next): started = time.perf_counter() response = await call_next(request) elapsed_ms = (time.perf_counter() - started) * 1000 logger.info("http_access", extra={"trace_id": request.state.trace_id, "path": request.url.path, "status": response.status_code, "latency_ms": round(elapsed_ms, 2)}) return response
145
+ pattern-either:
146
+ - pattern: |-
147
+ @app.middleware("http")
148
+ async def m(request, call_next):
149
+ return await call_next(request)
150
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-008\\b'
151
+ message: |-
152
+ RunSec Detection [LOG-008]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures
153
+ languages:
154
+ - generic
155
+ severity: WARNING
156
+ - id: runsec.observability.log-009
157
+ metadata:
158
+ runsec_version: v1.0
159
+ confidence: |-
160
+ 0.9
161
+ exploit_scenario: |-
162
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
163
+ fix_template: |-
164
+ record = {"event": "payment_approved", "id": pid, "trace_id": trace_id, "ts": datetime.now(timezone.utc).isoformat()} record["sig"] = hmac_sha256(audit_signing_key, json.dumps(record, sort_keys=True)) await append_only_audit_store.write(record)
165
+ pattern-either:
166
+ - pattern: |-
167
+ await audit_log.write({"event": "payment_approved", "id": pid})
168
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-009\\b'
169
+ message: |-
170
+ RunSec Detection [LOG-009]: OWASP ASVS v4.0.3 V10 Malicious Code and Business Logic; OWASP Top 10 (2021) A09
171
+ languages:
172
+ - generic
173
+ severity: WARNING
174
+ - id: runsec.observability.log-010
175
+ metadata:
176
+ runsec_version: v1.0
177
+ confidence: |-
178
+ 0.9
179
+ exploit_scenario: |-
180
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
181
+ fix_template: |-
182
+ @app.exception_handler(Exception) async def handle_exc(request: Request, exc: Exception): trace_id = getattr(request.state, "trace_id", "n/a") logger.exception("unhandled", extra={"trace_id": trace_id, "path": request.url.path}) return JSONResponse(status_code=500, content={"detail": "internal server error", "trace_id": trace_id})
183
+ pattern-either:
184
+ - pattern: |-
185
+ @app.get("/x")
186
+ async def x():
187
+ raise RuntimeError("db password is wrong: secret=...")
188
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-010\\b'
189
+ message: |-
190
+ RunSec Detection [LOG-010]: OWASP Top 10 (2021) A09; OWASP ASVS v4.0.3 V7 Error Handling
191
+ languages:
192
+ - generic
193
+ severity: WARNING
194
+ - id: runsec.observability.log-011
195
+ metadata:
196
+ runsec_version: v1.0
197
+ confidence: |-
198
+ 0.9
199
+ exploit_scenario: |-
200
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
201
+ fix_template: |-
202
+ def sanitize_for_log(value: str) -> str: return value.replace("\\r", "\\\\r").replace("\\n", "\\\\n") @app.get("/search") async def search(q: str): safe_q = sanitize_for_log(q) logger.info("search query=%s", safe_q) return {"ok": True}
203
+ pattern-either:
204
+ - pattern: |-
205
+ @app.get("/search")
206
+ async def search(q: str):
207
+ logger.info("search query=%s", q)
208
+ return {"ok": True}
209
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-011\\b'
210
+ message: |-
211
+ RunSec Detection [LOG-011]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V8 Logging and Error Handling; CWE-117
212
+ languages:
213
+ - generic
214
+ severity: WARNING
215
+ - id: runsec.observability.log-012
216
+ metadata:
217
+ runsec_version: v1.0
218
+ confidence: |-
219
+ 0.9
220
+ exploit_scenario: |-
221
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
222
+ fix_template: |-
223
+ except Exception: logger.exception("failed", extra={"trace_id": trace_id, "context": {"operation": "payment_create"}}) raise # production logger must not capture locals or full frame dumps
224
+ pattern-either:
225
+ - pattern: |-
226
+ except Exception:
227
+ logger.exception("failed", extra={"locals": locals()})
228
+ raise
229
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-012\\b'
230
+ message: |-
231
+ RunSec Detection [LOG-012]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V8 Logging and Error Handling
232
+ languages:
233
+ - generic
234
+ severity: WARNING
235
+ - id: runsec.observability.log-013
236
+ metadata:
237
+ runsec_version: v1.0
238
+ confidence: |-
239
+ 0.9
240
+ exploit_scenario: |-
241
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
242
+ fix_template: |-
243
+ async def security_heartbeat_task() -> None: while True: await audit_log.write({"event": "security_heartbeat", "service": "api", "status": "ok", "ts": datetime.now(timezone.utc).isoformat()}) await asyncio.sleep(60) @app.on_event("startup") async def start_heartbeat() -> None: asyncio.create_task(security_heartbeat_task())
244
+ pattern-either:
245
+ - pattern: |-
246
+ # no periodic liveness/integrity security event
247
+ pass
248
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-013\\b'
249
+ message: |-
250
+ RunSec Detection [LOG-013]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V8 Logging and Error Handling
251
+ languages:
252
+ - generic
253
+ severity: WARNING
254
+ - id: runsec.observability.log-014
255
+ metadata:
256
+ runsec_version: v1.0
257
+ confidence: |-
258
+ 0.9
259
+ exploit_scenario: |-
260
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
261
+ fix_template: |-
262
+ @app.post("/admin/users/{uid}/disable") async def disable_user(uid: int, actor=Depends(current_user)): logger.info("admin action requested", extra={"trace_id": trace_id, "actor_id": actor.id}) await security_audit_log.write({"event": "admin_user_disable", "actor_id": actor.id, "target_user_id": uid, "trace_id": trace_id, "ts": datetime.now(timezone.utc).isoformat()})
263
+ pattern-either:
264
+ - pattern: |-
265
+ @app.post("/admin/users/{uid}/disable")
266
+ async def disable_user(uid: int):
267
+ logger.info("disabled user %s", uid)
268
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-014\\b'
269
+ message: |-
270
+ RunSec Detection [LOG-014]: OWASP Top 10 (2021) A09 Security Logging and Monitoring Failures; OWASP ASVS v4.0.3 V8 Logging and Error Handling
271
+ languages:
272
+ - generic
273
+ severity: WARNING
274
+ - id: runsec.observability.log-015
275
+ metadata:
276
+ runsec_version: v1.0
277
+ confidence: |-
278
+ 0.9
279
+ exploit_scenario: |-
280
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
281
+ fix_template: |-
282
+ Structured logging + redaction filter для password fields.
283
+ pattern-either:
284
+ - pattern: |-
285
+ syslog.syslog(syslog.LOG_INFO, f"user_pass={password}")
286
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-015\\b'
287
+ message: |-
288
+ RunSec Detection [LOG-015]: CWE-312
289
+ languages:
290
+ - generic
291
+ severity: WARNING
292
+ - id: runsec.observability.log-016
293
+ metadata:
294
+ runsec_version: v1.0
295
+ confidence: |-
296
+ 0.9
297
+ exploit_scenario: |-
298
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
299
+ fix_template: |-
300
+ Log scrubber sidecar; deny print(environ) in prod.
301
+ pattern-either:
302
+ - pattern: |-
303
+ print(os.environ) в startup лог
304
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-016\\b'
305
+ message: |-
306
+ RunSec Detection [LOG-016]: CWE-532
307
+ languages:
308
+ - generic
309
+ severity: WARNING
310
+ - id: runsec.observability.log-017
311
+ metadata:
312
+ runsec_version: v1.0
313
+ confidence: |-
314
+ 0.9
315
+ exploit_scenario: |-
316
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
317
+ fix_template: |-
318
+ Token hash or presence flag only in EventLog.
319
+ pattern-either:
320
+ - pattern: |-
321
+ EventLog.WriteEntry("Auth", $"token={accessToken}")
322
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-017\\b'
323
+ message: |-
324
+ RunSec Detection [LOG-017]: CWE-312
325
+ languages:
326
+ - generic
327
+ severity: WARNING
328
+ - id: runsec.observability.log-018
329
+ metadata:
330
+ runsec_version: v1.0
331
+ confidence: |-
332
+ 0.9
333
+ exploit_scenario: |-
334
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
335
+ fix_template: |-
336
+ Redact Authorization/Cookie keys globally.
337
+ pattern-either:
338
+ - pattern: |-
339
+ logger.info({"Authorization": f"Bearer {tok}"})
340
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-018\\b'
341
+ message: |-
342
+ RunSec Detection [LOG-018]: CWE-532
343
+ languages:
344
+ - generic
345
+ severity: WARNING
346
+ - id: runsec.observability.log-019
347
+ metadata:
348
+ runsec_version: v1.0
349
+ confidence: |-
350
+ 0.9
351
+ exploit_scenario: |-
352
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
353
+ fix_template: |-
354
+ OTel semantic conventions + scrubbing processor.
355
+ pattern-either:
356
+ - pattern: |-
357
+ span.set_attribute("user.password", pwd)
358
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-019\\b'
359
+ message: |-
360
+ RunSec Detection [LOG-019]: CWE-532
361
+ languages:
362
+ - generic
363
+ severity: WARNING
364
+ - id: runsec.observability.log-020
365
+ metadata:
366
+ runsec_version: v1.0
367
+ confidence: |-
368
+ 0.9
369
+ exploit_scenario: |-
370
+ Атакующий доставляет входные данные, соответствующие anti-pattern; реальный ущерб зависит от приёмника (sink), конфигурации и границ доверия.
371
+ fix_template: |-
372
+ Sampling + redaction; max body length 0 in prod logs.
373
+ pattern-either:
374
+ - pattern: |-
375
+ logger.debug("upstream=%s", response.text)
376
+ - pattern-regex: 'Vulnerable:\\s*LOG\\-020\\b'
377
+ message: |-
378
+ RunSec Detection [LOG-020]: CWE-779
379
+ languages:
380
+ - generic
381
+ severity: WARNING