7
\$\begingroup\$

I made a program to read the source code from a url. To reach this url I need to specify a token. After read the source code, I extract a url in json format, andIi redirect my domain to this url. It's not relevant to what I'm asking, but I want explain what I'm doing.

As you can see, on my domain http://localhost/test, I have a query string called token that is used to read the source code of a different domain. After this I redirect to a page.

I defined the domain which I will read the source code but I don't know if someone could pass a value to the $_GET['token'] in a way that this will go to a different domain. I'm reading the source code from a url and using the result on my website, so I don't know if someone could do some kind of attack to my server. I'm not sure how these kind of attacks works, and I felt that I should ask someone that has more knowledge than I.

What do you think about my code?

php:

 //i use this condition to make sure that nobody can access the url directly,
 //and later make sure that the request is from my domain
    if(!empty($_SERVER['HTTP_REFERER'])){
        //if $_GET[] is empty then $.. is = NULL, else $.. is = $_GET[] 
        $source = (empty($_GET['source']) ? NULL : $_GET['source']);
        $token = (empty($_GET['token']) ? NULL : $_GET['token']);

        if(!empty($source) && !empty($token)){
            if($source == 'player'){
                //check if the request is from the same domain
                if(preg_match('/^http:\/\/localhost\/test/', $_SERVER['HTTP_REFERER'])){ 
                    //inside this if() i read the source
                    //code from this url bellow
                    $urlPost = 'https://www.player.com/?token='.$token;
                    $url = file_get_contents($urlPost);
                    preg_match('/CONFIG = (.*)/', $url, $matches);

                    $jsn =  json_decode($matches[1]);
                    $streams = $jsn->streams;

                    foreach($streams as $i){
                        //this variable will be used to redirect the src 
                        //iframe to a url that contains a video
                        $vdUrl = $i->url; 
                    }
                    //redirect to the url that i got from the source code
                    die(header('location:'.$vdUrl));
                }else{
                    //if the request is not from the same domain then 
                    //redirect to 404 Not Found
                    die(header('HTTP/1.1 404 Not Found'));
                }
            }else{
                die(header('HTTP/1.1 404 Not Found'));
            }
        }

    }

html:

<iframe src="http://localhost/test/?source=player&token=145215d1ww"></iframe>
\$\endgroup\$
9
\$\begingroup\$

The Security

The main point here is your assumption that HTTP_REFERER could prevent someone from using this code. Unfortunately it doesn't. Referrer, just like any other HTTP header, is easily faked, one is setting it routinely with any software that is doing HTTP requests. So be advised that it is an ostrich-style defense.

You should understand that there is absolutely no way to protect the information which is shown in the browser. The only way to restrict an access to a script is to make it password protected.

Moreover, I suppose that a concerned user could easily guess the domain from which you are requesting the data, and then just bluntly take the token from the source of your page and then just use it at their own disposal. Consider storing the token inside your PHP code instead.

The code.

That said, your code could be syntactically improved as well. First of all, just like it said in the other answer, you could combine all conditions in one. But it mustn't be done at the expense of readability. So first define your conditions and then check them at once.

After that you could just write your code without any conditions. A loop is unnecessary if there is only one value in the array

$referrer = $_SERVER['HTTP_REFERER'] ?? '';
$access = preg_match('!^http://localhost/test!', $referrer);
$token = $_GET['token'] ?? '';
$source = $_GET['source'] ?? '';
$source_ok = $source == 'player';

if (!$referrer || !$access || !$token || !$source || !$source_ok) {
    header('HTTP/1.1 404 Not Found');
    die;
}
$urlPost = 'https://www.player.com/?token='.$token;
$url = file_get_contents($urlPost);
preg_match('/CONFIG = (.*)/', $url, $matches);
$jsn =  json_decode($matches[1]);
$vdUrl = $jsn->streams[0]->url;
header('location:'.$vdUrl);

Note: if $_GET['source'] ?? ''; operator is giving you an error, consider upgrading your PHP version immediately, because it is not supported anymore.

\$\endgroup\$
  • \$\begingroup\$ What is the purpose of this regex? !^http://localhost/test! It's not matching regex101.com/r/QpREDg/1 \$\endgroup\$ – boss Feb 21 at 18:20
3
\$\begingroup\$

not a php expert but I think you might improve your code a bit to make it more clean.

the piece of code:

if($source == 'player'){
   //check if the request is from the same domain
   if(preg_match('/^http:\/\/localhost\/test/', $_SERVER['HTTP_REFERER'])){

       // your code...

   } else {
       die(header('HTTP/1.1 404 Not Found'));
   } 
} else {
  die(header('HTTP/1.1 404 Not Found'));
}

might become simply

if(!$source == 'player' || !preg_match('/^http:\/\/localhost\/test/', $_SERVER['HTTP_REFERER']))
   die(header('HTTP/1.1 404 Not Found'))

//your code here

For your question I would wait for some expert

\$\endgroup\$
  • \$\begingroup\$ Just for your info, no code that couldn't be read (because of scrolling) can be considered simple. \$\endgroup\$ – Your Common Sense Feb 21 at 8:03
  • \$\begingroup\$ Yes i could have combined both conditions into one, thanks for the advice \$\endgroup\$ – boss Feb 21 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.