CWE-183: Permissive List of Allowed Inputs
Learn about CWE-183 (Permissive List of Allowed Inputs), its security impact, exploitation methods, and prevention guidelines.
What is Permissive List of Allowed Inputs?
• Overview: Permissive List of Allowed Inputs, CWE-183, occurs when a security mechanism allows a broader range of inputs than intended, leading to potentially unsafe inputs being accepted. This can happen when the list of allowed inputs is too broad or not well-defined, assuming all inputs are safe without thorough validation.
• Exploitation Methods:
- Attackers can exploit this vulnerability by providing inputs that are technically allowed but are malicious or harmful, bypassing intended security controls.
- Common attack patterns include SQL injection, cross-site scripting (XSS), or using special characters or input formats that were not explicitly excluded but can cause harm.
• Security Impact:
- Direct consequences include unauthorized data access, data corruption, or unexpected behavior of the application.
- Potential cascading effects could involve lateral movement within a network, exposing other vulnerabilities, or compromising other systems.
- Business impact might include data breaches, loss of customer trust, legal penalties, and financial losses.
• Prevention Guidelines:
- Specific code-level fixes involve refining input validation logic by specifying tight constraints on what is allowed, rather than focusing on what should be denied.
- Security best practices include employing a whitelist approach, where only explicitly safe inputs are allowed, and continuously reviewing and updating this list.
- Recommended tools and frameworks include using libraries that provide robust input validation, such as OWASP's ESAPI for Java or similar security libraries for other languages.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: Not Language-Specific
Affected Technologies: Not specified
Vulnerable Code Example
import re
def is_allowed_file(filename):
# Vulnerable code: The regex pattern is too permissive and allows dangerous file extensions
allowed_extension_pattern = r".*\.(jpg|jpeg|png|gif|bmp|tiff|svg)\$"
return re.match(allowed_extension_pattern, filename.lower()) is not None
def upload_file(filename, content):
if is_allowed_file(filename):
# Code to save the file
pass
else:
raise ValueError("File type not allowed")
Explanation
The vulnerability in the code above lies in the regex pattern used to determine if a file's extension is allowed. The pattern is too permissive because it allows any file with the specified extensions, but it doesn't prevent filenames like image.jpg.exe
which can be dangerous if executed on the server. The regex matches any string that contains one of the allowed extensions, even if additional dangerous extensions follow.
How to fix Permissive List of Allowed Inputs?
To fix this vulnerability, we need to ensure that the filename ends exactly with one of the allowed extensions. Instead of relying on a permissive regex pattern, we should use a stricter approach that checks the file extension directly. This can be done by using string methods to verify the file extension, ensuring it precisely matches one of the allowed types, and ignoring any additional characters after the extension.
Fixed Code Example
def is_allowed_file(filename):
# Fixed code: Use a strict check for file extension using a set
allowed_extensions = {'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg'}
# Split the filename from the last period and check if the extension is in the allowed set
if '.' in filename:
file_extension = filename.rsplit('.', 1)[-1].lower()
return file_extension in allowed_extensions
return False
def upload_file(filename, content):
if is_allowed_file(filename):
# Code to save the file
pass
else:
raise ValueError("File type not allowed")
Explanation
The fixed version replaces the permissive regex with a strict check using a set of allowed file extensions. The method rsplit('.', 1)[-1]
ensures that we are only examining the actual file extension by splitting the filename from the last period. This approach prevents filenames with double extensions (e.g., file.jpg.exe
) from being mistakenly allowed since only the last segment after the final period is checked against the allowed extensions. Additionally, it checks if a period is present in the filename before attempting to split, which prevents errors for filenames without extensions.