Skip to content

Add Cybersecurity PoC Agent Notebook #688

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Dhivya-Bharathy
Copy link
Contributor

@Dhivya-Bharathy Dhivya-Bharathy commented Jun 25, 2025

Adds a Google Colab notebook for the Pocky CVE PoC Query Tool.
Enables automated search and validation of CVE proof-of-concept exploits.
Includes API key setup, core logic, and a sample validation workflow.

Summary by CodeRabbit

  • New Features
    • Added a bilingual AI chatbot example for answering questions about Chilean government services, featuring translation and web search capabilities.
    • Introduced a cybersecurity agent example that automates searching, analyzing, and validating Proof-of-Concept exploits for CVE vulnerabilities.

Copy link
Contributor

coderabbitai bot commented Jun 25, 2025

Walkthrough

Two new Jupyter notebook examples are introduced. The first demonstrates a bilingual AI chatbot for Chilean government services using translation and Firecrawl API search. The second presents an automated agent workflow for cybersecurity, simulating the extraction and validation of Proof-of-Concept exploits for CVEs with dummy agent classes and a sample flow.

Changes

File(s) Change Summary
examples/cookbooks/Chile_Government_Services_Assistant.ipynb New notebook: Implements a bilingual AI chatbot for Chilean government services using translation helpers and a FirecrawlTool class.
examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb New notebook: Demonstrates an agent workflow for CVE PoC validation with sample classes and a main function for the process.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Chatbot
    participant FirecrawlTool
    participant Translator

    User->>Chatbot: Enter query (English)
    Chatbot->>Translator: Translate to Spanish
    Translator-->>Chatbot: Query (Spanish)
    Chatbot->>FirecrawlTool: Search ChileAtiende with query
    FirecrawlTool-->>Chatbot: Results (Spanish)
    Chatbot->>Translator: Translate results to English
    Translator-->>Chatbot: Results (English)
    Chatbot->>User: Display answer or ask for rephrasing
Loading
sequenceDiagram
    participant User
    participant run_pocky_for_cve
    participant AttackIntentAgent
    participant ValidationAgent

    User->>run_pocky_for_cve: Provide CVE ID
    run_pocky_for_cve->>AttackIntentAgent: Extract attack intent from CVE description
    AttackIntentAgent-->>run_pocky_for_cve: Attack intent
    run_pocky_for_cve->>ValidationAgent: Validate PoC against attack intent
    ValidationAgent-->>run_pocky_for_cve: Validation result
    run_pocky_for_cve->>User: Output result
Loading

Suggested labels

Review effort 2/5, Possible security concern

Poem

🐇
Two notebooks hop into view,
One helps Chileans, answers true—
The other sniffs out cyber threats,
With agents running clever tests.
From search to chat, from code to scan,
These rabbits code because they can!
🌱✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @Dhivya-Bharathy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily aims to add a Google Colab notebook for the Pocky CVE PoC Query Tool, enabling automated search and validation of CVE proof-of-concept exploits. Additionally, it introduces another Google Colab notebook that functions as an AI chatbot for Chilean government services.

Highlights

  • New Pocky CVE PoC Agent Notebook: Introduces examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb, a Google Colab notebook designed to automate the search, analysis, and validation of CVE Proof-of-Concept (PoC) exploits.
  • Automated PoC Validation Workflow: The Pocky notebook includes a workflow for setting up API keys (Exa, OpenAI), defining dummy agent classes for intent extraction and validation, and demonstrating how to query and validate a CVE PoC.
  • New Chile Government Services Assistant Notebook: Adds examples/cookbooks/Chile_Government_Services_Assistant.ipynb, a Google Colab notebook that provides an AI chatbot for answering questions about Chilean government services.
  • Multi-language AI Chatbot: The Chile Government Services Assistant notebook features integration with the Firecrawl API for searching and deep_translator for real-time English-Spanish translation of user queries and search results.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

codecov bot commented Jun 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 14.50%. Comparing base (e9f23e1) to head (eb6232a).
Report is 170 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #688   +/-   ##
=======================================
  Coverage   14.50%   14.50%           
=======================================
  Files          25       25           
  Lines        2517     2517           
  Branches      357      357           
=======================================
  Hits          365      365           
  Misses       2136     2136           
  Partials       16       16           
Flag Coverage Δ
quick-validation 0.00% <ø> (ø)
unit-tests 14.50% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request adds two new Google Colab notebooks, one for a Chile Government Services Assistant and another for a Pocky Cybersecurity PoC Agent. The review identified a medium severity issue in both notebooks related to the insecure handling of API keys, where they are hardcoded directly in the notebook. This could lead to exposure of sensitive information if the notebook is shared or made public. The review suggests using a more secure method for handling API keys, such as storing them in a dedicated secrets management system or using environment variables in a more robust way.

Comment on lines +69 to +70
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider using a more secure method for handling API keys, such as storing them in a dedicated secrets management system or using environment variables in a more robust way that avoids hardcoding them directly in the notebook. This is especially important if the notebook is shared or made public. This is a medium severity issue because it exposes sensitive information.

os.environ['FIRECRAWL_API_KEY'] = os.getenv('FIRECRAWL_API_KEY', 'your api key here')
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your api key here')

Comment on lines +78 to +80
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_BASE_URL\"] = \"https://api.openai.com/v1\" # Optional, for custom OpenAI endpoints"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider using a more secure method for handling API keys, such as storing them in a dedicated secrets management system or using environment variables in a more robust way that avoids hardcoding them directly in the notebook. This is especially important if the notebook is shared or made public. This is a medium severity issue because it exposes sensitive information.

os.environ["EXA_API_KEY"] = os.getenv("EXA_API_KEY", "your api key")
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your api key")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")  # Optional, for custom OpenAI endpoints

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
examples/cookbooks/Chile_Government_Services_Assistant.ipynb (3)

94-109: Translation functions need improvement.

The translation functions have basic error handling but could be more robust and informative.

Enhanced error handling and validation:

 def translate_to_spanish(text):
+    if not text or not text.strip():
+        return text
     try:
         return GoogleTranslator(source='auto', target='es').translate(text)
     except Exception as e:
-        print("Translation to Spanish failed:", e)
+        print(f"Translation to Spanish failed: {e}")
         return text

 def translate_to_english(text):
+    if not text or not text.strip():
+        return text
     try:
         # Remove Markdown images and None values before translation
         text = str(text).replace("None", "")
         text = re.sub(r'!\[.*?\]\(.*?\)', '', text)
+        # Also remove HTML tags that might interfere
+        text = re.sub(r'<[^>]+>', '', text)
         return GoogleTranslator(source='auto', target='en').translate(text)
     except Exception as e:
-        print("Translation to English failed:", e)
+        print(f"Translation to English failed: {e}")
         return text

150-153: URL filtering is too restrictive.

The current filtering only allows URLs starting with a very specific pattern and excludes PDFs entirely. This might miss relevant government information.

Consider more flexible filtering:

                 filtered_results = [
                     result for result in search_result.data
-                    if str(result.get("url", "")).startswith("https://www.chileatiende.gob.cl/fichas") and not str(result.get("url", "")).endswith("pdf")
+                    if ("chileatiende.gob.cl" in str(result.get("url", "")) or 
+                        "gob.cl" in str(result.get("url", ""))) and 
+                       not str(result.get("url", "")).endswith("pdf")
                 ]

131-135: Missing API key validation in FirecrawlTool initialization.

The constructor checks for API key presence but doesn't validate if the tool can actually connect to the service.

Add connection validation:

     def __init__(self, api_key, instruction: str, template: str):
         if not api_key:
             raise ValueError("Firecrawl API key not provided.")
+        if api_key == "your api key here":
+            raise ValueError("Please replace the placeholder API key with your actual Firecrawl API key.")
         self.app = FirecrawlApp(api_key=api_key)
         self.instruction = instruction
         self.template = template
+        # Test connection (optional)
+        try:
+            # Simple test search to validate API key
+            test_result = self.app.search(query="test", limit=1)
+        except Exception as e:
+            print(f"Warning: Could not validate Firecrawl API key: {e}")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f3ce5c and eb6232a.

📒 Files selected for processing (2)
  • examples/cookbooks/Chile_Government_Services_Assistant.ipynb (1 hunks)
  • examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test-examples
  • GitHub Check: performance-test
  • GitHub Check: test-core (3.11)
  • GitHub Check: quick-test
  • GitHub Check: Run tests and collect coverage

Comment on lines +105 to +118
"class ValidationAgent:\n",
" def __init__(self, input_json):\n",
" self.input_json = input_json\n",
" def run(self):\n",
" # Dummy validation logic for notebook demo\n",
" data = json.loads(self.input_json)\n",
" return True if \"attack_intent\" in data and \"poc_sample\" in data else False\n",
"\n",
"class AttackIntentAgent:\n",
" def __init__(self, description):\n",
" self.description = description\n",
" def run(self):\n",
" # Dummy intent extraction for notebook demo\n",
" return f\"Intent for: {self.description[:50]}...\""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Dummy agent classes lack real functionality.

The current dummy implementations are too simplistic for a meaningful demonstration. The ValidationAgent only checks for key existence, and AttackIntentAgent returns a truncated string.

Consider implementing more realistic functionality:

 class ValidationAgent:
     def __init__(self, input_json):
         self.input_json = input_json
+        self.client = OpenAI()
     
     def run(self):
-        # Dummy validation logic for notebook demo
         data = json.loads(self.input_json)
-        return True if "attack_intent" in data and "poc_sample" in data else False
+        if not ("attack_intent" in data and "poc_sample" in data):
+            return False
+        
+        # Use the validation prompt with actual OpenAI API
+        try:
+            response = self.client.chat.completions.create(
+                model="gpt-3.5-turbo",
+                messages=[
+                    {"role": "system", "content": validation_prompt},
+                    {"role": "user", "content": self.input_json}
+                ]
+            )
+            result = json.loads(response.choices[0].message.content)
+            return result.get("valid", False)
+        except Exception as e:
+            print(f"Validation error: {e}")
+            return False

 class AttackIntentAgent:
     def __init__(self, description):
         self.description = description
+        self.client = OpenAI()
     
     def run(self):
-        # Dummy intent extraction for notebook demo
-        return f"Intent for: {self.description[:50]}..."
+        try:
+            response = self.client.chat.completions.create(
+                model="gpt-3.5-turbo",
+                messages=[
+                    {"role": "system", "content": "Extract and describe the attack intent from this CVE description."},
+                    {"role": "user", "content": self.description}
+                ]
+            )
+            return response.choices[0].message.content
+        except Exception as e:
+            print(f"Intent extraction error: {e}")
+            return f"Error extracting intent: {e}"

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 105 to
118, the ValidationAgent and AttackIntentAgent classes have overly simplistic
dummy implementations that do not provide meaningful validation or intent
extraction. Enhance ValidationAgent to perform deeper validation of the input
JSON structure and content beyond just key existence, and improve
AttackIntentAgent to analyze the description text more thoroughly to extract or
infer a plausible attack intent rather than returning a simple truncated string.

Comment on lines +77 to +80
"# Set your API keys here (replace with your actual keys)\n",
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_BASE_URL\"] = \"https://api.openai.com/v1\" # Optional, for custom OpenAI endpoints"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security risk: Hardcoded API key placeholders.

The hardcoded placeholder API keys pose a security risk and usability issue. Users might accidentally commit real keys or forget to replace them.

Consider this improvement:

-# Set your API keys here (replace with your actual keys)
-os.environ["EXA_API_KEY"] = "your api key"
-os.environ["OPENAI_API_KEY"] = "your api key"
-os.environ["OPENAI_BASE_URL"] = "https://api.openai.com/v1"  # Optional, for custom OpenAI endpoints
+# Set your API keys here
+from getpass import getpass
+
+if not os.environ.get("EXA_API_KEY"):
+    os.environ["EXA_API_KEY"] = getpass("Enter your EXA API key: ")
+if not os.environ.get("OPENAI_API_KEY"):
+    os.environ["OPENAI_API_KEY"] = getpass("Enter your OpenAI API key: ")
+os.environ["OPENAI_BASE_URL"] = "https://api.openai.com/v1"  # Optional, for custom OpenAI endpoints
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"# Set your API keys here (replace with your actual keys)\n",
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n",
"os.environ[\"OPENAI_BASE_URL\"] = \"https://api.openai.com/v1\" # Optional, for custom OpenAI endpoints"
# Set your API keys here
from getpass import getpass
if not os.environ.get("EXA_API_KEY"):
os.environ["EXA_API_KEY"] = getpass("Enter your EXA API key: ")
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass("Enter your OpenAI API key: ")
os.environ["OPENAI_BASE_URL"] = "https://api.openai.com/v1" # Optional, for custom OpenAI endpoints
🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 77 to 80,
the API keys are hardcoded as placeholder strings, which risks accidental
exposure or misuse. Replace these hardcoded assignments by prompting users to
set their API keys externally, such as through environment variables or a secure
configuration file, and update the code to read the keys from those secure
sources instead of embedding them directly.

Comment on lines +174 to +190
"def run_pocky_for_cve(cve_id):\n",
" # Example: Simulate fetching a description and PoC (replace with real logic)\n",
" description = f\"Description for {cve_id} (replace with real Exa/OpenAI search)\"\n",
" poc_sample = f\"PoC code for {cve_id} (replace with real PoC search)\"\n",
"\n",
" # Stage 2: Attack Intent\n",
" intent = AttackIntentAgent(description).run()\n",
" print(f\"Attack Intent: {intent}\")\n",
"\n",
" # Stage 3: Validation\n",
" validation_input = json.dumps({\"attack_intent\": intent, \"poc_sample\": poc_sample}, indent=2)\n",
" valid = ValidationAgent(validation_input).run()\n",
" print(f\"Validation Result: {valid}\")\n",
" if valid:\n",
" print(f\"PoC for {cve_id} is valid and ready to use.\")\n",
" else:\n",
" print(f\"PoC for {cve_id} failed validation.\")"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Main function lacks real CVE data integration.

The function uses placeholder strings instead of integrating with the installed dependencies (exa-py, requests) to fetch real CVE data.

Implement real CVE data fetching:

 def run_pocky_for_cve(cve_id):
-    # Example: Simulate fetching a description and PoC (replace with real logic)
-    description = f"Description for {cve_id} (replace with real Exa/OpenAI search)"
-    poc_sample = f"PoC code for {cve_id} (replace with real PoC search)"
+    # Fetch CVE description from public sources
+    try:
+        import requests
+        cve_response = requests.get(f"https://cve.circl.lu/api/cve/{cve_id}")
+        if cve_response.status_code == 200:
+            cve_data = cve_response.json()
+            description = cve_data.get('summary', f'No description found for {cve_id}')
+        else:
+            description = f"Could not fetch description for {cve_id}"
+        
+        # Use Exa to search for PoC samples
+        exa = Exa(api_key=os.environ.get("EXA_API_KEY"))
+        search_results = exa.search(
+            f"{cve_id} proof of concept exploit github",
+            num_results=3,
+            include_domains=["github.com", "exploit-db.com"]
+        )
+        poc_sample = search_results.results[0].text if search_results.results else "No PoC found"
+        
+    except Exception as e:
+        print(f"Error fetching data: {e}")
+        description = f"Error fetching description for {cve_id}"
+        poc_sample = "Error fetching PoC"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"def run_pocky_for_cve(cve_id):\n",
" # Example: Simulate fetching a description and PoC (replace with real logic)\n",
" description = f\"Description for {cve_id} (replace with real Exa/OpenAI search)\"\n",
" poc_sample = f\"PoC code for {cve_id} (replace with real PoC search)\"\n",
"\n",
" # Stage 2: Attack Intent\n",
" intent = AttackIntentAgent(description).run()\n",
" print(f\"Attack Intent: {intent}\")\n",
"\n",
" # Stage 3: Validation\n",
" validation_input = json.dumps({\"attack_intent\": intent, \"poc_sample\": poc_sample}, indent=2)\n",
" valid = ValidationAgent(validation_input).run()\n",
" print(f\"Validation Result: {valid}\")\n",
" if valid:\n",
" print(f\"PoC for {cve_id} is valid and ready to use.\")\n",
" else:\n",
" print(f\"PoC for {cve_id} failed validation.\")"
def run_pocky_for_cve(cve_id):
# Fetch CVE description from public sources
try:
import requests
cve_response = requests.get(f"https://cve.circl.lu/api/cve/{cve_id}")
if cve_response.status_code == 200:
cve_data = cve_response.json()
description = cve_data.get('summary', f'No description found for {cve_id}')
else:
description = f"Could not fetch description for {cve_id}"
# Use Exa to search for PoC samples
exa = Exa(api_key=os.environ.get("EXA_API_KEY"))
search_results = exa.search(
f"{cve_id} proof of concept exploit github",
num_results=3,
include_domains=["github.com", "exploit-db.com"]
)
poc_sample = search_results.results[0].text if search_results.results else "No PoC found"
except Exception as e:
print(f"Error fetching data: {e}")
description = f"Error fetching description for {cve_id}"
poc_sample = "Error fetching PoC"
# Stage 2: Attack Intent
intent = AttackIntentAgent(description).run()
print(f"Attack Intent: {intent}")
# Stage 3: Validation
validation_input = json.dumps({"attack_intent": intent, "poc_sample": poc_sample}, indent=2)
valid = ValidationAgent(validation_input).run()
print(f"Validation Result: {valid}")
if valid:
print(f"PoC for {cve_id} is valid and ready to use.")
else:
print(f"PoC for {cve_id} failed validation.")
🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 174 to
190, the run_pocky_for_cve function uses placeholder strings instead of fetching
real CVE data. Replace the placeholder description and PoC sample with actual
data retrieval logic by using the installed dependencies like exa-py or requests
to query a CVE database or API. Ensure the function fetches real CVE
descriptions and PoC code dynamically before proceeding with the attack intent
and validation stages.

Comment on lines +69 to +70
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security risk: Hardcoded API key placeholders.

Similar to the other notebook, hardcoded placeholder API keys create security and usability risks.

Apply the same secure approach:

-os.environ['FIRECRAWL_API_KEY'] = "your api key here"
-os.environ['OPENAI_API_KEY'] = "your api key here"
+from getpass import getpass
+
+if not os.environ.get('FIRECRAWL_API_KEY'):
+    os.environ['FIRECRAWL_API_KEY'] = getpass("Enter your Firecrawl API key: ")
+if not os.environ.get('OPENAI_API_KEY'):
+    os.environ['OPENAI_API_KEY'] = getpass("Enter your OpenAI API key: ")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
from getpass import getpass
if not os.environ.get('FIRECRAWL_API_KEY'):
os.environ['FIRECRAWL_API_KEY'] = getpass("Enter your Firecrawl API key: ")
if not os.environ.get('OPENAI_API_KEY'):
os.environ['OPENAI_API_KEY'] = getpass("Enter your OpenAI API key: ")
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb at lines 69-70,
the API keys are hardcoded as placeholders in the environment variables, which
poses security risks. Remove these hardcoded strings and instead instruct users
to set their API keys securely outside the notebook, such as through environment
variables in their system or a secure secrets manager, and access them
dynamically within the code.

Comment on lines +264 to +282
"while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in [\"exit\", \"quit\"]:\n",
" print(\"Tomás: It was a pleasure to help you. Goodbye!\")\n",
" break\n",
"\n",
" # Translate English input to Spanish for Firecrawl\n",
" spanish_query = translate_to_spanish(user_input)\n",
" spanish_answer = firecrawl_tool.search(spanish_query)\n",
"\n",
" # Only translate if we got a real answer\n",
" if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and \"Error\" not in spanish_answer:\n",
" try:\n",
" english_answer = translate_to_english(spanish_answer)\n",
" print(\"\\nTomás (in English):\\n\", english_answer)\n",
" except Exception as e:\n",
" print(f\"\\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\\n{spanish_answer}\\n(Translation error: {e})\")\n",
" else:\n",
" print(\"\\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.\")"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Chat loop lacks comprehensive error handling.

The main chat loop doesn't handle potential exceptions from API calls, which could crash the entire interaction.

Add proper error handling:

 while True:
-    user_input = input("\nYou: ")
+    try:
+        user_input = input("\nYou: ")
+    except (KeyboardInterrupt, EOFError):
+        print("\nTomás: It was a pleasure to help you. Goodbye!")
+        break
+        
     if user_input.lower() in ["exit", "quit"]:
         print("Tomás: It was a pleasure to help you. Goodbye!")
         break

-    # Translate English input to Spanish for Firecrawl
-    spanish_query = translate_to_spanish(user_input)
-    spanish_answer = firecrawl_tool.search(spanish_query)
+    try:
+        # Translate English input to Spanish for Firecrawl
+        spanish_query = translate_to_spanish(user_input)
+        spanish_answer = firecrawl_tool.search(spanish_query)
+    except Exception as e:
+        print(f"\nTomás: Sorry, I encountered an error while searching: {e}")
+        continue

     # Only translate if we got a real answer
     if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and "Error" not in spanish_answer:
         try:
             english_answer = translate_to_english(spanish_answer)
             print("\nTomás (in English):\n", english_answer)
         except Exception as e:
             print(f"\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\n{spanish_answer}\n(Translation error: {e})")
     else:
         print("\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in [\"exit\", \"quit\"]:\n",
" print(\"Tomás: It was a pleasure to help you. Goodbye!\")\n",
" break\n",
"\n",
" # Translate English input to Spanish for Firecrawl\n",
" spanish_query = translate_to_spanish(user_input)\n",
" spanish_answer = firecrawl_tool.search(spanish_query)\n",
"\n",
" # Only translate if we got a real answer\n",
" if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and \"Error\" not in spanish_answer:\n",
" try:\n",
" english_answer = translate_to_english(spanish_answer)\n",
" print(\"\\nTomás (in English):\\n\", english_answer)\n",
" except Exception as e:\n",
" print(f\"\\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\\n{spanish_answer}\\n(Translation error: {e})\")\n",
" else:\n",
" print(\"\\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.\")"
while True:
try:
user_input = input("\nYou: ")
except (KeyboardInterrupt, EOFError):
print("\nTomás: It was a pleasure to help you. Goodbye!")
break
if user_input.lower() in ["exit", "quit"]:
print("Tomás: It was a pleasure to help you. Goodbye!")
break
try:
# Translate English input to Spanish for Firecrawl
spanish_query = translate_to_spanish(user_input)
spanish_answer = firecrawl_tool.search(spanish_query)
except Exception as e:
print(f"\nTomás: Sorry, I encountered an error while searching: {e}")
continue
# Only translate if we got a real answer
if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and "Error" not in spanish_answer:
try:
english_answer = translate_to_english(spanish_answer)
print("\nTomás (in English):\n", english_answer)
except Exception as e:
print(
f"\nTomás: I found information, but couldn't translate it. "
f"Here it is in Spanish:\n{spanish_answer}\n(Translation error: {e})"
)
else:
print(
"\nTomás: Sorry, I couldn't find relevant information. "
"Try rephrasing your question or ask about another service."
)
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb around lines 264
to 282, the main chat loop lacks error handling for API calls like
translate_to_spanish, firecrawl_tool.search, and translate_to_english, risking
crashes. Wrap the entire loop body inside a try-except block to catch exceptions
from these calls, and in the except block, print a user-friendly error message
and continue the loop to maintain interaction stability.

@Dhivya-Bharathy Dhivya-Bharathy changed the title Add-Pocky_Cybersecurity_PoC_Agent Notebook Add Cybersecurity PoC Agent Notebook Jun 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant