PRG pattern technique with input validation - php

I have implemented the Post/Redirect/Get Pattern to avoid http post requests to be sent to the server each time the web page is reloaded, but i get a problem.
The Welcome message should only be displayed once when the password is set to test. In my case, it is never displayed, unless you comment out the 4th line.
If you remove that line, PRG pattern is not applied, hence form gets resubmitted on each page reload
The code below is a full working code, paste that directly in your code for testing. or here
<?php
$self = htmlspecialchars($_SERVER["PHP_SELF"]);
if(isset($_POST['Code2']) && ( $_POST['Code2'] == "test")) {
header('Location: '.$self, true, 303);exit; //redirection on the same page
?> <span id="welcome-msg"></span> <!-- Display welcome Message -->
<?php } ?>
<form method="post">
Code:<br>
<input type="text" name="Code2"> <input type="submit">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$("#welcome-msg").html("Welcome").fadeOut(5500);
</script>

Here is a simple PoC that uses PHP sessions instead of cookies. A client session is identified by a cookie but the client has no control over the data the session stores. You could, in theory, put more sensitive data into the "welcome" message this way, although the login method is still very basic and should at least be done over HTTPS.
<?php
// Start PHP session management
session_start();
$self = htmlspecialchars($_SERVER["PHP_SELF"]);
if (isset($_POST['Code2']) && $_POST['Code2'] === "test") {
// Code is correct, flash the welcome message after redirect
$_SESSION["flash_welcome"] = true;
header('Location: '.$self, true, 303);
exit;
} else if (isset($_POST['Code2']) && $_POST['Code2'] !== "test") {
// Code was sent but is incorrect, flash the incorrect message after redirect
$_SESSION["flash_incorrect"] = true;
header('Location: '.$self, true, 303);
exit;
}
if ($_SESSION["flash_welcome"]) {
// Display welcome message
?><span id="welcome-msg">Welcome</span><?php
}
if ($_SESSION["flash_incorrect"]) {
// Display incorrect message
?><span id="incorrect-msg">Incorrect code</span><?php
}
// Clear flash messages
$_SESSION["flash_welcome"] = false;
$_SESSION["flash_incorrect"] = false;
?>
<form method="post">
Code:<br><input type="text" name="Code2">
<input type="submit">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>$("#welcome-msg,#incorrect-msg").fadeOut(5500);</script>

Your <span id="welcome-msg"></span> is located after a redirection and after an exit() inside an if statement
If the condition exists or not, your span will never be displayed.
You need to move it out of the "if", or add it before the redirection and "exit()"
<?php
$self = htmlspecialchars($_SERVER["PHP_SELF"]);
if(isset($_POST['Code2']) && ( $_POST['Code2']== "test")) {
header('Location: '.$self, true, 303);
exit;
} ?>
<span id="welcome-msg"></span>
<form method="post">
Code:<br>
<input type="text" name="Code2"> <input onclick="event.preventDefault()" type="submit">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$("#welcome-msg").html("Welcome").fadeOut(5500);
</script>
https://www.tehplayground.com/Hf25u68JYljxkjQu

Related

PHP - refresh entire page from an included file?

At the top of every page I have a header (header.inc.php) that has a login field that I add with
include 'login.php';
The code there is:
<?php
include 'checkPassword.php';
if (isset($_POST['login'])) {
if (checkLogin($_POST['username'], $_POST['password'])) {
session_start();
$_SESSION['isLoggedIn'] = true;
header("Refresh:0");
exit();
} else {
echo '<h1>nope</h1>';
}
}
?>
<div id="login"> <!-- Login field with link to registration -->
<fieldset>
<form method="POST" action="login.php">
<Legend>Login</Legend>
Username <input type="text" name="username" <?php if (isset($username)) {echo "value=$username";} ?>>
Password <input type="password" name="password"/>
<input type="submit" name="login">
<div id="register">
Not a member? Click here to register!
</div>
</form>
</fieldset>
</div>
I've seen a few different methods for using header() to load a certain page, but the login appears at the top of every page, therefore I'd like a way for the PHP to refer to itself. However, all the methods I've found so far refer to 'login.php', instead of the page the overall page that contains the header and login.
try this one
<?php
include 'checkPassword.php';
if (isset($_POST['login'])) {
if (checkLogin($_POST['username'], $_POST['password'])) {
session_start();
$_SESSION['isLoggedIn'] = true;
header("Refresh:0");
exit();
} else {
echo '<h1>nope</h1>';
}
}
?>
It refreshes your current page, and if you need to redirect it to another page, use following:
header("Refresh:0; url=page2.php");
echo meta tag like this: URL is the one where the page should be redirected to after refresh.
echo "<meta http-equiv=\"refresh\" content=\"0;URL=upload.php\">";

$_GET to access a page?

I have a page secured.php with an URL containing a GET-parameter that comes from index.php by using form method="post" where after processing the script an user-id will be stored in a SESSION as well be added as a GET-parameter u=12345 by a header-function that redirects to secured.php?u=12345.
By checking if isset($_GET['u']){ the GET-paramater u is available, everything is fine. I can validate it and so on...
The problem now is that when submitting a form even here by using form method="post" on secured.php?u=12345 the GET-parameter u will be used to header but when executing the header function the GET-parameter u for some reason won't be there anymore and if ( !isset($_GET['u']) ){will do some stuff that actually should not be done.
if ( !isset($_GET['u']) ){
some stuff
}
if (isset($_POST['something']) === true){
header("Location: secured.php?u=12345&b=example");
}
I really would appreciate if there is someone who could help me out. Thanks in advance.
Let check this:
1: index.php
<?php
session_start();
$_SESSION['U_ID'] = '12345';
?>
<html>
<body>
<form action="secured.php?u=<?php echo $_SESSION['U_ID']; ?>" method="post">
Name: <input type="text" name="name"><br>
<input type="submit">
</form>
</body>
</html>
2: secured.php
<?php
if ( !isset($_GET['u']) ){
//some stuff
} else {
if (isset($_POST["name"]) && $_POST["name"] != ''){
$re_url = 'secured.php?u='.$_GET['u'].'&b=example';
header('Location: '.$re_url);
}
}
?>
Just small answer

How to prevent user from bypassing php authentication

We call it html1 for simplicity.
When a user goes to html1, there's a login2.php login page to enable access to client.php which is the hidden page.
It then goes to checklogin.php...if the password and user name matches...it then goes to the hidden client.php page...if not..it goes back to homepage.
The user has to login to be able to view the contents of hidden client.php page.
However the user can access client.php by typing in ..../client.php on the address bar...therefore bypassing the auth page and rendering it useless. I can just type servername/client.php...and it still shows me the contents of client.php...but I want client.php...to be private!
How do I prevent this from happening?
thanks.
first login page...
<html>
<head>
<title>Login Form</title>
</head>
<body>
<h2>Login Form</h2>
<table>
<form method="post" action="checklogin2.php">
<div id="name">User Id: <input type="text" name="****"></div>
<div id="password">Password: <input type="password" name="*******"></div>
<div class="button"><input type="submit" value="Login"></div>
</form>
</table>
</body>
</html>
then it goes to....
checklogin2.php
<?php
$*** = $_POST['****'];
$***** = $_POST['***'];
if($uid == '****' and $***** == '*****')
{
session_start();
$_SESSION['sid']=session_id();
header("location:securepage.php");
}
else
{
header("location:index.html");
}
?>
Then it goes to...
securepage.php
<?php
session_start();
if($_SESSION['sid']==session_id())
{
header("location:client.php");
echo "<a href='logout.php'>Logout</a>";
}
else
{
header("location:login.php");
}
?>
In the beginning of your every page you have to check if user is authorized.
On checklogin.php if user entered correct login and password, just set something like
$_SESSION['authorized'] = TRUE;
...and on other pages just check if user is authorized:
if (isset($_SESSION['authorized']) && $_SESSION['authorized'] === TRUE) {
// Alright, let's show all the hidden functionality!
echo "Psst! Hey! Wanna buy some weed?";
} else {
// User is not authorized!
header('Location: login.php');
exit();
}
Note that you don't have to mess with cookies, session IDs etc. - just add session_start() before everything and freely use $_SESSION var.
This is the main pro of sessions (and $_SESSION variable in particular): you can remember some data among different pages on same website.
All pages has to check if the user is authed. I would recommend using objects, and always inherit a class that checks this for you. It's not fun to have the same code everywhere, doing the same thing.
if($_SERVER["PHP_SELF"] == '/yourpagefolder/yourpage.php' && !isset($_SESSION['login_user'])){
header('location: login.php');
}

PHP sessions not being set

I have a code which logs in via AJAX and then passes the data to a .php file to check it against the SQL. for a test, the username and password is me - me however even tho this comes back from the check it doesn't log me in, it seems like the session is not being set.
log.php
<script type="text/javascript">
$(document).ready(function()
{
$("#login_form").submit(function()
{
//remove all the class add the messagebox classes and start fading
$("#msgbox").removeClass().addClass('messagebox').text('Validating....').fadeIn(1000);
//check the username exists or not from ajax
$.post("ejaxlog.php",{ username:$('#username').val(),password:$('#password').val(),rand:Math.random() } ,function(data)
{
if($.trim(data)=='yes') //if correct login detail
{
$("#msgbox").fadeTo(200,0.1,function() //start fading the messagebox
{
//add message and change the class of the box and start fading
$(this).html('Logging in.....').addClass('messageboxok').fadeTo(900,1,
function()
{
//redirect to secure page
document.location='http://www.google.com';
});
});
}
else
{
$("#msgbox").fadeTo(200,0.1,function() //start fading the messagebox
{
//add message and change the class of the box and start fading
$(this).html('Your login detail sucks...').addClass('messageboxerror').fadeTo(900,1);
});
}
});
return false; //not to post the form physically
});
//now call the ajax also focus move from
$("#password").blur(function()
{
$("#login_form").trigger('submit');
});
});
</script>
<link type="text/css" href="formboxes.css" rel="stylesheet">
</head>
<body>
<?
echo $_SESSION['u_name'];?>
<form method="post" action="" id="login_form">
<div align="center">
<div >
User Name : <input name="username" type="text" id="username" value="" maxlength="20" />
</div>
<div style="margin-top:5px" >
Password :
<input name="password" type="password" id="password" value="" maxlength="20" />
</div>
<div class="buttondiv">
<input name="Submit" type="submit" id="submit" value="Login" style="margin-left:-10px; height:23px" /> <span id="msgbox" style="display:none"></span>
</div>
</div>
</form>
this then checks the MySQL via the next code, is it is successful it echos out "yes" which i see in my HTTP headers (so must be correct) but it doesnt redirect me to "eindex.php" as specified in the log.php file.
<?php
session_start();
require("../mcfrdb.php");
// Included database once using the require method
?>
<?php
$username = mysql_real_escape_string(stripslashes($_POST['username']));
$pass = mysql_real_escape_string(stripslashes($_POST['password']));
$result = mysql_query("SELECT user, pass FROM mcfruse WHERE user='$username'")or die(mysql_error());
$row=mysql_fetch_array($result);
if(mysql_num_rows($result)>0)
{
if(strcmp($row['pass'],$pass)==0)
{
echo "yes";
$_SESSION['name']=$username;
}
else
echo "no";
}
else
echo "no";
My HTML when using firebug says
yes
so the yes is being echo'ed which means it passes the right pwd and it validates, but it still says "Login detail sucks" and doesnt redirect me to eindex.php
eindex.php
<?php
session_start();
if(!isset($_SESSION['name']))
header("Location:../index.php");
//if logout then destroy the session and redirect the user
if(isset($_GET['logout']))
{
session_destroy();
header("Location:../index.php");
}
require("../mcfrdb.php");
?>
I've checked the code over a few times but couldnt find anything. All replies and any help appreciated.
Many thanks.
EDIT: even adding in the md5 pwd hashing (omitted from this code) i still get "yes" and when I echo the username and hash, they are bot matching, the session is not being set still however and not redirecting me. on if($.trim(data)=='yes')
Any page you access via AJAX is a separate request and you will need to call session_start() in order for the session super global to be populated.
Your ejaxlog.php returns yes? Are you sure? Try adding alert(data) or console.log(data) to see what does it return. Seems that your script returns not yes or not only yes (may be, some error?). Obviously, you are not redirected because your JavaScript receives not appropriate string, so it does not redirects you.
Again, try logging/alerting the data which is returned by the script. Or install something like FireBug for FireFox to see all the requests done by the JavaScript.
use session_start() at the top of your ejaxlog.php page

Cookies are Not Being Set Properly in PHP Script

Im very new in php and try to use cookie but it is not woking in my site, can anyone guide me please , what is going wrong in my code:
<?php
session_start();
?>
<script>
function Redirect(url)
{
location.href = url;
}
</script>
<?php
define('_VALID_ACCESS', true);
include_once "includes/connect.php";
include_once "includes/login.php";
if(empty($_POST['loginname']) || empty($_POST['password']))
{
$msg = "User or password is empty";
}
else
{
if(login($_POST['loginname'], $_POST['password']) == true)
{
$usern = $_POST['loginname'];
session_register('loginname');
$loginname = $usern;
sleep(1);
if(activestatus($_POST['loginname'], $_POST['password']) == true)
{
$usern = $_POST['loginname'];
session_register('loginname');
$loginname = $usern;
sleep(1);
$hour = time() + 3600;
setcookie("ID_my_site", $_POST['loginname'], $hour);
setcookie("Key_my_site", $_POST['password'], $hour);
$test = $_COOKIE["ID_my_site"];
$msg = "<script> Redirect ('home.html?testname=".$test."')</script>";
//header("Location: home.html");
}
else
{
$msg = "<script> Redirect ('valid.php?testname=".$usern."')</script>";
}
}
else
{
$msg = "<font color=red>User or Password is wrong</font>";
}
}
echo '<div id="divTarget">' . $msg . '</div>';
?>
<link rel="stylesheet" href="css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="css/blueprint/print.css" type="text/css" media="print">
<link rel="stylesheet" href="css/blueprint/ie.css" type="text/css" media="screen, projection">
<body>
<div class="container" id="login_container">
<form id="login" action="action.php" method="post" name="loginform" >
<fieldset id="login_screen" style="width:350px">
<label id="login_label" for="login">User Login </label>
<br><br>
<label for="login">Email Address</label>
<input type="text" name="loginname" id="loginname" value="email#coolmates.com">
<p id="space"><label for="password">Password</label>
<input type="password" id="password" name="password" value="********" ></p>
<input type="checkbox">Keep me signed in until i signout
<p id="test"><input type="submit" value="Submit"></p>
<a href="forgetpassword.html">Forgot
your password</a> |<span id="free">Not a member?</span>Sign up<blink><span id="free">Free</span></blink>
</p>
</fieldset>
</form> </div>
</body>
Turn on display_errors and set your error_reporting to E_ALL and you should see an error message about 'headers already sent' - you have to call setcookie() BEFORE ANY HTML IS SENT. From php.net/setcookie:
setcookie() defines a cookie to be
sent along with the rest of the HTTP
headers. Like other headers, cookies
must be sent before any output from
your script (this is a protocol
restriction). This requires that you
place calls to this function prior to
any output, including and
tags as well as any whitespace.
In the code block that you posted this bit:
<script>
function Redirect(url)
{
location.href = url;
}
</script>
Is being output directly to the browser well before you ever attempt to set the cookies.
Your two possibilities would be to use output buffering so that you output everything at the very end or to switch to a method where all of your processing code is executed first in one script and there you set $_SESSION and cookie values and then include a second script at the tail end of the first that contains the code to be output to the browser.
Try this (specifying the root of your site) :
setcookie("ID_my_site", $_POST['loginname'], $hour,'/');
or try this (adding quotes to your loginname) :
setcookie("ID_my_site", "$_POST['loginname']", $hour,'/');
1st you don't need session_register, you can just do.
Since session_register is the preferred method since 4.1.0 and deprecated as of PHP 5.3
$_SESSION["loginname"] = $_POST["loginname"]
2nd if you are going to use sessions, your flow could be better, since this does not work.
$_SESSION["foo"] = 1;
header("Location: stuff.php");
Then you can't view the session data in stuff.php. You could either send the user to the main page, and do the authentication there, and if it passes then you just continue on with the loading of the main page, and if it doesn't, then you send the user back to the login page like this.
if($_SESSION["authenticated"] == 0)
{
header("Location: login.php");
die();
}
Also you should not be storing a password is cookie data -- this is a big security No-No!!!
If you want to do something like that set a unique - random - identifier that changes when they login and use that instead (you should still MD5 it)

Categories