Source code disclosure happens when an unauthorized party gets access to the source code of a web application or API. This can be caused by web server misconfigurations or vulnerabilities in the web application or API. Source code disclosure is often considered a type of information disclosure attack.
Web applications and APIs are usually built using two different approaches:
In cases where the source code is executed directly, if the web server fails to recognize that a file should be executed by an interpreter, it will respond by sending the source file itself to the requesting web browser (instead of interpreting the source server-side and sending only the result).
Source code disclosure can also occur even when the source code is precompiled. Although most development environments rely on repositories, the actual source code might temporarily be stored in a different directory in plain text. If web vulnerabilities make it possible to access such a directory, you have source code disclosure.
The source code of an application may contain sensitive information. Attackers may use this information for their direct competitive advantage or for privilege escalation/privilege elevation to help them continue the attack. Here are some typical attack scenarios:
Source code disclosure vulnerabilities can result from many different types of vulnerabilities and server misconfigurations. Here are some examples of typical vulnerabilities and misconfigurations that cause source code disclosure:
Note that the above list is not exhaustive. For example, attackers can use techniques that prevent code from being interpreted in order to gain access to the raw source code instead of the interpreted result.
Source code disclosure is classified in the OWASP Top 10 as A01:2021 – Broken Access Control, in the Common Weakness Enumeration as CWE-540: Inclusion of Sensitive Information in Source Code, and by the Web Application Security Consortium as WASC-13: Information Leakage. Note that each of these classifications uses different criteria to define the main security risk, such as exposing information included in the source code or enforcing insufficient access control that allows exposure in the first place.
In this example, the attacker finds a local file inclusion vulnerability on example.com and accesses the following download.php file:
<?php
// Import global config values
include('admin/config.php');
// Get the filename provided by the user
$filepath = $_GET['filename'];
if ($filepath) {
// Database connection string
$connection = mysqli_connect($cfg['DATABASE']['HOST'], $cfg['DATABASE']['UNAME'], $cfg['DATABASE']['PASS'], 'logs');
if (!$connection) {
die('Could not connect: '.mysqli_connect_error($connection));
}
$user_agent = $_SERVER['HTTP_USER_AGENT'];
// Used by stats.php to track download trends
$sql = "INSERT INTO stats VALUES ('$filepath', now(), '$user_agent')";
$result = mysqli_query($connection, $sql);
if (!$result) {
echo 'DB Error: '.mysqli_error($connection);
exit;
}
// Clean up and send the file
mysqli_close($connection);
header('Content-Disposition: attachment; filename=' . basename($filepath));
readfile($filepath);
}
?>
An analysis of the download.php source code reveals information that allows for escalation. For example, the comment Used by stats.php to track download trends suggests the existence of a stats.php file, and there is an include directive for the admin/config.php file. Exploiting the same vulnerability, the attacker can now download both these files, starting with config.php:
<?php
$cfg['TITLE'] = 'Example';
$cfg['BASE_URL'] = 'http://www.example.com/';
$cfg['DATABASE']['TYPE'] = 'mysql';
$cfg['DATABASE']['HOST'] = 'localhost';
$cfg['DATABASE']['UNAME'] = 'root';
$cfg['DATABASE']['PASS'] = 'nx01-74656-ds9-b5';
?>
Now the attacker knows that the database is hosted on the same server as the web application, and that the database server is MySQL.
The second file to download is stats.php:
<?php
// Import global config values
include('admin/config.php');
print '<table style="width:100%">';
print '<tr><th>Available Files</th>';
print '<tr><td><a href="' . $cfg['BASE_URL'] . 'stats.php?filename=aboutus.pdf">About Us (PDF)</a></td>';
print '<tr><td><a href="' . $cfg['BASE_URL'] . 'stats.php?filename=pricing.html">Pricing (HTML)</a></td>';
print '<tr><td><a href="' . $cfg['BASE_URL'] . 'stats.php?filename=services.pdf">Services (PDF)</a></td>';
print '</table>';
print '<br><br>';
$filepath = $_GET['filename'];
if ($filepath) {
$connection = mysqli_connect($cfg['DATABASE']['HOST'], $cfg['DATABASE']['UNAME'], $cfg['DATABASE']['PASS'], 'logs');
if (!$connection) {
die('Could not connect: '.mysqli_connect_error($connection));
}
$sql = "SELECT * FROM stats WHERE filename = '$filepath'";
$result = mysqli_query($connection, $sql) or die(mysqli_error($connection));
print '<table style="width:100%; border: 1px solid black; text-align: left;">';
print '<tr><th>Filename</th><th>Timestamp</th><th>User-Agent String</th></tr>';
while ($row = mysqli_fetch_assoc($result)) {
print "<tr>";
foreach ($row as $column => $value) {
print "<td style='text-align: left;'>$value</td>";
}
print "</tr>";
}
print '</table>';
}
?>
The stats.php file lists the download history for a particular set of files. The records are fetched directly from the same table that download.php uses to log downloads. The file path is taken directly from the request with no input validation. Because the developer did not use a parameterized query, the app probably has an SQL injection vulnerability. For example, the attacker may try calling the following URL:
http://www.example.com/stats.php?filename=%27%20UNION%20SELECT%20%40%40version%2C%20null%2C%20null%23
Without URL encoding, the filename value is ' UNION SELECT @@version, null, null#
. If executed by the server, this query displays the database version and confirms there is an SQL injection vulnerability. From now on, the malicious hacker can escalate the attack even further.
Since there are many different vulnerabilities and misconfigurations that can cause source code disclosure, including web vulnerabilities, web server misconfigurations, and network vulnerabilities, you may need to use different methods and tools to discover all possible causes. Using a modern dynamic application security testing tool such as Invicti or Acunetix by Invicti, you can discover web vulnerabilities and web server misconfigurations. The SCA functionality available in such products also lets you discover open-source components that are known to have such vulnerabilities.
Note that some limited source code exposure may sometimes be intentional, for example, on web pages with educational content. Any automated scanning should therefore be paired with manual security reviews. Periodic penetration testing is also needed to deal with complex business logic vulnerabilities and other security issues that require manual intervention.
Source code disclosure can be caused by many different vulnerabilities and misconfigurations, so there is no single way to prevent it. To avoid source code disclosure, follow these general recommendations:
Source code disclosure is a cybersecurity issue that lets an attacker access server-side source code. This issue can be caused by different types of web and network vulnerabilities. Source code disclosure is closely related to other information disclosure issues.
Read more about vulnerabilities that cause information disclosure and related attacks.
Source code disclosure can be a serious security and financial risk, especially if the source code has high business value or contains sensitive information that allows malicious hackers to perform other attacks. For example, the attacker may sell your source code to a competitor or, if they find your database credentials in the source, gain access to customer lists and other sensitive data in your systems. By analyzing your source code, attackers can also find defects such as SQL injection vulnerabilities and exploit them for further attacks.
Learn about SQL injections and how they can be used to attack your databases.
To avoid source code disclosure, make sure your web servers are securely configured and your web applications don’t have vulnerabilities such as local file inclusion (LFI). You can use automated web application security scanners such as Invicti to check this. Additionally, you can use network scanners to check if your specific web server version is safe from information disclosure vulnerabilities. Remediation of this information security issue depends on the root cause.