About three years ago, when I redesigned my website, I decided to separately log requests sent to its 404 pages. My goal was not so much to find pages that were no longer available on my site, but to see which URLs were being targeted by automated attacks and security scans carried out across the internet.
In other words, besides requests caused by visitors entering an incorrect URL or by me somehow breaking a link, what I was really curious about was which URLs bots were trying to access.
Over the years, I have accumulated enough data to build a meaningful picture from it. I examined 810 records in the database, grouped similar paths together, and analyzed those that were meaningful from a security perspective.
The purpose of this article is not simply to say, “These are the attacks that reached my site.” Instead, I want to turn it into an easy-to-understand security guide explaining which URLs attackers check on an internet-facing website, what they are trying to learn or which vulnerability they are looking for with each request, and what a site owner should do in such cases.
Because internet-facing servers are often scanned by automated bots on a random and large-scale basis rather than being specifically selected by attackers. These bots can try hundreds of different software components, administration panels, known vulnerabilities, and forgotten file paths in sequence on every domain name or IP address they encounter. The important thing is to understand which of these automated scans could actually pose a risk to your system.
1. The Most Important Warning in the Logs: /.env
The URL by far attempted most often in the list is /.env.
This path was attempted 34,000 times after combining different records. Such a high frequency is not a coincidence. The .env file can be used by modern applications, particularly PHP, Laravel, Node.js, and similar technologies, to store database connection details, API keys, application secrets, and various authentication credentials.
The attacker's logic is quite simple: “Is there a .env file in the root directory of this server that can accidentally be read over the web?”
If the answer is yes, the attacker may sometimes obtain a username, password, database information, SMTP account, API key, or application secret key directly. From that point on, the problem may no longer concern only the website itself, but also the security of other services connected to it.
The Open Worldwide Application Security Project (OWASP), a global cybersecurity community that provides free resources, standards, and tools to improve the security of software and web applications, also emphasizes that accidentally exposing secrets in code repositories, environment variables, and similar locations is a serious security problem.
For this reason, files such as .env should never be left somewhere directly accessible by the web server. If the file is necessary, it should be kept outside the web root or explicitly blocked by the web server.
More importantly, if such a file is found to have been accidentally exposed to the internet, simply deleting the file is not enough. If it contained a password or key, those credentials should be considered compromised and changed.
For the same reason, variations such as /.env.bak, /api/.env, /app/.env, /backend/.env, /admin/.env, /core/.env, /laravel/.env, /public/.env, /storage/.env, /database/.env, and /vendor/.env found in the logs are not random either. The attacker is not looking for a single file, but for different configuration files that developers may have accidentally left behind.
2. Looking for Source Code: /.git/config
One of the other major warning groups is /.git/config. This URL was attempted more than 4,000 times.
The .git directory contains repository information for a project managed with Git. The config file is part of the Git configuration specific to that repository. The important point from an attacker's perspective is this: if a .git directory has accidentally been left under the web server, the problem may be more than simply exposing a configuration file. It can be the first step toward accessing the application's source code, previous versions, file names, and sensitive information that previously existed in the project.
In particular, if a password or API key was accidentally added to the Git history, it may remain in previous commits even if the developer later deletes that line.
For this reason, the safest solution is not to put a .git directory in the web root of a production server. If it needs to be there, access to it should be strictly blocked at the web server level.
When /.git/config scans are considered together with .env scans, they show that the attacker is not actually targeting a single technology. The goal is to collect as much information as possible from files that a developer might have forgotten to protect.
3. “Is This Site Running WordPress?”: /wp-login.php
The second most frequently requested path in the logs is wp-login.php, with approximately 15,000 attempts.
Here, the attacker's primary goal is not to directly exploit a vulnerability, but to determine whether the site is running WordPress.
Attackers want to learn what infrastructure you are using. Since there are hundreds of thousands of websites exposed to the internet, bots can simply try standard WordPress paths. If /wp-login.php responds, they can assume that “there is a high probability that this is WordPress” and move on to the next stage.
If the site is indeed running WordPress, the next step may be to try username and password combinations one after another. This is known as a brute-force attack. WordPress's official security documentation also states that brute-force attacks are among the most common types of attacks against WordPress.
There is an important distinction here: the presence of wp-login.php is not itself a security vulnerability. The problem arises when this entry point is combined with weak passwords, unlimited attempts, stolen credentials, or another application vulnerability. Therefore, in addition to strong and unique passwords, WordPress sites should use two-factor authentication, preferably passkeys or similarly strong authentication methods, and rate-limit login attempts in particular.
4. An Old Feature That Is Still a Live Attack Surface: /xmlrpc.php
The /xmlrpc.php URL is also among the most frequently attempted paths. XML-RPC is an older mechanism that allows WordPress to perform certain operations remotely. Today, it has become one of the points frequently targeted by attackers, particularly for brute-force attempts. WordPress's own security documentation also states that xmlrpc.php is frequently targeted, particularly because of the system.multicall method, and that it can be disabled if it is not being used.
One advantage this can provide to an attacker is the ability to combine a large number of authentication attempts into a single XML-RPC request. Therefore, looking only at /wp-login.php requests may not be enough to see all password attacks against a WordPress site.
If you do not use XML-RPC, disabling it is a reasonable defense. If you do use it, access should be restricted and rate limiting should be applied. In particular, if Jetpack or another integration is being used, you should check which features actually require XML-RPC rather than disabling it completely.
5. The WordPress Administration Panel: /wp-admin/, install.php and admin-ajax.php
The logs show /wp-admin/index.php being attempted 2,831 times, /wp-admin/css/ 2,395 times, and /wp-admin/install.php 821 times.
Each of these provides different information.
/wp-admin/ and the paths beneath it tell the attacker whether the site's WordPress administration panel exists. From there, the target may be a direct attack on the administrator account.
/wp-admin/install.php, on the other hand, is looking for something different: a WordPress installation that was left in its setup stage or was incorrectly configured.
Under normal circumstances, this file should not provide a useful installation interface to an attacker on an already-installed WordPress site. However, because attackers also look specifically for forgotten test sites, old installations, and incorrectly configured systems, this URL appears on automated scanning lists.
/wp-admin/admin-ajax.php is somewhat more interesting. Finding this URL is not inherently bad; WordPress plugins genuinely use this endpoint for AJAX operations. WordPress's own documentation explains that AJAX requests can be processed through this file.
The actual risk lies in coding errors or authorization problems in plugins that use this endpoint. For example, if a plugin performs a critical operation simply because an AJAX request was received, an attacker may try to call that operation directly.
WordPress's nonce mechanism is an important defense for such operations, but a nonce is not an authorization mechanism by itself; actual permission checks must also be performed.
6. A More Serious Signal for WordPress Installations: wp-content/themes/seotheme/db.php and Similar PHP Files
Perhaps the most striking part of the records is the requests that directly call various PHP files that would be suspicious in a genuine WordPress installation.
For example:
/wp-content/themes/seotheme/db.php?u
/wp-content/themes/seotheme/mar.php
/wp-content/plugins/seoplugins/mar.php
/wp-content/themes/pridmag/db.php?u
In addition, names such as /shell.php, /wso.php, /mar.php, /up.php, /indoxploit.php, /olux.php, /sidwso.php, and /wp-content/alfa.php were also attempted hundreds of times.
This is a more aggressive form of scanning than simply checking whether WordPress is present.
A significant portion of these filenames appear in automated scans looking for files that have been used as webshells or backdoors. For example, the seotheme/db.php path has been associated in security investigations with malicious files created on compromised WordPress sites.
The attacker's logic is: “Has another attacker already compromised this site and left a webshell behind?”
The attacker does not necessarily have to find the vulnerability and upload the file themselves. If a shell previously placed by someone else is already present, finding and using it may be enough.
Once a webshell is found, what the attacker can do depends on the file's permissions. They may be able to read files, create new files, execute malicious code, establish persistent access, or use the site for spam and other attacks.
7. A Shortcut to the Database: adminer.php and Hundreds of phpMyAdmin Paths
The logs contain direct requests for adminer.php 383 times.
In addition, dozens of different database administration paths such as /phpmyadmin/, /phpmy/, /db/phpMyAdmin/, /sql/phpmyadmin/, /mysql/web/, and /dbadmin/ were scanned. Their total reaches thousands of requests.
The purpose of this type of scanning is clear: “Is there a database administration interface exposed to the internet on this server?”
Adminer is a powerful database administration tool that runs from a single PHP file. Its own documentation recommends protecting the administration interface with IP restrictions, additional authentication, or other access controls rather than leaving it exposed to the internet.
The risk can be significant. If such a panel is accessible and its credentials have been compromised, an attacker may be able to read, modify, or delete the database. On systems such as WordPress, database access can also lead to the loss of control over user accounts and the application itself. Security guides on the subject also point out that publicly accessible Adminer installations can pose a serious risk to the database and therefore to the application.
For this reason, Adminer or phpMyAdmin should only be used when genuinely necessary and, where possible, should only be accessible behind a VPN, internal network, IP allowlist, or additional authentication layer.
8. Scans Looking for Tomcat Administration: /manager/html
The /manager/html path was attempted more than 2,000 times. This address is associated with Tomcat Manager, the administration interface for Java-based Apache Tomcat servers.
Normally, this address may have no meaning on a particular website. However, attackers also try it on the assumption that Tomcat Manager may be running on the server. If it is, the risk is serious. Tomcat Manager allows authorized users to list and manage applications and deploy new applications. Tomcat's official documentation explicitly includes the ability to install a new application by uploading a WAR file.
Therefore, if /manager/html is actually accessible, it should not be treated merely as “an administration page that was accidentally left open.” Strong authentication, network-level access restrictions, and, where possible, keeping the administration interface completely off the public internet are necessary.
9. Learning How the Application Works: /actuator/gateway/routes
The paths /actuator/gateway/routes and /actuator/health were attempted quite frequently in the logs. These target Actuator management endpoints in Spring Boot applications.
What an attacker is interested in here is discovering which management interfaces the application exposes externally and how much information can be obtained from them. Spring Boot's official documentation also warns that Actuator endpoints can contain sensitive information and recommends exposing only the necessary endpoints over HTTP. The fact that only the health endpoint is exposed over HTTP by default is particularly important from a security perspective.
A path such as gateway/routes returning a response can provide an attacker with valuable information about the application's architecture: which services exist, which paths are routed to other systems, and how the application is configured.
If you use such an application, you should make sure to check whether Actuator endpoints are exposed to the internet.
10. Gathering Information: phpinfo.php, /_profiler/phpinfo, /server-status and /debug/default/view?panel=config
The common purpose of the paths in this group is to gather information before directly attempting to gain access to the system.
The logs contain requests for:
/_profiler/phpinfo
/phpinfo.php
/phpinfo
/server-status
/debug/default/view?panel=config
and these addresses were attempted hundreds of times.
phpinfo() can provide extensive information about the PHP version, compiled modules, server variables, and various configuration details. The information itself does not always allow a direct attack, but it can make it easier for an attacker to target subsequent attempts.
/server-status is Apache's server status page. Apache's documentation explicitly provides examples of restricting access to this page because it can provide information about the server's operating status and requests.
Similarly, leaving application debug interfaces enabled on production servers is undesirable. A debug screen can expose configuration, error, and application information that a normal visitor should never see.
For this reason, in production environments, phpinfo, debug toolbars, profilers, and status pages should either be disabled or made accessible only from an administrative network.
11. If You Have a File Upload Feature, Be Careful: upload.php and /upload/
Paths such as /upload.php and /upload/ can lead to major vulnerabilities.
File upload features are of particular interest to attackers. This is not because file uploading itself is a vulnerability, but because a poorly designed upload mechanism can give an attacker the ability to create files on the server.
For example, if a system that is supposed to accept only images also accepts PHP files, and PHP can be executed in the directory where the uploaded file is stored, the problem can become much more serious.
For this reason, checking the file extension alone is not sufficient in file upload systems. The MIME type, file contents, execution permissions of the upload directory, file naming, and access permissions should all be evaluated together.
12. Identifying Which CMS Is Being Used: /sites/default/files/, templates/beez3/
Some of the paths in the logs are intended less to attack the site than to fingerprint it, much like determining whether a site is running WordPress.
For example, /sites/default/files/ can be associated with Drupal installations, while paths such as templates/beez3/ can be associated with the Joomla ecosystem.
On the WordPress side, it is notable that requests for /wp-includes/wlwmanifest.xml were attempted under many different locations. Scanning possible installation paths such as /wordpress/, /blog/, /wp/, /test/, /cms/, /site/, and /news/ one by one is a typical example of this.
The attacker's logic here is to answer the question: “Which CMS is exposed?”
Once the technology, and possibly even its version, has been identified, subsequent scanning can become much more targeted. For example, an attacker who discovers that Joomla is being used can look for vulnerabilities in specific versions of Joomla extensions or themes rather than searching for general web vulnerabilities.
That is why keeping software, themes, and plugins up to date is one of the most important responses to this type of scanning.
13. Router and IoT Administration Paths: /boaform/admin/formLogin, /HNAP1 and Similar Paths
The logs also contain administration paths such as /boaform/admin/formLogin, /HNAP1, and /portal/redlion that would not normally be expected to exist on a regular website.
Their purpose is to find administration interfaces belonging to different devices and network products, rather than the website itself.
What is interesting here is that attackers do not even care whether the target IP is actually a web server. There are bots that try hundreds of standard administration URLs for different products against an address on the internet.
At one point in the list, there is also a request targeting a URL such as setup.cgi with the intention of directly executing a system command. This shows that automated scanning does not stop at “does this device exist?” but can also attempt known command-execution vulnerabilities in specific products.
If a router, IoT device, or similar administration service is actually running on the server, it is important that publicly exposed administration ports be accessible only from the networks that actually need them.
What All These Records Have in Common
Most of the attacks in this list actually follow a three-stage logic:
First, they ask “What technology is being used?”
Then they check “Is there a standard file that leaks information or provides administration?”
Finally, they try to determine “Is there a known vulnerability or a previously installed backdoor?”
For example, when an attacker tries wp-login.php, xmlrpc.php, various wp-content/plugins/ paths, and suspicious PHP files one after another, this is not actually a single event; these are parts of an automated attack chain.
Similarly, trying .env, .git/config, sftp-config.json, /.aws/credentials, /config/aws.yml, and various config.json paths together shows that the attacker is trying to obtain passwords and API keys not directly through application vulnerabilities, but from files that have accidentally been left exposed to the internet.
So What Should a Site Owner Do?
The most important conclusion from these records is that a web site cannot be protected against attacks through application code alone.
First, make sure that the web root does not contain .env, .git, .aws, backup configuration files, old .bak files, or files created during development.
Second, administration panels should not be left exposed to the internet. If WordPress, phpMyAdmin, Adminer, Tomcat Manager, debug panels, or another administration interface is necessary, it should be kept behind a VPN, IP restriction, or separate access layer whenever possible.
Third, if you use WordPress, login attempts should be limited, strong authentication should be used, and unnecessary XML-RPC access should be disabled. WordPress itself recommends rate limiting for login and XML-RPC at the server, proxy, or WAF level.
Fourth, themes and plugins should be kept up to date. The fact that specific plugin or theme directories are targeted in the logs shows that attackers are looking for known components rather than blindly scanning every part of WordPress.
Fifth, you should monitor not only HTTP 404 responses but also 200, 403, and 500 responses. An attacker trying /.env 10,000 times is just noise if they never reach the file. But if a request for /.env returns 200 even once, it is a serious security incident that needs to be investigated regardless of how frequently it occurred.
Finally, monitoring filesystem changes is extremely valuable. The appearance of previously nonexistent PHP files, especially in wp-content, uploads, wp-includes, or similar directories, is a much stronger indication of an attack than URL logs alone.
404 Logs Are Actually a Small Source of Threat Intelligence
When I looked back at these three years of logs, the most interesting result for me was how much information requests to a 404 page can actually contain.
A URL is not merely a “not found” message. The number of times a URL was attempted, which technologies attackers prioritize, which files they specifically search for, and how automated scans across the internet behave can turn these records into a small source of threat intelligence.
The address that stood out most in my logs was /.env. It was followed by WordPress login endpoints, XML-RPC, Git configuration, webshell filenames, database administration panels, and various administration services.
Seeing the paths taken by unsuccessful attacks is also an important part of defense. The system I started three years ago with the idea of “let me log the 404s” has, in retrospect, become a small archive of the attack surface my site has been exposed to on the internet.
And perhaps the most practical conclusion of this article is this: if you keep 404 logs on a website, do not read them only from an SEO perspective by asking, “Which old URLs are broken?” There is a small summary of the attacks against your site hidden in that list.