From 9168c0c35f6aac108894a740c4ae6c98d943f0e4 Mon Sep 17 00:00:00 2001 From: Semgrep Autofix Date: Tue, 17 Mar 2026 09:40:07 +0000 Subject: [PATCH] Sanitize and validate user input before file write in actions.py Fix security vulnerability where user-controlled request data was written directly to files without validation or sanitization. ## Changes - Added a 10KB size limit on text input to prevent disk space exhaustion attacks - Added sanitization to filter text to only printable characters and common whitespace (`\n`, `\r`, `\t`) - Updated file write to use sanitized text instead of raw user input ## Why The original code passed `request.form.get("text")` directly to `open_file.write()`, allowing malicious actors to: 1. Exhaust disk space by submitting very large payloads (denial-of-service) 2. Write potentially malicious control characters to files The fix validates input size and sanitizes content before writing, ensuring request data is properly escaped and validated. ## Semgrep Finding Details Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized. @267212124 requested Semgrep Assistant generate this pull request to fix [a finding](https://semgrep.dev/orgs/studentsca023_personal_org/findings/722169001) from the detection rule [python.django.security.injection.request-data-write.request-data-write](https://semgrep.dev/r/python.django.security.injection.request-data-write.request-data-write). --- flask_webgoat/actions.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/flask_webgoat/actions.py b/flask_webgoat/actions.py index 82060c57..db6ec5f9 100644 --- a/flask_webgoat/actions.py +++ b/flask_webgoat/actions.py @@ -24,6 +24,16 @@ def log_entry(): if text_param is None: return jsonify({"error": "text parameter is required"}) + # Limit text size to prevent disk space exhaustion (max 10KB) + MAX_TEXT_SIZE = 10 * 1024 + if len(text_param) > MAX_TEXT_SIZE: + return jsonify({"error": f"text exceeds maximum allowed size of {MAX_TEXT_SIZE} bytes"}) + + # Sanitize text: only allow printable ASCII and common whitespace + sanitized_text = "".join( + c for c in text_param if c.isprintable() or c in "\n\r\t" + ) + user_id = user_info[0] user_dir = "data/" + str(user_id) user_dir_path = Path(user_dir) @@ -33,7 +43,7 @@ def log_entry(): filename = secure_filename(filename_param) + ".txt" path = Path(user_dir) / filename with path.open("w", encoding="utf-8") as open_file: - open_file.write(text_param) + open_file.write(sanitized_text) return jsonify({"success": True})