Autor Zpráva
Loup
Profil *
Zdravím, vytvářím stránky, na kterých se uživatel registruje a potom si může rezervovat termíny v kalendáři. Použil jsem registrační formulář z těchto stránek. Při vyplnění formuláře a jeho odeslání mi Google Chrome zahlásí:
"Chyba serveru
Při načítání adresy http://localhost/securelogin/register.php narazily stránky na chybu. Na této adrese možná právě probíhá údržba stránek, nebo jsou stránky chybně nakonfigurovány."

Na různých fórech je tato hláška většinou asociovaná s chybnou syntaxí formuláře. Zkusil jsem do skriptu register.php vepsat řádek, který úspěšně vložil do tabulky v databázi konstantní hodnoty (tedy ne pomocí proměnných, ale přímo). Komunikace s databází tedy očividně funguje. Chyba by tedy měla tkvět někde ve skriptu, ale moc se mi to nezdá, protože v diskuzi pod článkem na php-developerovi se o tomto problému nikdo nezmiňuje. Přijde mi, že chyba je někde na půli cesty. Prosím poraďte, nebo já už nevím kudyma. Budu moc vděčnej.


<?php
//require user configuration and database connection parameters
require('config.php');

//pre-define validation parameters

$usernamenotempty=TRUE;
$usernamevalidate=TRUE;
$usernamenotduplicate=TRUE;
$passwordnotempty=TRUE;
$passwordmatch=TRUE;
$passwordvalidate=TRUE;
$captchavalidation= TRUE;

//Check if user submitted the desired password and username
if ((isset($_POST["desired_password"])) && (isset($_POST["desired_username"])) && (isset($_POST["desired_password1"])))  {
    
//Username and Password has been submitted by the user
//Receive and validate the submitted information

//sanitize user inputs

function sanitize($data){
$data=trim($data);
$data=htmlspecialchars($data);
$data=mysql_real_escape_string($data);
return $data;
}

$desired_username=sanitize($_POST["desired_username"]);
$desired_password=sanitize($_POST["desired_password"]);
$desired_password1=sanitize($_POST["desired_password1"]);

//validate username

if (empty($desired_username)) {
$usernamenotempty=FALSE;
} else {
$usernamenotempty=TRUE;
}

if ((!(ctype_alnum($desired_username))) || ((strlen($desired_username)) >11)) {
$usernamevalidate=FALSE;
} else {
$usernamevalidate=TRUE;
}

if (!($fetch = mysql_fetch_array( mysql_query("SELECT `username` FROM `authentication` WHERE `username`='$desired_username'")))) {
//no records for this user in the MySQL database
$usernamenotduplicate=TRUE;
}
else {
$usernamenotduplicate=FALSE;
}

//validate password

if (empty($desired_password)) {
$passwordnotempty=FALSE;
} else {
$passwordnotempty=TRUE;
}

if ((!(ctype_alnum($desired_password))) || ((strlen($desired_password)) < 8)) {
$passwordvalidate=FALSE;
} else {
$passwordvalidate=TRUE;
}

if ($desired_password==$desired_password1) {
$passwordmatch=TRUE;
} else {
$passwordmatch=FALSE;
}

//Validate recaptcha
require_once('recaptchalib.php');
$resp = recaptcha_check_answer ($privatekey,
                                $_SERVER["REMOTE_ADDR"],
                                $_POST["recaptcha_challenge_field"],
                                $_POST["recaptcha_response_field"]);

if (!$resp->is_valid) {
//captcha validation fails
$captchavalidation=FALSE;
} else {
$captchavalidation=TRUE;    
}

if (($usernamenotempty==TRUE)
&& ($usernamevalidate==TRUE)
&& ($usernamenotduplicate==TRUE)
&& ($passwordnotempty==TRUE)
&& ($passwordmatch==TRUE)
&& ($passwordvalidate==TRUE)
&& ($captchavalidation==TRUE)) {
//The username, password and recaptcha validation succeeds.

//Hash the password
//This is very important for security reasons because once the password has been compromised,
//The attacker cannot still get the plain text password equivalent without brute force.

function HashPassword($input)
{
//Credits: http://krackstation.net/hashing-security.html <--tady není krack, ale tenhle web mi nedovolí tam napsat to slovo na c :)
//This is secure hashing the consist of strong hash algorithm sha 256 and using highly random salt
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); 
$hash = hash("sha256", $salt . $input); 
$final = $salt . $hash; 
return $final;
}

$hashedpassword= HashPassword($desired_password);

//Insert username and the hashed password to MySQL database

mysql_query("INSERT INTO `authentication` (`username`, `password`) VALUES ('$desired_username', '$hashedpassword')") or die(mysql_error());
//Send notification to webmaster
$message = "New member has just registered: $desired_username";
mail($email, $subject, $message, $from);
//redirect to login page
header(sprintf("Location: %s", $loginpage_url));    
exit;
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>Register as a Valid User</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
.invalid {
border: 1px solid #000000;
background: #FF00FF;
}
</style>
</head>
<body >
<h2>User registration Form</h2>
<br />
Hi! This private website is restricted to public access. If you want to see the content, please register below. You will be redirected to a login page after successful registration.
<br /><br />
<!-- Start of registration form -->
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="POST">
Username: (<i>alphanumeric less than 12 characters</i>) <input type="text" class="<?php if (($usernamenotempty==FALSE) || ($usernamevalidate==FALSE) || ($usernamenotduplicate==FALSE))  echo "invalid"; ?>" id="desired_username" name="desired_username"><br /><br />
Password: (<i>alphanumeric greater than 8 characters</i>) <input name="desired_password" type="password" class="<?php if (($passwordnotempty==FALSE) || ($passwordmatch==FALSE) || ($passwordvalidate==FALSE)) echo "invalid"; ?>" id="desired_password" ><br /><br />
Type the password again: <input name="desired_password1" type="password" class="<?php if (($passwordnotempty==FALSE) || ($passwordmatch==FALSE) || ($passwordvalidate==FALSE)) echo "invalid"; ?>" id="desired_password1" ><br />
<br /><br />
Type the captcha below:
<br /> <br />
<?php
require_once('recaptchalib.php');
echo recaptcha_get_html($publickey);
?>
<br /><br />
<input type="submit" value="Register">
<br /><br />
<a href="index.php">Back to Homepage</a><br />
<!-- Display validation errors -->
<?php if ($captchavalidation==FALSE) echo '<font color="red">Please enter correct captcha</font>'; ?><br />
<?php if ($usernamenotempty==FALSE) echo '<font color="red">You have entered an empty username.</font>'; ?><br />
<?php if ($usernamevalidate==FALSE) echo '<font color="red">Your username should be alphanumeric and less than 12 characters.</font>'; ?><br />
<?php if ($usernamenotduplicate==FALSE) echo '<font color="red">Please choose another username, your username is already used.</font>'; ?><br />
<?php if ($passwordnotempty==FALSE) echo '<font color="red">Your password is empty.</font>'; ?><br />
<?php if ($passwordmatch==FALSE) echo '<font color="red">Your password does not match.</font>'; ?><br />
<?php if ($passwordvalidate==FALSE) echo '<font color="red">Your password should be alphanumeric and greater 8 characters.</font>'; ?><br />
<?php if ($captchavalidation==FALSE) echo '<font color="red">Your captcha is invalid.</font>'; ?><br />
</form>
<!-- End of registration form -->
</body>
</html>



V souboru config.php mám potom nastaveny tyto hodnoty:
$username = "root";
$password = "tady je moje heslo";
$hostname = "localhost";
$database = "název databáze";
$domain = "http://localhost/";
$privatekey ="kód ze serveru http://www.google.com/recaptcha";
$publickey = "kód ze serveru http://www.google.com/recaptcha";
To, co je kurzívou jsem vyplnil těmi skutečnými údaji.

Používám:
Windows XP Home Edition SP3
PHP 5.2.17.17
Apache 2.2.22.0
MySQL Server 4.1
Loup
Profil *
Když zkusím vepsat řádek:
echo mysql_query(select * from authentication);
a zakomentuju přesměrování a zápis do databáze, tak to hlásí tu stejnou chybu.
mimochodec
Profil
Loup:
Na různých fórech je tato hláška většinou asociovaná s chybnou syntaxí formuláře.

Myslím že je v první řadě spojována s wordpressem.
Loup
Profil *
WordPress ani žádné jiné CMS nepoužívám.
mimochodec
Profil
No nevím, ale tu hlášku určitě negeneruje php a když jsem hledal, našel jsem http://www.google.cz/search?client=opera&rls=cs&q=narazily+str%C3%A1nky+na+chybu.+Na+t%C3%A9to+adrese+mo%C5%BEn%C3%A1+pr%C3%A1v%C4%9B+prob%C3%ADh%C3%A1+%C3%BAdr%C5%BEba+str%C3%A1nek,+nebo+jsou+str%C3%A1nky+chybn%C4%9B&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest
Davex
Profil
Loup:
Možná to bude tím, že není definována proměnná $loginpage_url.

Jinak nechápu, jak může fungovat databáze, když se k ní skript nepřipojuje, to je záhada.
Loup
Profil *
V souboru config.php je řádek:
$loginpage_url= $domain.'securelogin/';$loginpage_url= $domain.'securelogin/';



Když vložím:
mysql_query("insert into authentication (username, password) VALUES ('loupacek', 'heslo')");
před
$hashedpassword= HashPassword($desired_password);
tak se data do databáze uloží. Když ho ale vložím až za něj, tak se data neuloží.
Přičemž to samozřejmě pokaždé vyhodí to chybový hlášení. Jo a prve jsem přehlídl jeho druhou část:
Chyba protokolu HTTP 500 (Internal Server Error): Při pokusu o splnění požadavku došlo na serveru k neočekávané situaci.
Loup
Profil *
Ok, takže jsem zatím zjistil, že je něco v nepořádku s hashováním hesla. Když zakomentuju všechny pasáže, ve kterých se hashuje a použiju při kontrole formuláře skutečné heslo, tak se mi daří se zaregistrovat i přihlásit. Teď ale fakt netuším, co může být blbě s hashem. S tímhle dělám poprvé v životě.
abc_
Profil *
Loup:
Verze PHP na serveru?
Keeehi
Profil
Začal bych tímto:
var_dump(function_exists('mcrypt_create_iv'));
var_dump(function_exists('hash'));
Loup
Profil *
Áha, takže mcrypt_create_iv nemám. Co s tím? Jak to napravit? Dá se to nějak připojit?
Keeehi
Profil
V komentářích jsem našel toto:
function alt_mcrypt_create_iv ($size) {
    $iv = '';
    for($i = 0; $i < $size; $i++) {
        $iv .= chr(rand(0,255));
    }
    return $iv;
}
Loup
Profil *
No, já si asi vystačím s tou funkcí samotnou, jestli chápu správně, o co jde. Jenom mi vrtá hlavou, proč ta funkce samotná není nalezena (stejně jako i MCRYPT_DEV_URANDOM), když knihovnu php_mcrypt.dll mám ve složce \ext se všema ostatníma.


Tak už vím, proč to nešlo předtím. Ta knihovna byla zakomentovaná v php.ini, ale já ji odkomentoval a php spustil znova a pořád se chová, jakoby tam prostě nebyla.
Loup
Profil *
mcrypt_create_iv už funguje, ale MCRYPT_DEV_URANDOM pořád ne. Našel jsem tohle, ale nejsem si jistý, jak mi to má pomoct.
Keeehi
Profil
Loup:
V jednoduchosti, v tom odkazu je, že pokud jsi na windows, tak máš použít MCRYPT_RAND. Celé mi to však přijde zbytečně složité. alt_mcrypt_create_iv by úplně stačilo, stejně jsou to všechno pseudonáhodné generátory.
Loup
Profil *
No dobře, to by v zásadě asi šlo. A myslíš, že bude stačit mcrypt_create_iv? Protože alt_mcrypt_create_iv taky nemám.
Keeehi
Profil
alt_mcrypt_create_iv není žádná oficiální funkce. je to uživatelská funkce, která dělá to samé jako mcrypt_create_iv, jen jinak. To alt_ znamená alternativní verze. Její kód je v [#12].
Loup
Profil *
Ach so! Už tomu začínám rozumět.
Loup
Profil *
Děkuju moc všem a hlavně Keeehimu. Moc jste mi pomohli a už mi to jede.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: