Why PHP_SELF Should Be Avoided When Creating Website Links

When looking for articles about PHP_SELF, it seems like most only refer to the dangers of using the variable with HTML forms. However, there are risks with using it in other parts of a website. For example, it may be tempting to use the variable within the href attribute for links. The problem is that those links become susceptible to Cross-Site Scripting (XSS). Let's take a closer look at the security vulnerability of PHP_SELF and a simple alternative to avoid the problem altogether.

Video Length: 0:03:18

Purpose of PHP_SELF

For those unfamiliar, PHP_SELF is a server variable typically used in PHP scripts to link one page to itself. For example, a page may initially display a list of products with links for viewing more information about each item. If a link is clicked, an ID is passed to the same page for displaying the product details.

The Problem

As shown in the video, using PHP_SELF for links isn't recommended due to being vulnerable to Cross-Site Scripting (XSS). For example, let's say our page (http://www.example.com/products.php) utilizes the server variable. We can visit the page with Firefox and start injecting code. Note that some browsers, like Internet Explorer, block XSS activity.

If our anchor tag looks like

<a href="<?php print $_SERVER['PHP_SELF']; ?>?view=1">View More Info</a>

We can hack the URL by

  1. Adding a forward slash ("/") to make Firefox think there's another folder
  2. Typing a double quote to close the href attribute
  3. Creating an onmouseover event to redirect visitors somewhere else

The new URL looks like

http://www.example.com/products.php/" onmouseover="window.location="http://www.google.com/"'

On the surface, the link shouldn't look any different. But the source code, on the other hand, shows that the onmouseover event is now part of the link (see Figure 1).

Screenshot showing the source code after the XSS attempt
Figure 1. Source Code Showing the Event Trigger

Alternate Solution

Instead of using PHP_SELF for links, it's just as easy to use the page's file name instead. Since our script was named "products.php", the anchor tag would be changed to

<a href="products.php?view=1">View More Info</a>

Conclusion

Although PHP_SELF seems like a useful option when creating links that lead to the same page, the security risk involved with the variable isn't worth it—especially when the alternative is so simple.

9 Comments

  • #1 Reply via Twitter on 03.13.12 at 8:14 am

    Comment from @john_j_owens via Twitter:

    @pnichman I used PHP_SELF when I was developing in CodeIgniter. It was to help me find paths for CSS and script files. Needs a review!

  • #2 Patrick Nichols on 03.13.12 at 8:26 am

    @john_j_owens – I would love to hear what you find out. Good luck.

  • #3 Reply via Twitter on 03.13.12 at 10:42 pm

    Comment from @MichaelPierre via Twitter:

    "@pnichman: @MichaelPierre – Thanks for the RT by the way." (Np. I used PHP_SELF in some code snippets recently. Your post was helpful.)

  • #4 Patrick Nichols on 03.14.12 at 5:24 am

    Awesome, I appreciate the feedback. “@MichaelPierre: Np. I used PHP_SELF in some code snippets recently. Your post was helpful.”

  • #5 Rob on 12.14.12 at 12:11 pm

    Or use the following:

    $php_self = filter_var($_SERVER['PHP_SELF'], FILTER_SANITIZE_STRING);

  • #6 Conal on 06.24.13 at 3:05 pm

    Interesting article.

    So, if I understand this right instead of saying $_SERVER['PHP_SELF'] I can simply type thisisthesamefile.php and it won't have the same XSS vulnerabilities?

  • #7 Patrick Nichols on 06.26.13 at 10:42 pm

    @Conal – That is correct.

  • #8 Stefan on 08.25.15 at 8:18 am

    Thank you for a helpful and interesting article, but I have a question. Are there any security risks involved in using PHP_SELF aside from those mentioned? I use it to concatenate variables in order to generate a URL for a file to be loaded. Does this pose any security risks?

  • #9 Patrick Nichols on 08.27.15 at 5:23 pm

    @Stefan – I imagine that it depends on how the variables are used. Do you use the full value from PHP_SELF…or do you extract a portion of the value?

    Is there a way you can check PHP_SELF to make sure it can only contain a valid value? For example, are all the possible variable names defined somewhere? If so, you could check that the concatenated variable (the one created with PHP_SELF) exists before using it.

Leave a Comment