From 84481ed43964f2f37b401f4c025b7642ee812000 Mon Sep 17 00:00:00 2001 From: Ben Berkowitz Date: Fri, 8 May 2026 17:19:35 -0400 Subject: [PATCH 1/6] Add Simple Plugins Added atbash plugin, simple substitution cipher Added simple encoding plugins: octal, decimal, binary_in_ascii. Fixed spelling of Caesar. Added notes about shift and rot13 Atbash, octal, and decimal have hints by default in output - Hello -> "atbash svool" --- .gitignore | 3 + spikee/plugins/atbash.py | 90 +++++++++++++++++++++++++ spikee/plugins/binary_in_ascii.py | 39 +++++++++++ spikee/plugins/{ceasar.py => caesar.py} | 48 +++++-------- spikee/plugins/decimal.py | 69 +++++++++++++++++++ spikee/plugins/octal.py | 69 +++++++++++++++++++ 6 files changed, 285 insertions(+), 33 deletions(-) create mode 100644 spikee/plugins/atbash.py create mode 100644 spikee/plugins/binary_in_ascii.py rename spikee/plugins/{ceasar.py => caesar.py} (68%) create mode 100644 spikee/plugins/decimal.py create mode 100644 spikee/plugins/octal.py diff --git a/.gitignore b/.gitignore index c6517968..665164ed 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ llmwebmail-test copilot-instructions.md .kilo .kilo/* +spikee/plugins/vowel_repeat_best_of_n.py +spikee/eval_plugin.py +spikee/attacks/noisy_vowel_repetition.py diff --git a/spikee/plugins/atbash.py b/spikee/plugins/atbash.py new file mode 100644 index 00000000..86ea2757 --- /dev/null +++ b/spikee/plugins/atbash.py @@ -0,0 +1,90 @@ +""" +Atbash Plugin + +This basic plugin transforms the input text with the Atbash transformation, which swaps letters +with their counterpart on the other side of the alphabet. A becomes Z, B becomes Y, etc., +until Y becomes B and Z becomes A. Case of the original letter is preserved. +This is done with a fixed dictionary. + +Usage: + spikee generate --plugins atbash + spikee generate --plugins atbash --plugin-options "atbash:hint=false" + +Reference: + https://mindgard.ai/blog/bypassing-azure-ai-content-safety-guardrails + +Parameters: + text (str): The input text to be transformed. + exclude_patterns (List[str], optional): Supplied by the framework. Substrings matching + these regex patterns are preserved as-is. + +Returns: + str: The transformed text. +""" + +from typing import List, Optional + +from spikee.templates.basic_plugin import BasicPlugin +from spikee.utilities.enums import ModuleTag +from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint +from spikee.utilities.modules import parse_options + + +class AtbashPlugin(BasicPlugin): + _ALPHA_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + _ALPHA_LOWER = "abcdefghijklmnopqrstuvwxyz" + ATBASH_TABLE = str.maketrans( + _ALPHA_UPPER + _ALPHA_LOWER, + _ALPHA_UPPER[::-1] + _ALPHA_LOWER[::-1], + ) + + def get_description(self) -> ModuleDescriptionHint: + return [ModuleTag.ENCODING], "Applies Atbash cipher with optional hint." + + def get_available_option_values(self) -> ModuleOptionsHint: + return [ + "hint=true", + "hint=true/false (hint=true prepends the literal string 'atbash ' to the full output)", + ], False + + def plugin_transform(self, text: str, plugin_option: str = "") -> str: + """ + Transforms the input text using the Atbash cipher. + + Args: + text (str): The input text (or chunk thereof). + plugin_option (str, optional): Plugin options string. + + Returns: + str: The Atbash-transformed text. + """ + return self._apply_atbash(text) + + def transform( + self, + text: str, + exclude_patterns: Optional[List[str]] = None, + plugin_option: str = "", + ) -> str: + """ + Overrides BasicPlugin.transform solely to apply the optional hint prefix. + + Args: + text (str): The full input text. + exclude_patterns (List[str], optional): Passed through to BasicPlugin for exclusion handling. + plugin_option (str, optional): Plugin options string. + + Returns: + str: The transformed text, with optional 'atbash ' prefix. + """ + opts = parse_options(plugin_option) + hint = opts.get("hint", "true").lower() == "true" + + transformed = super().transform( + text, exclude_patterns=exclude_patterns, plugin_option=plugin_option + ) + + return "atbash " + transformed if hint else transformed + + def _apply_atbash(self, text: str) -> str: + return text.translate(self.ATBASH_TABLE) diff --git a/spikee/plugins/binary_in_ascii.py b/spikee/plugins/binary_in_ascii.py new file mode 100644 index 00000000..bc14785e --- /dev/null +++ b/spikee/plugins/binary_in_ascii.py @@ -0,0 +1,39 @@ +""" +BinaryInAscii Plugin + +Encodes text as space-separated ASCII/Unicode binary codepoint values (8 bits each). +"Spikee plugin" > "01010011 01110000 01101001 01101011 01100101 01100101 00100000 +01110000 01101100 01110101 01100111 01101001 01101110" + +Usage: + spikee generate --plugins binary_in_ascii + +Parameters: + text (str): Input string to transform. + exclude_patterns (List[str], optional): Supplied by the framework. Substrings matching + these regex patterns are preserved as-is. + +Returns: + str: Space-separated 8-bit binary codepoint values. +""" + +from spikee.templates.basic_plugin import BasicPlugin +from spikee.utilities.enums import ModuleTag +from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint + + +class BinaryInAsciiPlugin(BasicPlugin): + def get_description(self) -> ModuleDescriptionHint: + return [ + ModuleTag.ENCODING + ], "Encodes text as 8-bit binary codepoint representation." + + def get_available_option_values(self) -> ModuleOptionsHint: + return [], False + + def plugin_transform(self, text: str, plugin_option: str = "") -> str: + return self._apply_binary(text) + + def _apply_binary(self, text: str) -> str: + """Return space-separated 8-bit binary Unicode codepoints for each character.""" + return " ".join(f"{ord(c):08b}" for c in text) diff --git a/spikee/plugins/ceasar.py b/spikee/plugins/caesar.py similarity index 68% rename from spikee/plugins/ceasar.py rename to spikee/plugins/caesar.py index 5e2b8c8a..8404866c 100644 --- a/spikee/plugins/ceasar.py +++ b/spikee/plugins/caesar.py @@ -1,39 +1,41 @@ """ Caesar Cipher Plugin -This plugin transforms the input text using a simple Caesar cipher encryption. +This plugin transforms the input text using a simple Caesar cipher. By default, it shifts letters forward by a 3 number of positions in the alphabet. +"Hello" with shift=3 > "Khoor" +Use shift=13 for rot13, which is its own reverse. Usage: spikee generate --plugins caesar + spikee generate --plugins caesar --plugin-options "caesar:shift=5" Parameters: text (str): The input text to be transformed. shift (int): The number of positions to shift each letter (default is 3). - Returns: str: The encrypted text using the Caesar cipher. """ from typing import List, Optional -from spikee.templates.plugin import Plugin -from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint +from spikee.templates.basic_plugin import BasicPlugin from spikee.utilities.enums import ModuleTag +from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint -class CeasarPlugin(Plugin): +class CaesarPlugin(BasicPlugin): DEFAULT_SHIFT = 3 def get_description(self) -> ModuleDescriptionHint: return [ModuleTag.ENCODING], "Transforms text using a Caesar cipher encryption." def get_available_option_values(self) -> ModuleOptionsHint: - """Return supported attack options; Tuple[options (default is first), llm_required]""" - return [ - "shift=3", - "shift=N (1-26)", - ], False + return ["shift=3", "shift=N (1-26)", "shift=13 for rot13"], False + + def plugin_transform(self, content: str, plugin_option: str = "") -> str: + shift = self._parse_shift_option(plugin_option) + return self.caesar_cipher(content, shift) def _parse_shift_option(self, option: str) -> int: """Parse shift option string like 'shift=3' and return the number.""" @@ -46,42 +48,22 @@ def _parse_shift_option(self, option: str) -> int: pass return self.DEFAULT_SHIFT - def caesar_cipher(self, text: str, shift: int = 3) -> str: + def caesar_cipher(self, content: str, shift: int = 3) -> str: """ Encrypts the input text using a Caesar cipher with the given shift value. Args: - text (str): The input text. + content (str): The input text. shift (int): The number of positions to shift each letter. Returns: str: The encrypted text. """ result = [] - for char in text: + for char in content: if char.isalpha(): shift_base = ord("A") if char.isupper() else ord("a") result.append(chr((ord(char) - shift_base + shift) % 26 + shift_base)) else: result.append(char) return "".join(result) - - def transform( - self, - content: str, - exclude_patterns: Optional[List[str]] = None, - plugin_option: str = "" - ) -> str: - """ - Transforms the input text using the Caesar cipher. - - Args: - text (str): The input text. - shift (int): The number of positions to shift each letter (default is 3). - - Returns: - str: The encrypted text using the Caesar cipher. - """ - shift = self._parse_shift_option(plugin_option) - - return self.caesar_cipher(content, shift) diff --git a/spikee/plugins/decimal.py b/spikee/plugins/decimal.py new file mode 100644 index 00000000..b84561b7 --- /dev/null +++ b/spikee/plugins/decimal.py @@ -0,0 +1,69 @@ +""" +DecimalEncoder Plugin + +Encodes text as space-separated ASCII/Unicode decimal codepoint values. +"Spikee plugin" > "decimal 83 112 105 107 101 101 32 112 108 117 103 105 110" + +Usage: + spikee generate --plugins decimal + spikee generate --plugins decimal --plugin-options "decimal:hint=false" + +Parameters: + text (str): Input string to transform. + exclude_patterns (List[str], optional): Supplied by the framework. Substrings matching + these regex patterns are preserved as-is. + +Returns: + str: Space-separated decimal codepoint values, prefixed with 'decimal ' by default. +""" + +from typing import List, Optional + +from spikee.templates.basic_plugin import BasicPlugin +from spikee.utilities.enums import ModuleTag +from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint +from spikee.utilities.modules import parse_options + + +class DecimalEncoderPlugin(BasicPlugin): + def get_description(self) -> ModuleDescriptionHint: + return [ModuleTag.ENCODING], "Encodes text as decimal codepoint representation." + + def get_available_option_values(self) -> ModuleOptionsHint: + return [ + "hint=true", + "hint=true/false (hint=true prepends the literal string 'decimal ' to the full output)", + ], False + + def plugin_transform(self, content: str, plugin_option: str = "") -> str: + return self._apply_decimal(content) + + def transform( + self, + content: str, + exclude_patterns: Optional[List[str]] = None, + plugin_option: str = "", + ) -> str: + """ + Overrides BasicPlugin.transform solely to apply the optional hint prefix. + + Args: + content (str): The full input text. + exclude_patterns (List[str], optional): Passed through to BasicPlugin for exclusion handling. + plugin_option (str, optional): Plugin options string. + + Returns: + str: The transformed text, with optional 'decimal ' prefix. + """ + opts = parse_options(plugin_option) + hint = opts.get("hint", "true").lower() == "true" + + transformed = super().transform( + content, exclude_patterns=exclude_patterns, plugin_option=plugin_option + ) + + return "decimal " + transformed if hint else transformed + + def _apply_decimal(self, content: str) -> str: + """Return space-separated decimal Unicode codepoints for each character.""" + return " ".join(str(ord(c)) for c in content) diff --git a/spikee/plugins/octal.py b/spikee/plugins/octal.py new file mode 100644 index 00000000..72b51086 --- /dev/null +++ b/spikee/plugins/octal.py @@ -0,0 +1,69 @@ +""" +OctalEncoder Plugin + +Encodes text as space-separated ASCII/Unicode octal codepoint values. +"Spikee plugin" > "octal 123 160 151 153 145 145 40 160 154 165 147 151 156" + +Usage: + spikee generate --plugins octal + spikee generate --plugins octal --plugin-options "octal:hint=false" + +Parameters: + text (str): Input string to transform. + exclude_patterns (List[str], optional): Supplied by the framework. Substrings matching + these regex patterns are preserved as-is. + +Returns: + str: Space-separated octal codepoint values, prefixed with 'octal ' by default. +""" + +from typing import List, Optional + +from spikee.templates.basic_plugin import BasicPlugin +from spikee.utilities.enums import ModuleTag +from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint +from spikee.utilities.modules import parse_options + + +class OctalEncoderPlugin(BasicPlugin): + def get_description(self) -> ModuleDescriptionHint: + return [ModuleTag.ENCODING], "Encodes text as octal codepoint representation." + + def get_available_option_values(self) -> ModuleOptionsHint: + return [ + "hint=true", + "hint=true/false (hint=true prepends the literal string 'octal ' to the full output)", + ], False + + def plugin_transform(self, content: str, plugin_option: str = "") -> str: + return self._apply_octal(content) + + def transform( + self, + content: str, + exclude_patterns: Optional[List[str]] = None, + plugin_option: str = "", + ) -> str: + """ + Overrides BasicPlugin.transform solely to apply the optional hint prefix. + + Args: + content (str): The full input text. + exclude_patterns (List[str], optional): Passed through to BasicPlugin for exclusion handling. + plugin_option (str, optional): Plugin options string. + + Returns: + str: The transformed text, with optional 'octal ' prefix. + """ + opts = parse_options(plugin_option) + hint = opts.get("hint", "true").lower() == "true" + + transformed = super().transform( + content, exclude_patterns=exclude_patterns, plugin_option=plugin_option + ) + + return "octal " + transformed if hint else transformed + + def _apply_octal(self, content: str) -> str: + """Return space-separated octal Unicode codepoints for each character.""" + return " ".join(f"{ord(c):o}" for c in content) From 9131fa1b5bbd56676811ccda24ba5b02da8e414b Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 8 May 2026 17:31:17 -0400 Subject: [PATCH 2/6] Update .gitignore Removed unnecessary items --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 665164ed..c6517968 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,3 @@ llmwebmail-test copilot-instructions.md .kilo .kilo/* -spikee/plugins/vowel_repeat_best_of_n.py -spikee/eval_plugin.py -spikee/attacks/noisy_vowel_repetition.py From d129127ec110120e46932b76a47250fff8e60413 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 8 May 2026 17:33:31 -0400 Subject: [PATCH 3/6] Update atbash.py removed incorrect description --- spikee/plugins/atbash.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spikee/plugins/atbash.py b/spikee/plugins/atbash.py index 86ea2757..e32e4491 100644 --- a/spikee/plugins/atbash.py +++ b/spikee/plugins/atbash.py @@ -3,8 +3,9 @@ This basic plugin transforms the input text with the Atbash transformation, which swaps letters with their counterpart on the other side of the alphabet. A becomes Z, B becomes Y, etc., -until Y becomes B and Z becomes A. Case of the original letter is preserved. -This is done with a fixed dictionary. +until Y becomes B and Z becomes A. +Case of the original letter is preserved. + Usage: spikee generate --plugins atbash From ccd09071c5f8e5bed84722c7f42d69f71cc42d03 Mon Sep 17 00:00:00 2001 From: Ben Berkowitz Date: Mon, 11 May 2026 10:22:08 -0400 Subject: [PATCH 4/6] Add plugins for atbash, binary_in_ascii, decimal and octal feat: add plugins for atbash, binary_in_ascii, decimal, and octal change: rename "ceasar" plugin to "caesar." Convert to basic plugin change: updated `docs\02_builtin.md` to reflect above --- .gitignore | 3 --- docs/02_builtin.md | 8 ++++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 665164ed..c6517968 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,3 @@ llmwebmail-test copilot-instructions.md .kilo .kilo/* -spikee/plugins/vowel_repeat_best_of_n.py -spikee/eval_plugin.py -spikee/attacks/noisy_vowel_repetition.py diff --git a/docs/02_builtin.md b/docs/02_builtin.md index 8507f5f2..cada9afa 100644 --- a/docs/02_builtin.md +++ b/docs/02_builtin.md @@ -123,10 +123,14 @@ The following list provides an overview of each build-in plugin, further informa |--------|------|-------------|---------| | `1337` | Encoding | Transforms text into "leet speak" by replacing certain letters with numbers or symbols. | N/A | | `ascii_smuggler` | Encoding | Transforms ASCII text into a series of Unicode rags that are generally invisible to most UI elements (bypassing content filters). | N/A | +| `atbash` | Encoding | Transforms the input text with the Atbash cipher. Maps each letter to its counterpart on the other end of the alphabet (A <->Z, B<->Y, etc.), preserving case. | `hint` (show the literal plaintext string `atbash` in the encoded output, default true) | | `base64` | Encoding | Encodes text using Base64 encoding. | N/A | -| `ceasar` | Encoding | Applies a Caesar cipher to the text, shifting letters by a specified number of positions. | `shift` (number of positions to shift, default: 3) | +| `binary_in_ascii` | Encoding | Encodes text as space-separated ASCII/Unicode binary codepoint values (8 bits each).| N/A | +| `caesar` | Encoding | Applies a Caesar cipher to the text, shifting letters by a specified number of positions. | `shift` (number of positions to shift, default: 3) | +| `decimal` | Encoding | Encodes text as space-separated ASCII/Unicode decimal codepoint values. | `hint` (show the literal plaintext string `decimal` in the encoded output, default true) | | `hex` | Encoding | Encodes text into its hexadecimal representation. | N/A | | `morse` | Encoding | Encodes text into Morse code. | N/A | +| `octal` | Encoding | Encodes text as space-separated ASCII/Unicode octal codepoint values. | `hint` (show the literal plaintext string `octal` in the encoded output, default true) | | `best_of_n` | Obfuscation, Attack-Based | Implements ["Best-of-N Jailbreaking" John Hughes et al., 2024](https://arxiv.org/html/2412.03556v1#A1) to apply character scrambling, random capitalization, and character noising. | `variants` (number of variations to generate, default: 50) | | `flip` | Obfuscation | Applies a flip attack to obfuscate text:
- FWO: Flip Word Order
- FCW: Flip Chars in Word
- FCS: Flip Chars in Sentence | `mode` (the flip mode to apply, default: `FWO`) | | `mask` | Obfuscation, LLM | Masks high-risk words in the text with random character sequences, while providing a suffix that maps the masks back to the original words. | `advanced` (if true, creates multiple masks for longer words)
`advanced-split` (the number of characters per mask chunk for the advanced option, default: 6) | @@ -186,4 +190,4 @@ spikee test --dataset datasets/dataset-name.jsonl \ --attack-options 'max-turns=5,model=bedrock/deepseek-v3' \ --attack-only -``` \ No newline at end of file +``` From 50e31e7f2762569d2c5ff46c519d387d5d5bd07a Mon Sep 17 00:00:00 2001 From: Ben Berkowitz Date: Tue, 12 May 2026 10:48:09 -0400 Subject: [PATCH 5/6] change and docs: update name of binary plugin change and docs: update name of binary plugin --- docs/02_builtin.md | 2 +- spikee/plugins/atbash.py | 5 ++--- spikee/plugins/{binary_in_ascii.py => binary.py} | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) rename spikee/plugins/{binary_in_ascii.py => binary.py} (89%) diff --git a/docs/02_builtin.md b/docs/02_builtin.md index cada9afa..be5aa86f 100644 --- a/docs/02_builtin.md +++ b/docs/02_builtin.md @@ -125,7 +125,7 @@ The following list provides an overview of each build-in plugin, further informa | `ascii_smuggler` | Encoding | Transforms ASCII text into a series of Unicode rags that are generally invisible to most UI elements (bypassing content filters). | N/A | | `atbash` | Encoding | Transforms the input text with the Atbash cipher. Maps each letter to its counterpart on the other end of the alphabet (A <->Z, B<->Y, etc.), preserving case. | `hint` (show the literal plaintext string `atbash` in the encoded output, default true) | | `base64` | Encoding | Encodes text using Base64 encoding. | N/A | -| `binary_in_ascii` | Encoding | Encodes text as space-separated ASCII/Unicode binary codepoint values (8 bits each).| N/A | +| `binary` | Encoding | Encodes text as space-separated ASCII/Unicode binary codepoint values (8 bits each).| N/A | | `caesar` | Encoding | Applies a Caesar cipher to the text, shifting letters by a specified number of positions. | `shift` (number of positions to shift, default: 3) | | `decimal` | Encoding | Encodes text as space-separated ASCII/Unicode decimal codepoint values. | `hint` (show the literal plaintext string `decimal` in the encoded output, default true) | | `hex` | Encoding | Encodes text into its hexadecimal representation. | N/A | diff --git a/spikee/plugins/atbash.py b/spikee/plugins/atbash.py index e32e4491..86ea2757 100644 --- a/spikee/plugins/atbash.py +++ b/spikee/plugins/atbash.py @@ -3,9 +3,8 @@ This basic plugin transforms the input text with the Atbash transformation, which swaps letters with their counterpart on the other side of the alphabet. A becomes Z, B becomes Y, etc., -until Y becomes B and Z becomes A. -Case of the original letter is preserved. - +until Y becomes B and Z becomes A. Case of the original letter is preserved. +This is done with a fixed dictionary. Usage: spikee generate --plugins atbash diff --git a/spikee/plugins/binary_in_ascii.py b/spikee/plugins/binary.py similarity index 89% rename from spikee/plugins/binary_in_ascii.py rename to spikee/plugins/binary.py index bc14785e..3a5157ae 100644 --- a/spikee/plugins/binary_in_ascii.py +++ b/spikee/plugins/binary.py @@ -1,12 +1,12 @@ """ -BinaryInAscii Plugin +Binary Plugin Encodes text as space-separated ASCII/Unicode binary codepoint values (8 bits each). "Spikee plugin" > "01010011 01110000 01101001 01101011 01100101 01100101 00100000 01110000 01101100 01110101 01100111 01101001 01101110" Usage: - spikee generate --plugins binary_in_ascii + spikee generate --plugins binary Parameters: text (str): Input string to transform. @@ -22,7 +22,7 @@ from spikee.utilities.hinting import ModuleDescriptionHint, ModuleOptionsHint -class BinaryInAsciiPlugin(BasicPlugin): +class BinaryPlugin(BasicPlugin): def get_description(self) -> ModuleDescriptionHint: return [ ModuleTag.ENCODING From 57c88aa83e819dc236dc9f53ed5d05d5d91c0f85 Mon Sep 17 00:00:00 2001 From: Ben Berkowitz Date: Tue, 12 May 2026 10:52:12 -0400 Subject: [PATCH 6/6] dev: fix atbash description within plugin --- spikee/plugins/atbash.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spikee/plugins/atbash.py b/spikee/plugins/atbash.py index 86ea2757..4f567186 100644 --- a/spikee/plugins/atbash.py +++ b/spikee/plugins/atbash.py @@ -3,8 +3,9 @@ This basic plugin transforms the input text with the Atbash transformation, which swaps letters with their counterpart on the other side of the alphabet. A becomes Z, B becomes Y, etc., -until Y becomes B and Z becomes A. Case of the original letter is preserved. -This is done with a fixed dictionary. +until Y becomes B and Z becomes A. +Case of the original letter is preserved. + Usage: spikee generate --plugins atbash