Sanitize Tags Unicode Block at prompt level (#4047)
This commit is contained in:
@@ -1,4 +1,19 @@
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
|
||||
/// Sanitize Unicode Tags Block characters from text
|
||||
/// Used to prevent Unicode-based prompt injection attacks
|
||||
///
|
||||
/// This function removes invisible Unicode Tags Block characters (U+E0000-U+E007F)
|
||||
/// that can be used for steganographic attacks while preserving legitimate Unicode.
|
||||
pub fn sanitize_unicode_tags(text: &str) -> String {
|
||||
let normalized: String = text.nfc().collect();
|
||||
|
||||
normalized
|
||||
.chars()
|
||||
.filter(|&c| !matches!(c, '\u{E0000}'..='\u{E007F}'))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Safely truncate a string at character boundaries, not byte boundaries
|
||||
///
|
||||
@@ -30,6 +45,45 @@ pub fn is_token_cancelled(cancellation_token: &Option<CancellationToken>) -> boo
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_unicode_tags() {
|
||||
// Test that Unicode Tags Block characters are removed
|
||||
let malicious = "Hello\u{E0041}\u{E0042}\u{E0043}world"; // Invisible "ABC"
|
||||
let cleaned = sanitize_unicode_tags(malicious);
|
||||
assert_eq!(cleaned, "Helloworld");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_unicode_tags_preserves_legitimate_unicode() {
|
||||
// Test that legitimate Unicode characters are preserved
|
||||
let clean_text = "Hello world 世界 🌍";
|
||||
let cleaned = sanitize_unicode_tags(clean_text);
|
||||
assert_eq!(cleaned, clean_text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_unicode_tags_empty_string() {
|
||||
let empty = "";
|
||||
let cleaned = sanitize_unicode_tags(empty);
|
||||
assert_eq!(cleaned, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_unicode_tags_only_malicious() {
|
||||
// Test string containing only Unicode Tags characters
|
||||
let only_malicious = "\u{E0041}\u{E0042}\u{E0043}";
|
||||
let cleaned = sanitize_unicode_tags(only_malicious);
|
||||
assert_eq!(cleaned, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_unicode_tags_mixed_content() {
|
||||
// Test mixed legitimate and malicious Unicode
|
||||
let mixed = "Hello\u{E0041} 世界\u{E0042} 🌍\u{E0043}!";
|
||||
let cleaned = sanitize_unicode_tags(mixed);
|
||||
assert_eq!(cleaned, "Hello 世界 🌍!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_safe_truncate_ascii() {
|
||||
assert_eq!(safe_truncate("hello world", 20), "hello world");
|
||||
|
||||
Reference in New Issue
Block a user