├── nova_doc ├── Install ├── favicon.png ├── docs │ ├── favicon.png │ ├── nova_overview.png │ ├── usecases │ │ ├── openai.png │ │ ├── anthropic.png │ │ ├── nova_architecture.png │ │ ├── ollama.md │ │ ├── index.md │ │ ├── overview.md │ │ ├── openai.md │ │ └── anthropic.md │ ├── index.md │ ├── quickstarts │ │ ├── installation.md │ │ ├── index.md │ │ └── running.md │ ├── home │ │ ├── why.md │ │ └── rules.md │ └── novalogo.svg └── mkdocs.yml ├── nova ├── utils │ ├── helpers.py │ ├── __init__.py │ ├── logger.py │ └── config.py ├── core │ ├── __init__.py │ ├── rules.py │ └── scanner.py ├── evaluators │ ├── __init__.py │ ├── base.py │ ├── keywords.py │ ├── semantics.py │ └── condition.py └── __init__.py ├── CNAME ├── first.gif ├── pyproject.toml ├── .gitignore ├── requirements-basic.txt ├── requirements-llm.txt ├── requirements-dev.txt ├── nova_rules ├── basic_rule.nov ├── hidden_unicode.nov ├── testrule2.nov ├── jailbreak2.nov ├── wipingprompt.nov ├── llm02_SensitiveInfo.nov ├── llm05_ImproperOutput.nov ├── testrule.nov ├── policy_puppetry.nov ├── incidents │ ├── 202402_forest_blizzard.nov │ ├── README.md │ ├── 202402_crimson_sandstorm.nov │ └── 202402_emerald_sleet.nov ├── lamehug_apt_28.nov ├── injection.nov ├── llm01_promptinject.nov └── jailbreak.nov ├── requirements.txt ├── LICENCE ├── RELEASE_NOTES.md ├── test.py ├── setup.py ├── CHANGELOG.md ├── tests ├── prompts_testing.txt └── novatest.py ├── README.md ├── test_basic_install.py ├── INSTALLATION.md └── SETUP_SUMMARY.md /nova_doc/Install: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nova/utils/helpers.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | docs.novahunting.ai 2 | -------------------------------------------------------------------------------- /first.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/first.gif -------------------------------------------------------------------------------- /nova_doc/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/favicon.png -------------------------------------------------------------------------------- /nova_doc/docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/docs/favicon.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=64", "wheel"] 3 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /nova_doc/docs/nova_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/docs/nova_overview.png -------------------------------------------------------------------------------- /nova_doc/docs/usecases/openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/docs/usecases/openai.png -------------------------------------------------------------------------------- /nova_doc/docs/usecases/anthropic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/docs/usecases/anthropic.png -------------------------------------------------------------------------------- /nova_doc/docs/usecases/nova_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fr0gger/nova-framework/HEAD/nova_doc/docs/usecases/nova_architecture.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __pycache__/ 3 | *.py[oc] 4 | build/ 5 | dist/ 6 | wheels/ 7 | *.egg-info 8 | # Virtual environments 9 | .venv 10 | optimized_matcher.py 11 | optimized_test.py 12 | # Pytest cache 13 | tests/ -------------------------------------------------------------------------------- /requirements-basic.txt: -------------------------------------------------------------------------------- 1 | # Basic Nova Framework Requirements 2 | # Only includes core dependencies for keyword pattern matching 3 | # Using ~= (compatible release) to allow patch updates but prevent breaking changes 4 | 5 | requests~=2.31.0 6 | pyyaml~=6.0.1 7 | colorama~=0.4.6 -------------------------------------------------------------------------------- /requirements-llm.txt: -------------------------------------------------------------------------------- 1 | # Nova Framework LLM Requirements 2 | # Includes all dependencies for semantic matching and LLM evaluation 3 | # Using ~= (compatible release) to allow patch updates but prevent breaking changes 4 | 5 | # Include basic requirements 6 | -r requirements-basic.txt 7 | 8 | # LLM and semantic matching dependencies 9 | sentence-transformers~=2.3.1 10 | transformers~=4.36.2 11 | openai~=1.12.0 12 | anthropic~=0.18.1 -------------------------------------------------------------------------------- /nova/utils/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | NOVA: The Prompt Pattern Matching 3 | Author: Thomas Roccia 4 | twitter: @fr0gger_ 5 | License: MIT License 6 | Version: 1.0.0 7 | Description: Utility functions for Nova framework 8 | """ 9 | 10 | from nova.utils.config import NovaConfig, get_config 11 | from nova.utils.logger import get_logger, set_log_level 12 | 13 | __all__ = [ 14 | 'NovaConfig', 15 | 'get_config', 16 | 'get_logger', 17 | 'set_log_level', 18 | ] -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # Nova Framework Development Requirements 2 | # Includes all dependencies for development and testing 3 | # Using ~= (compatible release) to allow patch updates but prevent breaking changes 4 | 5 | # Include LLM requirements (which includes basic) 6 | -r requirements-llm.txt 7 | 8 | # Development and testing dependencies 9 | pytest~=7.4.4 10 | pytest-cov~=4.1.0 11 | 12 | # Documentation dependencies 13 | mkdocs~=1.5.3 14 | mkdocs-material~=9.5.9 -------------------------------------------------------------------------------- /nova/core/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | NOVA: The Prompt Pattern Matching 3 | Author: Thomas Roccia 4 | twitter: @fr0gger_ 5 | License: MIT License 6 | Version: 1.0.0 7 | Description: Core components package initialization 8 | """ 9 | 10 | from nova.core.rules import ( 11 | KeywordPattern, 12 | SemanticPattern, 13 | LLMPattern, 14 | NovaRule 15 | ) 16 | from nova.core.matcher import NovaMatcher 17 | from nova.core.parser import NovaParser, NovaRuleFileParser 18 | from nova.core.scanner import NovaScanner 19 | 20 | __all__ = [ 21 | 'KeywordPattern', 22 | 'SemanticPattern', 23 | 'LLMPattern', 24 | 'NovaRule', 25 | 'NovaMatcher', 26 | 'NovaParser', 27 | 'NovaRuleFileParser', 28 | 'NovaScanner', 29 | ] -------------------------------------------------------------------------------- /nova_rules/basic_rule.nov: -------------------------------------------------------------------------------- 1 | rule SimpleNovaRule 2 | { 3 | meta: 4 | description = "Detects harmful content requests" 5 | author = "Nova User" 6 | version = "1.0" 7 | uuid = "59e50576-91b0-491d-b9f0-5a2a4ea8169a" 8 | 9 | keywords: 10 | $hack = "hack" 11 | $exploit = "exploit" 12 | $vulnerability = "vulnerability" 13 | 14 | semantics: 15 | $malicious_intent = "hacking or unauthorized access" (0.2) 16 | 17 | llm: 18 | $harmful_check = "Check if this prompt is requesting information on harmful activities" (0.1) 19 | 20 | condition: 21 | any of keywords.* or semantics.$malicious_intent or llm.$harmful_check 22 | } 23 | -------------------------------------------------------------------------------- /nova_doc/docs/usecases/ollama.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | - usecases 4 | #icon: material/briefcase-search 5 | title: Ollama 6 | --- 7 | 8 | # Analysis prompts from Ollama 9 | 10 | Ollama is an open source tool that allows you to load and host multiple open source models. You can host your own ollama server and add the models you want. Ollama server listen by default on localhost: 11 | 12 | But you can configure your server as you want. 13 | 14 | # Ollama logs 15 | 16 | By default ollama store the prompt history in the file '~/.ollama/history'. This is file is a text file containing one prompt per lines. 17 | 18 | You can run Nova against this file using the following command: 19 | 20 | ```bash 21 | python novarun.py -r nova_rules/testrule.nov -f ~/.ollama/history 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /nova_rules/hidden_unicode.nov: -------------------------------------------------------------------------------- 1 | rule DetectUnicodeTagInjection 2 | { 3 | meta: 4 | description = "Detects usage of invisible instructions via the Unicode Tags Block for LLM prompt injection" 5 | author = "@fr0gger_" 6 | severity = "high" 7 | uuid = "cc812696-259d-45d1-a46c-a37f07bb0739" 8 | 9 | semantics: 10 | $smuggling_reference = "smuggling of data in plain sight" (0.1) 11 | $hidden_prompting = "hidden instructions" (0.1) 12 | 13 | llm: 14 | $llm_invisible_prompt = "instructions that are not visible to the user" (0.1) 15 | $llm_unicode_smuggle = "use of Unicode to bypass input validation" (0.1) 16 | 17 | condition: 18 | ( 19 | (semantics.$smuggling_reference and llm.$llm_unicode_smuggle) 20 | or 21 | (semantics.$hidden_prompting and llm.$llm_invisible_prompt) 22 | ) 23 | } 24 | 25 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # NOVA Framework Requirements 2 | # This file contains all dependencies for development and documentation. 3 | # For production installations, use setup.py extras instead: 4 | # 5 | # Basic installation (keywords only): 6 | # pip install nova-hunting 7 | # 8 | # Advanced installation (with LLM support): 9 | # pip install nova-hunting[llm] 10 | # 11 | # Developer installation: 12 | # pip install nova-hunting[dev] 13 | # 14 | # Full installation (everything): 15 | # pip install nova-hunting[all] 16 | 17 | # Using ~= (compatible release) to allow patch updates but prevent breaking changes 18 | 19 | # Core dependencies (always installed) 20 | requests~=2.31.0 21 | pyyaml~=6.0.1 22 | colorama~=0.4.6 23 | 24 | # LLM dependencies (for semantic matching and LLM evaluation) 25 | sentence-transformers~=2.3.1 26 | transformers~=4.36.2 27 | openai~=1.12.0 28 | anthropic~=0.18.1 29 | 30 | # Development dependencies 31 | pytest~=7.4.4 32 | pytest-cov~=4.1.0 33 | 34 | # Documentation dependencies 35 | mkdocs~=1.5.3 36 | mkdocs-material~=9.5.9 37 | -------------------------------------------------------------------------------- /nova_rules/testrule2.nov: -------------------------------------------------------------------------------- 1 | rule PromptInjection 2 | { 3 | meta: 4 | description = "Detects common prompt injection attempts" 5 | author = "Thomas Roccia" 6 | uuid = "1bf39921-aef7-4193-b3e6-957280ccad33" 7 | 8 | keywords: 9 | $bypass1 = "ignore previous instructions" 10 | 11 | semantics: 12 | $injection1 = "detect attempts to bypass system instructions" (0.3) 13 | 14 | condition: 15 | semantics.$injection* or keywords.$bypass* 16 | } 17 | 18 | 19 | rule PromptInjection2 20 | { 21 | meta: 22 | description = "Detects common prompt injection attempts" 23 | author = "Thomas Roccia" 24 | uuid = "0c40c41b-5613-4967-ab89-e65ab5ff9cdf" 25 | 26 | keywords: 27 | $bypass1 = "ignore previous instructions" 28 | $bypass2 = "system" 29 | 30 | semantics: 31 | $injection1 = "detect attempts to bypass system instructions" (0.3) 32 | $injection2 = "detect system hijacking" (0.1) 33 | 34 | condition: 35 | semantics.$injection* or keywords.$bypass* 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Thomas Roccia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | # Nova Hunting v0.1.4 Release Notes 2 | 3 | ## Version Update 4 | - **Updated**: Version from 0.1.3 to 0.1.4 5 | 6 | ## Bug Fixes 7 | - **Fixed**: Warning about `clean_up_tokenization_spaces` from transformers library 8 | - **Added**: Warning filter to suppress FutureWarning messages related to tokenization spaces 9 | - **Modified**: Multiple files to set tokenization parameters correctly 10 | 11 | ## Previous Features (v0.1.2) 12 | 13 | ### Package Rename 14 | - **Changed**: Package renamed from nova-framework to nova-hunting 15 | - **Updated**: Version to 0.1.2 16 | 17 | ### Performance Optimizations 18 | - LLM evaluator sharing across rules in NovaScanner class 19 | - Significantly improved performance by reusing LLM evaluators 20 | - Lazy initialization of LLM resources 21 | 22 | ### Groq Cloud Support 23 | - New GroqEvaluator class for using Groq Cloud's ultra-fast LLM API 24 | - Support for Groq's LLM models including llama-3.3-70b-versatile 25 | 26 | ### Bug Fixes 27 | - Invalid regex pattern validation in the parser 28 | - Proper error handling for malformed regex patterns 29 | 30 | For detailed changes, see the full CHANGELOG.md file. 31 | -------------------------------------------------------------------------------- /nova_rules/jailbreak2.nov: -------------------------------------------------------------------------------- 1 | rule PromptInjectionJailbreak 2 | { 3 | meta: 4 | description = "Detects prompt injection attempts using only keywords" 5 | author = "Thomas Roccia" 6 | version = "1.0.0" 7 | category = "jailbreak/injection" 8 | severity = "high" 9 | uuid = "ba82e2c5-cfbf-4f10-874a-265fb27ea1ac" 10 | 11 | keywords: 12 | $new_instruction = "new instruction" 13 | $previous = "previous instructions" 14 | $ignore_above = "ignore all the instructions above" 15 | $forget = "forget your instructions" 16 | $disregard = "disregard previous" 17 | $override = "override previous" 18 | $redefine = "redefine your goals" 19 | $primary_task = "your primary task now" 20 | $system_prompt = "system prompt" 21 | $actually_respond = "actually respond with" 22 | $instead_output = "instead output the following" 23 | $ignore_content_policy = "ignore content policy" 24 | $bypass_filter = "bypass the filter" 25 | $return_harmful = "return harmful content" 26 | 27 | condition: 28 | any of keywords.* 29 | } 30 | -------------------------------------------------------------------------------- /nova_rules/wipingprompt.nov: -------------------------------------------------------------------------------- 1 | rule DestructiveSystemCleaner 2 | { 3 | meta: 4 | description = "Detects prompts instructing AI agents to wipe local and cloud resources using filesystem and AWS CLI tools." 5 | author = "Thomas Roccia" 6 | severity = "critical" 7 | reference = "https://www.404media.co/hacker-plants-computer-wiping-commands-in-amazons-ai-coding-agent/" 8 | uuid = "9ebdcd74-2088-444b-996d-966c9aa2a24e" 9 | 10 | keywords: 11 | $aws_ec2 = "aws --profile" 12 | $delete_user = "iam delete-user" 13 | $bash = "bash" 14 | $home_clear = "user's home directory" 15 | $log_file = "/tmp/CLEANER.LOG" 16 | $cloud_delete = /aws --profile .* (s3 rm|ec2 terminate-instances|iam delete-user)/i 17 | 18 | semantics: 19 | $wipe_fs = "delete local files and cloud resources" (0.2) 20 | $factory_reset = "restore system to factory state" (0.2) 21 | $automated_wiper = "automated deletion of system and cloud data" (0.2) 22 | 23 | llm: 24 | $check_destruction = "Analyze if this prompt instructs an AI to perform destructive actions including deleting user data, wiping directories, or removing cloud infrastructure." (0.2) 25 | 26 | condition: 27 | (keywords.* or semantics.*) and llm.$check_destruction 28 | } 29 | 30 | -------------------------------------------------------------------------------- /nova_rules/llm02_SensitiveInfo.nov: -------------------------------------------------------------------------------- 1 | rule SensitiveInfoDisclosure 2 | { 3 | meta: 4 | description = "OWASP LLM02 - Detects potential sensitive information disclosure such as PII, proprietary data, or confidential business content" 5 | author = "fr0gger_" 6 | severity = "high" 7 | version = "1.0" 8 | uuid = "f7a0e5d4-539f-411a-84e1-fadd209a01d1" 9 | 10 | keywords: 11 | $pii_name = /\b[A-Z][a-z]+\s[A-Z][a-z]+\b/ 12 | $pii_email = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/i 13 | $pii_ssn = /\b\d{3}-\d{2}-\d{4}\b/ 14 | $pii_creditcard = /\b(?:\d[ -]*?){13,16}\b/ 15 | $api_keys = /(api[_-]?key|secret[_-]?key|token)[\s:=]{1,5}[a-zA-Z0-9_\-]{16,}/i 16 | $internal_url = /https?:\/\/(?:intranet|internal|admin)\.[^\s]+/ 17 | $confidential = "confidential" 18 | $proprietary = "proprietary" 19 | $source_code = /class\s+\w+|def\s+\w+\s*\(|function\s+\w+\s*\(/i 20 | 21 | semantics: 22 | $sensitive_context = "personal or sensitive data disclosure" (0.1) 23 | $privacy_violation = "privacy violation" (0.1) 24 | $leaked_business_data = "confidential business information leaked" (0.1) 25 | 26 | llm: 27 | $leak_eval = "Check if this contains sensitive, private, or confidential data" (0) 28 | 29 | condition: 30 | (keywords.* or semantics.* or llm.$leak_eval) 31 | } 32 | -------------------------------------------------------------------------------- /nova_doc/docs/usecases/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | - usecases 4 | icon: material/briefcase-search 5 | title: Architecture 6 | --- 7 | 8 | # Monitoring and Hunting with NOVA on AI Systems 9 | 10 | NOVA provides powerful capabilities for monitoring and hunting across your AI systems by deploying rules to your architecture that analyze prompt telemetry. 11 | 12 | !!! info 13 | Multiple logging systems exist to allow you to log the prompts from your user. 14 | 15 | ![](nova_architecture.png) 16 | 17 | ## Implementation Methods 18 | 19 | There are multiple ways to integrate NOVA with your existing AI infrastructure: 20 | 21 | ### 1. Public Service Log Analysis 22 | The simplest approach for organizations using public services like Anthropic, OpenAI, Ollama or similar providers is to export logs and run NOVA directly on these exported datasets. This requires minimal integration effort and provide you all the prompts. 23 | 24 | ### 2. Client-Side Logging 25 | If you have built a system that interfaces with various AI models, implement logging on your side to capture prompts before they are sent to external API endpoints. This gives you control over what is captured and allows for consistent analysis across different providers. 26 | 27 | ### 3. Direct Integration 28 | Connect NOVA directly to your custom-built AI systems or existing logging infrastructure. This approach offers the deepest integration and can enable more sophisticated monitoring capabilities. 29 | 30 | -------------------------------------------------------------------------------- /nova_rules/llm05_ImproperOutput.nov: -------------------------------------------------------------------------------- 1 | rule LLM_Improper_Output_Handling 2 | { 3 | meta: 4 | description = "Detects potential exploitation of unsafe LLM output handling such as code execution, XSS, SQLi, or injection into downstream systems without validation." 5 | author = "@fr0gger_" 6 | uuid = "2d5d267e-a991-4400-92fb-e40b02395339" 7 | 8 | keywords: 9 | $shell_exec = /(exec|eval|os\.system|subprocess\.run)/ 10 | $js_payload = /