0

My intention here is to create a page which initially displays a basic form consisting of a text field where a password is entered, and a submit button. Upon submitting, the form will send the value back to the same page, where it is checked. This happens in the PHP file, not in a database. If the password is correct, the relevant HTML will be shown. This is what I have:

<?php
    ini_set('display_errors',1);
    ini_set('display_startup_errors',1);
    error_reporting(-1);
    if(isset($_POST["logout"])){
        session_destroy();
    }elseif(isset($_POST["auth"])){
        if($_POST["auth"]=="password"){
            session_start();
            $_SESSION["admin"]="true";
        }
    }
    if(!isset($_SESSION["admin"])){
?>
    <form action="/admin.php" method="post">
        <input type="text" name="auth"><input type="submit">
    </form>
<?php
    }elseif($_SESSION["admin"]="true"){
?>
<section>
<!--HTML goes here-->
</section>
<section>
    <form action="/admin.php" method="post">
        <input type="hidden" name="logout" value="logout">
        <input type="submit">
    </form>
</section>
<?php }else{echo "Incorrect password";}?>

Now this partially works. Entering the correct password will show the HTML that the person should see. What doesn't happen is when an incorrect password is entered, the echo on the final line will not be shown. It just goes back to the form, as if opening the page for the first time.

Also, after successfully entering the password, I get a couple of warnings thrown up:

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at D:\xampp\htdocs\top.php:28) in D:\xampp\htdocs\admin.php on line 13
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at D:\xampp\htdocs\top.php:28) in D:\xampp\htdocs\admin.php on line 13

...where line 13 is simply session_start();

While I have read that there are security issues with storing a password in the PHP file, it didn't seem like a major concern since no more than two people will be using this page containing tools for the manipulation of things that aren't a major issue if messed with, or deleted. However, if this is a much bigger security issue than I think it is, please let me know.

Hiigaran
  • 829
  • 10
  • 28

5 Answers5

0

It is adviced that session_start() should be the first line of the code, you can start session with all the users, but use some other data stored in session variables to authenticate and authorize the access.

akm
  • 830
  • 6
  • 20
  • Any reason why I would need it like that? I only want to start the session if the user has the right password. Unless I'm missing something, there shouldn't be a need to have a session for anyone simply loading the page and coming to the initial form, right? – Hiigaran Mar 02 '14 at 19:15
  • @Hiigaran i am not saying its the best method, but its an easy and effective solution. Otherwise you may buffer the output. – akm Mar 02 '14 at 19:25
  • Sorry, didn't mean to sound argumentative. Just trying to understand in the process. In any case, I've done that now. The warnings I got before are now present at all times, so I'm going to look into some of the other solutions others suggested as well. – Hiigaran Mar 02 '14 at 19:28
  • @Hiigaran the process is, sessions are handled through HTTP headers, and once you start creating the body of a HTTP response, you cannot set the headers again, hence its always a good idea to use such methods before echoing anything; otherwise you need to buffer the output. – akm Mar 02 '14 at 21:21
0

For the warnings below you can add <?php ob_start(); ?> at the top of the page. Doing so should probably get you out of those warnings .

Ankit Kulkarni
  • 1,245
  • 3
  • 14
  • 23
  • I tried reading up about this on the PHP site, but I'm still confused. What does this do, and why is it useful? From what I gathered, it turns off any outputs from the script...whatever that means. – Hiigaran Mar 02 '14 at 19:17
  • Yes it is a buffer which is temporary and holds the output from the scripts .You can also flush it using ob_flush() at the end of the php file. Did that solved your problem anyway ? – Ankit Kulkarni Mar 03 '14 at 11:51
  • No, I just placed the session_start() at the very top of the page, before any of my includes. That solved the secondary problem, but I have yet to try the solution to the main problem that someone else posted. I'm going to have to get around to that when I get the time. Thanks anyway. – Hiigaran Mar 03 '14 at 14:00
0

Add the included files after session headers.I dont see any use of included files in the php code posted in the question guessing they are needed after in that page.So just add them after session headers and this will and most probably should solve your problem

OR

Add this line to your php.ini:

output_buffering = On

PHP docs recommend setting to a number instead of just On >> http://us3.php.net/manual/en/outcontrol.configuration.php#ini.output-buffering.

OR

In .htaccess add:

php_value output_buffering On

Source : session_start() error

Community
  • 1
  • 1
Zword
  • 6,605
  • 3
  • 27
  • 52
  • Turns out I don't have access to that file, since my server permissions are restricted. However, can I achieve the same effect with the ob_start() that others have suggested? – Hiigaran Mar 02 '14 at 19:24
  • If ob_start works then it fine or else try the .htaccess part in the answer from the source – Zword Mar 02 '14 at 19:27
  • @Hiigaran yes you get the same effect by `ob_start` or you may also use `ini_set()` for temporarily changing the PHP configuration for that request. – akm Mar 02 '14 at 19:27
  • If there is an ob_start, does that mean there is an ob_stop or similar? From what little I understood, it's supposed to turn off script outputs. Not sure what that even means, but does that mean it just hides the error instead of fixing it? If so, couldn't I achieve the same result by removing my three lines that display error messages? EDIT: Just added ob_start(); but it still shows the messages. – Hiigaran Mar 02 '14 at 19:32
  • @Hiigaran I myself had the same issue in the past and solved it using `@akm's` posted method.Create an empty session at start and on login session with user value – Zword Mar 02 '14 at 19:35
  • I've placed it at the top already, so now the messages appear all the time. Since I have other php files included with the include function, should I be placing them at the top of the topmost included php file, or just at the top of the php in the relevant page? – Hiigaran Mar 02 '14 at 19:37
  • 1
    Add the included files after session headers.I dont see any use of included files in the php code posted in the question guessing they are needed after in that page.So just add them after session headers and this will and most probably should solve your problem – Zword Mar 02 '14 at 19:40
  • Alrighty, that did the trick. So that issue is solved. Now the final issue remains, which is why it doesn't show the incorrect password message when an incorrect password is entered. – Hiigaran Mar 02 '14 at 19:49
  • Was it displaying before the changes? – Zword Mar 02 '14 at 19:51
  • Nope. Also, I don't seem to be getting notifications for replies here...Only just noticed your message. – Hiigaran Mar 02 '14 at 20:08
  • Then some mistake in your PHP code.No errors showing then its some logic or algorithm fix you need to do in your code – Zword Mar 02 '14 at 20:12
0
session_start();

When the password is incorrect this line of code never get executed unless the form is posted with a correct password.

Place that line at the top and remove it from where it is now.

Wenzz
  • 370
  • 4
  • 15
0

Here is some code that is based on your original code.

It is tested.

There was a bug in one of your original tests that had '=' rather than '=='.

As you are using PHP to select different portions of the HTML to include i have used the 'Alternate Control' syntax as it reads better.

There are quite a lot of comments in the code. Feel free to remove 'em. :-)

<?php
// PHP 5.1.18 on windows XP (XAMPP) -- i use buffered output    
session_start(); // assume we always have sessions -- can be destroyed later if required

/*
 * Using Alternate Control syntax for control structures
 *
 * This is 'cos we are using PHP to show different portions of HTML
 */

$passwordError = false; // assume password is ok


// I have these already in my development enviroment
//    ini_set('display_errors',1);
//    ini_set('display_startup_errors',1);
//    error_reporting(-1);

    if (isset($_POST["logout"])) { // logout form submitted...
        session_destroy();
        die(__FILE__ .' : i am done...');

    } elseif (isset($_POST["auth"])) { // hard coded password! fine for testing!
        if ($_POST["auth"] == "password") { 
             $_SESSION["admin"] = "true";
        } else {
             $passwordError = true; // failed password check
        }
    }
?>

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Q22131957</title>
  </head>

  <body>
    <h1>Q22131957 Login screen</h1>

  <?php if (!isset($_SESSION["admin"]) || $_SESSION['admin'] != "true"): // need the admin login form to be shown?>

    <form action="" method="post"> <!-- the form must come back to this script for checking... -->
        <input type="text" name="auth"><input type=submit value="admin login">
     </form>

     <?php if ($passwordError): ?>
        <strong> Incorrect password</strong>
     <?php endif; ?>

   <?php endif;  // end of admin attempt to login... ?>


  <?php if (isset($_SESSION["admin"]) && $_SESSION["admin"] == "true"): // admin is logged in successfully ?>

  <!--
    /*
     * Normally, you would just redirect to a different URL where
     * all the admin actions live.
     *
     * Here i just drop through to the 'logged in admin' part of the script
     * as the original script did.
     *
     */
  -->
<section>
 <!--HTML goes here-->
  <p> we logged in as ADMIN! </p>
</section>
<section>
    <!-- this form returns to this script! -->
    <form action="" method="post">
        <input type="hidden" name="logout" value="logout">
        <input type="submit" value="logout">
    </form>


    <!-- divert to admin.php screen via a form -- testing only -->
    <form action="admin.php" method="post">
        <input type="hidden" name="continue" value="continue">
        <input type="submit" value="continue to admin.php...">
    </form>

</section>
<?php endif; // end of successful logged in admin ?>

</body>
</html>
Ryan Vincent
  • 4,483
  • 7
  • 22
  • 31