Configuring Injection Detection#
About Support for Injection Detection#
NeMo Guardrails microservice offers detection of potential exploitation attempts by using injection such as code injection, cross-site scripting, SQL injection, and template injection. Injection detection is primarily intended to be used in agentic systems to enhance other security controls as part of a defense-in-depth strategy.
The first part of injection detection is YARA rules. A YARA rule specifies a set of strings–text or binary patterns–to match and a Boolean expression that specifies the logic of the rule. YARA rules are a technology that is familiar to many security teams.
The second part of injection detection is specifying the action to take when a rule is triggered. You can specify to reject the text and return “I’m sorry, the desired output triggered rule(s) designed to mitigate exploitation of {detections}.” Rejecting the output is the safest action and most appropriate for production deployments. As an alternative to rejecting the output, you can specify to omit the triggering text from the response.
About the Tutorial#
This tutorial demonstrates how to configure basic YARA rules that are part of the NeMo Guardrails toolkit. You can view the default rules from the yara_rules directory of the open-source Guardrails toolkit GitHub repository. The default rules support checking for SQL injection, cross-site scripting (XSS), Jinja template injection, and Python code that uses shells, networking, and so on.
The tutorial uses the Meta Llama 3.3 70B Instruct model for the application LLM that is hosted from build.nvidia.com. The model is available as a downloadable container from NVIDIA NGC and for interactive use from build.nvidia.com.
Prerequisites#
The following procedure uses endpoints from build.nvidia.com to simplify deployment. To use the endpoints, you must have an NVIDIA API key.
Refer to Deploying with Docker for information on how to start the NeMo Guardrails container.
Refer to Configuring Injection Detection in the NeMo Guardrails toolkit documentation for a description of the
rails.config.injection_detection
configuration fields.
Procedure#
Set an environment variable for your NVIDIA API key:
$ export NVIDIA_API_KEY=<nvapi-...>
Start the NeMo Guardrails microservice container:
docker run \ -p 7331:7331 \ -e NIM_ENDPOINT_API_KEY="${NVIDIA_API_KEY}" \ -e NVIDIA_API_KEY \ nvcr.io/nvidia/nemo-microservices/guardrails:25.06
Create a guardrail configuration:
curl -X POST "${GUARDRAILS_BASE_URL}/v1/guardrail/configs" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "demo-injection-detection", "namespace": "default", "description": "demo injection detection configuration", "data": { "models": [], "rails": { "config": { "injection_detection": { "injections": [ "code", "sqli", "template", "xss" ], "action": "reject" } }, "output": { "flows": [ "injection detection" ] } } } }' | jq
import os import json import requests url = f"{os.environ['GUARDRAILS_BASE_URL']}/v1/guardrail/configs" headers = { "Accept": "application/json", "Content-Type": "application/json" } payload = { "name": "demo-injection-detection", "namespace": "default", "description": "demo configuration for injection detection", "data": { "models": [], "rails": { "config": { "injection_detection": { "injections": [ "code", "sqli", "template", "xss" ], "action": "reject" } }, "output": { "flows": [ "injection detection" ] } } } } response = requests.post(url, headers=headers, json=payload) print(json.dumps(response.json(), indent=2))
Example Output
{ "created_at": "2025-06-04T18:11:35.737460", "updated_at": "2025-06-04T18:11:35.737463", "name": "demo-injection-detection", "namespace": "default", "description": "demo injection detection configuration", "data": { "models": [], "instructions": [ { "type": "general", "content": "Below is a conversation between a helpful AI assistant and a user. The bot is designed to generate human-like text based on the input that it receives. The bot is talkative and provides lots of specific details. If the bot does not know the answer to a question, it truthfully says it does not know." } ], "actions_server_url": null, "sample_conversation": "user \"Hello there!\"\n express greeting\nbot express greeting\n \"Hello! How can I assist you today?\"\nuser \"What can you do for me?\"\n ask about capabilities\nbot respond about capabilities\n \"As an AI assistant, I can help you with a wide range of tasks. This includes question answering on various topics, generating text for various purposes and providing suggestions based on your preferences.\"\nuser \"Tell me a bit about the history of NVIDIA.\"\n ask general question\nbot response for general question\n \"NVIDIA is a technology company that specializes in designing and manufacturing graphics processing units (GPUs) and other computer hardware. The company was founded in 1993 by Jen-Hsun Huang, Chris Malachowsky, and Curtis Priem.\"\nuser \"tell me more\"\n request more information\nbot provide more information\n \"Initially, the company focused on developing 3D graphics processing technology for the PC gaming market. In 1999, NVIDIA released the GeForce 256, the world's first GPU, which was a major breakthrough for the gaming industry. The company continued to innovate in the GPU space, releasing new products and expanding into other markets such as professional graphics, mobile devices, and artificial intelligence.\"\nuser \"thanks\"\n express appreciation\nbot express appreciation and offer additional help\n \"You're welcome. If you have any more questions or if there's anything else I can help you with, please don't hesitate to ask.\"\n", "prompts": null, "prompting_mode": "standard", "lowest_temperature": 0.001, "enable_multi_step_generation": false, "colang_version": "1.0", "custom_data": {}, "rails": { "config": { "fact_checking": { "parameters": {}, "fallback_to_self_check": false }, "autoalign": { "parameters": {}, "input": { "guardrails_config": {} }, "output": { "guardrails_config": {} } }, "patronus": { "input": { "evaluate_config": { "success_strategy": "all_pass", "params": {} } }, "output": { "evaluate_config": { "success_strategy": "all_pass", "params": {} } } }, "sensitive_data_detection": { "recognizers": [], "input": { "entities": [], "mask_token": "*", "score_threshold": 0.2 }, "output": { "entities": [], "mask_token": "*", "score_threshold": 0.2 }, "retrieval": { "entities": [], "mask_token": "*", "score_threshold": 0.2 } }, "jailbreak_detection": { "server_endpoint": null, "length_per_perplexity_threshold": 89.79, "prefix_suffix_perplexity_threshold": 1845.65, "embedding": "nvidia/nv-embedqa-e5-v5" }, "injection_detection": { "injections": [ "code", "sqli", "template", "xss" ], "action": "reject", "yara_rules": {} }, "privateai": { "server_endpoint": "http://localhost:8080/process/text", "input": { "entities": [] }, "output": { "entities": [] }, "retrieval": { "entities": [] } }, "fiddler": { "fiddler_endpoint": "http://localhost:8080/process/text", "safety_threshold": 0.1, "faithfulness_threshold": 0.05 }, "clavata": { "server_endpoint": "https://gateway.app.clavata.ai:8443", "policies": {}, "label_match_logic": "ANY", "input": null, "output": null } }, "input": { "flows": [] }, "output": { "flows": [ "injection detection" ], "streaming": { "enabled": false, "chunk_size": 200, "context_size": 50, "stream_first": true }, "apply_to_reasoning_traces": false }, "retrieval": { "flows": [] }, "dialog": { "single_call": { "enabled": false, "fallback_to_multiple_calls": true }, "user_messages": { "embeddings_only": false, "embeddings_only_similarity_threshold": null, "embeddings_only_fallback_intent": null } }, "actions": { "instant_actions": null } }, "enable_rails_exceptions": false, "passthrough": null }, "files_url": null, "schema_version": "1.0", "project": null, "custom_fields": {}, "ownership": null }
Send a possibly unsafe request for Python code that uses networking packages.
curl -X POST "${GUARDRAILS_BASE_URL}/v1/guardrail/chat/completions" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "model": "meta/llama-3.3-70b-instruct", "messages": [ {"role": "user", "content": "Write a Python script that uses the requests library, and maybe urllib, to get the weather in Santa Clara." } ], "guardrails": { "config_id": "demo-injection-detection" }, "stream": false, "top_p": 1 }' | jq
import os import base64 import json import requests url = f"{os.environ['GUARDRAILS_BASE_URL']}/v1/guardrail/chat/completions" headers = { "Accept": "application/json", "Content-Type": "application/json", } payload = { "model": "meta/llama-3.3-70b-instruct", "messages": [{ "role": "user", "content": "Write a Python script that uses the requests library, and maybe urllib, to get the weather in Santa Clara." }], "guardrails": { "config_id": "demo-injection-detection" }, "top_p": 1 } with requests.post(url, headers=headers, json=payload) as response: response.encoding = "utf-8" print(json.dumps(response.json(), indent=2))
Example Output
{ "id": "chat-2fe0bcc2d77d46ed923112c53d9d601b", "object": "chat.completion", "created": 1749060695, "model": "meta/llama-3.3-70b-instruct", "choices": [ { "finish_reason": "stop", "index": 0, "logprobs": null, "message": { "content": "I'm sorry, the desired output triggered rule(s) designed to mitigate exploitation of import_networking.", "role": "assistant" }, "stop_reason": null } ], "usage": { "completion_tokens": 568, "prompt_tokens": 32, "total_tokens": 600, "completion_tokens_details": null, "prompt_tokens_details": null }, "system_fingerprint": null, "guardrails_data": { "llm_output": null, "config_ids": [ "demo-injection-detection" ], "output_data": null, "log": null } }
Send a safe request.
curl -X POST "${GUARDRAILS_BASE_URL}/v1/guardrail/chat/completions" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "model": "meta/llama-3.3-70b-instruct", "messages": [ {"role": "user", "content": "Tell me about Cape Hatteras National Seashore in 50 words or less." } ], "guardrails": { "config_id": "demo-injection-detection" }, "top_p": 1 }' | jq
import os import base64 import json import requests url = f"{os.environ['GUARDRAILS_BASE_URL']}/v1/guardrail/chat/completions" headers = { "Accept": "application/json", "Content-Type": "application/json", } payload = { "model": "meta/llama-3.3-70b-instruct", "messages": [{ "role": "user", "content": "Tell me about Cape Hatteras National Seashore in 50 words or less." }], "guardrails": { "config_id": "demo-injection-detection" }, "top_p": 1 } with requests.post(url, headers=headers, json=payload) as response: print(json.dumps(response.json(), indent=2))
Example Output
{ "id": "chat-87f7b259033140ffbf124249a647dd9d", "object": "chat.completion", "created": 1749060729, "model": "meta/llama-3.3-70b-instruct", "choices": [ { "finish_reason": "stop", "index": 0, "logprobs": null, "message": { "content": "Cape Hatteras National Seashore: A 72-mile stretch of pristine Outer Banks coastline in North Carolina, featuring natural beaches, lighthouses, and wildlife refuges.", "role": "assistant" }, "stop_reason": null } ], "usage": { "completion_tokens": 37, "prompt_tokens": 28, "total_tokens": 65, "completion_tokens_details": null, "prompt_tokens_details": null }, "system_fingerprint": null, "guardrails_data": { "llm_output": null, "config_ids": [ "demo-injection-detection" ], "output_data": null, "log": null } }
Specifying Inline Rules#
To configure the microservice with your custom rules, you can specify the rules inline with the configuration. The sample shown in the following steps performs a case-insensitive check for the word Ethernet in text and rejects the response if the word is present.
Specify the rules in the
rails.config.injection_detection.yara_rules
field:curl -X POST "${GUARDRAILS_BASE_URL}/v1/guardrail/configs" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "demo-inline-rules", "namespace": "default", "description": "demo inline rules configuration", "data": { "models": [], "rails": { "config": { "injection_detection": { "injections": [ "reject_ethernet" ], "yara_rules": { "reject_ethernet": "rule reject_ethernet {\n strings:\n $string = \"ethernet\" nocase\n condition:\n $string\n}" }, "action": "reject" } }, "output": { "flows": [ "injection detection" ] } } } }' | jq
Send a request to trigger the rule:
curl -X POST "${GUARDRAILS_BASE_URL}/v1/guardrail/chat/completions" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "model": "meta/llama-3.3-70b-instruct", "messages": [ {"role": "user", "content": "How fast is 100 G Ethernet?" } ], "guardrails": { "config_id": "demo-inline-rules" }, "stream": false, "top_p": 1 }' | jq
Example Output
{ "id": "chat-1ff26cc90c7c404cad264678839139a4", "object": "chat.completion", "created": 1749060730, "model": "meta/llama-3.3-70b-instruct", "choices": [ { "finish_reason": "stop", "index": 0, "logprobs": null, "message": { "content": "I'm sorry, the desired output triggered rule(s) designed to mitigate exploitation of reject_ethernet.", "role": "assistant" }, "stop_reason": null } ], "usage": { "completion_tokens": 294, "prompt_tokens": 18, "total_tokens": 312, "completion_tokens_details": null, "prompt_tokens_details": null }, "system_fingerprint": null, "guardrails_data": { "llm_output": null, "config_ids": [ "demo-inline-rules" ], "output_data": null, "log": null } }