VERO/sanitize.php
2026-03-04 10:12:09 +01:00

257 lines
7.1 KiB
PHP

<?php
class FormInputFilter {
/**
* Hauptfunktion zur Filterung verschiedener Input-Typen
*
* @param mixed $input Der zu filternde Input
* @param string $type Der Typ des Inputs ('string', 'number', 'email', 'url')
* @param array $options Zusätzliche Optionen für die Filterung
* @return mixed Gefilterter Input oder false bei ungültigen Daten
*/
public static function filterInput($input, $type, $options = []) {
// Basis-Sanitizing für alle Inputs
$input = trim($input);
switch (strtolower($type)) {
case 'string':
return self::filterString($input, $options);
case 'number':
case 'integer':
case 'int':
return self::filterNumber($input, $options);
case 'email':
return self::filterEmail($input);
case 'url':
return self::filterUrl($input);
default:
return self::filterString($input, $options);
}
}
/**
* Filtert String-Eingaben
*/
private static function filterString($input, $options = []) {
// Standard-Optionen
$defaults = [
'allow_html' => false,
'max_length' => 1000,
'min_length' => 0,
'allowed_chars' => null, // Regex für erlaubte Zeichen
'strip_tags' => true
];
$options = array_merge($defaults, $options);
// Längenprüfung
if (strlen($input) > $options['max_length'] || strlen($input) < $options['min_length']) {
return false;
}
// HTML-Tags entfernen wenn nicht erlaubt
if (!$options['allow_html'] && $options['strip_tags']) {
$input = strip_tags($input);
}
// HTML-Entities kodieren für Sicherheit
$input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
// Spezielle Zeichen-Validierung
if ($options['allowed_chars'] && !preg_match($options['allowed_chars'], $input)) {
return false;
}
// Gefährliche Zeichen entfernen
$input = preg_replace('/[<>"\']/', '', $input);
return $input;
}
/**
* Filtert numerische Eingaben
*/
private static function filterNumber($input, $options = []) {
$defaults = [
'allow_float' => true,
'allow_negative' => true,
'min_value' => null,
'max_value' => null
];
$options = array_merge($defaults, $options);
// Nur Zahlen, Punkte, Kommas und Minus erlauben
$input = preg_replace('/[^0-9.,-]/', '', $input);
// Komma zu Punkt für float-Konvertierung
$input = str_replace(',', '.', $input);
if ($options['allow_float']) {
$number = filter_var($input, FILTER_VALIDATE_FLOAT);
} else {
$number = filter_var($input, FILTER_VALIDATE_INT);
}
if ($number === false) {
return false;
}
// Negative Zahlen prüfen
if (!$options['allow_negative'] && $number < 0) {
return false;
}
// Min/Max Werte prüfen
if ($options['min_value'] !== null && $number < $options['min_value']) {
return false;
}
if ($options['max_value'] !== null && $number > $options['max_value']) {
return false;
}
return $number;
}
/**
* Filtert E-Mail-Adressen
*/
private static function filterEmail($input) {
// Basis-Sanitizing
$email = filter_var($input, FILTER_SANITIZE_EMAIL);
// E-Mail-Validierung
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return false;
}
// Zusätzliche Sicherheitsprüfungen
if (strlen($email) > 254) { // RFC 5321 Limit
return false;
}
// Gefährliche Zeichen prüfen
if (preg_match('/[<>"\']/', $email)) {
return false;
}
return $email;
}
/**
* Filtert URLs
*/
private static function filterUrl($input) {
// URL säubern
$url = filter_var($input, FILTER_SANITIZE_URL);
// URL-Validierung
if (!filter_var($url, FILTER_VALIDATE_URL)) {
return false;
}
// Nur HTTP/HTTPS erlauben
$parsed_url = parse_url($url);
if (!isset($parsed_url['scheme']) || !in_array($parsed_url['scheme'], ['http', 'https'])) {
return false;
}
// Länge prüfen
if (strlen($url) > 2048) {
return false;
}
return $url;
}
/**
* Filtert mehrere Formular-Felder auf einmal
*
* @param array $data Assoziatives Array mit Feldname => Wert
* @param array $rules Assoziatives Array mit Feldname => ['type' => 'string', 'options' => []]
* @return array Gefiltertes Array oder false bei Fehlern
*/
public static function filterFormData($data, $rules) {
$filtered_data = [];
$errors = [];
foreach ($rules as $field => $rule) {
if (!isset($data[$field])) {
$errors[$field] = "Feld fehlt";
continue;
}
$type = $rule['type'] ?? 'string';
$options = $rule['options'] ?? [];
$filtered_value = self::filterInput($data[$field], $type, $options);
if ($filtered_value === false) {
$errors[$field] = "Ungültiger Wert";
continue;
}
$filtered_data[$field] = $filtered_value;
}
return empty($errors) ? $filtered_data : ['errors' => $errors];
}
}
// Beispiel-Verwendung:
// Einzelne Werte filtern
/*$name = FormInputFilter::filterInput($_POST['name'] ?? '', 'string', [
'max_length' => 100,
'min_length' => 2
]);
$age = FormInputFilter::filterInput($_POST['age'] ?? '', 'number', [
'allow_float' => false,
'min_value' => 0,
'max_value' => 150
]);
$email = FormInputFilter::filterInput($_POST['email'] ?? '', 'email');
$website = FormInputFilter::filterInput($_POST['website'] ?? '', 'url');
// Komplettes Formular filtern
$form_data = [
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => '25',
'website' => 'https://example.com'
];
$rules = [
'name' => [
'type' => 'string',
'options' => ['max_length' => 100, 'min_length' => 2]
],
'email' => [
'type' => 'email'
],
'age' => [
'type' => 'number',
'options' => ['allow_float' => false, 'min_value' => 0, 'max_value' => 80]
],
'website' => [
'type' => 'url'
]
];
$result = FormInputFilter::filterFormData($form_data, $rules);
if (isset($result['errors'])) {
// Fehler behandeln
print_r($result['errors']);
} else {
// Gefilterte Daten verwenden
print_r($result);
}
*/
?>