Enigmatic adlı üyeden alıntı: mesajı görüntüle
Evet kodumuz aşağıdaki gibi, güvenlik kodu yok, 30 saniye içinde yada sizin belirleyeceğiniz bir süre kadar yeniden mesaj yazılmasını engeller, bu engeli ancak curl ile random proxy kullanarak ya da modeminiz 30 saniye içinde yeni bir ip alıyorsa resetleyip öyle aşabilirsiniz (benim modem 20 saniyede yeni ip alıyor mesela), ayrıca dışarıdan direk post gönderimini engellemek için gizli bir hidden input ile key gönderiyoruz, buna CSRF koruması da deniyor, kıracak olan varsa buyursun kırsın, bizde yeni birşey öğrenmiş oluruz.
(Ufak tefek hatalar olabilir, inceden inceye kontrol etmedim.)
Tablo:
CREATE TABLE messages (
  id int(11) NOT NULL auto_increment,
  message text NOT NULL,
  name varchar(25) NOT NULL,
  ip varchar(15) NOT NULL,
  time timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (id)
);
Dosya (herhangi bir isimle kaydedin)
<?php
session_start();
@setlocale(LC_ALL, 'turkish');
// connect
mysql_connect('localhost','root','0000') or die (mysql_error());
mysql_select_db('flood') or die (mysql_error());
// settings
$floodtime = 30;
$charlimit = 100;
###################################################################################################
if(empty($_REQUEST['flood']))
{
$ip = $_SERVER['REMOTE_ADDR'];
$_SESSION['ip'] = $ip;
$time = time();
$key = md5($ip).md5(microtime());
if(!isset($_SESSION['key'])){
$_SESSION['key'] = $key;
}
 echo '
 <h4>Flood Koruması</h4>
 <form method="POST" action="'.$_SERVER['PHP_SELF'].'?flood=message">
 İsim :&nbsp;&nbsp;&nbsp;&nbsp;<input type="text" name="name"><br />
 Mesaj : <textarea name="message" rows="10" cols="30"></textarea>
 <input type="hidden" name="key" value="'.$key.'"><br /><hr />
 * Mesajınız en çok '.$charlimit.' karakter olabilir.<br />
 * Yeniden mesaj gönderme süresi : '.$floodtime.' sn.<br /><hr />
 <input type="submit" value="Send Message">
 </form>
 ';
}
###################################################################################################
if($_REQUEST['flood']=='message')
{
 if(empty($_POST['key']) || empty($_SESSION['key']) || $_POST['key'] != $_SESSION['key'])
 {
  die ('<a href="'.$_SERVER['PHP_SELF'].'">Yeni flood denemesi yap!</a>');
 }
 elseif(empty($_POST['name']) || empty($_POST['message']))
 {
  header('Refresh:3 url='.$_SERVER['PHP_SELF']);
  die ('Lütfen boş alan bırakmayınız !');
 }
 elseif($charlimit < strlen($_POST['message']))
 {
  header('Refresh:3 url='.$_SERVER['PHP_SELF']);
  die ('Mesajınız en çok '.$charlimit.' karakter olabilir.');
 }
 else
 {
  $sql = mysql_query("SELECT * FROM messages WHERE ip = '$_SESSION[ip]' ORDER BY time DESC LIMIT 1") or die (mysql_error());
  $res = @mysql_fetch_row($sql);
  $dbtime = strtotime($res['4']);
  $nowtime = time();
  if(($nowtime - $dbtime) < $floodtime)
  {
   header('Refresh:3 url='.$_SERVER['PHP_SELF']);
   die ('Yeniden mesaj gönderebilmek için '.($floodtime - ($nowtime - $dbtime)).' saniye beklemelisiniz !');
  }
  else
  {
   header('Refresh:3 url='.$_SERVER['PHP_SELF']);
   $message = mysql_real_escape_string(strip_tags(trim($_POST['message'])));
   $name = mysql_real_escape_string(strip_tags(trim($_POST['name'])));
   mysql_query("INSERT INTO messages (message,name,ip,time) VALUES ('$message','$name','$_SESSION[ip]',NOW())") or die ('Bir problem oldu, daha sonra tekrar deneyiniz.');
   echo 'Mesajınınız eklendi..<br /><a href="'.$_SERVER['PHP_SELF'].'">Başka mesaj ekle!</a>';
  }
 }
}
?>
Kodun oldukça güvenli fakat bir kaç eksik var.
$_SERVER['PHP_SELF']
xss açığı oluşturur.
bknz. Temizlemek lazım kullanmadan önce.
xss açığı olunca sayfadaki key değeri çok rahat alınabilinir ve kullanıcının haberi olmadan veri postlanabilinir.
CSRF için key yerine referrer kontrolü yapmak daha iyi olur, çünkü javascript ile sahte referrer gönderilemez.