0

So I have this in my .htaccess file, trying to rid myself of the .php following each URL on my site. And it works, just as intended, it takes the .php out, just like a charm. However, this rewrite condition is breaking my login functionality. Once inside the login wall, there is not a problem, I can scoot around to any one of the files, but for some reason, I can not login with this Condition in place. As soon as I delete it, users can login.

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]

In case you want my php file for the login page (index.php)

<?php
 ob_start();
 session_start();
 require_once 'dbconnect.php';

 // it will never let you open index(login) page if session is set
 if ( isset($_SESSION['User'])!="" ) {
  header("Location: home.php");
  exit;
 }

 $error = false;

 if( isset($_POST['btn-login']) ) { 

  // old source code with no relevance
  $email = trim($_POST['email']);
  $email = strip_tags($email);
  $email = htmlspecialchars($email);

  $pass = trim($_POST['pass']);
  $pass = strip_tags($pass);
  $pass = htmlspecialchars($pass);

  if(empty($email)){
   $error = true;
   $emailError = "Please enter your email address.";
  } else if ( !filter_var($email,FILTER_VALIDATE_EMAIL) ) {
   $error = true;
   $emailError = "Please enter valid email address.";
  }

  if(empty($pass)){
   $error = true;
   $passError = "Please enter your password.";
  }

  // if there's no error, continue to login
  if (!$error) {


  $conn = new mysqli($servername, $username, $dbpassword, $dbname);

   $password = hash('sha256', $pass); // password hashing using SHA256 do not use, it's not secure

   $sql = "SELECT UserID, FirstName, Password FROM Users WHERE Email='$email'";
   $result = $conn->query($sql);
   $row = $result->fetch_assoc();
   $count = $result->num_rows;

   if( $count == 1 && $row['Password']==$password ) {
    $_SESSION['User'] = $row['UserID'];
    header("Location: home.php");
   } else {
    $errMSG = "Incorrect Credentials, Try again...";
   }

  }

 }
?>

Thanks guys

Sharkn8do
  • 143
  • 2
  • 14
  • Which of the conditions prevents the login? – Jay Blanchard Dec 13 '16 at 17:04
  • 1
    Despite your efforts [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)***. Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). – Jay Blanchard Dec 13 '16 at 17:05
  • ***You shouldn't use [SHA1 password hashes](https://konklone.com/post/why-google-is-hurrying-the-web-to-kill-sha-1)*** or ***[MD5 password hashes](http://security.stackexchange.com/questions/19906/is-md5-considered-insecure)*** and you really should use PHP's [built-in functions](http://jayblanchard.net/proper_password_hashing_with_PHP.html) to handle password security. Make sure you [don't escape passwords](http://stackoverflow.com/q/36628418/1011527) or use any other cleansing mechanism on them before hashing. Doing so *changes* the password and causes unnecessary additional coding. – Jay Blanchard Dec 13 '16 at 17:05
  • @JayBlanchard updated the question to only show the problematic one – Sharkn8do Dec 13 '16 at 17:08
  • @RegularlyScheduledProgramming yes, sharkn8do is a shitty programmer, I get it. This site isn't close to live yet, I am aware of vulnerabilities to SQL injection, functionality came first, security is going to be my next to last pass, after I get this bundle of dung polished – Sharkn8do Dec 13 '16 at 17:11
  • Nothing personal meant by it, but people (like me) copy and paste things from Stack all the time, and they might think from your comments about preventing SQL injection that what you did works, and it doesn't. – RegularlyScheduledProgramming Dec 13 '16 at 17:14
  • I know, I'm on 4 hours of sleep in finals week, editing Apache rules, I'm a bit testy. Edited to show what not to do – Sharkn8do Dec 13 '16 at 17:18
  • Thanks, and best of luck with your finals. – RegularlyScheduledProgramming Dec 13 '16 at 17:19
  • thanks, now back to your regularly scheduled programming hahaha – Sharkn8do Dec 13 '16 at 17:21

1 Answers1

0

Based on the fact that rule is causing your issue, I'm guessing that you are posting to index.php rather than index, more on why that is a problem below.

There are 2 quick fixes for this. You can change your login form to post to /index. Something like:

<form method="post" action="/path/to/index">

Note the missing .php in the action. Alternatively, you could exclude your index.php from your redirect rules by adding a line to your .htaccess file:

# To externally redirect /dir/foo.php to /dir/foo
RewriteRule ^index\.php$ - [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=307,L,NC]

That is my personal preference for something like this since a /index URL lacks the prettiness of something like /home anyway so you probably never really want to display that to users regardless.

The reason that the above is necessary is that since your rule will redirect /index.php to /index any POST parameters sent to index.php will be stripped out during the redirect to index. The only way around this that I've ever seen is to use a 307 redirect: Why doesn't HTTP have POST redirect?

As the other answer says, there is potential for misuse with 307 and it is not 100% effective. There is also the possibility of a bad UX since many browsers will (and should) prompt the user to confirm the repeat of post data.

To apply this fix you could modify your htaccess like this

RewriteRule ^ %1 [R=307,L,NC]

I would not recommend this since it is not really necessary for your situation and is not as reliable as the first 2 options.

Community
  • 1
  • 1
TheGentleman
  • 2,324
  • 13
  • 17