Zabezpieczenie formularza kontaktowego przed spamem oraz

0

Witam wszystkich. Zabrałem się za zabezpieczenie formularza kontaktowego na swojej stronie(przed ostatnia rzecz do zrobienie na własnej stronie) i mam problem jak zwykle z sesjami oraz ciastkami. A tego trzeba tutaj użyć. Chciałbym prosić wszystkich użytkowników o pomoc w tym skrypcie. Mam już wszystko napisane, ale chcę to zabezpieczyć. Po pierwsze chcę zrobić przepisywanie pierwszej i ostatnie cyfry z kodu wylosowanego, a po drugie chcę po wysłaniu jednej wiadomości dodać ciastko na 10 minut, żeby nie otrzymywać niepotrzebnego spamu. I napisałem coś takiego(pokaże cały kod)

kontakt.php

<?php
include('functions/bbc.php');
include('include/db.php');
echo '<h2>Kontakt</h2>';
$zapytanie = "SELECT * FROM `kontakt` WHERE `id`='1'";
$idzapytania = mysql_query($zapytanie);
while ($wiersz = mysql_fetch_array($idzapytania))
{
echo ''.stripslashes(bbc($wiersz['tresc'])).'<br />';
}
if(!isset($_COOKIE['kontakt']))
{
if(isset($_POST['tresc']))
{
echo '<div align="center"><form action="/kontakt.html" method="post"><br />
Nick:<br /><input type="text" name="nick" value="'.$_POST['nick'].'" /><br />
Twój email:<br /><input type="text" name="email" value="'.$_POST['email'].'" /><br />
Temat:<br /><input type="text" name="temat" value="'.$_POST['temat'].'" /><br />
Treść:<br /><textarea name="tresc" cols="30" rows="10">'.$_POST['tresc'].'</textarea><br />
Przepisz pierwszą i ostatnią liczbe:<br />';
echo $_SESSION['liczba'];
echo '<br /><input type="text" name="liczba" /><br /><br />
<input class="przycisk_kontakt" name="wyslij" type="submit" value="Wyślij" />
<input class="przycisk_kontakt" name="wyczysc" type="reset" value="Wyczyść" /></form><br /><br /></div>';
}
else
{
echo '<div align="center"><form action="/kontakt.html" method="post"><br />
Nick:<br /><input type="text" name="nick" /><br />
Twój email:<br /><input type="text" name="email" /><br />
Temat:<br /><input type="text" name="temat" /><br />
Treść:<br /><textarea name="tresc" cols="30" rows="10"></textarea><br />';
echo 'Przepisz pierwszą i ostatnią liczbe:<br />';
$kod=''; 
for($i=0;$i<3;$i++)
{
$kod.=rand(0,9);
}
$_SESSION['liczba']=$kod;
echo $kod;
$pomoc = $kod[0].$kod[2];
echo '<br /><input type="text" name="liczba" /><br /><br />
<input class="przycisk_kontakt" name="wyslij" type="submit" value="Wyślij" />
<input class="przycisk_kontakt" name="wyczysc" type="reset" value="Wyczyść" /></form><br /><br /></div>';
}
if(isset($_POST['wyslij'])) 
{
if(empty($_POST['nick']) or empty($_POST['email']) or empty($_POST['temat']) or empty($_POST['tresc']) or empty($_POST['liczba'])) 
{
echo '<div align="center"><font color="red"><b>Wypełnij wszystkie pola formularza!</b></font></div><br />';
}
elseif(!$_POST["email"] || !preg_match("/^[-0-9a-zA-Z_\.]+@([-0-9a-zA-Z_\.]+\.)+([0-9a-zA-Z]){2,4}$/i", $_POST["email"]))
{
echo '<div align="center"><font color="red"><b>Podany email jest nieprawidłowy!</b></font></div><br />';
}
elseif($_SESSION['liczba']!=$kod)
{
echo '<div align="center"><font color="red"><b>Podany kod jest nieprawidłowy!</b></font></div><br />';
}
else
{
setcookie("kontakt", 1, time()+10*60);
$message = 'Nick: '.$_POST['nick'].'<br /> email: '.$_POST['email'].'<br /> Temat: '.$_POST['temat'].'<br /> Treść: '.$_POST['tresc'].'';
$naglowki = 'From: '.$_POST['nick'].''.PHP_EOL.'Reply-To: '.$_POST['nick'].''.PHP_EOL.'Content-type: text/html; charset=utf-8';
mail('[email protected]', 'Wiadomość ze strony WWW', $message, $naglowki);
echo '<div align="center"><font color="green"><b>Wiadomość została wysłana poprawnie!</b></font></div><meta http-equiv="Refresh" content="3; url=/kontakt.html" /><br />';
}
}
}
else
{
echo '<div align="center"><font color="green"><br /><b>Nie można wysłać ponownie wiadomości. Prosimy spróbować za 10 minut.</b></font></div>';
}
mysql_close($connect);
?>

Proszę o pomoc.
Z góry dziękuje :)

0

Usunąłem swój post w tamtym temacie, teraz możesz zdjąć swój drugi, a potem cały temat.
Żeby nie otrzymywać spamu możesz użyć reCaptcha albo tego: http://code.google.com/p/cool-php-captcha/

0

W tym rzecz, że nie chcę używać gotowców :)

0

No to jak koniecznie chcesz się czegoś poduczyć, polecam trik stosowany na 4P, który od użytkowników z wyłączonym JS wymaga przepisania zadanego kodu od tyłu, a jeśli masz włączony JS jakiś tam freakowaty kod sam to robi.

Serwer może generować coś takiego:

<form ...>
<input type="hidden" name="costam" id="costam" value="">
</form>

<script type="text/javascript">
var kod = String.fromCharCode(73) + 'A' + String.fromCharCode(104).toUpperCase() + String.fromCharCode(122) + 'F' + String.fromCharCode(67);
//powyższa linia może składać się z losowych składników, np. raz będzie:
//String.fromCharCode(73) + 'A' + String.fromCharCode(104).toUpperCase() + String.fromCharCode(122) + 'F' + String.fromCharCode(67);
//raz będzie:
//'A' + String.fromCharCode(107).toUpperCase() + String.fromCharCode(68) + String.fromCharCode(121) + 'OG';
kod = kod.toUpperCase();

document.getElementById('costam').value = kod;</script>

Chociaż wysiliłem się w połowie i napisałem przypadek który koniecznie wymaga włączonego JS ;]

Edit: Taki sobie poryty kod napisałem:

<?php
session_start();

class strangeAntiSpam {
	//tworzy 8 znakowy kod
	public createCode() {
		return strtoupper(substr(MD5(time() . rand(1, 999)), 1, 8));
	}
	
	//koduje podany string tworząc z niego dziwny kod JS
	public createStrangeJs($code) {
		return $this->_merge($this->_obfuscate($code));
	}
	
	//udziwnia kod tekstowy
	protected _obfuscate($textcode) {
		$code = str_split($textcode);
		for($i=0; $i<count($code); $i++) {
			$rand = rand(1, 6);
			switch($rand) {
				case 2: $code[$i] = '\''.$code[$i].$code[$i+1].'\''; $code[$i+1] = '\'\''; $i++; break;
				case 3: $code[$i] = 'String.fromCharCode('.ord($code[$i]).')'; break;
				case 4: $code[$i] = 'String.fromCharCode('.ord($code[$i]).').toUpperCase()'; break;
				case 5: $code[$i] = 'String.fromCharCode('.ord(strtolower($code[$i])).').toUpperCase()'; break;
				case 6: $code[$i] = '\''.$code[$i].'\'.concat(\''.$code[$i+1].'\')'; $code[$i+1] = '\'\''; $i++; break;
				default: $code[$i] = '\''.$code[$i].'\''; break;
			}
		}
		$textcode = $this->_merge($code);
		return $textcode;
	}
	
	//łączy tablicę dziwnych kodów
	protected _merge($code) {
		$rand = rand(1, 4);
		switch($rand) {
			case 1: $final = implode('+', $code); break;
			case 2: $final = implode(' +', $code); break;
			case 3: $final = implode('+ ', $code); break;
			default: $final = implode(' + ', $code); break;
		}
		return $code;
	}
}

if ($_POST['codefield'] && $_POST['imie']) {
	if ($_POST['codefield'] == $_SESSION['codefield']) {
		echo('Wszystko zadzialalo poprawnie. Imie: ' . $_POST['imie']);
	} else {
		echo('Zly kod, wtf?');
	}
	exit();
}

$anti = new strangeAntiSpam;
$code = $anti->createCode();
$code2 = $anti->createCode();
$jscode = $anti->createStrangeJs($code);
unset($anti);

$_SESSION['codefield'] = $code;

echo('<span style="color: red;" id="jsnie">WLACZ JS BO NIE ZADZIALA</span>
<form action="" method="POST" id="wyslij" style="display: none;">
Imie: <input type="text" name="imie" value="">
<input type="hidden" name="codefield" id="codefield" value="'.$code2.'">
<input type="submit" value="OK">
</form>

<script type="text/javascript">
document.getElementById(\'codefield\').value = '.$jscode.';
document.getElementById(\'jsnie\').style.display = \'none\';
document.getElementById(\'wyslij\').style.display = \'\';
</script>');
?>

Generuje poryty skrypt JS który wstawi do ukrytego pola codefield właściwy kod tekstowy który również jest zapisany w sesji. Oprócz tego przy samym generowaniu formularza jest podstawiany jakiśtam value do pola, dla małej zmyłki. Anyway jeśli nie mamy JS to formularz się nie pokaże, za to ujrzymy wiadomość o tym, że włączenie JS jest wymagane. Jak chcesz sposób działający też bez JS to pogłówkuj ;P

0

jeśli byś się zdecydował na gotowca to mogę ci polecić moją captche w php : http://mijagi.vot.pl/index.php/2009/08/skrypt-captcha-w-php/

Btw, ciastko nie jest żadnym zabezpieczeniem przed spamem/floodem, przecież można ich nie akceptować lub po prostu usunąć
Tutaj masz link, który podejrzewam, że też ci się przyda http://mijagi.vot.pl/index.php/2009/08/zabezpieczenie-strony-przes-spamem/

0
mijagi napisał(a)

jeśli byś się zdecydował na gotowca to mogę ci polecić moją captche w php : http://mijagi.vot.pl/index.php/2009/08/skrypt-captcha-w-php/

Btw, ciastko nie jest żadnym zabezpieczeniem przed spamem/floodem, przecież można ich nie akceptować lub po prostu usunąć
Tutaj masz link, który podejrzewam, że też ci się przyda http://mijagi.vot.pl/index.php/2009/08/zabezpieczenie-strony-przes-spamem/

Twoja captcha jest hmm... Dość wymyślna:

user image

I może być trudna do odczytania dla człowieka, za to robot nie powinien mieć większych problemów, bo listę backgroundów można sobie zrobić, a kolory pomagają odseparować literki, po czym można po prostu je trochę poobracać i poskalować żeby znaleźć charakterystyczne punkty - taka uwaga przyszłość.

0

Jednak zostałbym przy swoim kodzie... Dlaczego otrzymuje błąd, jeżeli wpiszę dobry kod?

0

Debuguj... To nie boli.
Może dlatego:

elseif($_SESSION['liczba']!=$kod)

Powinno być $_POST['kod'] czy jakoś...

Poza tym za każdym odświeżeniem strony jak dobrze widze generujesz nowy kod i zapisujesz go do sesji, a potem porównujesz z poprzednim oO

0

Właśnie, że nie generuje za każdym razem nowego(chyba) bo po przeładowaniu strony pokazuje ten sam.

0

@Demonical Monk:
Można dodająć fajne czcionki i backgroundy uzyskać coś takiego :
user image
lub takiego :
user image
Chciałbym zobaczyć crackera pod takie coś:>

@nansss:
znalazłem w twojej stronce sql injectionka, radzę ci połatać to :)

0

Właśnie nie wiem jak to wszystko połatać. Sporo czytałem o tym, ale nie mam pojęcia co powoduje błędy :)

0

Filtr Hue&Saturation, walimy Saturation na maksa i tło idzie w pi...
user image
Teraz wydzielamy grupy określonych kolorów obok siebie
user image
Trochę obracamy, skalujemy aż coś się do tego dopasuje:
user image
Wynik:
user image

Ale nie o tym temat, ja polecam poczytać:
http://4programmers.net/PHP/Ochrona_przed_SQL_Injection_-_podstawy
Podstawy PHP - Ochrona przed XSS

@down
Dużo krąży po internecie "captcha crackingów"...

0

@Demonical Monk:
no ciekawe, ciekawe :> zapodasz kod do takiego crackowania?

0

Może po prostu ludzie powinni wreszcie zrozumieć że powinni być bardziej odpowiedzialni za swoje czyny i nie być złośliwi? Bez tego nasza cywilizacja się nie rozwinie.

0
mijagi napisał(a)

zapodasz kod do takiego crackowania?

Wypraszam sobie, wszystko tylko nie 'crackowania'.

0

Jedna z możliwości to sprawdzanie, czy z danego IP w danym czasie nie nastąpiło wykonanie pewnych czynności (jak zapisanie do bazy danych) więcej niż dopuszczalną ilość razy. Przypuszczalnie nikt nie robi tego praktycznie częściej niż raz na minutę, więc to już jest jakieś zabezpieczenie przez błyskawicznym rozrostem bazy danych.
W systemie aplikacji internetowych, który stosuję, każde otwarcie sesji (pierwsze wejście na stronę internetową) blokuje pewne zasoby pamięci operacyjnej w części serwerowej aplikacji client-server. Gdybym nie stosował takiego zabezpieczenia, cały serwer byłby błyskawicznie zablokowany przez osobę wchodzącą na stronę z automatu kilka razy na sekundę, z powodu tego że zabrakłoby pamięci operacyjnej, bo jak wiadomo stronicowanie w pamięci zewnętrznej jest ograniczone i po przekroczeniu pewnej ilości wykorzystanej pamięci zewnętrznej jako pamięci wirtualnej wszystkie programy zaczynają bardzo wolno działać w wyniku ich przełączania do pamięci operacyjnej.

0

Przepraszam, ale nie mogę, więc zapytam: Widziałeś kiedyś Mariuszu PHP?
Tam się nie alokuje pamięci, jak w większości języków skryptowych.

0

@Demonical Monk:
Wiesz, że obróbka tej captchy w programie graficznym mija się przecież z celem, już szybciej jest <ort>po prostu</ort> przeczytać kod, chodziło mi o kod, który by to automatyzował i mógł zaspamować stronę łamiąc te captcha, no ale chyba coś nie jesteś skory pochwalić się kodem...

0

Ja nie mam na to kodu, pokazałem ci tylko sposób w jaki działają łamacze captchy, w google jest tego sporo, polecam poszukać. Nawet na google code coś widziałem.

0
Demonical Monk napisał(a)

Przepraszam, ale nie mogę, więc zapytam: Widziałeś kiedyś Mariuszu PHP?
Tam się nie alokuje pamięci, jak w większości języków skryptowych.

Nie chodzi tylko o zużywanie pamięci operacyjnej ale spamowanie to masowe zapisywanie do bazy danych czyli zajmowanie pamięci zewnętrznej i tu też możemy zastosować to zabezpieczenie, żeby użytkownicy za często nie zapisywali. Ostatecznie i tak bez moderatora, który od czasu do czasu czyści niepotrzebne wpisy, się nie obędzie, ale przynajmniej będzie dziesięć tysięcy razy mniej wpisów do usunięcia.

0

Przecież ten formularz wysyła maile, a nie wrzuca to do bazy...

0
Demonical Monk napisał(a)

Przecież ten formularz wysyła maile, a nie wrzuca to do bazy...

Na jedno wychodzi. Nie chcemy przeglądać tysięcy wiadomości.

Poza tym nie używam php bo po co uczyć się drugiego języka programowania skoro mogę tego uniknąć. Zupełnie dobrze daję sobie radę bez php przy tworzeniu aplikacji internetowych. Jedynym problemem jest potrzeba lepszego wyszukiwania klientów, bo jest mniejsze zapotrzebowanie na aplikacje internetowe, które nie są w php. Jednak rynek zagraniczny jest otwarty na inne technologie i da się w USA znaleźć zamówienia.

0
Mariusz Jędrzejowski napisał(a)

Poza tym nie używam php bo po co uczyć się drugiego języka programowania skoro mogę tego uniknąć.

Z ciekawości, Java czy C#? Z drugiej strony opis podejścia do zagadnienia średnio do tych języków pasuje.

0
deus napisał(a)
Mariusz Jędrzejowski napisał(a)

Poza tym nie używam php bo po co uczyć się drugiego języka programowania skoro mogę tego uniknąć.

Z ciekawości, Java czy C#? Z drugiej strony opis podejścia do zagadnienia średnio do tych języków pasuje.

Używam Delphi.

0

Współczuję klientom...

0
deus napisał(a)

Współczuję klientom...

Aplikacja ma pełne możliwości. Można w niej umieścić wszystko i robi się nią błyskawicznie z minimalną znajomością html, java script i ajax. Strony przełączają się znacznie szybciej niż w php. Klienci zagraniczni i tak używają serwerów VPS, bo ich na to stać, więc po prostu wynajmują VPS z systemem windows 2003 server. Cena takich serwerów w USA jest najmniejsza, już od 15 USD miesięcznie. W Europie jest drożej i ceny rozpoczynają się od 15 euro miesięcznie.

0

Tu nie chodzi o pieniądze, używanie niszowego frameworka dla powoli wymierającego języka nie może się dla klienta skończyć dobrze w dłuższej perspektywie.

0
deus napisał(a)

Tu nie chodzi o pieniądze, używanie niszowego frameworka dla powoli wymierającego języka nie może się dla klienta skończyć dobrze w dłuższej perspektywie.

Stawianie Windows Server na VPSie też...

0

Owszem, ale w każdej chwili można łatwo oprogramowanie i konfigurację przenieść na dedyk, niewielkim kosztem. Zmiana języka i technologii to konieczność przepisania oprogramowania, co ani tanie ani proste nie będzie.

0
Demonical Monk napisał(a)
deus napisał(a)

Tu nie chodzi o pieniądze, używanie niszowego frameworka dla powoli wymierającego języka nie może się dla klienta skończyć dobrze w dłuższej perspektywie.

Stawianie Windows Server na VPSie też...

Dlaczego? Coraz czesciej sie teraz przeciez idzie w kierunku wirtualizacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1