Robert B.: Warnung! Beware! Uwaga!

Beitrag lesen

Moin,

die Sache mit dem Kontext(-Wechsel) ist mir noch nicht klar, das muss ich noch weiter erforschen. Escape-/Quote? Hm... Bedenke: Ich bin Neuling. Bei C# gibt's sowas meines Wissens nach nicht oder ich hab's nicht gebraucht.

Kontextwechsel gibt es potenziell überall:

  • Ausgabe nach HTML
  • Speichern von Texten in einer CSV-Datei
  • Zusammenbauen von SQL-Statements

Als Neuling ist es besonders wichtig, das direkt zu lernen, weil das einem viel Ärger ersparen kann.

Noch speichere ich die Texte und alles andere in ganz normalen Textdateien, darin habe ich Übung und in C# ist das die einfachste, schnellste Lösung. Da zeigt sich jetzt auch, warum Zeilenumrüche ein Problem darstellen.

Wenn Zeilenumbrüche ein Problem darstellen, dann musst du den Kontextwechsel in dein zeilenbasiertes Format korrekt behandeln.

Ich 'nehme sie raus, nur was passiert, wenn jemand sich 'nen Request bastelt, der im $_POST z.b. <?php gefährlicher_Code; ?> 'reinschreibt?

Das kommt darauf an, wo dieser String landet – in welchem Kontext.

Meine Texte schreibe ich alle in Notepadd++, das ist fest auf UTF-8 eingestellt, Unicode geht da gar nicht.

UTF-8 ist Unicode und Notepad++ hat so ein schönes Menü genannt Codierung und da finde zumindest ich einiges an Unicode-Codierungen 😉

Tja, das error_log...! Ich hatte früher mal phpinfo() gestartet, weil ich die PHP-Version wissen wollte (is' 8.0.27, XAMPP läuft mit 8.2) und mich mit den Server-Einstellungen befasst hatte - sind zuviele. Aber den Eintrag "error_log" habe ich gefunden - Scrennshot hängt an.

Ansonsten hilft dir natürlich auch das Error Reporting von PHP weiter.

if ($treffer)// Nutzername/Passwort ok.
{
	ob_start();
	$sid = trim(substr($s_user, 0, 4), ' {}');
	session_start();
	$_SESSION['user_id'] = $sid;
	$_SESSION['user_nm'] = trim($treffer[1]);
	$insert = "gnDas Einloggen war erfolgreich!";
	#header('Location: pinwand_html.php');
	ob_end_flush();
	include "pinwand_anm_html.php";
	exit;
}

Wie schon erwähnt: Nach der Benutzernamen/Passwortprüfung (ja, mit password_verify) sollte die Seite "pinwand_html,php" aufgerufen werden, aber das tut er nicht. Das exit(); steht jetzt nur für das include... da, damit er nicht mehr den Rest durchläuft. Ohne das exit funktioniert's auch nicht, er verlässt die Seite einfach nicht, ignoriert das Setzen des Headers.

Kann es sein, dass der ganze Zweig gar nicht ausgeführt wird, weil die Bedingung nicht erfüllt ist?

(Ob ich das mit dem ob_start(); und ob_end_flush(); richtig gemacht habe, weiß ich nicht.

Die Frage kannst du mit Hilfe des PHP-Handbuch Kapitels zum Output Buffering eventuell selbst beantworten.

<?php
/*array*/	$aa_post = array(); $aa_get = array(); $aa_files = array(); $aa_muster = array(); $a_user = array();
/*string*/	$anm_nm = "default"; $insert = ""; $post_id;
/*int*/		$anm_nm_id = 0;
/*bool*/		$b_post = !empty($_POST); $b_get = !empty($_GET); $b_files = !empty($_FILES); $b_tm = "false";

### $_GET-Übergabe einlesen, schützen
	if (!$b_get)
	{
		foreach ($_GET as $key => $val)
			$aa_get[htmlspecialchars($key)] = htmlspecialchars($val);
	}

Der Zweig hier ↑ wird nur ausgeführt, wenn $_GET leer ist, aber dann hat foreach nichts zu tun und $aa_get bleibt auch leer.

Unabhängig davon: Sofern du die Schlüssel und Werte nicht ausschließlich im HTML-Kontext ausgibst, kannst du dir das htmlspecialchars an der Stelle sparen.

### bei leerer Übergabe sofort zur Anmeldung
	if (!$b_post)
	{
		include "pinwand_anm_html.php";
		exit;
	}

Hier ↑ scheint die Bedingung korrekt.

###  $_POST-Übergabe einlesen, schützen
	if ($b_post)
	{
		$send = htmlspecialchars($_POST["send"]);
		if ($send == "Anmelden" || $send == "Anlegen" || $send == "Speichern")
			foreach ($_POST as $key => $val)
			{
				$key = htmlspecialchars($key);
				if (str_starts_with($key, 'b64_')) $val = base64_encode(htmlspecialchars($val));
				$aa_post[$key] = $val;
				#if (str_starts_with($key, 'hash_')) $aa_post['hash'] = password_hash($val, PASSWORD_DEFAULT);
			}
		else exit;

Du kannst formal auf die geschweiften Klammern beim if verzichten, aus Gründen der Nachvollziehbarkeit ist das aber wenig empfehlenswert.

$send braucht hier nicht mit htmlspecialchars behandelt zu werden, da du es ja nur gegen konstante Strings vergleichst. Und da möchtest du gerne mit === vergleichen, also auf inhaltliche und Typgleichheit. Allerdings fehlt dir noch die Prüfung, ob $_POST überhaupt einen Schlüssel send enthält.

Für Base64-Encodierung brauchst du vorher auch kein htmlspecialchars, denn nach Base64 bleiben nur 64 Zeichen übrig und keines davon ist im HTML-Kontext gefährlich.

So hat den deine Ermahnung - andere gaben sie ja auch schon - sehr geholfen. Jedenfalls hab ich mächtig dazu gelernt und erfahren, dass PHP doch schwieriger ist, als ich dachte. Ich bin da recht blauäugig 'rangegangen: "Was andere können, kann ich auch". Bei C# hat's geklappt, hier wird's das schlussendlich auch.

In C# musst du dich aber doch auch mit deiner Umgebung und den Dokumentationen auseinandersetzen.

Viele Grüße
Robert