1

I'm new to php and sqlite and I'm trying to modify the registration form of a website. I did what I thought were all the necessary changes but I can't make it work now since when I use a email to register it tells me it already exists. The form used a username before and checked if the username already existed. If it did then it displays a message. Now I don't want to use a username but the email to register and, even though the database is empty, it always tells me that the email already exists. I left only the email for registration to make it simpler to understand. But even then the problem persists.

I think there's a problem while checking the database but I don't know where the problem lies. I don't understand very well the flow between the php pages so if someone could help me clarify what is exactly happening I would appreciate it. Here is the code of the registration page.

Participate.php:

<hr class="structure" />
<h1 class="out">Main content</h1>
<div class="eb1"> 
  <!--TYPO3SEARCH_begin-->
  <h2 class="out">Topinformationen</h2>
  <!--TYPO3SEARCH_end--> 
</div>
<div class="eb2"> 
  <!--TYPO3SEARCH_begin-->
  <h2>Participate</h2>
<p>Please register.</p>
  <!-- ###LOGIN_FORM### -->
<div class="box big form">

<form id="participateForm" action="#" target="_top" onSubmit="return checkform();" method="post" name="participate">
    <fieldset class="nolegend">
        <legend>Particpate</legend>
        <div>
            <label for="email">
                <span> Email:* <?php echo isset($_POST['email']) ? '<strong>The email &ldquo;' .$_POST['email']. '&rdquo; already exists. </strong>' : ''; ?></span><input type="email" name="email" required/>
            </label>
        </div>
    </fieldset>
    <div class="morelink">
        <p><input type="submit" name="submit" value="Participate" onclick="show('form'); return FALSE;"/></p>
    </div>
</form>
</div><!-- box big form -->
</div>

So if I understand correctly when you click the Participate button the page calls itself (action="#") with the email as a post variable. The thing is that there's nothing on this particular page that uses that variable so I guess this code is reloading the index.php page which starts like this.

index.php:

<?PHP
    //Session wird gestartet
    session_start();
        //Includ PHP functions
    @include("./data/php/functions.php");
        //Funktionen werden ausgeführt
    if(isset($_GET['do']))
    {
    if($_GET["do"]=="logout"){
        logout();
     }
    }
     else if (!empty($_GET["email"])&& !session()){
        login($_GET["email"]);
     }
     if(postvar("submit")=="login" && !session()){
         login(0,0);
     }
     else if (postvar("submit")=="participate" && !session()){
         register();
     }
     else if (postvar("submit")=="emote" && session()){
         saveMood();
     }

?>

Within this functions.php code that is included in the index.php page are the functions to access the database. So two of those functions are these.

functions.php:

function postvar($var)
{
    if (isset($_POST[$var])){
    $erg = $_POST["$var"];
    $erg = trim($erg);
    }
    else 
    $erg=NULL;
    return $erg;
}

function register()
{
    global $open, $settings, $db_usr;

    $email = postvar("email");

    //if($privacy && $terms)
    if(TRUE)
    {
        $query = "SELECT * FROM usr_data WHERE email='".$email."'";
        $res_usr = $db_usr->prepare($query);
        $res_usr->execute();
        $count=$res_usr->fetchColumn();

        if($count!=1){

        $query ="INSERT INTO usr_data (email, regtime, status, sessionID) VALUES ('".$email."', '".time()."','0', 'new')";
        $db_usr->query($query);

        header("Location: ".$settings["Main"]."?open=Login&info=1");
        }
        else
        {
        //$open="Login_Failed";
        }
    }
}

So what I think it's happening is this and I will appreciate if someone tells me if I'm completely lost or if I need to put some other part of the code to clarify. So the participate.php calls itself with the email send on this post variable. Somehow, and I don't know exactly how, the functions.php code is called and this register function is used to check if the email exists and, if not, to add it to the database. The thing is that it's not working. This code worked before when instead of email it used a username. The registration actually worked then.

By the way the checkform() function that is called in the Participate.php code just does this.

function checkform()
  {
                if (document.participate.email.value ==  "")
                 {
                      alert('Please enter an email.');
                      document.participate.email.focus();
                      return false;
                }

  }

Edit 1:

Original Code Participate.php

 <hr class="structure" />
<h1 class="out">Main content</h1>
<div class="eb1"> 
  <!--TYPO3SEARCH_begin-->
  <h2 class="out">Topinformationen</h2>
  <!--TYPO3SEARCH_end--> 
</div>
<div class="eb2"> 
  <!--TYPO3SEARCH_begin-->
  <h2>Participate</h2>
<p>Register here.</p>
  <!-- ###LOGIN_FORM### -->
<div class="box big form">

<form id="participateForm" action="#" target="_top" onSubmit="return checkform();" method="post" name="participate">
    <fieldset class="nolegend">
        <legend>Particpate</legend>
        <div>
            <label for="user">
                <span> Username: <?php echo isset($_POST['username']) ? '<strong>The username &ldquo;' .$_POST['username']. '&rdquo; already exists. Please chose a different one.</strong>' : ''; ?></span><input type="text" name="username" required/>
            </label>
        </div>
        <div>
            <label for="pass">
                <span>Password (at least 8 characters):</span><input type="password" name="password" required pattern="^([0-9a-zA-Z]{8,20})"/>
            </label>
        </div>
        <div>
            <label for="passRT">
                <span>Re-type Password: </span><input type="password" name="passwordRT" required pattern="^([0-9a-zA-Z]{8,20})"/>
            </label>
        </div>
        <div>
            <label for="email">
                 Email: <input type="email" name="email" required placeholder="Enter a valid email address"> 
            </label>
        </div>
        <div>
            <label for="birth">
                <span>Year of Birth (yyyy): </span><input type="text" name="YearOfBirth" value="<?php echo isset($_POST['YearOfBirth']) ? htmlspecialchars($_POST['YearOfBirth']) : ''; ?>" required pattern="\d{4}"/>
            </label>
        </div>
        <div>
            <label for="adress">
                Home adress (Street, ZIP-Code, City): <input name="adress" type="text"  value="<?php echo isset($_POST['adress']) ? htmlspecialchars($_POST['adress']) : ''; ?>" required/>
            </label>
        </div>
        <div>

                <table><tr><td>Gender:</td>
                <td align="center"><label><input id="Female" type="radio" name="sex" value="1" required/>Female</label></td><td align="center"><label><input type="radio"  name="sex" value="2"  />Male</label></td><td align="center"></td></tr></table>
        </div>
        <div>
        <label for"agreetext">
        <textarea rows="10" readonly="readonly" id="agreetext" name="agreetext"> Privacy Policy: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ac vulputate risus, eu scelerisque elit. Aenean eget ligula et est rutrum hendrerit at sed sapien. Nunc nunc dolor, sagittis at enim eget, imperdiet cursus magna. Nam fringilla mauris id tellus placerat, ut tincidunt urna semper. Vestibulum vel blandit nisi, nec pulvinar dolor. Fusce vitae faucibus enim, a aliquet purus. Vivamus dapibus aliquet massa ut rhoncus. Nulla sit amet fermentum neque. Integer a velit vitae mauris convallis semper. Sed consequat consequat nibh, a ultricies nisi efficitur vitae.

Terms and Conditions: Aliquam aliquam condimentum quam, sed aliquet felis suscipit in. Nulla at ex at ex scelerisque commodo eget eget dui. Quisque nunc ante, cursus ut turpis et, ornare rutrum mi. In eget quam bibendum, egestas massa quis, porttitor arcu. Phasellus vel consequat turpis, non imperdiet augue. Donec euismod, sem sed pretium elementum, libero dolor venenatis lorem, quis tincidunt odio nunc quis diam. Maecenas nec risus vitae tortor pulvinar elementum. Nam convallis porttitor tellus, ac ultricies purus pretium venenatis. Curabitur condimentum sapien mauris, ac bibendum leo pulvinar elementum. Vestibulum ante sem, posuere a nisl eu, maximus elementum diam.</textarea>
</label>
</div>
<div><p><input onchange="this.setCustomValidity(validity.valueMissing ? 'Please indicate that you accept the privacy policy' : '');" id="privacy_policy" type="checkbox" required name="privacy_policy"> I accept the privacy policy</p><p>
    <input onchange="this.setCustomValidity(validity.valueMissing ? 'Please indicate that you accept the Terms and Conditions' : '');" id="terms" type="checkbox" required name="terms"> I accept the       Terms and Conditions</p></div>
    </fieldset>
    <div class="morelink">
        <p><input type="submit" name="submit" value="participate" onclick="show('form'); return FALSE;"/></p>
    </div>
</form>
</div><!-- box big form -->
</div>

<!-- eb2 --> 

Edit 2:

Original Functions.php code

function register()
{
    global $open, $settings, $db_usr;

    $username = postvar("username");
    $pw = postvar("password");
    $pww = postvar("passwordRT");
    $year = postvar("YearOfBirth");
    $adress = postvar("adress");
    $sex = postvar("sex");
    $email = postvar("email");
    $privacy = postvar("privacy_policy");
    $terms = postvar("terms");

    //if($privacy && $terms)
    if(TRUE)
    {
        $query = "SELECT * FROM usr_data WHERE username='".$username."'";
        $res_usr = $db_usr->prepare($query);
        $res_usr->execute();
        $count=$res_usr->fetchColumn();

        echo $count;


        if($count!=1){

        $query ="INSERT INTO usr_data (username, password, regtime, status, sessionID, birth, sex, email, home) VALUES ('".$username."', '".md5($pw)."', '".time()."','0', 'new', '".intval($year)."','".intval($sex)."','".$email."' ,'".$adress."')"; 
        $db_usr->query($query);


        header("Location: ".$settings["Main"]."?open=Login&info=1");
        }
        else
        {
        //$open="Login_Failed";
        }
    }
}

Edit 3:

Login.php code

<hr class="structure" />
<h1 class="out">Main content</h1>
<div class="eb1"> 
  <!--TYPO3SEARCH_begin-->
  <h2 class="out">Topinformationen</h2>
  <!--TYPO3SEARCH_end--> 
</div>
<div class="eb2"> 
  <!--TYPO3SEARCH_begin-->
  <h2>Login</h2>
  <!-- ###LOGIN_FORM### -->
  <?PHP
  if($_GET["info"]==1){
  echo '<p><strong>Congratulations!</strong> Your registration has been successfully submitted. You can login now.</p>';
  }
  ?>
<div class="box big form">


<form id="loginForm" action="#" target="_top" method="post" >
    <fieldset class="nolegend">
        <legend>Login</legend>
        <div>
            <label for="user">
                <span class="toplabel">Username: </span><br class="none" />
                <input type="text" name="username" required/>
            </label><br class="none" />
        </div>
        <div>
            <label for="pass">
                <span class="toplabel">Password: </span><br class="none" />
                <input type="password" id="lpw" name="password" required/>
            </label><br class="none" />
        </div>

    </fieldset>
    <div class="morelink">
        <p><input type="submit" name="submit" value="login" onclick="show('form'); return FALSE;"/></p>
    </div>
</form>
</div><!-- box big form -->

    <!--TYPO3SEARCH_end--> 
</div>
Atirag
  • 1,660
  • 7
  • 32
  • 60
  • Your form calls `checkform()` but it looks like the "already exists" message is being sent whenever `$_POST['email']` is set, but it will always be set when the form is posted. Do you have the code from before you attempted to modify it? It would help to see what the original architecture had been. – Michael Berkowski Jun 06 '15 at 14:36
  • I will add the original complete code from Participate.php to an edit but it's basically the same. The strange thing is that it works fine. – Atirag Jun 06 '15 at 14:42
  • To clarify, is it the form's `` tag `The email “' .$_POST['email']. '” already exists.` you're seeing as the output, or is it SQLite complaining of a duplicate key and record already existing? The `if ($count!=1)` could be problematic depending on what the `SELECT` query returns, causing the `INSERT` to execute and maybe a key violation in SQLite. – Michael Berkowski Jun 06 '15 at 14:52
  • Yes it is the forms tag the one that is showing. The if ($count!=1) part was not giving any problem on the original one but would you suggest to change it? – Atirag Jun 06 '15 at 15:02
  • Is there an easy way to print the query for the insert call to check if it is correctly built? – Atirag Jun 06 '15 at 15:17
  • It probably isn't the INSERT causing a problem. Do you have the original `functions.php`? The `isset($_POST['username'])` showing the error suggests that the `username` key may have been _deleted_ from the `$_POST` in order to proceed with the form process, and a similar action has not occurred with the `email` post key. But I don't see any code here which would have handled that. – Michael Berkowski Jun 06 '15 at 15:28
  • I just found out that if I comment out the header("Location: ".$settings["Main"]."?open=Login&info=1"); part on the original code then it loads the Participate.php page and shows the same "The username xxx already exists... " message. So that piece of code calls the Login.php page which I posted on the last edit. – Atirag Jun 06 '15 at 15:59
  • On the if part of the Login.php code if the Get call for info is equal to 1 then it shows that the registration is succesful. Which is what happens in the original code but not in the edited one. – Atirag Jun 06 '15 at 16:06
  • I think I found the problem and it was such a small detail. In the Participate.php I change the submit button value from "participate" to "Participate" so it would show on the submit button. On the index.php code when it makes the call to the register() function it checks that the value is "participate" with lowercase. So the problem was basically a letter. Thanks for the help @MichaelBerkowski – Atirag Jun 06 '15 at 16:25
  • 1
    Wow, glad you found it. That would have been very difficult for me to spot without being able to debug the code in production. Now that you have solved that, you should begin learning to use [`prepare()/bindParam()/execute()`](http://php.net/manual/en/pdo.prepare.php) with PDO. The `postvar()` function does not protect against SQL injection, leaving this code vulnerable to tampering (possibly even logging in with admin privileges) Get started [with the examples here](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – Michael Berkowski Jun 06 '15 at 16:29
  • Thanks a lot! I'll look into it! – Atirag Jun 06 '15 at 16:48

0 Answers0