Function still executes from link without active session - php

I got some code that executes with value's inside a $_GET and some code that checks for an active session. Yet, when I go to the link directly without active session it still executes the function and after that returns to the login page.
My code:
My loginheader:
<?php
session_start();
if (!isset($_SESSION['Username'])|| $_SESSION["Actief"] == 0||
$_SESSION["Actief"] == 2) {
return header("Location: main_login.php");
exit();
}
My webpage (only the needed code):
require "../loginheader.php";
require "../AdminOnlyHeader.php";
// --some code with sql instructions--
$result = ExecuteQuery($sql);`
AdminOnlyHeader is just to check for admin status. This too seems to be bypassed by just entering a link.
So if you still don't understand what I mean, here's a short summary of what I do:
I make one of those links that contain the get data needed to execute it;
I log out and get returned to the login page;
I enter the the link I made before;
After some loading I am still on the login page but when I look at my database I see that the record has been updated and thus the function (ExecuteQuery) was executed.

Remove return from
return header("Location: main_login.php");
We need two references to understand this:
Return part:
If called from the global scope, then execution of the current script file is ended. If the current script file was included or required, then control is passed back to the calling file.
Header part:
If you redirect but you don't die() / exit() the code is always executed and displayed.
Basically, since you returned, it won't reach the exit() part, meaning that it will return the execution to the main script - the one with the function that shouldn't be executed in this circumstance.

Related

Cookies should be set if specified cookie is not set, yet code ALWAYS creates new cookies

I want a script that firsts verifies that $_COOKIE['location'] is set. If $_COOKIE['location'] is not set, I want to save the entrance URL into $_COOKIE['EntryURL'] and set $_COOKIE['location'] to 'TRANS' while redirecting user to enter their zip or manually select their location.
So I have generated the following PHP:
if(!isset($_COOKIE['location'])) {
$EntryURL = $_SERVER['REQUEST_URI'];
if($EntryURL == '/') {
$EntryURL = '/index.php?pg=Home';
}
setcookie('EntryURL', $EntryURL);
setcookie('location', 'TRANS');
header("Location: MYSITE/index.php?pg=" . urlencode('Please Select Your Location'));
}
The problem that I am encountering, however, is that all of this code is being executed with or without $_COOKIE['location'] being set. The page opens, sees $_COOKIE['location'] is not set, sets $_COOKIE['EntryURL'] and sets $_COOKIE['location'] and properly redirects.
However, on the redirect page (which is included from the index, meaning that the same code will be called again) it STILL executes the same script, generating a second cookie for each and prevents the redirect code on my location query page from working properly (as it is accessing the $_COOKIE['EntryURL'] which has been rewritten, rather generated again as it is saved twice, to reflect the $_SERVER['REQUEST_URI'] from the location page.
I CANNOT understand how it is possible to execute this code block with or without location cookie being set. Hopefully I am doing something stupid that someone can quickly identify.

redirection without reloading the whole page

I have a framework and I think I'm following something like the MVC pattern: A framework (the model) an index page that controls the input (the controller) and the views pages (that are included inside main.php/the main html)
I read a lot about structure and logics, to write a good application. I read many comments like "Why are you outputting anything if all you are going to do is try and redirect the user to another page?". Well the answer is, the most common case: redirect after the user successfully logged in. Do I need to print something? Of course, the whole main page with a login form/post. How I'm supposed to do that redirection??
So I'm a bit confused about logics and structure of the application. How do you store all the output and do the header redirection without printing anything?
I was thinking about using javascript to do the redirection but I also read comments saying; "if you write good code (following a good logic/structre), you won't need to use hacks like javascript redirection". How is that even possible?
Because the php output_buffering should not be enabled.
I have the output_buffering enabled, and I can use header (after output) without any problem. If I use the javascript redirection the whole page reloads, but using header it just loads the content (the views content that are included in main.php).
So how do you do this without output_buffering?
If you want to redirect to a success page AND pass messages - say, after a successful login - an easy solution is to use "flash" sessions, where you store a message in a SESSION and then, as soon as it's used, you discard it. You don't need to sore anything in the output buffer for this.
This is a very basic example, but should give you the gist of it.
login.php
if($login_successful) {
// put your message in the session
$_SESSION['message'] = 'Login Successful';
// redirect to the success page
header('location: success.php');
}
success.php
<?php
session_start();
// check if $_SESSION['message'] exists
if(isset($_SESSION['message'])) {
// print the message
echo $_SESSION['message'];
// clear the session
$_SESSION['message'] = null;
}
Looks like you are mixing up some things here. What you are talking about are actually two different requests. Either the user wants to view the main page, or he wants to log in using that form on your main page. In your index.php you would have something like this (pseudocode):
if (isLoginRequest) {
// user wants to log in
if( validateLogin($loginFormData) ) {
redirect('successful');
} else {
displayLoginError();
}
} else {
// user wants to view main page
echo main.html
}
Update to answer the question in the comments: The better alternative would be to leave your form validation stuff in login.php and refer to that in your login form <form action="login.php" .... Then in your login.php you would have something like this:
if (loginSuccessful) {
redirect('success.php');
// no need to call die() or whatever
} else {
setFlashMessage('Login failed'); // set a flash message like timgavin described
redirect('index.php')
// also no die() or whatever
}
index.php then is responsible to display your main page and, if set, rendering the flash message from a failed login attempt.
Simple solution: Move the login post script from login.php to another file (login_post.php). The same for other scripts using header() after dom output. (no need to change the form action="")
In index.php:
$url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
//some more security checks like esc_url() (non-php function)
if ($url == '/login') {
include('header_pages/login_post.php');
}
// all these includes before including main.php
// where views pages are included and the DOM output starts
Since header() is inside the post script, no more headers already sent errors (And output_buffering off, of course).
Same for logout page that is currently being included inside main.php
Thanks to the other answers, they helped me finding this solution.

Tracking cached redirects in database (database not initialized when redirected)

I am looking for a way to serve cached redirects (via filesystem). So I would have a /cache/ folder with files like "google.txt" and using file_put_contents() insert 'http://www.google.com' into the 'google.txt' file.
The problem is that I want to actually track the ip's, views, etc.. in the database, but I want to redirect the user as quickly as possible. So I have created a simple flag function to be used. Here is some pseudocode to better illustrate:
if redirect_is_cached() //True if google.txt exists
redirect_to_link() //actual redirect header(location:...)
user_was_redirected_via_cache(TRUE) //STATIC: defaults to FALSE if no parameter is used.
//No exit because I want to track data but database isn't loaded.
...
code snipped out...later on in the script.
...
db_connect(); //Now we can access the database
if(user_was_redirected_via_cache()) { //TRUE since we flagged it earlier.
track_redirect();
exit();// Proper exit. We redirect user quickly,
// but continue script so we can track redirect.
}
else { continue with rest of script }
My questions are 1) does this follow "best practices" or is it kind of hackish? and 2) Does the user start getting redirected at the header() or the exit()? If the user doesn't start getting redirected until I actually exit() the script...this is kind of pointless.
Thanks for the help.

Redirecting Pages with PHP causing problems

I have a page which has a link to a php page which takes data from $_GET and updates a database. After that it returns the user to the homepage with:
header("Location: http://localhost/");
The thing is that this seems to "interrupt" the mysql part of the code. If I remove this redirect, everything in the database is updated, but when I put it back, nothing gets updated...
This is the database update code, I am using a class of mine as a mysql wrapper:
$conn->where('hash',$data1['hash']);
$conn->update(TABLE_ITEMS,$newData1);
$conn->where('hash',$data2['hash']);
$conn->update(TABLE_ITEMS,$newData2);
Notes:
-There is no text or echo()'s on the page and no space before the <?php tag
Order of Code:
Data received from $_SESSION and $_GET
Data processed and placed into arrays
Data placed into mysql database
header(); used to redirect page
Code
<?php
require_once('config.php');
import();
if ( isset ( $_GET['g'] ) && isset ( $_SESSION['itemA'] ) && isset ( $_SESSION['itemB'] ) ) {
$itemA = $_SESSION['gameA'];
$itemB = $_SESSION['gameB'];
$newData1 = processData($itemA);
$newData2 = processData($itemB);
$conn->update(TABLE_ITEMS,$newData1);
$conn->update(TABLE_ITEMS,$newData2);
header('Location: http://localhost/');
} else {
header('Location: http://localhost/');
}
If you send a header when previously content is outputted, you will get an error that may cause your script to stop execution. So if the header is above the update, the update may not be executed at all. It depends on your settings whether you see this error or not.
<?
echo 'yo';
header('Location: ....'); // <-- error
Update(); // Never gets executed
The output doesn't have to be an echo. It can even be a single space before the opening <?.
Without seeing much of the code, it's hard to be certain, but my guess would be that the PHP page is continuing to work exactly at it was before. What I would suggest might be happening is that the redirected page (ie your home page) is itself doing some database work which is overwriting the changes that had been done by the original page.
As I say, that's quite a wild guess in the absence of any more code (or even any detail about the data in question or what the site does), but I'd say it's worth investigating that possibility.
Try putting ob_start() at the top of the file. It sometimes helps. You can't output before calling header().
Show more code. It's to less of it to think what is wrong.
I have no idea why this worked, but it turned out that if I change this:
header("Location: http://localhost/");
to this:
header('Location: http://localhost/');
everything works. Weird!!

Strange problem with PHP and sessions

So the basis of this page is I set a session value when the page loads, and clear it on any other page they visit. Then the page can make an ajax call to download a file. If the session value matches the value I pass through the URL I allow them to download the file. If not I return a 404 error. I was having some weird issues, so I removed the 404 and set it to echo out the values instead to see what I was getting. Here is the top of the code on the page:
$code = $this->_request->getParam('code');
$confirm = $_SESSION['mp3_code'];
echo $code."-1-".$confirm;
if($code != $confirm)
echo $code."-2-".$confirm;//header("HTTP/1.1 404 Not Found");
else
{
Here is what displays on the page from the ajax call
12723430-1-12723430-2-
As you can see when it echos out the first time they exist, then somehow after I compare them and it fails you see that it echos out blank values like they suddenly ceased to exist. Any ideas?
It is imperative that you make sure to call session_start at the top of any script using sessions. I think this may be the case here.
In your code, it's echoing $code and $confirm. But $confirm is an empty string since you are not actually retrieving the session data (why has yet to be determined), the condition will most of the time evaluate to TRUE.

Categories