1 (edited by MattF 2007-05-28 18:23)

Topic: register.php and require/include

Another of my useless questions. big_smile With the register.php script, I've been playing with that script that Sirena has posted: http://punbb.org/forums/viewtopic.php?id=16076

but have struck an obstacle with trying to introduce an array into it. If one includes/requires a script where the second part of the mod goes in register.php, the $_POST check, (the first part of the mod in register.php), doesn't have access to the variables pulled from the array in that script. If the include/require is done at the top of the register.php script, the results are highly erratic. (I'm assuming the external script is being included twice)? Am I missing something blindingly obvious here as to how to get this to work?


Cheers,

Matt

Re: register.php and require/include

I'm not sure exactly what your question is smile
I think some example code might be helpful

3

Re: register.php and require/include

It always sounds so understandable in ones own head, doesn't it? big_smile Here are the relevant parts from register.php:

    197                 $language = $pun_config['o_default_lang'];
    198         }
    199
-----------------------------------------------------
    200         // anti-spam code variable checked here. Customise to suit your needs.
    201         if ($_POST['spamcode'] != $answer) {
    202                 message("$register_failed");
    203         }
------------------------------------------------------
    204
    205         $timezone = round($_POST['timezone'], 1);
    206         $save_pass = (!isset($_POST['save_pass']) || $_POST['save_pass'] != '1') ? '0' : '1';
    332 <?php if ($pun_config['o_regs_verify'] == '1'): ?>                                              <label><strong><?php echo $lang_register['Confirm e-mail'] ?></strong><br />
    333                                                 <input type="text" name="req_email2" size="50" maxlength="50" /><br/>
</label>
    334 <?php endif; ?>                                 </div>
    335                                 </fieldset>
    336                         </div>
    337
------------------------------------------------------
    338 <div class="inform">
    339         <fieldset>
    340                 <legend>Spambot prevention</legend>
    341                 <div class="infldset">
    342                         <p><?php echo ("$question"); ?></p>
    343                         <p><?php echo ("$hint"); ?></p>
    344                         <input method="post" type="text" name="spamcode" size="10" maxlength="10" /><br/>
    345                 </div>
    346         </fieldset>
    347 </div>
-------------------------------------------------------
    348
    349                         <div class="inform">
    350                                 <fieldset>
    351                                         <legend><?php echo $lang_prof_reg['Localisation legend'] ?></legend>

The sections between the dotted lines are the new code. I've left extra code above/below as markers of placement. With that bottom section of code, if I add:

<?php
require PUN_ROOT.'include/user/register.php';
?>

just before it, that require will pull the variables required from that script. However, when it gets to the $_POST check back up the top of the register.php file, (that first block of code), the variables aren't carried over to that check. If I put the require at the top of register.php, the script would appear to be being called twice, as the random(ish) variables it produces don't match. So, the question being, how do I carry the variables over to the post check? That include/user/register.php is merely arrays with a rand call to set a value for $hint, $answer and $question, i.e:

$number = rand(1, 2);
$hint = $hints[$number];
$answer = $answers[$number];
$question = $questions[$number];

Have I managed to explain it okay this time? big_smile


Thanks again,

Matt

Re: register.php and require/include

Aha, now I understand smile
You would need to store the generated values using a session or some other method (you need to put it at the beginning of the script). Alternately, you could have a hidden form element that is the index (you just have to make sure it's a valid index and keep in mind that someone can cheat with that if they know the answer to one question)

5

Re: register.php and require/include

So would creating a session be the most secure method of storing the data whilst it's needed? (I get the feeling a few hours with the php manual is what I'm going to be doing very soon). big_smile


Thanks again,

Matt

Re: register.php and require/include

Yes, since the data would be server side. Of course, the person could still keep making requests until they got to the one question they know, but meh

7

Re: register.php and require/include

I can't say as I've actually any interest in using this mod personally, but for some reason it just piqued my curiosity as to how one could make a randomish choice thing work. big_smile Just been looking at the php documentation, and I am getting steadily more confused, big_smile but from what bit has sunk in so far, is a session pretty much along the same lines as an array?

Re: register.php and require/include

No tongue
Session data is stored in an array, but sessions and arrays aren't really related

9

Re: register.php and require/include

Smartys wrote:

No tongue
Session data is stored in an array, but sessions and arrays aren't really related

But you can assign and read in somewhat the same manner as one would an array? The documentation is, as ever, slightly awkward to follow when one has not used that certain aspect before. big_smile

10

Re: register.php and require/include

Right, I think I've grasped the basics now, through reading and experimentation. big_smile One question on the tmpfile that's created by the session in the tmpdir. Is there a session command to remove that tmpfile when you've finished with the session?

Re: register.php and require/include

session_destroy (sessions will also be cleaned up if not used in a certain amount of time)

12

Re: register.php and require/include

Cheers. smile

This thing is giving me some grief, to say the least. big_smile I've required the file just below the registration enabled check:

if ($pun_config['o_regs_allow'] == '0')
        message($lang_register['No new regs']);

require_once PUN_ROOT.'include/user/register.php';

but for some reason the script is being called twice. Once when you initially go to the forum/register.php page to register, and a second time when you click on submit, so by the time it checks the info, it's altered. If I had any sense I'd call it a day before it drives me to distraction. big_smile

Re: register.php and require/include

Yes, because you're making two calls to the script, one when you view the form and one when you submit. That's why I suggested using sessions. It would go something like this:

session_start();
if (isset($_SESSION['hint']))
{
    $hint = $_SESSION['hint'];
    $answer = $_SESSION['answer'];
    $question = $_SESSION['question'];
}
else
{
    $number = rand(1, 2);

    $hint = $hints[$number];
    $answer = $answers[$number];
    $question = $questions[$number];

    $_SESSION['hint'] = $hint;
    $_SESSION['answer'] = $answer;
    $_SESSION['question'] = $question;
}

14

Re: register.php and require/include

Smartys wrote:

Yes, because you're making two calls to the script, one when you view the form and one when you submit. That's why I suggested using sessions. It would go something like this:

session_start();
if (isset($_SESSION['hint']))
{
    $hint = $_SESSION['hint'];
    $answer = $_SESSION['answer'];
    $question = $_SESSION['question'];
}
else
{
    $number = rand(1, 2);

    $hint = $hints[$number];
    $answer = $answers[$number];
    $question = $questions[$number];

    $_SESSION['hint'] = $hint;
    $_SESSION['answer'] = $answer;
    $_SESSION['question'] = $question;
}

(Now banging head firmly on desk). big_smile That first part is the missing link. It always looks so simple when someone points out ones glaring exemption. big_smile I'll blame a slight misunderstanding of sessions on this one. big_smile I had tried a $_GET['action'] check thinking that would stop it renewing itself, but then it didn't carry over, (which is where I was losing the plot). I never even thought of trying something like the first section above. I feel such a muppet, (again), for misinterpreting something so simple in theory. big_smile (Now hurrying off to try it out). big_smile Thanks once again.

15

Re: register.php and require/include

Well, that don't do it either. big_smile Just to make sure I'm not missing something blatant, here's the first portion from register.php:

//------------------------------------------------//

        // anti-spam code variable checked here. Customise to suit your needs.
        if (isset ($_POST['spamcode']) && $_POST['spamcode'] != $_SESSION['answer']) {
//              session_unset();
//              session_destroy();
                message("$register_failed");
        }
        else if (isset ($_POST['spamcode']) && $_POST['spamcode'] == $_SESSION['answer']) {
//              session_unset();
//              session_destroy();
        }

//------------------------------------------------//

The complete contents of include/user/register.php:

<?php

if (isset($_SESSION['hint']))
{
        $hint = $_SESSION['hint'];
        $answer = $_SESSION['answer'];
        $question = $_SESSION['question'];
}
else
{

$register_failed = 'The answer you supplied was incorrect. Please try again.';
$number = rand(1, 4);

//---Questions array---//

$questions = array(

'q1' => 'Test one',
'q2' => 'Test two',
'q3' => 'Test three',
'q4' => 'Test four'

);

//-----Hints array-----//

$hints = array(

'h1' => '<b>Hint: </b>Answer: One',
'h2' => '<b>Hint: </b>Answer: Two',
'h3' => '<b>Hint: </b>Answer: Three',
'h4' => '<b>Hint: </b>Answer: Four'

);

//----Answers array----//

$answers = array(

'a1' => 'One',
'a2' => 'Two',
'a3' => 'Three',
'a4' => 'Four'

);

//--Create the session variables--//

session_start();

$_SESSION['hint'] = $hints[h.$number];
$_SESSION['answer'] = $answers[a.$number];
$_SESSION['question'] = $questions[q.$number];

//session_write_close();

}

?>

I've reached the point of no idea. big_smile

16

Re: register.php and require/include

Just out of curiosity, does the stunned silence made I've made a major cockup in my design of that script, big_smile or is the implementation of the session, in theory, sound?


Cheers,

Matt

17 (edited by MattF 2007-06-05 23:56)

Re: register.php and require/include

Finally bested the beastie. big_smile big_smile big_smile

The session has to be started and the variables assigned in the register.php script itself, with another session start at the check point. big_smile big_smile The require script just needs to contain the arrays.

The method is:



register.php, (the new bits between the dashed lines):

if ($pun_config['o_regs_allow'] == '0')
        message($lang_register['No new regs']);

//-----------------------------------------------------------------------------//
require_once PUN_ROOT.'include/user/register.php';
//-----------------------------------------------------------------------------//
        // Make sure we got a valid language string
        if (isset($_POST['language']))
        {
                $language = preg_replace('#[\.\\\/]#', '', $_POST['language']);
                if (!file_exists(PUN_ROOT.'lang/'.$language.'/common.php'))
                                message($lang_common['Bad request']);
        }
        else
        {
                $language = $pun_config['o_default_lang'];
        }

//-----------------------------------------------------------------------------//

        // anti-spam code variable checked here. Customise to suit your needs.
        session_start();
        if (isset ($_POST['spamcode']) && $_POST['spamcode'] != $_SESSION['answer']) {
                session_unset();
                session_destroy();
                message("$register_failed");
        }
        else if (isset ($_POST['spamcode']) && $_POST['spamcode'] == $_SESSION['answer']) {
                session_unset();
                session_destroy();
        }

//-----------------------------------------------------------------------------//
//-----------------------------------------------------------------------------//
<div class="inform">
        <fieldset>
        <legend>Spambot prevention</legend>
                <div class="infldset">
<?php
                        session_start();
                        $_SESSION['hint'] = $hints[h.$number];
                        $_SESSION['answer'] = $answers[a.$number];
                        $_SESSION['question'] = $questions[q.$number];
?>
                        <p><b>Question:</b> <?php echo $_SESSION['question']; ?></p>
                        <p><b>Hint:</b> <?php echo $_SESSION['hint']; ?></p>
                        <input method="post" type="text" name="spamcode" size="10" maxlength="10" /><br/>
                </div>
        </fieldset>
</div>

//-----------------------------------------------------------------------------//

                        <div class="inform">
                                <fieldset>
                                        <legend><?php echo $lang_prof_reg['Localisation legend'] ?></legend>
                                        <div class="infldset">
                                                <label><?php echo $lang_prof_reg['Timezone'] ?>:

The contents of user/include/register.php, (new file):

<?php


$register_failed = 'The answer you supplied was incorrect. Please try again.';
$number = rand(1, 4);

//---Questions array---//

$questions = array(

'q1' => 'Test one',
'q2' => 'Test two',
'q3' => 'Test three',
'q4' => 'Test four'

);

//-----Hints array-----//

$hints = array(

'h1' => 'One',
'h2' => 'Two',
'h3' => 'Three',
'h4' => 'Four'

);

//----Answers array----//

$answers = array(

'a1' => 'One',
'a2' => 'Two',
'a3' => 'Three',
'a4' => 'Four'

);


?>

Knew I'd beat it eventually. big_smile big_smile big_smile

Re: register.php and require/include

That can be gotten around rather easily I'm afraid.
What happens if I don't have a valid session when I submit the form (like most bots won't)? All session variables won't be set. What happens if I also submit an empty value for spamcode? I'll bypass the spam check wink

What you need to do is initialize the session and its variables in include/user/register.php

19

Re: register.php and require/include

I hate this script. big_smile The empty post thing, that's one I missed. big_smile Easy enough to sort though. smile But........ not for love nor money will this work as intended when the session and variables are initialised in the external user/register.php script. And for the life of me I can't figure out why. I tried as you suggested last time and everything, and it just will not work.

Is that first section of the script in the root register.php file okay as is, (other than the lack of an empty post test)?


Cheers,

Matt

Re: register.php and require/include

The reason it doesn't work? You need to move your session_start() to before the if statement (I'm looking at here). Otherwise, $_SESSION is never set at that point

21

Re: register.php and require/include

Smartys wrote:

What happens if I don't have a valid session when I submit the form (like most bots won't)? All session variables won't be set.

Hope you don't mind me picking your brain again. smile In what way would this bit cause a problem?


Cheers,

Matt

Re: register.php and require/include

MattF wrote:
Smartys wrote:

What happens if I don't have a valid session when I submit the form (like most bots won't)? All session variables won't be set.

Hope you don't mind me picking your brain again. smile In what way would this bit cause a problem?


Cheers,

Matt

It's together with the other bit that it causes the issue (because ('' == null) evaluates to true)

23

Re: register.php and require/include

Smartys wrote:

It's together with the other bit that it causes the issue (because ('' == null) evaluates to true)

That's so simple and sneaky at the same time. big_smile Thanks for the pointer. smile Right. Final attempt. big_smile It appears to be working fine now, with the vars being set in the require file. I can only think that I must have set the checks wrong and been destroying the session before I got chance to use it. So, here's the revised version following, (I hope), your guidelines. smile

Hopefully I've covered all the caveats now with this section below?

//------------------------------------------------//

        session_start();
        if (isset ($_SESSION['answer']) && $_SESSION['answer'] == '' || $_POST['spamcode'] != $_SESSION['answer'])
        {
                session_unset();
                session_destroy();
                message("$register_failed");
        }
        else if (isset ($_SESSION['answer']) && $_POST['spamcode'] == $_SESSION['answer'])
        {
                session_unset();
                session_destroy();
        }

//------------------------------------------------//

The include/user/register.php file, (with the arrays stripped out to keep the post small). big_smile

<?php

$register_failed = 'The answer you supplied was incorrect. Please try again.';

session_start();
if (!isset($_SESSION['answer']) || $_SESSION['answer'] == '')
{

$number = rand(1, 4);

//----Arrays edited out for brevity----//

$_SESSION['hint'] = $hints[h.$number];
$_SESSION['answer'] = $answers[a.$number];
$_SESSION['question'] = $questions[q.$number];

}

?>

Does that one cover requirements for security and such now? I've given it about ten test tries, and at least it seems consistent at last. big_smile



Cheers,

Matt

Re: register.php and require/include

A couple things
1. You don't need session_start twice: in fact, that should be issuing a notice or a warning tongue
2. at the checkpoint in register.php, we know $_SESSION values will be set. So, the code can instead look like

        if (isset ($_POST['spamcode']) && $_POST['spamcode'] != '' && $_POST['spamcode'] == $_SESSION['answer'])
        {
                session_unset();
                session_destroy();
        }
        else
        {
                session_unset();
                session_destroy();
                message("$register_failed");
        }

25 (edited by MattF 2007-06-06 12:25)

Re: register.php and require/include

Cheers. smile That modified answer check bit works a treat. smile Hadn't noticed any warnings from the second session_start command, but have altered  it to use your code verbatim for the  answer check anyhow. I must have made a right royal cock up somewhere with my initial attempts at this script. big_smile big_smile At least now, thanks to your help, I think I've finally got the gist of exactly how the sessions work.  (With a cartload of failed attempts along the way). big_smile Thanks ever so much for all the help you've given me on this, btw. It's greatly appreciated. smile Does it pass muster now on the scripting security side of things, as it is?