257 lines
7.1 KiB
PHP
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);
|
|
}
|
|
*/
|
|
?>
|