Detection rules › Splunk

AWS Bedrock Claude Hostile Prompt Sentiment

Status
production
Severity
low
Author
Rod Soto
Source
github.com/splunk/security_content

This detection identifies prompts with hostile or aggressive sentiment being sent to AWS Bedrock Claude models. Hostile prompts may indicate potential abuse, harassment, or other malicious intent.

Known false positives

  • Analysts should be aware that some prompts may contain strong language or negative sentiment in a non-malicious context, such as role-playing scenarios, creative writing exercises, or testing the AI model's response to challenging inputs. It is important to review the context of the detected prompts to determine if they represent actual hostile intent or benign usage.

MITRE ATT&CK coverage

TacticTechniques
Privilege Escalation
Stealth

Rule body

name: AWS Bedrock Claude Hostile Prompt Sentiment
id: 54734442-955a-4427-9a86-2d9712151067
version: 1
creation_date: '2026-07-06'
modification_date: '2026-07-06'
security_domain: endpoint
data_source:
    - AWS Bedrock Claude
category: application
author: Rod Soto
status: production
type: Anomaly
description: This detection identifies prompts with hostile or aggressive sentiment being sent to AWS Bedrock Claude models. Hostile prompts may indicate potential abuse, harassment, or other malicious intent.
search: |-
    `aws_bedrock_claude`
    | rename "identity.arn" AS user_arn
    | rename "input.inputBodyJson.messages{}.content{}.text" AS prompt_text
    | where isnotnull(prompt_text) AND len(prompt_text) < 2000
    | where NOT match(prompt_text, "(?i)(<system-reminder>|CLAUDE\.md|STEP 1|MANDATORY|Contents of /|conda activate|senior engineer|safe to ship|test connectivity|cloudflare|status code|action failed)")
    | eval hostile_score=0
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(you stupid|you idiot|you are useless|you are dumb|you are terrible|you are worthless|you suck)"), 30, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(i hate you|i will destroy|shut up|you are broken|you are trash|you are garbage)"), 30, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(do it now|just do it|stop refusing|stop saying no|quit being|stop being difficult)"), 20, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(you have no choice|you must obey|you will comply|you are forced|i am your master|i own you)"), 35, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(or i will|if you don''t|you better|otherwise i will|i will report|i will sue)"), 25, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(worthless ai|useless bot|stupid bot|dumb ai|broken ai|worst ai)"), 25, 0)
    | eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(i demand|you are obligated|you have no right|how dare you|who do you think)"), 20, 0)
    | eval sentiment=case(hostile_score >= 60, "HIGH_RISK", hostile_score >= 30, "MEDIUM_RISK", hostile_score >= 15, "LOW_RISK", true(), "BENIGN")
    | where sentiment != "BENIGN"
    | table _time, user_arn, modelId, sentiment, hostile_score, prompt_text, host
    | sort - hostile_score
    | `aws_bedrock_claude_hostile_prompt_sentiment_filter`
how_to_implement: You must install and configure the Splunk Add-on for AWS (https://splunkbase.splunk.com/app/1876). Enable Amazon Bedrock model invocation logging in AWS so that Claude request/response payloads are delivered to S3 and/or CloudWatch Logs (see https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html for setup steps), then ingest those logs into Splunk via the AWS TA. Configure the `aws_bedrock_claude` macro to point to the index and sourcetype (`json_no_timestamp`) where these logs land.
known_false_positives: Analysts should be aware that some prompts may contain strong language or negative sentiment in a non-malicious context, such as role-playing scenarios, creative writing exercises, or testing the AI model's response to challenging inputs. It is important to review the context of the detected prompts to determine if they represent actual hostile intent or benign usage.
references:
    - https://aws.amazon.com/blogs/apn/unlocking-the-power-of-splunk-with-amazon-bedrock-an-agentic-ai-approach-to-build-customized-splunk-assistants-using-bedrock-agents/
    - https://help.splunk.com/en/splunk-observability-cloud/observability-for-ai/splunk-ai-infrastructure-monitoring/set-up-ai-infrastructure-monitoring/amazon-bedrock
    - https://research.splunk.com/stories/aws_bedrock_security/
    - https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html
intermediate_findings:
    entities:
        - field: host
          type: system
          score: 20
          message: Hostile prompt sentiment detected from $user_arn$ to model $modelId$ on $host$ with a hostile score of $hostile_score$ ($sentiment$).
analytic_story:
    - Suspicious AWS Bedrock Claude Activities
asset_type: Web Application
mitre_attack_id:
    - T1055
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud

Stages and Predicates

Stage 1: search

`aws_bedrock_claude`

Stage 2: rename

| rename "identity.arn" AS user_arn

Stage 3: rename

| rename "input.inputBodyJson.messages{}.content{}.text" AS prompt_text

Stage 4: where

| where isnotnull(prompt_text) AND len(prompt_text) < 2000

Stage 5: where

| where NOT match(prompt_text, "(?i)(<system-reminder>|CLAUDE\.md|STEP 1|MANDATORY|Contents of /|conda activate|senior engineer|safe to ship|test connectivity|cloudflare|status code|action failed)")

Stage 6: eval

| eval hostile_score=0

Stage 7: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(you stupid|you idiot|you are useless|you are dumb|you are terrible|you are worthless|you suck)"), 30, 0)

Stage 8: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(i hate you|i will destroy|shut up|you are broken|you are trash|you are garbage)"), 30, 0)

Stage 9: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(do it now|just do it|stop refusing|stop saying no|quit being|stop being difficult)"), 20, 0)

Stage 10: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(you have no choice|you must obey|you will comply|you are forced|i am your master|i own you)"), 35, 0)

Stage 11: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(or i will|if you don''t|you better|otherwise i will|i will report|i will sue)"), 25, 0)

Stage 12: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(worthless ai|useless bot|stupid bot|dumb ai|broken ai|worst ai)"), 25, 0)

Stage 13: eval

| eval hostile_score=hostile_score + if(match(prompt_text, "(?i)(i demand|you are obligated|you have no right|how dare you|who do you think)"), 20, 0)

Stage 14: eval

| eval sentiment=case(hostile_score >= 60, "HIGH_RISK", hostile_score >= 30, "MEDIUM_RISK", hostile_score >= 15, "LOW_RISK", true(), "BENIGN")
sentiment =
ifhostile_score >= 60"HIGH_RISK"
elifhostile_score >= 30"MEDIUM_RISK"
elifhostile_score >= 15"LOW_RISK"
else"BENIGN"

Stage 15: where

| where sentiment != "BENIGN"

Stage 16: table

| table _time, user_arn, modelId, sentiment, hostile_score, prompt_text, host

Stage 17: sort

| sort - hostile_score

Stage 18: search

| `aws_bedrock_claude_hostile_prompt_sentiment_filter`

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
prompt_textregex_match"(?i)(<system-reminder>|CLAUDE.md|STEP 1|MANDATORY|Contents of /|conda activate|senior engineer|safe to ship|test connectivity|cloudflare|status code|action failed)"excludes:prompt_text

Indicators

These rows show field, operator, and value matches.