Question

I have a form with this code:

<form action="/directory/" method="POST" target="_blank">
<input name="hello" type="hidden" value="something"/>
<input name="there" type="hidden" value="something"/>

Inside the /directory/ folder, I've placed an index.php file that would process the form, with this sort of code:

<?php 

if(isset($_POST['hello']));

switch ($_POST['hello']) {

    case "1":
        $var1 = "word1";
        break;

    case "2":
        $var1 = "word2";
        break;

    default:
        $var1 = "other";
}
?>

<?php 

if(isset($_POST['there']));

switch ($_POST['there']) {

    case "1":
        $var2 = "word3";
        break;

    case "2":
        $var2 = "word4";
        break;

    default:
        $var2 = "other";
}
?>   
<!doctype html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div>
Content, <?php echo $var1; ?>, Content, <?php echo $var2; ?>, Content.
</div>
</body>
</html>

But I don't want a curious user to be able to go directly to mydomain.com/directory/ and see the output of index.php, unless he got there through the form.

So how do I either hide/make index.php inaccessible, or maybe change something in the .php, while keeping more or less the action="/directory/" tag, the same?

What are the best possible practices?

Was it helpful?

Solution

But I don't want a curious user to be able to go directly to mydomain.com/directory/ and see the output of index.php, unless he got there through the form.

I don't think you understand how HTTP requests work. When the user submits the form, they didn't necessarily get there through the form. They're just submitting a POST request to a particular resource (in this case, /directory/index.php). In order for that resource to accept POST requests from users, they need to be able to access it.

All the form does is provide the user with information about what that resource expects in a POST request, such as the values it's looking for. But such a request can also be made manually, the server doesn't know the difference. You can restrict access to that resource to be only POST requests if you'd like. One way to accomplish that might be to have the page check for the existence of $_POST[] and make sure it has the values it expects (which you kind of do already).

If you want to ensure that users must first request the form and only then perform the POST request then you'll probably need to track that statefulness in some way. One approach is to provide a unique token as part of the form. A GUID in a hidden form field works well for this. When you display the form, you would track in your database the token that was generated (maybe even assign a time stamp to it so it can expire). Then in your POST handler page you'd compare the submitted token against known tokens from the database, displaying an error if it doesn't match. This would allow you to reject POST requests which don't contain a known token, requiring the user to first request the form before performing the POST.


In response to comments below, you can return an error instead of displaying content if some precondition of the page fails. This could be something as simple as:

<?php
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
?>
    <p>This is an error message.</p>
<?php
    } else {

?>
    <p>This is the normal page content.</p>
<?php
    }
?>

There are lots of different ways to organize that. Maybe end the response instead of putting the rest in an else block? My PHP is a bit rusty, but you should be able to figure something out. You can even just return an HTTP error code and let the user figure it out:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        header('HTTP/1.1 500 Internal Server Error');
    } else {
?>
    <p>This is the normal page content.</p>
<?php
    }
?>

There are lots of HTTP error codes to choose from for this. Ultimately the logic and layout is whatever you'd like it to be. You control what content is displayed to the user and the logical conditions under which that content is displayed.

OTHER TIPS

You should look into htaccess restrictions, visit this link :

http://www.javascriptkit.com/howto/htaccess.shtml

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top