Redirect to new URL safely using PHP

时间:2015-07-31 19:40:50

标签: php

I've got a contact form that currently reloads the root page after sending an email.

header('location: /?message=success');

This works just fine, although I'd now like it to go to the page URL stored in $_POST['contact_page']. However, using something like the following code doesn't seem like good practice:

header('location: http://'.$_POST['contact_page'].'?message=success');

My main concern is that someone could change the URL to something nefarious and then this command would execute it. (Also, with the message argument in the new URL, repeatedly running this code will cause more and more instances of the same argument to be added to the end.)

My question: what's a safe way to redirect the user to $_POST['contact_page'] using header (with an argument or two included, like message above)?

EDIT: The page variable was originally made using this code, $_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"], and ends up in the form www.mysite.com/whatever-page&maybe_some=leftover_arguments

4 个答案:

答案 0 :(得分:2)

You must make a whitelist of what's allowed in your $_POST variable.

The previous answer by LuckyBurger can be incorrect if your PHP is <5.1.2 since it was allowed to send multiple headers with newline.

答案 1 :(得分:1)

header('location: /'.$_POST['contact_page'].'?message=success');

to

header('location: http://www.yourdomain.com/'.$_POST['contact_page'].'?message=success');

答案 2 :(得分:1)

A better solution would be to just send the ID of your blog article in the form, and then translate that into a URL. Don't actually use this code, it's more an illustration:

HTML

<form>
  <input type='hidden' name='blog_id' value='3'>
</form>

PHP

<?php

// do your form processing

$blogId = $_POST['blog_id'];

// query the database to get the blog post slug/URL
// (this is just an example, don't actually put POST vars directly into queries)
$query = "SELECT p.slug, p.url FROM my_blog_posts p WHERE p.id={$blogId}";
$result = executeMyQuery($query);

$postSlug = $result['slug'];
// OR
$postUrl = $result['url'];

header("location: http://www.yourdomain.com/{$postSlug}?message=success");
// OR
header("location: http://www.yourdomain.com/{$postUrl}");

答案 3 :(得分:0)

因为这些链接可以转到帖子或网页 - 网站域名中的任何内容 - 并且允许链接列表将一直在增长,所以我采用了以下方法。它确保重定向中包含的唯一参数的格式为&#34; page_id&#34;并修剪其他任何东西。

$page_url=$_POST['contact_page'];     // The URL to redirect to
$url_root=strtok($page_url,"?");    // Everything before the PHP arguments
$url_arg1=strtok("&")."&";          // The first argument
$ok_arg="page_id=";                 
if (strncmp($ok_arg,$url_arg1,strlen($ok_arg))!=0){ // Ditch first argument if not a page/post ID
    $url_arg1="";
}
header('location: http://'.$url_root.'?'.$url_arg1.'message=success');