0

I have a simple form for a back button that is supposed to take the PHP $_SERVER['HTTP_REFERER'] and use that as the action for the button.

    <?php
        echo "<form class='BackButton' action='" . $_SERVER['HTTP_REFERER'] . "'>";
        echo "<input type='submit' class='button' value='Back' />";
        echo "</form>";
    ?>

When I navigate to the page with this button and hover over the button it has the correct action='http://engsys.corp.ftr.com//MaterialTracking_Filtered_State.php?search=in' Then when I click the button it drops the ?search=in and so the page that comes up isn't correct.

Why does it do this? I thought since it's in the action that it wouild all be sent?

Mike
  • 1,853
  • 3
  • 45
  • 75
  • 2
    This form could be XSS injected. See http://stackoverflow.com/questions/5934747/is-serverhttp-referer-safe – chris85 Jul 22 '16 at 14:54
  • Try method="POST" so you don't overwrite GET variables. This however has other implications. – apokryfos Jul 22 '16 at 15:03
  • @chris85 This is an intranet site used only by a few people. This should be safe as none of them are programmers. – Mike Jul 22 '16 at 15:10
  • It looks like a lot of trouble to go though just to implement something that can be done with JavaScript in like `history.go(-1)` – apokryfos Jul 22 '16 at 15:12
  • 1
    @Mike: What's your point? It doesn't matter if it's an intranet site or some people that don't currently have programming experience or access to Google are the only one's using it. Your site is still vulnerable to XSS and that's never a good thing. Regardless of whether it is internal or who is using it, you should ALWAYS be developing securely and smartly. – Trojan404 Jul 22 '16 at 15:30

1 Answers1

5

When you submit a for with method="GET" (which is the default) the existing query string will be replaced.

To preserve it: generate hidden inputs to copy the values across.

For example (and this can't handle array values in the query string):

<?php
$referer = "http://engsys.corp.ftr.com//MaterialTracking_Filtered_State.php?search=in";
$url = parse_url($referer);
parse_str($url['query'], $query);
?>

<form action="<?= htmlspecialchars($url['scheme']); ?>://<?= htmlspecialchars($url['host']); ?><?= htmlspecialchars($url['path']); ?>">
<?php  foreach ($query as $key => $value) { ?>
<input type="hidden" name="<?= htmlspecialchars($key); ?>" value="<?= htmlspecialchars($value); ?>">
<?php } ?>
<input type='submit' class='button' value='Back' />
</form>

That said, and having reread the question: You aren't collecting any user data, so you shouldn't be using a form.

Essentially you are generating a link, so use a link:

<a href="<?=htmlspecialchars($_SERVER['HTTP_REFERER']);?>">Back</a>

… but even that isn't a great idea. The Referer header is optional, and the button or link won't take them back. It will take them forward to a previous URL (with all the implications you might expect for the browser history list).

Browsers come with a built-in back button that works the same way everywhere. You can simply let them use that.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335