Note: to follow this post it is assumed that you have minimal programming knowledge in PHP.
This post is about a fragment of PHP code that you may have seen at the top of your favorite CMS or framework and which you have probably read that you should always include, for security, in the header of all the PHP files you develop, although without a very clear explanation of why. I am referring to this code:
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly }
This type of code is very common in WordPress files, although it actually appears in almost all frameworks and CMS. In the case of the CMS Joomla, for example, the only thing that changes is that, instead of ABSPATH, JEXEC is used. Otherwise, the logic is the same. This CMS arose from another one called Mambo, which also used similar code, but with _VALID_MOS as a constant. If we go back even further in time, we will find that the first CMS to use this type of code was PHP-Nuke (considered by some to be the first CMS in PHP).
The execution flow of PHP-Nuke (and most CMS and frameworks today) consisted of sequentially loading several files that, together, responded to the action performed by the user or visitor on the web. That is, imagine a website from that time, under the domain example.net and with this CMS installed. Every time the home page loaded, the system executed a sequence of files in an orderly manner (in this case it is just an example, not a real sequence): index.php => load_modules.php => modules.php. That is, in this sequence, index.php was loaded first, then this script loaded load_modules.php, and this in turn modules.php.
This execution chain did not always start with the first file (index.php). In fact, anyone could skip part of this flow by directly calling one of the other PHP files by its URL (e.g. http://example.net/load_modules.php or http://example.net/modules.php) , which, as we will see, could be dangerous in many cases.
How was this problem resolved? A security measure was introduced, adding codes to the beginning of each file, similar to this:
<?php if (!eregi("modules.php", $HTTP_SERVER_VARS['PHP_SELF'])) { die ("You can't access this file directly..."); }
Basically, this code, located in the header of a file called modules.php, checked to see if modules.php was being accessed directly via the URL. If so, the execution was stopped, displaying the message: "You can't access this file directly...". If $HTTP_SERVER_VARS['PHP_SELF'] did not contain modules.php, then it meant that we were in the normal flow of execution and were allowed to continue.
This code, however, had some limitations. First, the code was different for each file it was inserted into, which added complexity. Additionally, in certain circumstances, PHP did not assign a value to $HTTP_SERVER_VARS['PHP_SELF'], which limited its effectiveness.
So what did the developers do? They replaced all those code fragments with a simpler and more efficient version:
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly }
In this new code, which was already quite common in the PHP community, the existence of a constant was verified. This constant was defined and assigned a value in the first file of the flow (index.php or home.php or some similar file). Therefore, if this constant did not exist in some other file in the stream, it meant that someone had skipped the index.php file and was trying to access another file directly.
Dangers of someone launching a PHP file directly
Surely at this point you are thinking that breaking the chain of execution must be the most serious thing in the world. However, the reality is that, normally, it does not represent a significant danger.
Danger can arise when a PHP error exposes the path to our files. This should not worry us if we have error suppression configured on the server, and, even if the errors were not hidden, the exposed information would be minimal, providing just a few clues to a possible attacker.
It could also happen that someone accesses files that contain fragments of HTML (from views), revealing part of their content. In most cases, this should not be a cause for concern either.
Finally, it could happen that a developer, either due to inattention or lack of experience, inserts dangerous code without external dependency in the middle of an execution flow. This is very unusual, since normally the code of a framework or CMS depends on other classes, functions or external variables for its execution. Therefore, if you try to run a script directly through the URL, it will fail to find these dependencies and will not continue execution.
So why add the constant code if there is hardly any cause for concern? The reason is this: "This method also prevents accidental variable injection via an attack on register globals, preventing the PHP file from assuming it is inside the application when it really is not."
Register globals
Since the beginning of PHP, all variables sent through URLs (GET) or forms (POST) were automatically converted to global. That is, if the file download.php?filepath=/etc/passwd was accessed, in the download.php file (and in those that depended on it in the execution flow) echo $filepath could be used; and the result would be /etc/passwd.
Within download.php, there was no way to tell if the $filepath variable had been created by a previous file in the execution flow or if someone had spoofed it via the URL or with a POST. This generated large security holes. Let's see it with an example, assuming that the download.php file contains the following code:
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly }
The developer probably thought about implementing his code with a Front Controller pattern, that is, making all web requests go through a single input file (index.php, home.php, etc.). This file would be responsible for initializing the session, loading common variables, and finally, redirecting the request to a specific script (in this case download.php) to download the file.
However, an attacker could bypass the planned execution sequence by simply calling download.php?filepath=/etc/passwd as mentioned before. Thus, PHP would automatically create the global variable $filepath with the value /etc/passwd, allowing the attacker to download that file from the system. Serious mistake.
This is just the tip of the iceberg, as even more dangerous attacks could be carried out with minimal effort. For example, in code like the following, which the programmer could have left as an unfinished script:
<?php if (!eregi("modules.php", $HTTP_SERVER_VARS['PHP_SELF'])) { die ("You can't access this file directly..."); }
An attacker could execute any code using a Remote File Inclusion (RFI) attack. Thus, if the attacker created a My.class.php file on his own site https://mysite.net with any code he wanted to execute, he could call the vulnerable script by passing it his domain: codigo_inutil.php?base_path=https:// mysite.net, and the attack was completed.
Another example: in a script called remove_file.inc.php with the following code:
<?php if (!defined('MODULE_FILE')) { die ("You can't access this file directly..."); }
an attacker could call this file directly using a URL like remove_file.inc.php?filename=/etc/hosts, and thus attempt to delete the /etc/hosts file from the system (if the system allows it, or other files to which you have delete permissions).
In a CMS like WordPress, which also uses global variables internally, this type of attack was devastating. However, thanks to the constant technique, these and other PHP scripts were protected. Let's see it with the last example:
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly }
Now, if someone tried to access remove_file.inc.php?filename=/etc/hosts, the constant would block access. It is essential that it be a constant, because if it were a variable, of course, the attacker could inject it.
At this point you're probably wondering why PHP kept this functionality if it was so dangerous. Also, if you know other scripting languages (JSP, Ruby, etc.), you will see that they do not have something similar (which is why they do not use the constant technique either). Let us remember that PHP was born as a template system in C, and this behavior facilitated development. The good news is that, seeing the problems it caused, PHP maintainers decided to introduce a directive in php.ini called register_globals (activated by default) to allow disabling this functionality.
But since the problems persisted, they disabled it by default. Even so, many hosts continued to enable it for fear that their clients' projects would stop working, since much of the code at that time did not use the recommended HTTP_*_VARS variables to access the GET/POST/... values, but rather global variables.
Finally, seeing that the situation did not change, they made a drastic decision: eliminate this functionality in PHP 5.4 to avoid all these problems. Thus, nowadays, scripts like the ones we have seen (without using constants) no longer normally pose a danger, except for some harmless warning/notice in certain cases.
use today
Today, the constant technique is still common. However, what is sad—and the reason that led to this post—is that few developers know the real reason for its use.
As with other good practices of the past (such as copying parameters in a function to local variables to avoid dangers with references in the call, or using underscores in private variables to distinguish them), many still apply it just because someone once told them that it was a good practice, without considering whether it really adds value in current times. The reality is that, in the majority of cases, this technique is no longer necessary.
Some reasons why this practice has lost relevance are as follows:
Disappearance of *register globals: Since PHP 5.4, the functionality of registering GET and POST variables as PHP global variables no longer exists. As we have seen, without *register globals, the execution of individual scripts becomes harmless, eliminating the main reason for this practice.
Better design in current code: Even in versions prior to PHP 5.4, modern code is better designed, structured in classes and functions, which complicates access or manipulation through variables external. Even WordPress, which often uses global variables, minimizes these risks.
Use of *front-controllers: Nowadays, most web applications use well-designed *front-controllers, which ensure that the code of the Classes and functions will only be executed if the execution chain starts at the main entry point. So it doesn't matter if someone tries to upload files in isolation: the logic will not activate if the flow is not started from the right point.
Class autoloading: Since class autoloading is used in current development, the use of include or require has been greatly reduced. This means that, unless you are a novice developer, there should be no includes or requires that could present risks (such as Remote File Inclusion or Local File Inclusion).
Separation of public and private code: In many modern CMS and frameworks, public code (such as assets) is separated from private code (programming code). This measure is especially valuable as it ensures that if PHP fails on the server, the code in the PHP files (whether or not they use the constant technique) is not exposed. Although this was not specifically implemented to mitigate register globals, it helps avoid other security issues.
Extended use of friendly URLs: Nowadays, it is common to configure the server to use friendly URLs, which always forces a single entry point to programming. This makes it almost impossible for anyone to upload PHP files in isolation.
Suppressing error output in production: Most modern CMS and frameworks block error output by default, so attackers can't find clues about the internal workings of the application, something that could facilitate other types of attacks.
Although this technique is no longer necessary in the majority of cases, this does not mean that it is never useful. As a professional developer, it is essential to analyze each case and decide if the constant technique is relevant in the specific context in which you are working. This is a criterion that you should always apply, even in what you consider good practices.
Doubts? Here are some tips
If you are still not sure when to apply the constant technique, these recommendations can guide you:
- Always use the technique if you think your code can run on a version of PHP earlier than 5.4.
- Do not use it if the file only contains the definition of a class.
- Do not use it if the file contains only functions.
- Do not use if the file only includes HTML/CSS, unless the HTML exposes some type of valuable information.
- Do not use it if the file only contains constants.
For everything else, if you have doubts, apply it. In most cases it should not be harmful and could protect you in unexpected circumstances, especially if you are just starting out. With time and experience, you will be able to better evaluate when to apply this and other techniques.
Keep learning...
- register_globals - MediaWiki
- PHP: Using Register Globals - Manual
- Remote file inclusion vulnerabilities [LWN.net]
- Bugtraq: Serious security hole in Mambo Site Server version 3.0.X
The above is the detailed content of That strange PHP code in frameworks and CMS. For more information, please follow other related articles on the PHP Chinese website!

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values and handle functions that may return null values.

In PHP, use the clone keyword to create a copy of the object and customize the cloning behavior through the \_\_clone magic method. 1. Use the clone keyword to make a shallow copy, cloning the object's properties but not the object's properties. 2. The \_\_clone method can deeply copy nested objects to avoid shallow copying problems. 3. Pay attention to avoid circular references and performance problems in cloning, and optimize cloning operations to improve efficiency.

PHP is suitable for web development and content management systems, and Python is suitable for data science, machine learning and automation scripts. 1.PHP performs well in building fast and scalable websites and applications and is commonly used in CMS such as WordPress. 2. Python has performed outstandingly in the fields of data science and machine learning, with rich libraries such as NumPy and TensorFlow.

Key players in HTTP cache headers include Cache-Control, ETag, and Last-Modified. 1.Cache-Control is used to control caching policies. Example: Cache-Control:max-age=3600,public. 2. ETag verifies resource changes through unique identifiers, example: ETag: "686897696a7c876b7e". 3.Last-Modified indicates the resource's last modification time, example: Last-Modified:Wed,21Oct201507:28:00GMT.

In PHP, password_hash and password_verify functions should be used to implement secure password hashing, and MD5 or SHA1 should not be used. 1) password_hash generates a hash containing salt values to enhance security. 2) Password_verify verify password and ensure security by comparing hash values. 3) MD5 and SHA1 are vulnerable and lack salt values, and are not suitable for modern password security.

PHP is a server-side scripting language used for dynamic web development and server-side applications. 1.PHP is an interpreted language that does not require compilation and is suitable for rapid development. 2. PHP code is embedded in HTML, making it easy to develop web pages. 3. PHP processes server-side logic, generates HTML output, and supports user interaction and data processing. 4. PHP can interact with the database, process form submission, and execute server-side tasks.

PHP has shaped the network over the past few decades and will continue to play an important role in web development. 1) PHP originated in 1994 and has become the first choice for developers due to its ease of use and seamless integration with MySQL. 2) Its core functions include generating dynamic content and integrating with the database, allowing the website to be updated in real time and displayed in personalized manner. 3) The wide application and ecosystem of PHP have driven its long-term impact, but it also faces version updates and security challenges. 4) Performance improvements in recent years, such as the release of PHP7, enable it to compete with modern languages. 5) In the future, PHP needs to deal with new challenges such as containerization and microservices, but its flexibility and active community make it adaptable.

The core benefits of PHP include ease of learning, strong web development support, rich libraries and frameworks, high performance and scalability, cross-platform compatibility, and cost-effectiveness. 1) Easy to learn and use, suitable for beginners; 2) Good integration with web servers and supports multiple databases; 3) Have powerful frameworks such as Laravel; 4) High performance can be achieved through optimization; 5) Support multiple operating systems; 6) Open source to reduce development costs.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Zend Studio 13.0.1
Powerful PHP integrated development environment

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

WebStorm Mac version
Useful JavaScript development tools