Who sent you? - php

I have a series of input forms, all of them take a different form action. Each of those validates input. If ok, they go to different success pages. If fail, I want the form action/validation pages to set $_SESSION['error_messages'] and go to a common page which displays the errors and has a "resubmit" button.
Question ... how to get error form the resubmit button back to one of many possible input forms?
Edit: I don't see how $_SERVER['HTTP_REFERER'] is going to work. Again: form --> validation --> error_page
So, I guess that validation has to set a session variable from $_SERVER['HTTP_REFERER']

USing HTTP_REFERER is an option, but possibly not the most viable one, as the referrer header is easily spoofable (and not all the browsers will send it). This may or may not interfere with your process.
The easiest thing to do, as you are already setting error messages in $_SESSION is to also add a $_SESSION['redirect_url'] value.

Using $_SERVER['HTTP_REFERER'].
But, as per http://php.net/manual/en/reserved.variables.server.php
The address of the page (if any)
which referred the user agent to the
current page. This is set by the user
agent. Not all user agents will set
this, and some provide the ability to
modify HTTP_REFERER as a feature. In
short, it cannot really be trusted.
So, like Neal Donnan has suggested, passing the module_name in a hidden field and then resubmitting to http://project/'.$_POST['module_name'] would be best

You can use the HTTP_REFERER header, but this is not always reliable as the browser needs to set this.
A more reliable way would be to set a hidden field in each form with the url to redirect back to.

I'm assuming that you're using the same script, if not please post your code:
Input page:
<?php
/* this is the form page header */
/* parsing & filtering input */
if( my_form_is_valid($input_data) )
give_the_answer();
else
header('Location:' . $_POST['request_uri'] . '&status=error'); //make sure that's the first output
/* follow the DOM */
?>
<form id="myform">
<!-- some fields -->
<input type="hidden" name="request_uri" id="request_uri" value=<?=$_SERVER['REQUEST_URI']; ?>" />
</form>

Related

Use PHP to track links

I have various links in my website that point to a specific form.
Whenever someone fills out the form, I want to be able to know what link led them to the form.
I want to do this without having to create an individual line of PHP code for every link I create in the. Instead, I want to have some PHP code that picks up something from that link, and maybe inserts it into a hidden text box that gets its value or text from something that I tag in the link.
For example:
User clicks a link.
That link directs them to a form.
The link carries an identification that activates PHP code
When I recieve the form, I know what link was clicked to get to that form.
I want it to work with links in emails I send out as well.
Based on the information in your post, it sounds like you just want to send a token/ id.
Goto Form
Now on the form you can grab the token:
$token = $_GET['token']; // use proper testing first
Then use a switch or if statements to run whichever code you need.
<input type="hidden" value="<?php echo $token; ?>">
Additional:
As the //use proper testing first comment indicates, you should make sure the token being passed is valid and sanitized in case of attack. One option is to have tokens stored in a database when generated and then compared when validating. Also look into htmlspecialchars() and even strip_tags() for sanitizing.
If the token fails to validate, you should not output and should even have a warning message/redirect that there was an error.
You can use HTTP Referer to achieve this. In PHP, you can use
$referer = $_SERVER['HTTP_REFERER']
Use this for example :
if (isset($_SERVER['HTTP_REFERER']))
{
$ref = $_SERVER['HTTP_REFERER'];
}
then in your form something like:
<input type="hidden" value="<?php echo htmlspecialchars($ref, ENT_QUOTES); ?>" name="ref" />

php navigation validation

How to check if the user has entered the page by clicking on the button and not from copy pasting the URL ?
For example, if a user has clicked on Register I want him/her to go to that page only by clicking the Register button and not by copy pasting the link.
Also, is it a good practice to give the page name on the address bar or should I have to hide the page. If I am hiding the page will I be able to do that ?
For example, if localhost/projname/register.php. I don't want people to see the register or login or about or anything on the address bar except localhost/projname.
Maybe check if he used $_POST, something like:
<?php
if($_SERVER['REQUEST_METHOD'] == "POST"){
// do ya thing
}
else
{
?>
<form action="index.php" method="post">
are you sure? <input type="submit" value="yes">
</form>
<?php
}
?>
You can use the HTTP_REFERER data of the $_SERVER reserved variable to see where did the user come from.
if(empty($_SERVER['HTTP_REFERER'])) {
// if we are here, the user copy pasted the url.
}
As for your second question, you can't totally "hide the page" like you're suggesting. The web server must know which page to show, so the browser must know has well.
You can however obfuscate the page name. For example you can call the page "sfhjgdjkfg" so the user won't be able to know that this is the "registering" page. But I think it's really a bad idea, why in the first place want you to hide this ?
One method is to use $_SERVER['HTTP_REFERER'] to verify that they clicked a link from your site, but this method isn't fool-proof as many Firewall and Anti-virus suites will remove the Referrer information.
A better method would be to generate a temporary session token on the pages of your site, and check for that token when the Register page is opened.
If your form uses POST parameters, the browser will pass on some POST data. You could then check
if (empty($_POST)) {
//didn't click the button, just went straight to the url
}else{
//did click the button
}

Secure solution to hidden forms

I have this code:
<? if ($cur_post['poster_id'] == $forum_user['id']) { ?>
<div class="txt-box textarea required">
<label for="fld<?php echo ++ $forum_page['fld_count'] ?>"><span><?php echo $lang_post['Write message'] ?> <em><?php echo $lang_common['Required'] ?></em></span></label>
<div class="txt-input"><span class="fld-input"><textarea id="fld<?php echo $forum_page['fld_count'] ?>" name="req_message" rows="14" cols="95"><?php echo forum_htmlencode(isset($_POST['req_message']) ? $message : $cur_post['message']) ?></textarea></span></div>
</div>
</div>
<? }
else { ?>
<? } ?>
I need a more secure solution to hidden forms, because currently with this code when I press submit (as an admin) it says I must enter a value for the written message.
I can bypass this using hidden forms under the ELSE bit - but people with any knowledge can just bypass this using Inspect Element or Firebug and then post that value.
I need a more secure solution to this, so that people cannot edit Hidden forms. Do I post the old variable somehow to the form?
It's for a PunBB page (edit.php): http://punbb.informer.com/svn/punbb/tags/punbb-1.3.3/edit.php (original).
Thanks
This is always an interesting problem.
I suggest storing private data in the users $_SESSION with an index unique to the form + page call. I just came into a similar problem at work where I was starting to pass way too much private data through hidden form fields. Now I simply pass a unique id which I use to index the specific private form data in the session.
It's not a 100% solution. Storing the data in the session rather than in the form means a stale form can timeout (ie if the session is killed/timed out), but it's a worth while trade off I think.
I'm not entirely sure I understand the question. Are you trying to control how the form renders, or trying to figure out how to add 'sensitive' data the a form?
First, if you're worried about what parts of the form are being rendered on the page, anything in the else clause would only render if the conditions in the if clause were not true. The else is not 'hiding' part of the form.
Second, there is no such thing as a 'secure' client-side form. Generally speaking, you cannot control what data is submitted to your application, and anyone can submit any POST or GET data they want. Instead you have to handle it on the server-side by properly filtering to ensure that a user has the proper authorization to do what they're trying to do. It sounds like you need to require the user to identify as an admin when the form is processed (most likely through session data).

Refreshing page will re-send form data, is it possible to prevent this? (PHP)

I'm creating a form and using it to get data input to send to a MySQL database via php. If someone hits refresh on the page Firefox ressends the last set of information to the php page which in turn sends it to the database. Is there anyway to prevent this?
To fix that problem, there exists Post/Redirect/Get pattern you need to follow :)
Post/Redirect/Get (PRG) is a common
design pattern for web developers to
help avoid certain duplicate form
submissions and allow user agents to
behave more intuitively with bookmarks
and the refresh button.
You need to do a redirect to the same page:
$current_url = (empty($_SERVER['HTTPS']) ? "http://" : "https://") . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header ('Location: ' . $current_url);
exit ();
The usual way to do this is to use a redirect.
You get the request, use the data it contains to load your database or whatever, and then perform a redirect (I think you're supposed to use a 303 redirect for this, but I've heard of a lot of people using 302s to avoid certain browser glitches).
The net effect of this is that there was no POST data sent when the redirect occurred, so refreshing can't cause it to be resent and screw up your application/database.
If you don't like any of the above and are using JQUERY. You could do a simple load or ajax function to send the information to your script.
This will erase any chance of duplicate sending and you no page reload. I like this method best, it's fast and easy.
Another solution you can do is have your form send to another page, a bit like this:
<form action="chat_server.php" method="post">
Message: <input type="text" name="message" />
<input type="submit" />
</form>
On the chat_server.php file, you do what you need to do with the data and at the end, you do
echo '<meta http-equiv="REFRESH" content="0; url=chat.php" />';
Give it a try, should get rid of your problem.
Yes. After inserting data you do a redirect.
use a code in a hidden input and this code getting by a table codes for exmaple and if the code sending remove it from database and if the code not set in the table dont accept the query

What happens if you go to a GET style url with a POST request?

Let's say I have a page called display.php and the user is viewing display.php?page=3. I want to allow the user to do an action like voting via a POST request and then bring them back to the page they were on. So, If I do a POST request to display.php?page=3 would the page information also be available to the script?
The simple answer is 'yes'. You can use a GET-style URL as the submission URL for a POST form. PHP will have both the POST and GET information available to it in the usual ways when the form is submitted.
This is not to say that you should do this, but it will work.
In PHP, you can get request variables from the special global arrays:
$_GET['page'] (for GET requests)
$_POST['page'] (for POST requests)
$_REQUEST['page'] (for either)
It sounds like you are looking for "Redirect after Post", I would suggest separating display.php and vote.php into separate files. Vote looks something like this:
<?php
//vote.php
$page_number = (int)$_REQUEST['page'];
vote_for_page($page_number); //your voting logic
header('Location: display.php?page=' . $page_number); //return to display.php
Note that blindly accepting unsanitized form data can be hazardous to your app.
Edit: Some folks consider it bad form to use $_REQUEST to handle both cases. The hazard is that you may want to signal an error if you receive a GET when you expect a POST. Typically GET is reserved for viewing and POST is reserved for making changes (create/update/delete operations). Whether this is really a problem depends on your application.
Yes, the GET array is always filled with the URL parameters regardless of the request method. You can try it with a simple page like this:
<form action="test.php?a=b" method="post">
<input name="a"/>
<input type="submit"/>
</form>
<pre>
POST:
<?php print_r($_POST); ?>
GET:
<?php print_r($_GET); ?>
</pre>

Categories