Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Script Mods
 phpBB Adsense Mode

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 TLD Liste
 Webkatalog‑Verzeichnis

Partner
 Sprüche Treff

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

Sonderzeichen mit Backslash maskieren

Sie befinden sich: Home > Php Tutorial > Sonderzeichen mit...

Sonderzeichen mit Backslash maskieren


Eintrag am:  27.12.2022
Hits / Besucher:  1213
Sprache:  Deutsch
Kategorie:  Einsteiger Tutorials
Tutorial Art:  eigenes
Eingetragen von   schubertmedia schubertmedia
 
Beschreibung

Wer Benutzereingaben in PHP verarbeitet, muss Sonderzeichen wie Anführungszeichen oder Backslashes sicher behandeln. Die Funktion addslashes() setzt einen Backslash vor bestimmte Zeichen und macht sie dadurch in bestimmten Kontexten unschädlich. Für SQL-Injection-Schutz ist die Funktion allerdings nicht geeignet. Dieses Tutorial erklärt die Funktionsweise, zeigt warum Prepared Statements die bessere Wahl sind und in welchen Fällen addslashes() noch sinnvoll ist.

Syntax und Funktionsweise

addslashes() erwartet genau einen String als Parameter und gibt den geänderten String zurück. Maskiert werden genau vier Zeichen: Einfaches Anführungszeichen ', doppeltes Anführungszeichen ", Backslash \ und das NUL-Byte \0.

<?php

$text = "O'Reilly & Sons";
echo addslashes($text);
/* Ausgabe: O\'Reilly & Sons
Nur das Apostroph wird maskiert,
das kaufmaennische Und bleibt unveraendert */
?>

Zeichen wie <, >, & oder Umlaute werden nicht von addslashes() verändert. Wer HTML-Sonderzeichen schützen will, braucht stattdessen htmlspecialchars().

Welche Zeichen werden maskiert?

Das folgende Beispiel zeigt das Verhalten für verschiedene Eingaben in einer foreach-Schleife:

<?php

$tests = [
"Keine Sonderzeichen",
'Er sagte: "Hallo"',
"It's a test",
"Pfad: C:\\Daten\\Datei.txt",
"<p>HTML-Tag</p>",
];

foreach ($tests as $original) {
$escaped = addslashes($original);
echo $original . " => " . $escaped . "\n";
}
?>

Bei "Hallo" werden die Anführungszeichen maskiert, beim Apostroph in It's ebenso. Die Backslashes im Dateipfad werden verdoppelt. Der HTML-Tag <p> bleibt dagegen komplett unverändert, denn spitze Klammern gehören nicht zu den vier maskierten Zeichen.

Warum addslashes() nicht für SQL-Abfragen taugt

Früher wurde addslashes() häufig verwendet, um Eingaben vor dem Einfügen in eine SQL-Abfrage zu schützen. Das reicht aber nicht aus, und zwar aus einem konkreten technischen Grund.

Der Multibyte-Angriff

Bei Zeichensätzen wie GBK oder SJIS kann ein speziell konstruiertes Multibyte-Zeichen den Backslash von addslashes() wirkungslos machen. Das funktioniert so: Das Byte 0xbf27 enthält ein Apostroph (0x27). addslashes() setzt einen Backslash (0x5c) davor, und es entsteht 0xbf5c27. In GBK bilden 0xbf5c aber ein gültiges Multibyte-Zeichen. Die Datenbank liest also: gültiges Zeichen + ungeschütztes Apostroph. Der Backslash wurde buchstäblich verschluckt.

Deshalb sollte man sich nie auf addslashes() für Datenbank-Sicherheit verlassen. Auch mysqli_real_escape_string() ist nur dann sicher, wenn der Zeichensatz korrekt gesetzt ist. Prepared Statements umgehen das Problem komplett.

Migration: addslashes() durch Prepared Statements ersetzen

Die meisten Entwickler, die addslashes() im Code finden, müssen alten Code migrieren. Hier drei typische Fälle:

<?php

/* VORHER: INSERT mit addslashes */
$name = addslashes($_POST['name']);
$sql = "INSERT INTO users (name)
VALUES ('$name')";

/* NACHHER: INSERT mit Prepared Statement */
$stmt = $pdo->prepare(
'INSERT INTO users (name) VALUES (?)'
);
$stmt->execute([$_POST['name']]);
?>
<?php

/* VORHER: SELECT mit addslashes */
$name = addslashes($_GET['name']);
$sql = "SELECT * FROM users
WHERE name = '$name'";

/* NACHHER: SELECT mit benanntem Parameter */
$stmt = $pdo->prepare(
'SELECT * FROM users WHERE name = :name'
);
$stmt->execute(['name' => $_GET['name']]);
$user = $stmt->fetch();
?>
<?php

/* VORHER: LIKE-Suche mit addslashes */
$suche = addslashes($_GET['q']);
$sql = "SELECT * FROM artikel
WHERE titel LIKE '%$suche%'";

/* NACHHER: LIKE mit Prepared Statement */
$stmt = $pdo->prepare(
'SELECT * FROM artikel
WHERE titel LIKE ?'
);
$stmt->execute(['%' . $_GET['q'] . '%']);
?>

Bei Prepared Statements trennt die Datenbank den SQL-Befehl sauber von den Daten. Ein Angreifer kann so keine eigene SQL-Logik einschleusen, egal welche Zeichen in der Eingabe stehen.

Vergleich: Escaping-Methoden

Um die Unterschiede auf einen Blick zu sehen, hier eine Gegenüberstellung der drei gängigen Methoden:

addslashes() maskiert nur 4 Zeichen, kennt den Datenbank-Zeichensatz nicht und ist anfällig für Multibyte-Angriffe. Nicht für SQL empfohlen.

mysqli_real_escape_string() berücksichtigt den Zeichensatz der Verbindung und maskiert mehr Zeichen. Sicherer als addslashes(), aber erfordert eine aktive Datenbankverbindung und ist fehleranfällig bei falschem Zeichensatz.

Prepared Statements (PDO/MySQLi) trennen SQL-Code und Daten auf Protokollebene. Kein Escaping nötig, kein Zeichensatz-Problem, keine Angrifffläche. Das ist die empfohlene Methode.

Historischer Hintergrund: magic_quotes_gpc

Bis PHP 5.3 gab es die Einstellung magic_quotes_gpc. War sie aktiv, hat PHP automatisch addslashes() auf alle GET-, POST- und Cookie-Daten angewandt. Das führte oft zu doppelter Maskierung und unerwartetem Verhalten. Seit PHP 5.4 ist magic_quotes_gpc komplett entfernt. Wer alten Code pflegt, kann in sehr frühen Versionen noch auf Reste davon stoßen.

Troubleshooting: Zu viele Backslashes

Wenn ein String mehr Backslashes hat als erwartet, liegt es meistens an einer dieser Ursachen:

1. Doppeltes addslashes(): Der Code ruft die Funktion zweimal auf, einmal manuell und einmal durch ein Framework.

2. magic_quotes war aktiv und der Code hat zusätzlich manuell addslashes() aufgerufen.

3. Die Datenbank escaped beim Speichern nochmals, und beim Lesen kommen doppelte Backslashes zurück.

Zur Diagnose hilft var_dump() auf den betroffenen String, um die tatsächliche Anzahl der Backslashes sichtbar zu machen.

preg_quote() für Regex-Kontext

Ein häufiger Fehler ist, addslashes() für das Escaping in regulären Ausdrücken zu verwenden. Dort braucht man stattdessen preg_quote(), das Regex-Metazeichen wie ., *, + und ? escaped.

<?php

$suche = "Preis: 9.99$";

/* FALSCH: addslashes fuer Regex */
$pattern = '/' . addslashes($suche) . '/';
/* /Preis: 9.99$/ - Punkt und Dollar
werden als Regex-Zeichen interpretiert */

/* RICHTIG: preg_quote fuer Regex */
$pattern = '/' . preg_quote($suche, '/') . '/';
/* /Preis\: 9\.99\$/ - alles korrekt
als Literal escaped */
?>

LDAP-Injection

Ähnlich wie bei SQL hilft addslashes() auch bei LDAP-Queries nicht. LDAP hat eigene Sonderzeichen (*, (, ), \, NUL). Seit PHP 5.6 gibt es dafür die Funktion ldap_escape(), die speziell für LDAP-Kontexte gedacht ist.

Wann addslashes() noch sinnvoll ist

Für SQL-Abfragen ist addslashes() keine Lösung. Es gibt aber Situationen, in denen die Funktion ihren Zweck erfüllt:

CSV-Export: Wenn Felder Anführungszeichen enthalten, die innerhalb eines umschließenden Zeichens maskiert werden müssen.

Eigene Textformate: Beim Schreiben in Dateien, die ein bestimmtes Trennzeichen verwenden.

Serialisierte Daten: Manche ältere Speicherformate erfordern maskierte Anführungszeichen.

<?php

$feld = 'Er sagte "Ja"';
$maskiert = addslashes($feld);
echo $maskiert;
/* Ergebnis: Er sagte \"Ja\" */
?>

addslashes() auf Arrays anwenden

addslashes() akzeptiert nur Strings. Wer ein ganzes Array verarbeiten will, kann array_map() verwenden:

<?php

$eingaben = [
"it's",
'Er sagte "Nein"',
"Pfad: C:\\temp",
];

$maskiert = array_map('addslashes', $eingaben);
print_r($maskiert);
/* Array (
[0] => it\'s
[1] => Er sagte \"Nein\"
[2] => Pfad: C:\\\\temp
) */
?>

Rückgängig machen mit stripslashes()

Die Gegenfunktion zu addslashes() ist stripslashes(). Sie entfernt die von addslashes() hinzugefügten Backslashes wieder:

<?php

$original = "O'Brien";
$escaped = addslashes($original);
$restored = stripslashes($escaped);

echo $escaped; // O\'Brien
echo $restored; // O'Brien

var_dump($original === $restored);
// bool(true)
?>

Zusammenfassung

addslashes() maskiert vier Sonderzeichen mit einem Backslash. Für Datenbank-Sicherheit ist die Funktion nicht geeignet, weil sie bei Multibyte-Zeichensätzen umgangen werden kann. Prepared Statements sind die einzig sichere Methode für SQL-Abfragen. Für Regex-Escaping gibt es preg_quote(), für LDAP ldap_escape(). In bestimmten Kontexten wie CSV-Export oder eigenen Textformaten erfüllt addslashes() aber weiterhin seinen Zweck.

 

Tags:

 

Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.