Pass value via $_GET in include_once

Asked

Viewed 1,940 times

1

I need to pass a value to a page that’s on one include_once, but I don’t know how to solve:

The code I’m using for includes is in the main directory:

<?php
            if (isset($_GET["p"])){
                if (file_exists($_GET["p"])){
                    include_once($_GET["p"]);
                } else {
                    include_once("main.php");
                }
            } else {
                include_once("main.php");
            }
?>

And the page I want to call via $_GET is inside the directory /includes/users/.

The code below does not redirect to page edit.php only recharges the main.php.

echo "<td><a class='uk-button' href='index.php?p=includes/users/edit.php?id=$id'><i class='uk-icon-cog'></i> Edit</a>
                        <a class='uk-button uk-button-danger' href='#'><i class='uk-icon-trash'></i> Delete</a></td>";

What I can’t do is that page edit.php is loaded into include when it is set to ex: index.php?p=includes/users/edit.php?id=25. No parameter to page edit.php charges normally.

I imagine I should add something to the include code, but I haven’t found the solution yet.

  • If that’s what I understand, you can use the function header() to redirect to the page.

  • Who voted as impossible to reproduce or typo at least tried to understand the question?

  • @Brunoaugusto I did not vote and honestly did not understand anything, neither the question nor the answer...

2 answers

2

The problem is that querystrings are key=value pairs and the values of each key are all characters between the equal sign and the multiple argument connector (&), if there is more than one, or the end of the string.

If you debug $_GET['p'] inside the isset() will see that what is coming is not Edit.php and yes Edit.php? id=1

Just replace the second query with the multi-pair connective (&) that will work.

But I still keep a caveat that what you tried to do in that code is extremely dangerous because it could allow it to happen:

arquvo.php?var=http://www.outrosite.com/script_malicioso.php

And your program would run without question.

The least worst to do when working with querystrings is to know in advance the possible values for this variable that will be considered as file to be included and use a path known to you.

There are several ways, but the simplest of all is with conditional N:

if( $_GET['var'] == 'contato' ) {

    $arquivo = 'contato.php';

} else if( $_GET['var'] == 'empresa' ) {

    $arquivo = 'empresa.php';

} else {

    $arquivo = 'main.php';
}

include_once $arquivo;

You can use switches that will make the code relatively larger, but a little more robust or arrays that will make everything smaller at a cost of perfomrance (infímo, but present).

  • Then I’m aware of that risk already. What I can’t do is for the Edit.php page to be loaded into include when it is with parameter ex: index.php? p=includes/users/Edit.php? id=25 Page does not open.

  • +1 as an example of the safety risk

  • @Feliperodrigues you will not be able to pass a $_GET parameter through include. But you can see that it already exists in $_GET because it is interpreted globally. Try using the echo command '<pre>';var_dump($_GET);

  • 1

    There was a small misunderstanding of mine when I answered, now it is corrected.

  • @Brunoaugusto got it! I was using another ? to pass the value. And it was &, did not remember that! I will probably use a switch case as the user Kaminary exemplified.

  • 1

    @Brunoaugusto Reiterating the safety issue: the method file_exists() prevented external pages from being accessed. In this case, I imagine, include would be safe?

  • Yes, but if the attacker injects a file into the server with an exploit, the file will actually exist and include will continue to work quietly.

Show 2 more comments

2

Its code allows severe security failures by allowing the user to freely view any server file.

I recommend you try something like:

<?php
$page = 'main.php';

if (isset($_GET["p"])){
  switch($_GET["p"]){
    case '1':
      $page = 'conteudo.php';
      break;
    case '2':
      $page = 'edit.php';
      break;
  }
}

require_once($page);
?>

The solution is still bad, but it already gives a higher level of security to the application.

Explaining the problem

Imagine that you have a configuration file with the data for access to the database, this file is called example.config;

What would happen if the user passed the parameter to his code in this way: ?p=exemplo.config ??

Your code would include the configuration file and would show in the user’s browser the contents of the file.

  • Thanks @Kaminary, I will use a switch because I find it more organized than if.

  • reiterating the safety issue: the method file_exists() prevented external pages from being accessed. In this case, I imagine include would be safe?

  • @Feliperodrigues external pages yes, but in my example I use a configuration file that is in the server itself. In this case knowing the file path I have free access to it with your code;

  • Ah! Right, got it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.