CWE-433: Unparsed Raw Web Content Delivery
Learn about CWE-433 (Unparsed Raw Web Content Delivery), its security impact, exploitation methods, and prevention guidelines.
What is Unparsed Raw Web Content Delivery?
• Overview: Unparsed Raw Web Content Delivery (CWE-433) occurs when a web application stores raw files or code under the web document root with extensions not handled by the web server. This can result in the server delivering the raw content directly to users without processing, potentially exposing sensitive data.
• Exploitation Methods:
- Attackers can request files directly from the server that are stored with unhandled extensions.
- Common attack patterns include probing the server for files with uncommon extensions like ".inc" or ".pl" that might contain sensitive information such as configurations or credentials.
• Security Impact:
- Direct consequences include exposure of sensitive information such as database credentials, API keys, or internal configuration details.
- Potential cascading effects could lead to unauthorized access to the database, execution of unauthorized operations, or further exploitation of the application.
- Business impact includes data breaches, loss of customer trust, financial loss, and potential legal liabilities.
• Prevention Guidelines:
- Specific code-level fixes include ensuring all files are stored with appropriate extensions that are handled securely by the web server.
- Security best practices involve regularly reviewing and configuring the web server to handle or deny requests for files with uncommon or sensitive extensions.
- Recommended tools and frameworks include using web application firewalls (WAFs) to block unauthorized file requests, and employing security scanners to detect and remediate such vulnerabilities.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: Not Language-Specific
Affected Technologies: Not specified
Vulnerable Code Example
from flask import Flask, send_from_directory
import os
app = Flask(__name__)
# Vulnerable endpoint that serves files from the web root directory without parsing
@app.route('/download/<path:filename>')
def download_file(filename):
# Security Issue: Serving raw files directly from the web root, potentially exposing sensitive files
return send_from_directory(os.path.join(app.root_path, 'uploads'), filename)
Explanation
In this vulnerable code example, the endpoint /download/<path:filename>
serves files directly from the uploads
directory without any checks. This can lead to several security issues:
- Exposure of Sensitive Files: If sensitive files are stored in the
uploads
directory, they can be accessed by an attacker. - Path Traversal Attacks: Without proper validation, an attacker could attempt to access files outside the intended directory using path traversal techniques.
How to fix Unparsed Raw Web Content Delivery?
To fix the unparsed raw web content delivery issue, you should ensure that files served from your web server are properly sanitized, validated, and intended for public access. This involves:
- File Type Whitelisting: Ensure that only files with specific, safe extensions (e.g.,
.txt
,.jpg
) can be served. - Directory Whitelisting: Ensure that files are only served from specific directories that are intended for public access and do not contain sensitive information.
- Access Control: Implement access controls to ensure only authorized users can access certain files.
- Content-Type Headers: Set appropriate content-type headers to ensure files are interpreted correctly by the client's browser.
Fixed Code Example
from flask import Flask, send_from_directory, abort, safe_join
import os
app = Flask(__name__)
# Secure endpoint to serve validated and safe files only
@app.route('/download/<path:filename>')
def download_file(filename):
# Fix: Define a whitelist of allowed file extensions
ALLOWED_EXTENSIONS = {'txt', 'jpg', 'png', 'pdf'}
# Function to check if the file has an allowed extension
def is_allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# Use Flask's safe_join to prevent directory traversal attacks
safe_path = safe_join(app.root_path, 'uploads', filename)
if is_allowed_file(filename) and os.path.isfile(safe_path):
# Return the file only if it exists and has an allowed extension
return send_from_directory(os.path.join(app.root_path, 'uploads'), filename)
else:
# Abort with a 404 error if the file extension is not allowed or file does not exist
abort(404)
Improvements and Fixes
- File Extension Check: Added a function
is_allowed_file
to ensure only files with approved extensions are served. - Safe Path Handling: Used
safe_join
to prevent directory traversal attacks by ensuring the requested file path is within the intended directory. - Existence Check: Added a check to ensure the file exists before attempting to serve it.
- Abort on Unauthorized Access: If the file extension is not allowed or the file does not exist, the server responds with a 404 error, preventing access to unauthorized files.