Mein erstes Newsscript. Fragen zur Sicherheit und Funktionalität

floHate

Grünschnabel
Guten Morgen,

ich "entwerfe" gerade mein erstes NewsScript das ich später auch zum Download anbieten möchte. Ich habe mal angefangen mit dem InstalationsScript. Es ist das erste das ich selber schreibe als nehmt etwas rücksicht :>

Ich werde hier in diesem Thread nun bei Fragen oder bei Fehlern bei denen ich nicht weiter komme Posten damit ich nicht für jedes kleine Ding nen neuen Thread auf machen muss. Wäre also super wenn mir jemand helfen kann und öfters mal vorbeischaut ;)

Kommen wir mal zu meiner ersten Frage:

Ich möchte nun in der URL ?step=1 weitergeben. Damit steuer ich meine switch-abfrage an. Nur was ist wenn step nicht gegeben ist? Daher habe ich mir gedacht ich überpfrüfe dies am Anfang.

PHP:
if(!isset($_GET['step'])) { // guckt nach ob 'step' übergeben wurde
  $_GET['step'] = 0;    
}

So bitte nich lachen oder über mich herziehen ^^

  • Kann ich hier überhaupt "$_GET['step']" einen Wert übergeben?
  • Ist dies überhaupt nötig da ich ja in der SwitchAbfrage ein Default teil besitze?


Zu meiner 2. Frage. Bezüglich Sicherheit was eig. in einem Instalationsscript irrelevant ist. Aber ich möchte so auch mit Abfragen später arbeiten in dem NewsScript:

PHP:
		$sql = 'CREATE TABLE `fH_news` ( `ID` INT UNSIGNED NOT NULL AUTO_INCREMENT ,'
				. ' `userID` INT NOT NULL ,'
				. ' `headline` VARCHAR( 60 ) NOT NULL ,'
				. ' `text` TEXT NOT NULL ,'
				. ' `date` DATE NOT NULL ,'
				. ' PRIMARY KEY ( `ID` ) );'
				. ' ';
        
		$news = mysql_query($sql);
		if (!$news) { die("FATAL ERROR - Table: <i>fH_news</i>."); }

Sinnvoll? Sicher? Verbesserungsvorschläge?

Das wars dann auch erst einmal. Ich danke schon mal fürs Lesen.

Mfg floH
 
Ich möchte nun in der URL ?step=1 weitergeben. Damit steuer ich meine switch-abfrage an. Nur was ist wenn step nicht gegeben ist? Daher habe ich mir gedacht ich überpfrüfe dies am Anfang.

PHP:
if(!isset($_GET['step'])) { // guckt nach ob 'step' übergeben wurde
  $_GET['step'] = 0;    
}
Du koenntest $_GET['step'] nutzen um $step zu belegen. Um sicher zu sein, dass $step belegt ist und auch nicht von "draussen" kommt, fuer den Fall das register_globals=on ist solltest Du einen Standardwert setzen, z.B. wie hier 0.
Das koennte dann z.B. so aussehen:
PHP:
if ((!empty($_GET{'step'])) && (is_numeric($_GET['step'])))
{
 $step=$_GET['step'];
}
else
{
 $step=0;
}
Im Anschluss an diesen Code kannst Du sicher sein, dass die Variable $step mit einem Zahlenwert belegt ist. Denn sie wird in jedem Fall gesetzt, im Zweifelsfall eben mit 0.
Ich bevorzuge fuer solche Checks im uebrigen empty() anstelle von isset().
isset() gibt Dir schon true zurueck wenn Du ?step an den Link haengst. Damit empty() false ausgibt muss schon ?step=123 uebergeben werden. Weiterhin macht es hier Sinn zu pruefen ob es sich um einen Zahlenwert handelt, dementsprechend is_numeric().
PHP:
		$sql = 'CREATE TABLE `fH_news` ( `ID` INT UNSIGNED NOT NULL AUTO_INCREMENT ,'
				. ' `userID` INT NOT NULL ,'
				. ' `headline` VARCHAR( 60 ) NOT NULL ,'
				. ' `text` TEXT NOT NULL ,'
				. ' `date` DATE NOT NULL ,'
				. ' PRIMARY KEY ( `ID` ) );'
				. ' ';
        
		$news = mysql_query($sql);
		if (!$news) { die("FATAL ERROR - Table: <i>fH_news</i>."); }

Sinnvoll? Sicher? Verbesserungsvorschläge?
Der Code ist insofern sicher, dass es keine Moeglichkeit gibt ihn von aussen zu beeinflussen, alle hier vorkommenden Variablen werden von Dir gesetzt.
 
:) Super und danke für die schnelle Antwort.

Um auf die mysqlDB zu Connecten benutze ich immer noch das Beispiel von http://tut.php-q.net/. Ich bin damit eig. immer recht zufrieden gewesen.

  • Kann ich das weiterhin so verwenden oder gibt es eine bessere Lösung?
  • Sollte man das in eine Funktion packen?

PHP:
        //Try to connect to database
		@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
			die("Keine Verbindung zur Datenbank. Fehlermeldung:".mysql_error());
		//Try to use the database
		mysql_select_db(MYSQL_DATABASE) OR
			die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

Mfg floH
 
Der Code ist soweit eigentlich okay. Mir waere nicht bekannt, dass man Konstanten von aussen einschleusen koennte (von einer Code-Injection, z.B. ueber ein include() oder eval(), mal abgesehen). Du solltest aber moeglichst auf das @ verzichten.
Auf Produktionsservern sollten Fehler per Einstellung nicht angezeigt sondern geloggt werden. Und waehrend der Entwicklung ist die Anzeige der Fehler wichtig.
Daher empfehle ich Dir auch auf dem Entwicklungssystem das Error Reporting auf E_ALL zu setzen, entweder in der php.ini oder mit
PHP:
error_reporting(E_ALL);
Ob Du den Code so nutzt oder in eine Funktion packst ist eigentlich auch nicht wirklich wichtig. Ich nehme mal an, dass Du nur einmal die Verbindung mit der Datenbank herstellst und somit ist eine Funktion eigentlich nicht noetig. Und die Verbindung mehrfach aufzubauen ist eher unsinnig.
Bei mir findet die Verbindung zur Datenbank in einer Klasse statt, aber das liegt halt daran, dass eben die gesamte Abwicklung der Datenbank ueber diese Klasse laeuft.
Aber auch diesem Beispiel musst Du nicht zwingend folgen.
 
Ich würde die Schrittnummer eher auf eine positive natürliche Zahl bringen anstatt nur auf die numerische Eigenschaft zu prüfen. Denn auch „-1.2345“ ist numerisch.
PHP:
$_GET['step'] = ( (int) $_GET['step'] != 0 )
	? $_GET['step'] = abs((int) $_GET['step'])
	: 1;
Alternativ kann man aber auch nur positive natürliche Zahlen zulassen:
PHP:
$_GET['step'] = ( $_GET['step'] == (int) $_GET['step'] && (int) $_GET['step'] > 0 )
	? $_GET['step'] = (int) $_GET['step']
	: 1;
Falls dir diese Syntax nicht geläufig ist: das ist der so genannte ternäre Operator.
 
Hi. Ich habe ein Problem mit dem Datum :/ Das will nicht so wie ich will und den Fehler finde ich einfach nicht :mad:

Folgendes:

list.php
PHP:
//mySQL Abfrage
    $sql = "SELECT
                userID,
                headline,
                text,
                date
            FROM
                fh_news
            ORDER BY
                date DESC";
    $result = mysql_query($sql) OR die(mysql_error());
    if(mysql_num_rows($result)) {
        while($row = mysql_fetch_assoc($result)) {
            echo "<div class=\"content\">";
			echo "<h1>";
			echo $row['headline'];
			echo "</h1>";
			echo "<div class=\"descr\">";
			echo date("d.m.y H:i",$row['date']).' Uhr';
			echo "</div>";
			echo "<p>";
			echo nl2br($row['text']); // \n in <br /> umwandeln
			echo "</p>";
			echo "</div>";
        }
    } else {
        echo"<p>Keine News vorhanden</p>\n";
    }

add_entry.php
PHP:
//Try to connect to database
mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
die("Keine Verbindung zur Datenbank. Fehlermeldung:".mysql_error());
//Try to use the database
mysql_select_db(MYSQL_DATABASE) OR
die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

  if(!isset($_POST['headline'], $_POST['newstext'])) {
        die("Bitte Benutzen sie das Formular und füllen sie alles aus!\n");
    }

    if(trim($_POST['headline']) == "") {
        die("Bitte geben sie eine Überschrift ein.");
    }
    if(trim($_POST['newstext']) == "") {
        die("Bitte geben sie einen Text ein");
    }
    
    $time = time();

    $sql = "INSERT INTO fh_news
                (userID, headline, text, date)
            VALUES
                (1,
                '".addslashes(htmlspecialchars($_POST['headline']))."',
                '".addslashes(htmlspecialchars($_POST['newstext']))."',
                NOW())";

    mysql_query($sql) OR die(mysql_error());

    echo "<p>Vielen Dank für ihren Eintrag.</p>\n";

Das ist noch über meine Datenbank zu sagen: Momentan hab ich date auf TIMESTAMP. Ich hab :google: benutzt und alles durchgelesen und immer nur DATETIME gesehen aber damit geht es auch nicht. Ich möchte das Datum wie folgt ausgeben: d.m.y H:i

Wäre super wenn mir jemand auf die Sprünge helfen könne und evt. mal ein blick bezüglich sicherheit drauf werfen könnte. Über Konstruktive Kritik freue ich mich immer.

Mfg floH

------------------------------------

Ich habe die Lösung gefunden. Nur noch ein kleines Problem.

Ich habe jetzt die Tabelle 'date' auf VARCHAR geändert mit einer Länge von 15.

Dann habe ich ein Hidden Inputfeld hinzugefügt und dort das Datum eingespeichert.

Hier die Dateien:

list.php
PHP:
<?php
include "inc/config.php";

//Try to connect to database
mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
die("Keine Verbindung zur Datenbank. Fehlermeldung:".mysql_error());
//Try to use the database
mysql_select_db(MYSQL_DATABASE) OR
die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

echo '<?xml version="1.0" encoding="iso-8859-1"?>';
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">';
echo '<head>';
echo ' <title>News auflisten - NewsScript v.Beta1</title>';
echo ' <meta name="generator" content="Scribe! 2 [http://scribe.de]" />';
echo ' <meta name="author" content="floH, Florian, Florian Engel, Herr Engel" />';
echo ' <meta neme="copyright" content="2006 - Florian Engel" /> ';
echo ' <link rel="stylesheet" type="text/css" href="inc/news.css" />';
echo '</head>';
echo '<body>';

//mySQL Abfrage
    $sql = "SELECT
                userID,
                headline,
                text,
                date
            FROM
                fh_news
            ORDER BY
                date DESC";
    $result = mysql_query($sql) OR die(mysql_error());
    if(mysql_num_rows($result)) {
        while($row = mysql_fetch_assoc($result)) {
            echo "<div class=\"content\">";
			echo "<h1>";
			echo $row['headline'];
			echo "</h1>";
			echo "<div class=\"descr\">";
			echo $row['date'];
			echo "</div>";
			echo "<p>";
			echo nl2br($row['text']); // \n in <br /> umwandeln
			echo "</p>";
			echo "</div>";
        }
    } else {
        echo"<p>Keine News vorhanden</p>\n";
    }

echo '</body>';
echo '</html>';    
?>

add_entry.php
PHP:
<?php
//add_entry.php - Last update: 18.Nov.2006 by Florian Engel

include "inc/config.php";

//Starten der Fehlerroutine
if(isset($_POST['tocheck'])) 
  { 
  //Fehlerroutine
  
  //Variable zum Überprüfen ob alles ok ist
  $ready = 1; 
  
 // Hier wird geprüft ob Name leer ist
 if(empty($_POST['headline'])){
  $ready = 0; 
  //Fehlernachricht wird gesetzt
  $error[headline] = "Bitte eine Überschrift eingeben!";} 
  
 //Hier wird geprüft ob Email leer ist
 if(empty($_POST['newstext'])){
  $ready = 0; 
  //Fehlernachricht wird gesetzt
  $error[text] = "Bitte einen Text eingeben!";} 
  }
  
//Beenden der Fehlerroutine
if($ready)
  {  
//Daten in die Datenbank einfügen

//Try to connect to database
mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
die("Keine Verbindung zur Datenbank. Fehlermeldung:".mysql_error());
//Try to use the database
mysql_select_db(MYSQL_DATABASE) OR
die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

  if(!isset($_POST['headline'], $_POST['newstext'])) {
        die("Bitte Benutzen sie das Formular und füllen sie alles aus!\n");
    }

    if(trim($_POST['headline']) == "") {
        die("Bitte geben sie eine Überschrift ein.");
    }
    if(trim($_POST['newstext']) == "") {
        die("Bitte geben sie einen Text ein");
    }
    
    $time = time();

    $sql = "INSERT INTO fh_news
                (userID, headline, text, date)
            VALUES
                (1,
                '".addslashes(htmlspecialchars($_POST['headline']))."',
                '".addslashes(htmlspecialchars($_POST['newstext']))."',
                '".$_POST['date']."')";

    mysql_query($sql) OR die(mysql_error());

    echo "<p>Vielen Dank für ihren Eintrag.</p>\n";

//Eintragen der Daten bestätigen und nochmals Anzeigen  
  echo "Name --- ".$_POST['headline'];
  echo "<br>";
  echo "Email --- ".$_POST['newstext'];
  echo "<br>";
  echo '<a href="'.$_SERVER['PHP_SELF'].'">Zurück</a>';
  } 
else
  {
//Formular zum Eingeben der Daten  
?>  
<form name="add_entry" method="post" action="<?php echo $_SERVER['PHP_SELF']?>">
<blockquote><?php echo $error['headline'];?></blockquote><br />
Überschrift:<br />
<input name="headline" type="text" size="60" value="<?php echo $_POST['headline'];?>" /><br />
<blockquote><?php echo $error['text'];?></blockquote><br />
Newstext:<br />
<textarea name="newstext"><?php echo $_POST['newstext'];?></textarea><br>
<br>
<input type="hidden" name="tocheck" value="1" />
<input type="hidden" name="date" value="<?php echo date("d.m.y H:i")." Uhr"; ?>" /> 
<input type="submit" name="submit" value="Eintragen" />
</form>
<?php
  }
?>


-----
So nun hab ich folgendes Problem. Wenn ich eine News eintrage und dann das formular nicht schliese und einfach offen lasse wird ein "veraltetes" Datum angegeben. Es ist eig. nicht weiter tragisch aber wie könnte ich das am besten beheben? :)

Mfg floH
 
Zuletzt bearbeitet:
Zurück