@@ -1,3 +1,127 @@
< ? php
session_start ();
// --- Helper functions ---
function normalizeContactValue ( string $value ) : string
{
return trim ( $value );
}
function escapeContactValue ( string $value ) : string
{
return htmlspecialchars ( $value , ENT_QUOTES , 'UTF-8' );
}
function containsHeaderInjection ( string $value ) : bool
{
return ( bool ) preg_match ( '/[\r\n]/' , $value );
}
// --- Form processing ---
$formErrors = [];
$formSuccess = false ;
if ( ! empty ( $_SESSION [ 'form_success' ])) {
$formSuccess = true ;
unset ( $_SESSION [ 'form_success' ]);
}
if ( ! empty ( $_SESSION [ 'form_errors' ])) {
$formErrors = $_SESSION [ 'form_errors' ];
unset ( $_SESSION [ 'form_errors' ]);
}
if ( ! empty ( $_SESSION [ 'form_data' ])) {
$formData = $_SESSION [ 'form_data' ];
unset ( $_SESSION [ 'form_data' ]);
} else {
$formData = [ 'fname' => '' , 'lname' => '' , 'email' => '' , 'phone' => '' , 'interest' => 'Besichtigung anfragen' , 'message' => '' ];
}
if ( $_SERVER [ 'REQUEST_METHOD' ] === 'POST' ) {
// Collect and normalize input
$formData [ 'fname' ] = normalizeContactValue (( string ) ( $_POST [ 'fname' ] ? ? '' ));
$formData [ 'lname' ] = normalizeContactValue (( string ) ( $_POST [ 'lname' ] ? ? '' ));
$formData [ 'email' ] = normalizeContactValue (( string ) ( $_POST [ 'email' ] ? ? '' ));
$formData [ 'phone' ] = normalizeContactValue (( string ) ( $_POST [ 'phone' ] ? ? '' ));
$formData [ 'interest' ] = normalizeContactValue (( string ) ( $_POST [ 'interest' ] ? ? '' ));
$formData [ 'message' ] = normalizeContactValue (( string ) ( $_POST [ 'message' ] ? ? '' ));
// Honeypot check – hidden field must be empty
$honeypot = normalizeContactValue (( string ) ( $_POST [ 'website' ] ? ? '' ));
if ( $honeypot !== '' ) {
// Bot detected – pretend success
header ( 'Location: ' . $_SERVER [ 'REQUEST_URI' ] . '#form-result' );
$_SESSION [ 'form_success' ] = true ;
exit ;
} else {
// Server-side validation
if ( $formData [ 'fname' ] === '' ) {
$formErrors [] = 'Bitte geben Sie Ihren Vornamen an.' ;
}
if ( $formData [ 'lname' ] === '' ) {
$formErrors [] = 'Bitte geben Sie Ihren Nachnamen an.' ;
}
if ( $formData [ 'email' ] === '' || ! filter_var ( $formData [ 'email' ], FILTER_VALIDATE_EMAIL )) {
$formErrors [] = 'Bitte geben Sie eine gültige E-Mail-Adresse an.' ;
}
if ( $formData [ 'message' ] === '' ) {
$formErrors [] = 'Bitte geben Sie eine Nachricht ein.' ;
}
// Header injection check
if ( containsHeaderInjection ( $formData [ 'email' ]) || containsHeaderInjection ( $formData [ 'fname' ] . ' ' . $formData [ 'lname' ])) {
$formErrors [] = 'Ungültige Zeichen in den Eingabefeldern.' ;
}
// Minimum time check – form submitted too fast (< 3 seconds)
$formTime = isset ( $_POST [ 'form_time' ]) ? ( int ) $_POST [ 'form_time' ] : 0 ;
if ( $formTime > 0 && ( time () - $formTime ) < 3 ) {
$formErrors [] = 'Das Formular wurde zu schnell abgeschickt. Bitte versuchen Sie es erneut.' ;
}
// Session rate limit – max 1 submission per 60 seconds
$lastSubmit = $_SESSION [ 'last_contact_submit' ] ? ? 0 ;
if ( $lastSubmit && ( time () - $lastSubmit ) < 60 ) {
$formErrors [] = 'Bitte warten Sie einen Moment vor der nächsten Anfrage.' ;
}
// Send email if no errors
if ( empty ( $formErrors )) {
$to = 'mki@kies-media.de' ;
$subject = 'Kontaktanfrage: ' . $formData [ 'interest' ];
$body = " Von: { $formData [ 'fname' ] } { $formData [ 'lname' ] } \n "
. " E-Mail: { $formData [ 'email' ] } \n " ;
if ( $formData [ 'phone' ] !== '' ) {
$body .= " Telefon: { $formData [ 'phone' ] } \n " ;
}
$body .= " Anliegen: { $formData [ 'interest' ] } \n \n "
. $formData [ 'message' ];
$headers = " From: { $formData [ 'email' ] } \r \n " ;
$headers .= " Reply-To: { $formData [ 'email' ] } \r \n " ;
$headers .= " Content-Type: text/plain; charset=UTF-8 \r \n " ;
$headers .= " X-Mailer: PHP/ " . phpversion ();
$mailSent = mail ( $to , $subject , $body , $headers );
if ( $mailSent ) {
$_SESSION [ 'last_contact_submit' ] = time ();
header ( 'Location: ' . $_SERVER [ 'REQUEST_URI' ] . '#form-result' );
$_SESSION [ 'form_success' ] = true ;
exit ;
} else {
$formErrors [] = 'Leider konnte die E-Mail nicht gesendet werden. Bitte versuchen Sie es später erneut oder schreiben Sie uns direkt an mki@kies-media.de.' ;
}
}
}
if ( ! empty ( $formErrors )) {
header ( 'Location: ' . $_SERVER [ 'REQUEST_URI' ] . '#form-result' );
$_SESSION [ 'form_errors' ] = $formErrors ;
$_SESSION [ 'form_data' ] = $formData ;
exit ;
}
}
?>
<! doctype html >
< html lang = " de " >
< head >
@@ -531,15 +655,31 @@
paar Terminvorschläge an .
</ p >
< div class = " contact-form " >
< form id = " contactForm " >
< ? php if ( $formSuccess ) : ?>
< div id = " form-result " class = " form-success " style = " display: block " >
< p > Vielen Dank für Ihre Anfrage !</ p >
< br />
< small > Wir haben Ihre Nachricht erhalten und melden uns innerhalb von 24 Stunden bei Ihnen .</ small >
</ div >
< ? php else : ?>
< ? php if ( ! empty ( $formErrors )) : ?>
< div id = " form-result " class = " form-errors " >
< ul >
< ? php foreach ( $formErrors as $error ) : ?>
< li >< ? = escapeContactValue ( $error ) ?> </li>
< ? php endforeach ; ?>
</ ul >
</ div >
< ? php endif ; ?>
< form id = " contactForm " method = " post " >
< div class = " form-row " >
< div class = " form-field " >
< label for = " fname " > Vorname </ label >
< input type = " text " id = " fname " name = " fname " placeholder = " Max " required />
< input type = " text " id = " fname " name = " fname " placeholder = " Max " required value = " <?= escapeContactValue( $formData['fname'] ) ?> " />
</ div >
< div class = " form-field " >
< label for = " lname " > Nachname </ label >
< input type = " text " id = " lname " name = " lname " placeholder = " Mustermann " required />
< input type = " text " id = " lname " name = " lname " placeholder = " Mustermann " required value = " <?= escapeContactValue( $formData['lname'] ) ?> " />
</ div >
</ div >
< div class = " form-row " >
@@ -551,20 +691,25 @@
name = " email "
placeholder = " max@beispiel.de "
required
value = " <?= escapeContactValue( $formData['email'] ) ?> "
/>
</ div >
< div class = " form-field " >
< label for = " phone " > Telefon </ label >
< input type = " tel " id = " phone " name = " phone " placeholder = " +49 ... " />
< input type = " tel " id = " phone " name = " phone " placeholder = " +49 ... " value = " <?= escapeContactValue( $formData['phone'] ) ?> " />
</ div >
</ div >
< div class = " form-row " >
< div class = " form-field full " >
< label for = " interest " > Anliegen </ label >
< select id = " interest " name = " interest " >
< option > Besichtigung anfragen </ option >
< option > Allgemeine Informationen</ option >
< option > Mietbewerbung einreichen </ option >
< ? php
$interestOptions = [ 'Besichtigung anfragen' , ' Allgemeine Informationen' , 'Mietbewerbung einreichen' ];
foreach ( $interestOptions as $opt ) :
$selected = ( $formData [ 'interest' ] === $opt ) ? ' selected' : '' ;
?>
< option < ? = $selected ?> ><?= escapeContactValue($opt) ?></option>
< ? php endforeach ; ?>
</ select >
</ div >
</ div >
@@ -576,16 +721,20 @@
name = " message "
rows = " 4 "
placeholder = " Ihre Nachricht ... "
></ textarea >
required
>< ? = escapeContactValue ( $formData [ 'message' ]) ?> </textarea>
</ div >
</ div >
<!-- Honeypot : hidden field for spam bots -->
< div class = " hp-field " aria - hidden = " true " >
< label for = " website " > Website </ label >
< input type = " text " id = " website " name = " website " tabindex = " -1 " autocomplete = " off " />
</ div >
<!-- Form load timestamp for minimum - submit - time check -->
< input type = " hidden " name = " form_time " value = " <?= time() ?> " />
< button type = " submit " class = " btn-submit " > Anfrage absenden </ button >
</ form >
< div class = " form-success " id = " formSuccess " >
< p > Vielen Dank für Ihre Anfrage !</ p >
< br />
< small > Ihr E - Mail - Programm wurde geöffnet . Bitte senden Sie die E - Mail ab , damit Ihre Anfrage bei uns eingeht .</ small >
</ div >
< ? php endif ; ?>
</ div >
< div class = " contact-details " >
< p > Oder schreiben Sie uns direkt : < a href = " mailto:mki@kies-media.de " > mki @ kies - media . de </ a ></ p >