PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-waf/src/class-waf-transforms.php +403 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,403 @@
1 +<?php
2 +/**
3 + * Transforms for Jetpack Waf
4 + *
5 + * @package automattic/jetpack-waf
6 + */
7 +
8 +namespace Automattic\Jetpack\Waf;
9 +
10 +/**
11 + * Waf_Transforms class
12 + */
13 +class Waf_Transforms {
14 +
15 + /**
16 + * Decode a Base64-encoded string. This runs the decode without strict mode, to match Modsecurity's 'base64DecodeExt' transform function.
17 + *
18 + * @param string $value value to be decoded.
19 + * @return string
20 + */
21 + public function base64_decode_ext( $value ) {
22 + return base64_decode( $value );
23 + }
24 +
25 + /**
26 + * Characters to match when trimming a string.
27 + * Emulates `std::isspace` used by ModSecurity.
28 + *
29 + * @see https://en.cppreference.com/w/cpp/string/byte/isspace
30 + */
31 + const TRIM_CHARS = " \n\r\t\v\f";
32 +
33 + /**
34 + * Decode a Base64-encoded string. This runs the decode with strict mode, to match Modsecurity's 'base64Decode' transform function.
35 + *
36 + * @param string $value value to be decoded.
37 + * @return string
38 + */
39 + public function base64_decode( $value ) {
40 + return base64_decode( $value, true );
41 + }
42 +
43 + /**
44 + * Remove all characters that might escape a command line command
45 + *
46 + * @see https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#cmdLine
47 + * @param string $value value to be escaped.
48 + * @return string
49 + */
50 + public function cmd_line( $value ) {
51 + return strtolower(
52 + preg_replace(
53 + '/\s+/',
54 + ' ',
55 + str_replace(
56 + array( ',', ';' ),
57 + ' ',
58 + preg_replace(
59 + '/\s+(?=[\/\(])/',
60 + '',
61 + str_replace(
62 + array( '^', "'", '"', '\\' ),
63 + '',
64 + $value
65 + )
66 + )
67 + )
68 + )
69 + );
70 + }
71 +
72 + /**
73 + * Decode a SQL hex string.
74 + *
75 + * @example 414243 decodes to "ABC"
76 + * @param string $value value to be decoded.
77 + * @return string
78 + */
79 + public function sql_hex_decode( $value ) {
80 + return preg_replace_callback(
81 + '/0x[a-f0-9]+/i',
82 + function ( $matches ) {
83 + $str = substr( $matches[0], 2 );
84 + if ( 0 !== strlen( $str ) % 2 ) {
85 + $str = '0' . $str;
86 + }
87 + return hex2bin( $str );
88 + },
89 + $value
90 + );
91 + }
92 +
93 + /**
94 + * Encode a string using Base64 encoding.
95 + *
96 + * @param string $value value to be decoded.
97 + * @return string
98 + */
99 + public function base64_encode( $value ) {
100 + return base64_encode( $value );
101 + }
102 +
103 + /**
104 + * Convert all whitespace characters to a space and remove any repeated spaces.
105 + *
106 + * @param string $value value to be converted.
107 + * @return string
108 + */
109 + public function compress_whitespace( $value ) {
110 + return preg_replace( '/\s+/', ' ', $value );
111 + }
112 +
113 + /**
114 + * Encode string (possibly containing binary characters) by replacing each input byte with two hexadecimal characters.
115 + *
116 + * @param string $value value to be encoded.
117 + * @return string
118 + */
119 + public function hex_encode( $value ) {
120 + return bin2hex( $value );
121 + }
122 +
123 + /**
124 + * Decode string that was previously encoded by hexEncode()
125 + *
126 + * @param string $value value to be decoded.
127 + * @return string
128 + */
129 + public function hex_decode( $value ) {
130 + return pack( 'H*', $value );
131 + }
132 +
133 + /**
134 + * Decode the characters encoded as HTML entities.
135 + *
136 + * @param mixed $value value do be decoded.
137 + * @return string
138 + */
139 + public function html_entity_decode( $value ) {
140 + return html_entity_decode( $value, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );
141 + }
142 +
143 + /**
144 + * Return the length of the input string.
145 + *
146 + * @param string $value input string.
147 + * @return int
148 + */
149 + public function length( $value ) {
150 + return strlen( $value );
151 + }
152 +
153 + /**
154 + * Convert all characters to lowercase.
155 + *
156 + * @param string $value string to be converted.
157 + * @return string
158 + */
159 + public function lowercase( $value ) {
160 + return strtolower( $value );
161 + }
162 +
163 + /**
164 + * Calculate an md5 hash for the given data
165 + *
166 + * @param mixed $value value to be hashed.
167 + * @return string
168 + */
169 + public function md5( $value ) {
170 + return md5( $value, true );
171 + }
172 +
173 + /**
174 + * Removes multiple slashes, directory self-references, and directory back-references (except when at the beginning of the input) from input string.
175 + *
176 + * @param string $value value to be normalized.
177 + * @return string
178 + */
179 + public function normalize_path( $value ) {
180 + $parts = explode(
181 + '/',
182 + // replace any duplicate slashes with a single one.
183 + preg_replace( '~/{2,}~', '/', $value )
184 + );
185 +
186 + $i = 0;
187 + while ( isset( $parts[ $i ] ) ) {
188 + switch ( $parts[ $i ] ) {
189 + // If this folder is a self-reference, remove it.
190 + case '..':
191 + // If this folder is a backreference, remove it unless we're already at the root.
192 + if ( isset( $parts[ $i - 1 ] ) && ! in_array( $parts[ $i - 1 ], array( '', '..' ), true ) ) {
193 + array_splice( $parts, $i - 1, 2 );
194 + --$i;
195 + continue 2;
196 + }
197 + break;
198 + case '.':
199 + array_splice( $parts, $i, 1 );
200 + continue 2;
201 + }
202 + ++$i;
203 + }
204 +
205 + return implode( '/', $parts );
206 + }
207 +
208 + /**
209 + * Convert backslash characters to forward slashes, and then normalize using `normalizePath`
210 + *
211 + * @param string $value to be normalized.
212 + * @return string
213 + */
214 + public function normalize_path_win( $value ) {
215 + return $this->normalize_path( str_replace( '\\', '/', $value ) );
216 + }
217 +
218 + /**
219 + * Removes all NUL bytes from input.
220 + *
221 + * @param string $value value to be filtered.
222 + * @return string
223 + */
224 + public function remove_nulls( $value ) {
225 + return str_replace( "\x0", '', $value );
226 + }
227 +
228 + /**
229 + * Remove all whitespace characters from input.
230 + *
231 + * @param string $value value to be filtered.
232 + * @return string
233 + */
234 + public function remove_whitespace( $value ) {
235 + return preg_replace( '/\s/', '', $value );
236 + }
237 +
238 + /**
239 + * Replaces each occurrence of a C-style comment (/ * ... * /) with a single space.
240 + * Unterminated comments will also be replaced with a space. However, a standalone termination of a comment (* /) will not be acted upon.
241 + *
242 + * @param string $value value to be filtered.
243 + * @return string
244 + */
245 + public function replace_comments( $value ) {
246 + $value = preg_replace( '~/\*.*?\*/|/\*.*?$~Ds', ' ', $value );
247 + return explode( '/*', $value, 2 )[0];
248 + }
249 +
250 + /**
251 + * Removes common comments chars (/ *, * /, --, #).
252 + *
253 + * @param string $value value to be filtered.
254 + * @return string
255 + */
256 + public function remove_comments_char( $value ) {
257 + return preg_replace( '~/*|*/|--|#|//~', '', $value );
258 + }
259 +
260 + /**
261 + * Replaces each NUL byte in input with a space.
262 + *
263 + * @param string $value value to be filtered.
264 + * @return string
265 + */
266 + public function replace_nulls( $value ) {
267 + return str_replace( "\x0", ' ', $value );
268 + }
269 +
270 + /**
271 + * Decode a URL-encoded input string.
272 + *
273 + * @param string $value value to be decoded.
274 + * @return string
275 + */
276 + public function url_decode( $value ) {
277 + return urldecode( $value );
278 + }
279 +
280 + /**
281 + * Decode a URL-encoded input string.
282 + *
283 + * @param string $value value to be decoded.
284 + * @return string
285 + */
286 + public function url_decode_uni( $value ) {
287 + error_log( 'JETPACKWAF TRANSFORM NOT IMPLEMENTED: urlDecodeUni' );
288 + return $value;
289 + }
290 +
291 + /**
292 + * Decode a json encoded input string.
293 + *
294 + * @param string $value value to be decoded.
295 + * @return string
296 + */
297 + public function js_decode( $value ) {
298 + error_log( 'JETPACKWAF TRANSFORM NOT IMPLEMENTED: jsDecode' );
299 + return $value;
300 + }
301 +
302 + /**
303 + * Convert all characters to uppercase.
304 + *
305 + * @param string $value value to be encoded.
306 + * @return string
307 + */
308 + public function uppercase( $value ) {
309 + return strtoupper( $value );
310 + }
311 +
312 + /**
313 + * Calculate a SHA1 hash from the input string.
314 + *
315 + * @param mixed $value value to be hashed.
316 + * @return string
317 + */
318 + public function sha1( $value ) {
319 + return sha1( $value, true );
320 + }
321 +
322 + /**
323 + * Remove whitespace from the left side of the input string.
324 + *
325 + * @param string $value value to be trimmed.
326 + * @return string
327 + */
328 + public function trim_left( $value ) {
329 + return ltrim( $value, self::TRIM_CHARS );
330 + }
331 +
332 + /**
333 + * Remove whitespace from the right side of the input string.
334 + *
335 + * @param string $value value to be trimmed.
336 + * @return string
337 + */
338 + public function trim_right( $value ) {
339 + return rtrim( $value, self::TRIM_CHARS );
340 + }
341 +
342 + /**
343 + * Remove whitespace from both sides of the input string.
344 + *
345 + * @param string $value value to be trimmed.
346 + * @return string
347 + */
348 + public function trim( $value ) {
349 + return trim( $value, self::TRIM_CHARS );
350 + }
351 +
352 + /**
353 + * Convert UTF-8 characters to Unicode characters.
354 + *
355 + * This function iterates through each character of the input string, checks the ASCII value,
356 + * and converts it to its corresponding Unicode representation. It handles characters that are
357 + * represented with 1 to 4 bytes in UTF-8.
358 + *
359 + * @param string $str The string value to be encoded from UTF-8 to Unicode.
360 + * @return string The converted string with Unicode representation.
361 + */
362 + public function utf8_to_unicode( $str ) {
363 + $unicodeStr = '';
364 + $strLen = strlen( $str );
365 + $i = 0;
366 +
367 + // Iterate through each character of the input string.
368 + while ( $i < $strLen ) {
369 + // Get the ASCII value of the current character.
370 + $value = ord( $str[ $i ] );
371 +
372 + if ( $value < 128 ) {
373 + // If the character is in the ASCII range (0-127), directly add it to the Unicode string.
374 + $unicodeStr .= chr( $value );
375 + ++$i;
376 + } else {
377 + // For characters outside the ASCII range, determine the number of bytes in the UTF-8 representation.
378 + $unicodeValue = '';
379 + if ( $value >= 192 && $value <= 223 ) {
380 + // For characters represented with 2 bytes in UTF-8.
381 + $unicodeValue = ( ord( $str[ $i ] ) & 0x1F ) << 6 | ( ord( $str[ $i + 1 ] ) & 0x3F );
382 + $i += 2;
383 + } elseif ( $value >= 224 && $value <= 239 ) {
384 + // For characters represented with 3 bytes in UTF-8.
385 + $unicodeValue = ( ord( $str[ $i ] ) & 0x0F ) << 12 | ( ord( $str[ $i + 1 ] ) & 0x3F ) << 6 | ( ord( $str[ $i + 2 ] ) & 0x3F );
386 + $i += 3;
387 + } elseif ( $value >= 240 && $value <= 247 ) {
388 + // For characters represented with 4 bytes in UTF-8.
389 + $unicodeValue = ( ord( $str[ $i ] ) & 0x07 ) << 18 | ( ord( $str[ $i + 1 ] ) & 0x3F ) << 12 | ( ord( $str[ $i + 2 ] ) & 0x3F ) << 6 | ( ord( $str[ $i + 3 ] ) & 0x3F );
390 + $i += 4;
391 + } else {
392 + // If the sequence does not match any known UTF-8 pattern, skip to the next character.
393 + ++$i;
394 + continue;
395 + }
396 + // Convert the Unicode value to a formatted string and append it to the Unicode string.
397 + $unicodeStr .= sprintf( '%%u%04X', $unicodeValue );
398 + }
399 + }
400 +
401 + return strtolower( $unicodeStr );
402 + }
403 +}