wafrift_encoding/encoding/keyword/
sql.rs1use crate::error::EncodeError;
4use std::fmt::Write as _;
5
6pub fn between_obfuscate(payload: &str) -> String {
10 let mut result = String::with_capacity(payload.len() * 3);
11 for ch in payload.chars() {
12 if ch == '=' {
13 result.push_str(" BETWEEN 0 AND ");
16 } else if ch == '>' {
17 result.push_str(" NOT BETWEEN 0 AND ");
18 } else {
19 result.push(ch);
20 }
21 }
22 result
23}
24
25pub fn unmagic_quotes(payload: impl AsRef<[u8]>) -> Result<String, EncodeError> {
30 let payload = payload.as_ref();
31 let payload_str = std::str::from_utf8(payload).map_err(|_| EncodeError::InvalidUtf8)?;
32 Ok(payload_str.replace('\'', "%bf%27"))
35}
36
37pub fn percentage_prefix(payload: &str) -> String {
42 let mut out = String::with_capacity(payload.len() * 2);
43 for ch in payload.chars() {
44 let _ = write!(&mut out, "%{ch}");
45 }
46 out
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn between_obfuscate_basic() {
55 assert_eq!(between_obfuscate("id=1"), "id BETWEEN 0 AND 1");
56 assert_eq!(between_obfuscate("id>0"), "id NOT BETWEEN 0 AND 0");
57 }
58
59 #[test]
60 fn unmagic_quotes_basic() {
61 assert_eq!(unmagic_quotes("' OR 1=1--").unwrap(), "%bf%27 OR 1=1--");
62 }
63
64 #[test]
65 fn percentage_prefix_basic() {
66 assert_eq!(percentage_prefix("SELECT"), "%S%E%L%E%C%T");
67 }
68}