|
|
|
|
@ -17,6 +17,35 @@ class safer_sql { |
|
|
|
|
* @link https://www.neuralegion.com/blog/sql-injection-payloads/ |
|
|
|
|
* @link https://ismailtasdelen.medium.com/sql-injection-payload-list-b97656cfd66b |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
// NoSQL attacks and now SQL attacks as JSON is used EveryWhere |
|
|
|
|
private static function found_bad_json(string $string): bool { |
|
|
|
|
if (function_exists("str_contains")) { |
|
|
|
|
if (str_contains($string, '[]') === true) return true; // GET Array |
|
|
|
|
} |
|
|
|
|
if (preg_match('/.match/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/&&/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\|\|/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$where/', $string) === 1) return true; |
|
|
|
|
if (preg_match("/mapReduce/", $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$group/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$regex/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$exists/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$ne/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$gt/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$lt/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$eq/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$nin/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$where/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$or/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$and/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$in/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$accumulator/', $string) === 1) return true; |
|
|
|
|
if (preg_match('/\$function/', $string) === 1) return true; |
|
|
|
|
if (preg_match("/:/", $string) === 1 && |
|
|
|
|
preg_match("/{/", $string) === 1) return true; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Stacked queries can be used to execute multiple queries in succession. |
|
|
|
|
private static function found_sql_stacker(string $string): bool { |
|
|
|
|
@ -228,8 +257,14 @@ class safer_sql { |
|
|
|
|
if (preg_match("/\)\)/", $string) === 1) return true; |
|
|
|
|
if (preg_match("/\//", $string) === 1) return true; |
|
|
|
|
if (function_exists("str_contains")) { |
|
|
|
|
if (str_contains($string, '\')') === true) return true; |
|
|
|
|
if (str_contains($string, '\")') === true) return true; |
|
|
|
|
if (str_contains($string, '\`)') === true) return true; |
|
|
|
|
if (str_contains($string, '\\') === true) return true; |
|
|
|
|
if (str_contains($string, '%00') === true) return true; |
|
|
|
|
if (str_contains($string, '\' or 1=1-- -') === true) return true; // Normal SQL |
|
|
|
|
if (str_contains($string, '\' || 1==1//') === true) return true; // Mongo SQL |
|
|
|
|
if (str_contains($string, '\' || 1==1%00') === true) return true; // Mongo SQL |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
@ -270,6 +305,7 @@ class safer_sql { |
|
|
|
|
if (self::found_sql_admin_attack($string) === true) return true; |
|
|
|
|
if (self::found_sql_bad_symbols($string) === true) return true; |
|
|
|
|
if (self::found_sql_statement($string) === true) return true; |
|
|
|
|
if (self::found_bad_json($string) === true) return true; |
|
|
|
|
if (self::found_sql_comment($string) === true && |
|
|
|
|
self::found_quotes_in($string) === true) { |
|
|
|
|
return true; |
|
|
|
|
@ -401,10 +437,10 @@ class safer_sql { |
|
|
|
|
/* |
|
|
|
|
* At this Point: Never allow Quotes, @$*=()%` |
|
|
|
|
* Limit allowed chars now, to safe ones! |
|
|
|
|
* _!. are safe-ish....oh-boy! |
|
|
|
|
*/ |
|
|
|
|
$safer = preg_replace('/[^a-zA-Z0-9_!.\s]/', "", $string); |
|
|
|
|
$safer = self::try_to_clean_sql($safer); |
|
|
|
|
$cleaner = self::try_to_clean_sql($string); |
|
|
|
|
$safer = preg_replace('/[^a-zA-Z0-9.\s]/', "", $cleaner); |
|
|
|
|
|
|
|
|
|
if (self::found_sql_keyword($safer)) { |
|
|
|
|
throw new \Exception("MySQL keyword found after injection, attempt!"); |
|
|
|
|
} |
|
|
|
|
@ -413,20 +449,4 @@ class safer_sql { |
|
|
|
|
return ["text"=>$string, "danger"=>false]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$test = $argv[1]; |
|
|
|
|
try { |
|
|
|
|
$results = \tts\safer_sql::get_safer_sql_text($test); |
|
|
|
|
} catch (\Exception $e) { |
|
|
|
|
echo $e->getMessage(); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
if ($results["danger"]) { |
|
|
|
|
echo "Possibe injection, attempt!" . PHP_EOL; |
|
|
|
|
echo $results["text"]; |
|
|
|
|
exit(1); |
|
|
|
|
} else { |
|
|
|
|
echo $results["text"]; |
|
|
|
|
|
|
|
|
|
} |