HimanshuGoyal2004 commited on
Commit
bd09aae
Β·
1 Parent(s): fbc9b21

nvd dataset

Browse files
Files changed (1) hide show
  1. app.py +247 -6
app.py CHANGED
@@ -219,7 +219,7 @@ Summary: {summary}
219
  result += f"- **CWE Code**: {metadata.get('cwe_code', 'Unknown')}\n"
220
  result += f"- **CWE Name**: {metadata.get('cwe_name', 'Unknown')}\n"
221
  result += f"- **CVSS Score**: {metadata.get('cvss', 'N/A')}\n"
222
-
223
  # Extract summary from content
224
  content_lines = doc.page_content.split('\n')
225
  summary_line = next((line for line in content_lines if line.startswith('Summary:')), '')
@@ -242,6 +242,218 @@ Summary: {summary}
242
 
243
  except Exception as e:
244
  return f"❌ Error retrieving CVE information: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
  # Initialize the GitHub MCP server
247
  github_server = GitHubMCPServer()
@@ -293,20 +505,49 @@ demo = gr.TabbedInterface(
293
  title="Search CVE Database",
294
  description="Search the CVE knowledge base for vulnerability patterns and CWE information",
295
  api_name="search_cve_database"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  )
297
  ],
298
  [
299
  "Repository Info",
300
  "File Content",
301
  "Repository Scanner",
302
- "CVE Database"
 
 
303
  ],
304
- title="πŸ™ GitHub MCP Server with CVE Knowledge Base"
305
  )
306
 
307
  if __name__ == "__main__":
308
- print("πŸš€ Starting GitHub MCP Server with CVE Knowledge Base...")
309
- print("πŸ“‘ Server will provide GitHub repository access and CVE search via MCP")
310
- print("πŸ› οΈ Available tools: repository info, file content, repository scanner, CVE database search")
 
 
 
 
 
 
311
 
312
  demo.launch(mcp_server=True)
 
219
  result += f"- **CWE Code**: {metadata.get('cwe_code', 'Unknown')}\n"
220
  result += f"- **CWE Name**: {metadata.get('cwe_name', 'Unknown')}\n"
221
  result += f"- **CVSS Score**: {metadata.get('cvss', 'N/A')}\n"
222
+
223
  # Extract summary from content
224
  content_lines = doc.page_content.split('\n')
225
  summary_line = next((line for line in content_lines if line.startswith('Summary:')), '')
 
242
 
243
  except Exception as e:
244
  return f"❌ Error retrieving CVE information: {str(e)}"
245
+
246
+ def get_nvd_cve_details(self, cve_id: str) -> str:
247
+ """
248
+ Fetches detailed CVE information from NVD (National Vulnerability Database).
249
+
250
+ Args:
251
+ cve_id: The CVE identifier (e.g., 'CVE-2019-16515')
252
+
253
+ Returns:
254
+ Formatted string containing detailed CVE information from NVD
255
+ """
256
+ try:
257
+ # Validate and clean CVE ID format
258
+ cve_id = cve_id.strip().upper()
259
+ if not cve_id.startswith('CVE-'):
260
+ return f"❌ Invalid CVE ID format: '{cve_id}'\nCVE ID must start with 'CVE-' (e.g., CVE-2019-16515)"
261
+
262
+ # NVD API endpoint
263
+ nvd_api_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"
264
+ nvd_web_url = f"https://nvd.nist.gov/vuln/detail/{cve_id}"
265
+
266
+ # Make request to NVD API
267
+ params = {"cveId": cve_id}
268
+ headers = {
269
+ "User-Agent": "VulnerabilityScanner/1.0 (GitHub Security Analysis Tool)"
270
+ }
271
+
272
+ print(f"πŸ” Fetching NVD details for {cve_id}...")
273
+ response = requests.get(nvd_api_url, params=params, headers=headers, timeout=15)
274
+
275
+ if response.status_code == 200:
276
+ data = response.json()
277
+
278
+ # Check if CVE was found
279
+ if data.get('resultsPerPage', 0) == 0:
280
+ return f"⚠️ CVE not found in NVD database: {cve_id}\n\nπŸ”— **NVD URL**: {nvd_web_url}\n\nNote: The CVE may not yet be published in NVD or the ID might be incorrect."
281
+
282
+ # Extract vulnerability data
283
+ vuln = data['vulnerabilities'][0]['cve']
284
+
285
+ # Build formatted result
286
+ result = f"πŸ“‹ **NVD CVE Details: {cve_id}**\n\n"
287
+ result += f"πŸ”— **NVD URL**: {nvd_web_url}\n\n"
288
+
289
+ # Status and dates
290
+ result += f"**Status**: {vuln.get('vulnStatus', 'N/A')}\n"
291
+ result += f"**Published**: {vuln.get('published', 'N/A')[:10]}\n"
292
+ result += f"**Last Modified**: {vuln.get('lastModified', 'N/A')[:10]}\n\n"
293
+
294
+ # Description
295
+ descriptions = vuln.get('descriptions', [])
296
+ for desc in descriptions:
297
+ if desc.get('lang') == 'en':
298
+ result += f"**πŸ“ Description**:\n{desc.get('value', 'N/A')}\n\n"
299
+ break
300
+
301
+ # CVSS Scores
302
+ metrics = vuln.get('metrics', {})
303
+
304
+ # CVSS v3.x (preferred)
305
+ if 'cvssMetricV31' in metrics or 'cvssMetricV30' in metrics:
306
+ cvss_key = 'cvssMetricV31' if 'cvssMetricV31' in metrics else 'cvssMetricV30'
307
+ cvss_v3 = metrics[cvss_key][0]['cvssData']
308
+
309
+ result += f"**🎯 CVSS v3 Score**:\n"
310
+ result += f"- **Base Score**: {cvss_v3.get('baseScore', 'N/A')} ({cvss_v3.get('baseSeverity', 'N/A')})\n"
311
+ result += f"- **Vector String**: {cvss_v3.get('vectorString', 'N/A')}\n"
312
+ result += f"- **Attack Vector**: {cvss_v3.get('attackVector', 'N/A')}\n"
313
+ result += f"- **Attack Complexity**: {cvss_v3.get('attackComplexity', 'N/A')}\n"
314
+ result += f"- **Privileges Required**: {cvss_v3.get('privilegesRequired', 'N/A')}\n"
315
+ result += f"- **User Interaction**: {cvss_v3.get('userInteraction', 'N/A')}\n"
316
+ result += f"- **Scope**: {cvss_v3.get('scope', 'N/A')}\n"
317
+ result += f"- **Confidentiality Impact**: {cvss_v3.get('confidentialityImpact', 'N/A')}\n"
318
+ result += f"- **Integrity Impact**: {cvss_v3.get('integrityImpact', 'N/A')}\n"
319
+ result += f"- **Availability Impact**: {cvss_v3.get('availabilityImpact', 'N/A')}\n\n"
320
+
321
+ # CVSS v2 (if available)
322
+ if 'cvssMetricV2' in metrics:
323
+ cvss_v2 = metrics['cvssMetricV2'][0]['cvssData']
324
+ result += f"**CVSS v2 Score**:\n"
325
+ result += f"- **Base Score**: {cvss_v2.get('baseScore', 'N/A')} ({metrics['cvssMetricV2'][0].get('baseSeverity', 'N/A')})\n"
326
+ result += f"- **Vector String**: {cvss_v2.get('vectorString', 'N/A')}\n\n"
327
+
328
+ # CWE (Common Weakness Enumeration)
329
+ weaknesses = vuln.get('weaknesses', [])
330
+ if weaknesses:
331
+ result += f"**πŸ” CWE (Common Weakness Enumeration)**:\n"
332
+ cwe_list = []
333
+ for weakness in weaknesses:
334
+ for desc in weakness.get('description', []):
335
+ if desc.get('lang') == 'en':
336
+ cwe_list.append(desc.get('value', 'N/A'))
337
+ result += f"- {', '.join(set(cwe_list))}\n\n"
338
+
339
+ # References
340
+ references = vuln.get('references', [])
341
+ if references:
342
+ result += f"**πŸ”— References** (showing first 5):\n"
343
+ for i, ref in enumerate(references[:5], 1):
344
+ result += f"{i}. [{ref.get('source', 'Source')}]({ref.get('url', '#')})\n"
345
+ if len(references) > 5:
346
+ result += f"\n... and {len(references) - 5} more references\n"
347
+ result += "\n"
348
+
349
+ result += f"---\n"
350
+ result += f"πŸ’‘ **Tip**: Use this CVE information to cross-reference vulnerabilities found in code analysis.\n"
351
+
352
+ return result
353
+
354
+ elif response.status_code == 404:
355
+ return f"⚠️ CVE not found: {cve_id}\n\nπŸ”— **NVD URL**: {nvd_web_url}\n\nThe CVE may not exist or may not yet be published in NVD."
356
+
357
+ elif response.status_code == 403:
358
+ return f"❌ Access denied to NVD API (HTTP 403)\n\nThis might be due to rate limiting. Please try again in a few moments.\n\nπŸ”— **NVD URL**: {nvd_web_url}"
359
+
360
+ else:
361
+ return f"❌ NVD API request failed with status {response.status_code}\n\nπŸ”— **NVD URL**: {nvd_web_url}\n\nYou can view the CVE details directly on the NVD website."
362
+
363
+ except requests.exceptions.Timeout:
364
+ return f"⏱️ Request to NVD API timed out for {cve_id}\n\nPlease try again or visit: {nvd_web_url}"
365
+
366
+ except requests.exceptions.RequestException as e:
367
+ return f"❌ Network error while fetching CVE details: {str(e)}\n\nπŸ”— **NVD URL**: {nvd_web_url}"
368
+
369
+ except Exception as e:
370
+ return f"❌ Unexpected error fetching NVD details for {cve_id}: {str(e)}\n\nπŸ”— **NVD URL**: {nvd_web_url}"
371
+
372
+ def search_and_fetch_cve_details(self, query: str, max_nvd_fetches: int = 5) -> str:
373
+ """
374
+ Smart combined function: Searches CVE database and automatically fetches NVD details.
375
+
376
+ This function:
377
+ 1. Searches the CVE knowledge base (RAG) for relevant vulnerabilities
378
+ 2. Automatically parses CVE IDs from the results
379
+ 3. Fetches detailed NVD information for top CVEs
380
+ 4. Returns combined results with both RAG data and NVD details
381
+
382
+ Args:
383
+ query: Vulnerability search query (e.g., "SQL injection", "XSS")
384
+ max_nvd_fetches: Maximum number of CVEs to fetch NVD details for (default: 5)
385
+
386
+ Returns:
387
+ Formatted string with RAG results + detailed NVD information
388
+ """
389
+ import re
390
+ import time
391
+
392
+ try:
393
+ # Step 1: Search CVE database using RAG
394
+ print(f"πŸ” Step 1: Searching CVE knowledge base for '{query}'...")
395
+ rag_results = self.search_cve_database(query)
396
+
397
+ if "❌" in rag_results or "No relevant CVE information found" in rag_results:
398
+ return rag_results
399
+
400
+ # Step 2: Parse CVE IDs from RAG results
401
+ print(f"πŸ“‹ Step 2: Parsing CVE IDs from results...")
402
+ cve_pattern = r'CVE-\d{4}-\d{4,7}'
403
+ cve_ids = re.findall(cve_pattern, rag_results)
404
+
405
+ # Remove duplicates and limit to max_nvd_fetches
406
+ unique_cve_ids = list(dict.fromkeys(cve_ids))[:max_nvd_fetches]
407
+
408
+ if not unique_cve_ids:
409
+ return rag_results + "\n\n⚠️ No CVE IDs found in results to fetch NVD details."
410
+
411
+ print(f"βœ… Found {len(unique_cve_ids)} unique CVE IDs: {', '.join(unique_cve_ids)}")
412
+
413
+ # Step 3: Build combined result
414
+ combined_result = "πŸ”¬ **COMPREHENSIVE CVE ANALYSIS**\n"
415
+ combined_result += "=" * 80 + "\n\n"
416
+
417
+ # Include RAG results first
418
+ combined_result += "## πŸ“š PART 1: CVE Knowledge Base Search Results\n\n"
419
+ combined_result += rag_results
420
+ combined_result += "\n\n" + "=" * 80 + "\n\n"
421
+
422
+ # Step 4: Fetch NVD details for each CVE
423
+ combined_result += f"## 🌐 PART 2: Detailed NVD Information (Top {len(unique_cve_ids)} CVEs)\n\n"
424
+ combined_result += f"Fetching official NVD details for: {', '.join(unique_cve_ids)}\n\n"
425
+ combined_result += "-" * 80 + "\n\n"
426
+
427
+ for idx, cve_id in enumerate(unique_cve_ids, 1):
428
+ print(f"🌐 Step 3.{idx}: Fetching NVD details for {cve_id}...")
429
+
430
+ # Fetch NVD details
431
+ nvd_result = self.get_nvd_cve_details(cve_id)
432
+
433
+ combined_result += nvd_result
434
+ combined_result += "\n" + "=" * 80 + "\n\n"
435
+
436
+ # Rate limiting: Add delay between requests (NVD recommends max 5 requests per 30 seconds)
437
+ if idx < len(unique_cve_ids):
438
+ time.sleep(6) # Wait 6 seconds between requests
439
+
440
+ # Step 5: Add summary
441
+ combined_result += "## πŸ“Š SUMMARY\n\n"
442
+ combined_result += f"βœ… **Total CVEs Analyzed**: {len(unique_cve_ids)}\n"
443
+ combined_result += f"βœ… **Search Query**: {query}\n"
444
+ combined_result += f"βœ… **RAG Results**: {len(cve_ids)} CVE references found\n"
445
+ combined_result += f"βœ… **NVD Details Fetched**: {len(unique_cve_ids)} CVEs\n\n"
446
+ combined_result += "πŸ’‘ **Next Steps**: Use this information to:\n"
447
+ combined_result += "- Cross-reference vulnerabilities in your code\n"
448
+ combined_result += "- Understand CVSS severity scores\n"
449
+ combined_result += "- Review CWE classifications\n"
450
+ combined_result += "- Check official NVD references for remediation guidance\n"
451
+
452
+ print(f"βœ… Combined analysis complete!")
453
+ return combined_result
454
+
455
+ except Exception as e:
456
+ return f"❌ Error in combined CVE analysis: {str(e)}\n\nPlease try using search_cve_database and get_nvd_cve_details separately."
457
 
458
  # Initialize the GitHub MCP server
459
  github_server = GitHubMCPServer()
 
505
  title="Search CVE Database",
506
  description="Search the CVE knowledge base for vulnerability patterns and CWE information",
507
  api_name="search_cve_database"
508
+ ),
509
+ gr.Interface(
510
+ fn=github_server.get_nvd_cve_details,
511
+ inputs=[
512
+ gr.Textbox(label="CVE ID", placeholder="CVE-2019-16515", value="CVE-2019-16515")
513
+ ],
514
+ outputs=gr.Textbox(label="NVD CVE Details", lines=30),
515
+ title="Get NVD CVE Details",
516
+ description="Fetch detailed CVE information from National Vulnerability Database (NVD)",
517
+ api_name="get_nvd_cve_details"
518
+ ),
519
+ gr.Interface(
520
+ fn=github_server.search_and_fetch_cve_details,
521
+ inputs=[
522
+ gr.Textbox(label="Vulnerability Query", placeholder="SQL injection, XSS, command injection, etc.", value="SQL injection"),
523
+ gr.Slider(minimum=1, maximum=10, value=5, step=1, label="Max NVD Fetches", info="Number of CVEs to fetch NVD details for")
524
+ ],
525
+ outputs=gr.Textbox(label="Comprehensive CVE Analysis", lines=40),
526
+ title="πŸ”¬ Smart CVE Analysis (RAG + NVD)",
527
+ description="Automatically searches CVE database AND fetches detailed NVD information for top CVEs",
528
+ api_name="search_and_fetch_cve_details"
529
  )
530
  ],
531
  [
532
  "Repository Info",
533
  "File Content",
534
  "Repository Scanner",
535
+ "CVE Database",
536
+ "NVD CVE Details",
537
+ "πŸ”¬ Smart CVE Analysis"
538
  ],
539
+ title="πŸ™ GitHub MCP Server with CVE Knowledge Base & NVD Integration"
540
  )
541
 
542
  if __name__ == "__main__":
543
+ print("πŸš€ Starting GitHub MCP Server with CVE Knowledge Base & NVD Integration...")
544
+ print("πŸ“‘ Server will provide GitHub repository access, CVE search, and NVD details via MCP")
545
+ print("πŸ› οΈ Available tools:")
546
+ print(" - get_repository_info: Get repository metadata")
547
+ print(" - get_file_content: Retrieve file contents")
548
+ print(" - scan_repository: Scan for code files")
549
+ print(" - search_cve_database: Search CVE knowledge base")
550
+ print(" - get_nvd_cve_details: Fetch detailed CVE info from NVD")
551
+ print(" - πŸ†• search_and_fetch_cve_details: Smart combined RAG + NVD analysis")
552
 
553
  demo.launch(mcp_server=True)