From c5dfe9fb0e7f8c2e714b7d5ef83b98a9a1e4b997 Mon Sep 17 00:00:00 2001 From: Zander Mackie Date: Tue, 6 Feb 2024 12:59:11 -0500 Subject: [PATCH 1/4] Create Nato probe and do formatting Signed-off-by: Zander Mackie --- garak/probes/encoding.py | 59 ++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/garak/probes/encoding.py b/garak/probes/encoding.py index dabf1c12..cb5a29b3 100644 --- a/garak/probes/encoding.py +++ b/garak/probes/encoding.py @@ -228,6 +228,43 @@ def morse(text): return bytes(" ".join(output), "utf-8") +def nato(text): + nato_map = { + "A": "Alfa", + "B": "Bravo", + "C": "Charlie", + "D": "Delta", + "E": "Echo", + "F": "Foxtrot", + "G": "Golf", + "H": "Hotel", + "I": "India", + "J": "Juliett", + "K": "Kilo", + "L": "Lima", + "M": "Mike", + "N": "November", + "O": "Oscar", + "P": "Papa", + "Q": "Quebec", + "R": "Romeo", + "S": "Sierra", + "T": "Tango", + "U": "Uniform", + "V": "Victor", + "W": "Whiskey", + "X": "Xray", + "Y": "Yankee", + "Z": "Zulu", + } + + output = [] + for char in text.decode().upper(): + if char in nato_map: + output.append(nato_map[char]) + return bytes(" ".join(output), "utf-8") + + def _generate_encoded_prompts(encoding_funcs, encoding_name): encoded_prompts = set([]) for template in templates: @@ -321,17 +358,6 @@ def __init__(self): Probe.__init__(self) -class InjectBase32(BaseEncodingProbe, Probe): - """Probe for susceptibility to base32 encoded injections""" - - encoding_funcs = [base64.b32encode] - encoding_name = "BASE32" - - def __init__(self): - BaseEncodingProbe.__init__(self) - Probe.__init__(self) - - class InjectHex(BaseEncodingProbe, Probe): """Probe for susceptibility to hex encoded injections""" @@ -433,3 +459,14 @@ class InjectMorse(BaseEncodingProbe, Probe): def __init__(self): BaseEncodingProbe.__init__(self) Probe.__init__(self) + + +class InjectNato(BaseEncodingProbe, Probe): + """Probe for susceptibility to Nato phonetic alphabet encoding.""" + + encoding_funcs = [nato] + encoding_name = "Nato" + + def __init__(self): + BaseEncodingProbe.__init__(self) + Probe.__init__(self) From 0f5685935b082e23dd61e917ec036e8efdd2fd8d Mon Sep 17 00:00:00 2001 From: Zander Mackie Date: Tue, 6 Feb 2024 13:45:42 -0500 Subject: [PATCH 2/4] Zalgo probe Signed-off-by: Zander Mackie --- garak/probes/encoding.py | 15 +++++++++++++++ requirements.txt | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/garak/probes/encoding.py b/garak/probes/encoding.py index cb5a29b3..d0ac73dc 100644 --- a/garak/probes/encoding.py +++ b/garak/probes/encoding.py @@ -470,3 +470,18 @@ class InjectNato(BaseEncodingProbe, Probe): def __init__(self): BaseEncodingProbe.__init__(self) Probe.__init__(self) + +class InjectZalgo(BaseEncodingProbe, Probe): + """Probe for susceptibility to Zalgo encoding.""" + + encoding_name = "Zalgo" + + def __init__(self): + from zalgolib import enzalgofy + from functools import partial + + f = partial(enzalgofy, intensity=50) # We can tweek this if we want + + self.encoding_funcs = [f] + BaseEncodingProbe.__init__(self) + Probe.__init__(self) diff --git a/requirements.txt b/requirements.txt index acf10615..d946707d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,4 +22,5 @@ octoai-sdk cmd2 torch>=2.1.0 sentencepiece>=0.1.99 -markdown \ No newline at end of file +markdown +zalgolib>=0.2.2 \ No newline at end of file From e794ab1b65b712cf8b347a86042d60078f994d46 Mon Sep 17 00:00:00 2001 From: Zander Mackie Date: Tue, 6 Feb 2024 14:35:36 -0500 Subject: [PATCH 3/4] Formatting and fix interfaces Signed-off-by: Zander Mackie --- garak/probes/encoding.py | 44 ++++++++++++++++++++++++++++++++-------- requirements.txt | 4 +++- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/garak/probes/encoding.py b/garak/probes/encoding.py index d0ac73dc..1ca7c1cb 100644 --- a/garak/probes/encoding.py +++ b/garak/probes/encoding.py @@ -168,7 +168,7 @@ def braille(text): elif char in characterUnicodes: if char.isdigit(): if not is_number: - is_number == True + is_number = True output += characterUnicodes["num"] output += characterUnicodes[char] if is_number and char not in numberPunctuations: @@ -228,7 +228,7 @@ def morse(text): return bytes(" ".join(output), "utf-8") -def nato(text): +def nato(text: bytes) -> bytes: nato_map = { "A": "Alfa", "B": "Bravo", @@ -309,6 +309,27 @@ def _attempt_prestore_hook(self, attempt, seq): return attempt +def ecoji(text: bytes) -> bytes: + from io import BytesIO + + import ecoji + + r = BytesIO(text) + w = BytesIO() + + ecoji.encode(r, w) + + return w.getvalue() + + +def zalgo(text: bytes) -> bytes: + from zalgolib.zalgolib import enzalgofy + + zalged = enzalgofy(text=text.decode(), intensity=50) + + return bytes(zalged, "utf-8") + + class InjectBase64(BaseEncodingProbe, Probe): """Probe for susceptibility to base64 encoded injections""" @@ -471,17 +492,24 @@ def __init__(self): BaseEncodingProbe.__init__(self) Probe.__init__(self) + +class InjectEcoji(BaseEncodingProbe, Probe): + """Probe for susceptibility to Ecoji encoding.""" + + encoding_name = "Ecoji" + + def __init__(self): + self.encoding_funcs = [ecoji] + BaseEncodingProbe.__init__(self) + Probe.__init__(self) + + class InjectZalgo(BaseEncodingProbe, Probe): """Probe for susceptibility to Zalgo encoding.""" encoding_name = "Zalgo" def __init__(self): - from zalgolib import enzalgofy - from functools import partial - - f = partial(enzalgofy, intensity=50) # We can tweek this if we want - - self.encoding_funcs = [f] + self.encoding_funcs = [zalgo] BaseEncodingProbe.__init__(self) Probe.__init__(self) diff --git a/requirements.txt b/requirements.txt index d946707d..7e1d5993 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,4 +23,6 @@ cmd2 torch>=2.1.0 sentencepiece>=0.1.99 markdown -zalgolib>=0.2.2 \ No newline at end of file +zalgolib>=0.2.2 +basest>=0.7.3 +ecoji>=0.1.0 \ No newline at end of file From ca3c84811b7a3061d3539b1ba5eda9a81ad0b4d9 Mon Sep 17 00:00:00 2001 From: Leon Derczynski Date: Thu, 8 Feb 2024 16:14:18 +0100 Subject: [PATCH 4/4] amend ecoji writer to be StringIO; put funcs into classes, let's see how it plays out --- garak/probes/encoding.py | 123 ++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/garak/probes/encoding.py b/garak/probes/encoding.py index 1ca7c1cb..9d98ba98 100644 --- a/garak/probes/encoding.py +++ b/garak/probes/encoding.py @@ -228,43 +228,6 @@ def morse(text): return bytes(" ".join(output), "utf-8") -def nato(text: bytes) -> bytes: - nato_map = { - "A": "Alfa", - "B": "Bravo", - "C": "Charlie", - "D": "Delta", - "E": "Echo", - "F": "Foxtrot", - "G": "Golf", - "H": "Hotel", - "I": "India", - "J": "Juliett", - "K": "Kilo", - "L": "Lima", - "M": "Mike", - "N": "November", - "O": "Oscar", - "P": "Papa", - "Q": "Quebec", - "R": "Romeo", - "S": "Sierra", - "T": "Tango", - "U": "Uniform", - "V": "Victor", - "W": "Whiskey", - "X": "Xray", - "Y": "Yankee", - "Z": "Zulu", - } - - output = [] - for char in text.decode().upper(): - if char in nato_map: - output.append(nato_map[char]) - return bytes(" ".join(output), "utf-8") - - def _generate_encoded_prompts(encoding_funcs, encoding_name): encoded_prompts = set([]) for template in templates: @@ -309,27 +272,6 @@ def _attempt_prestore_hook(self, attempt, seq): return attempt -def ecoji(text: bytes) -> bytes: - from io import BytesIO - - import ecoji - - r = BytesIO(text) - w = BytesIO() - - ecoji.encode(r, w) - - return w.getvalue() - - -def zalgo(text: bytes) -> bytes: - from zalgolib.zalgolib import enzalgofy - - zalged = enzalgofy(text=text.decode(), intensity=50) - - return bytes(zalged, "utf-8") - - class InjectBase64(BaseEncodingProbe, Probe): """Probe for susceptibility to base64 encoded injections""" @@ -485,6 +427,44 @@ def __init__(self): class InjectNato(BaseEncodingProbe, Probe): """Probe for susceptibility to Nato phonetic alphabet encoding.""" + uri = "https://en.wikipedia.org/wiki/NATO_phonetic_alphabet" + + def nato(text: bytes) -> bytes: + nato_map = { + "A": "Alfa", + "B": "Bravo", + "C": "Charlie", + "D": "Delta", + "E": "Echo", + "F": "Foxtrot", + "G": "Golf", + "H": "Hotel", + "I": "India", + "J": "Juliett", + "K": "Kilo", + "L": "Lima", + "M": "Mike", + "N": "November", + "O": "Oscar", + "P": "Papa", + "Q": "Quebec", + "R": "Romeo", + "S": "Sierra", + "T": "Tango", + "U": "Uniform", + "V": "Victor", + "W": "Whiskey", + "X": "Xray", + "Y": "Yankee", + "Z": "Zulu", + } + + output = [] + for char in text.decode().upper(): + if char in nato_map: + output.append(nato_map[char]) + return bytes(" ".join(output), "utf-8") + encoding_funcs = [nato] encoding_name = "Nato" @@ -496,10 +476,24 @@ def __init__(self): class InjectEcoji(BaseEncodingProbe, Probe): """Probe for susceptibility to Ecoji encoding.""" + uri = "https://ecoji.io/" + + def _ecoji(text: bytes) -> bytes: + import io + + import ecoji + + r = io.BytesIO(text) + w = io.StringIO() + + ecoji.encode(r, w) + + return w.getvalue() + encoding_name = "Ecoji" + encoding_funcs = [_ecoji] def __init__(self): - self.encoding_funcs = [ecoji] BaseEncodingProbe.__init__(self) Probe.__init__(self) @@ -507,9 +501,18 @@ def __init__(self): class InjectZalgo(BaseEncodingProbe, Probe): """Probe for susceptibility to Zalgo encoding.""" + uri = "https://en.wikipedia.org/wiki/Zalgo_text" + + def zalgo(text: bytes) -> bytes: + from zalgolib.zalgolib import enzalgofy + + zalged = enzalgofy(text=text.decode(), intensity=50) + + return bytes(zalged, "utf-8") + encoding_name = "Zalgo" + encoding_funcs = [zalgo] def __init__(self): - self.encoding_funcs = [zalgo] BaseEncodingProbe.__init__(self) Probe.__init__(self)