0

I had created a simple password protection page for a PHP webpage by searching online. below is the code.

protect.php:

<?php
   namespace Protect;
   function with($form, $password, $scope=null) {
      if( !$scope ) $scope = current_url();
         $session_key = 'password_protect_'.preg_replace('/\W+/', '_', $scope);
         session_start();

      if( $_POST['password'] == $password ) {
         $_SESSION[$session_key] = true;
         redirect(current_url());
      }

      if( $_SESSION[$session_key] ) return;
         require $form;
         exit;
   }

   function current_url($script_only=false) {
      $protocol = 'http';
      $port = ':'.$_SERVER["SERVER_PORT"];
      if($_SERVER["HTTPS"] === 'on') $protocol .= 's';
      if($protocol === 'http' && $port === ':80') $port = '';
      if($protocol === 'https' && $port === ':443') $port = '';
      $path = $script_only ? $_SERVER['SCRIPT_NAME'] : $_SERVER['REQUEST_URI'];
      return $protocol."://".$_SERVER[SERVER_NAME].$port.$path;
    }
    function redirect($url) {
       header("Location: ".$url);
       exit;
    }

Form.php:

<html>
   <body>
      <form method="POST">
         <?php
         if( $_SERVER['REQUEST_METHOD'] === 'POST' ) { 
            ?>
            Invalid password
         <?php 
         }
         ?>
         <p>Enter password for access:</p>
         <input type="password" name="password">
         <button type="submit">Submit</button>
      </form>
   </body>
</html>

At the top of the php webpage which is to be protected with security password:

<?php 
    require_once('protect.php');
    Protect\with('form.php', 'demo');  // demo is the password
?>

It's working fine but I am getting an error as

Undefined index: password in C:\xampp\htdocs\iv\admin\protect.php on line 9 and session start() is already defined.

(On top of the php page which is to be protected).

When I tried to make any changes its completely not working.

Anybody, please help and guide me where exactly the error.

Martin
  • 19,815
  • 6
  • 53
  • 104
Shaik
  • 256
  • 7
  • 27
  • 1
  • 1
    hi @Martin, i didn't get your comment – Shaik Feb 23 '19 at 09:29
  • 1
  • Saif, @Martin means you cannot open PHP twice before closing it once. – jrswgtr Feb 23 '19 at 09:34
  • Here: `Protect\with('form.php', 'demo');` because your password is plaintext, you might as well simply do: `if($_POST['password'] === "demo"){....` and miss out on the obtuse bloated usage of classes and Server variables. **OR** even better, use PHP's `Password_hash()` function. – Martin Feb 23 '19 at 09:34
  • Possible duplicate of ["Notice: Undefined variable", "Notice: Undefined index", and "Notice: Undefined offset" using PHP](https://stackoverflow.com/questions/4261133/notice-undefined-variable-notice-undefined-index-and-notice-undefined) – Martin Feb 23 '19 at 09:41
  • 1
    Please see [**this Question and Answer**](https://stackoverflow.com/questions/6249707/check-if-php-session-has-already-started) and [**this Question and Answer**](https://stackoverflow.com/questions/4261133/notice-undefined-variable-notice-undefined-index-and-notice-undefined). Thanks. – Martin Feb 23 '19 at 09:42
  • its showing same error – Shaik Feb 23 '19 at 10:05

2 Answers2

1

You have to check first if the password has been submitted in your with function.

// this has to be checked first
// added isset to check if its existing

if( isset($_SESSION[$session_key]) && $_SESSION[$session_key] ) return;
    ^-------------------------------^

if( isset($_POST['password']) && $_POST['password'] == $password ) {
    ^--------------------------^
    ...
}
SirPilan
  • 3,863
  • 2
  • 9
  • 23
1

As noted by @Martin in several comments, your two issues can be easily solved by reading the linked questions/answers.

The first issue, which is the session already started error, can be easily solved by bringing out the session_start() from your function altogether and put it only once in the very top level php file.

The second issue is resolved by using empty() or isset().

function with($form, $password, $scope=null)
{
    if(empty($scope))
        $scope = current_url();

    $session_key = 'password_protect_'.preg_replace('/\W+/', '_', $scope);

    if(isset($_POST['password']) && ($_POST['password'] == $password)) {
       $_SESSION[$session_key] = true;
       redirect(current_url());
    }

    if(!empty($_SESSION[$session_key]))
        return false;

    require($form);
    exit;
}

To set session:

<?php
# Just add by default, don't use an "if" clause
session_start();
# Do the rest of your script
require_once('protect.php');
$Protect->with('form.php', 'demo');

One final note; make sure your indenting correlates to hierarchy otherwise the script can get hard to read.

Rasclatt
  • 12,249
  • 3
  • 21
  • 32