Skip to content

[Aikido] Fix 11 security issues in jinja2, flask, werkzeug and 2 more - #21

Open
aikido-autofix[bot] wants to merge 1 commit into
masterfrom
fix/aikido-security-update-packages-82946966-1uat
Open

[Aikido] Fix 11 security issues in jinja2, flask, werkzeug and 2 more#21
aikido-autofix[bot] wants to merge 1 commit into
masterfrom
fix/aikido-security-update-packages-82946966-1uat

Conversation

@aikido-autofix

@aikido-autofix aikido-autofix Bot commented Aug 7, 2026

Copy link
Copy Markdown

Upgrade dependencies to fix path traversal, XSS injection, DoS attacks, and debugger PIN vulnerabilities. This update includes breaking changes that require manual migration.

⚠️ Code affected by breaking changes.

⚠️ The upgrade has multiple critical breaking changes that affect this codebase:

1. Python 2 Support Dropped

  • Where affected: Entire codebase (runtime.txt specifies python-2.7.13)

  • Impact: Werkzeug 2.0.0+ and Flask-Cors 4.0.0+ drop support for Python 2. The codebase uses Python 2-specific syntax (cStringIO, long, unicode, xrange) throughout multiple files (requestbin/__init__.py, requestbin/filters.py, requestbin/models.py)

  • Remediation: Upgrade to Python 3.8+ and migrate all Python 2 syntax to Python 3 (replace cStringIO with io.StringIO, remove long/unicode type checks, replace xrange with range)

2. werkzeug.contrib Module Removed

  • Where affected: requestbin/__init__.py:42

  • Impact: from werkzeug.contrib.fixers import ProxyFix will fail as the werkzeug.contrib module was removed in Werkzeug 1.0. ProxyFix was moved to werkzeug.middleware.proxy_fix

  • Remediation: Change import to from werkzeug.middleware.proxy_fix import ProxyFix

3. request.values Behavior Change for GET Requests

  • Where affected: requestbin/models.py:77 (self.form_data.append([k, input.values[k]]))

  • Impact: In Werkzeug 2.0+, request.values no longer includes form data for GET requests. This code iterates over input.form but accesses input.values[k], which may not contain the expected data

  • Remediation: Change input.values[k] to input.form[k] or input.form.getlist(k) to explicitly access form data

4. Timezone-Aware Datetime Values

  • Where affected: requestbin/filters.py:80,117 and requestbin/models.py:112 (uses datetime.datetime.utcfromtimestamp() and datetime.datetime.fromtimestamp())

  • Impact: Werkzeug 2.0+ returns timezone-aware datetime objects with tzinfo=timezone.utc. The code uses naive datetime objects which may cause comparison or serialization issues

  • Remediation: Update datetime handling to work with timezone-aware datetime objects or explicitly convert to naive datetimes if needed

All breaking changes by upgrading werkzeug from version 0.9.3 to 3.1.6 (CHANGELOG)

Version Description
0.10.0
Use stdlib ssl module instead of OpenSSL for the builtin server. OpenSSL contexts are not supported anymore, but instead ssl.SSLContext from the stdlib.
0.10.0
wrappers.Request.method is now always uppercase, eliminating inconsistencies of the WSGI environment.
0.11.0
mimetype parameters on request and response classes are now always converted to lowercase.
0.11.0
Changed cache so that cache never expires if timeout is 0. This also fixes an issue with redis setex.
0.12.0
The defaults of generate_password_hash have been changed to more secure ones.
0.12.0
Change Accept datastructure to sort by specificity first, allowing for more accurate results when using best_match for mime types.
0.13.0
response.age is parsed as a timedelta. Previously, it was incorrectly treated as a datetime.
0.13.0
Authorization.qop is a string instead of a set, to comply with RFC 2617.
0.13.0
An exception is raised when an encoded cookie is larger than, by default, 4093 bytes.
0.14.0
HTTP exceptions are now automatically caught by Request.application.
0.14.0
get_multi on cache clients now returns lists all the time.
0.14.0
The built-in HTTP server will no longer close a connection in cases where no HTTP body is expected (204, 204, HEAD requests etc.)
0.14.0
Werkzeug will no longer send the content-length header on 1xx or 204/304 responses.
0.16.0
Request cookies are parsed into a MultiDict to capture all values for cookies with the same key. cookies[key] returns the first value rather than the last.
0.16.0
Map and Rule have a merge_slashes option to collapse multiple slashes into one, similar to how many HTTP servers behave. This is enabled by default.
0.16.0
Range requests that span an entire file respond with 206 instead of 200, to be more compliant with RFC 7233.
0.16.0
The SharedDataMiddleware default fallback_mimetype is application/octet-stream. If a filename looks like a text mimetype, the utf-8 charset is added to it.
1.0.0
Drop support for Python 3.4.
2.0.0
Drop support for Python 2 and 3.5.
2.0.0
All datetime values are timezone-aware with tzinfo=timezone.utc.
2.0.0
Merge all request and response wrapper mixin code into single Request and Response classes. Using the mixin classes is no longer necessary and will show a deprecation warning.
2.0.0
Response.get_json() no longer caches the result, and the cache parameter is removed.
2.0.0
Response.freeze() generates an ETag header if one is not set. The no_etag parameter is no longer used.
2.0.0
The response generated by Unauthorized produces one WWW-Authenticate header per value in www_authenticate, rather than joining them into a single value.
2.0.0
Switch the parameter order of default_stream_factory to match the order used when calling it.
2.0.0
send_file sets conditional=True and max_age=None by default. Cache-Control is set to no-cache if max_age is not set, otherwise public.
2.0.0
Update the defaults used by generate_password_hash. Increase PBKDF2 iterations to 260000 from 150000. Increase salt length to 16 from 8.
2.0.0
The test Client request methods always return an instance of TestResponse. In addition to the normal behavior of Response, this class provides request with the request that produced the response, and history to track intermediate responses when follow_redirects is used.
2.0.0
Cookie names are no longer unquoted. This was against RFC 6265 and potentially allowed setting __Secure prefixed cookies.
2.0.0
Use SHA-1 instead of MD5 for generating ETags and the debugger pin, and in some tests.
2.0.0
LocalProxy matches the current Python data model special methods, including all r-ops, in-place ops, and async. __class__ is proxied, so the proxy will look like the object in more cases, including isinstance. Use issubclass(type(obj), LocalProxy) to check if an object is actually a proxy.
2.0.0
Local uses ContextVar on Python 3.7+ instead of threading.local.
2.0.0
request.values does not include form for GET requests.
2.1.0
Drop support for Python 3.6.
2.1.0
Using gevent or eventlet requires greenlet>=1.0 or PyPy>=7.3.7.
2.1.0
When passing a dict of URL values to Map.build, list values do not filter out None or collapse to a single value. Passing a MultiDict does collapse single items.
2.1.0
The development server uses HTTP/1.1, which enables keep-alive connections and chunked streaming responses, when threaded or processes is enabled.
2.1.0
The default status code for append_slash_redirect is 308 instead of 301.
2.1.0
Response.autocorrect_location_header is disabled by default. The Location header URL will remain relative, and exclude the scheme and domain, by default.
2.1.0
Request.get_json() will raise a 400 BadRequest error if the Content-Type header is not application/json.
2.2.0
If a custom converter needs to match a / it must set the class variable part_isolating = False.
2.3.0
Drop support for Python 3.7.
2.3.0
Request.get_json() will raise a 415 Unsupported Media Type error if the Content-Type header is not application/json, instead of a generic 400.
2.3.0
A URL converter's part_isolating defaults to False if its regex contains a /.
2.3.0
Increase default work factor for PBKDF2 to 600,000 iterations.
2.3.0
quote_header_value quotes the empty string.
2.3.0
dump_options_header skips None values rather than using a bare key.
2.3.0
dump_cookie allows domain values that do not include a dot ., and strips off a leading dot.
2.3.0
dump_cookie does not set path="/" unnecessarily by default.
2.3.0
Domain and path matching is used when sending cookies in requests. The domain and path parameters default to localhost and /.
2.3.0
If request.max_content_length is set, it is checked immediately when accessing the stream, and while reading from the stream in general, rather than only during form parsing.
2.3.0
The development server discards header keys that contain underscores _, as they are ambiguous with dashes - in WSGI.
2.3.0
secure_filename looks for more Windows reserved file names.
2.3.0
Percent encoding in URLs must always represent UTF-8 bytes. Invalid bytes are left percent encoded rather than replaced.
2.3.0
Header values that have charset information only allow ASCII, UTF-8, and ISO-8859-1.
2.3.0
generate_password_hash supports scrypt. Plain hash methods are deprecated, only scrypt and pbkdf2 are supported.
3.0.0
generate_password_hash uses scrypt by default.
3.1.0
Drop support for Python 3.8.
3.1.0
Request.max_form_memory_size defaults to 500kB instead of unlimited. Non-file form fields over this size will cause a RequestEntityTooLarge error.
3.1.0
Behavior of properties on request.cache_control and response.cache_control has been significantly adjusted.
3.1.0
Increase default work factor for PBKDF2 to 1,000,000 iterations.

All breaking changes by upgrading flask-cors from version 3.0.2 to 3.0.9 (CHANGELOG)

Version Description
3.0.3
If always_send=True, and '*' is in the allowed origins, and a request is made without an Origin header, no Access-Control-Allow-Origins header will now be returned (previously this header was sent, but this was a bug)

All breaking changes by upgrading Flask-Cors from version 3.0.2 to 3.0.9 (CHANGELOG)

Version Description
3.0.3
If always_send=True, and '*' is in the allowed origins, and a request is made without an Origin header, no Access-Control-Allow-Origins header will now be returned (previously this header was sent, but this was a bug)
✅ 11 CVEs resolved by this upgrade

This PR will resolve the following CVEs:

Issue Severity           Description
CVE-2024-34064
MEDIUM
[jinja2] The xmlattr filter fails to properly sanitize attribute keys, allowing injection of special characters (/, >, =) that enable XSS attacks when user-controlled keys are rendered in XML/HTML attributes.
CVE-2019-1010083
MEDIUM
[flask] The Pallets Project Flask before 1.0 is affected by: unexpected memory usage. The impact is: denial of service. The attack vector is: crafted encoded JSON data. The fixed version is: 1. NOTE: this may overlap CVE-2018-1000656.
CVE-2019-14322
HIGH
[werkzeug] In Pallets Werkzeug before 0.15.5, SharedDataMiddleware mishandles drive names (such as C:) in Windows pathnames.
CVE-2019-14806
MEDIUM
[werkzeug] Pallets Werkzeug before 0.15.3, when used with Docker, has insufficient debugger PIN randomness because Docker containers share the same machine id.
CVE-2023-25577
MEDIUM
[werkzeug] The multipart form data parser accepts unlimited parts without restriction, allowing attackers to cause denial of service through excessive CPU and memory consumption. Sending crafted multipart requests to endpoints accessing form/file data can exhaust worker processes and trigger out-of-memory conditions.
CVE-2024-34069
MEDIUM
[werkzeug] The debugger can be exploited for remote code execution if an attacker tricks a developer into visiting a controlled domain and entering the debugger PIN, then guesses a URL that triggers the debugger. This bypasses localhost-only protections.
CVE-2016-10516
MEDIUM
[werkzeug] A cross-site scripting (XSS) vulnerability in the debugger's render_full function allows remote attackers to inject arbitrary web script or HTML through exception messages. This enables attackers to execute malicious code in users' browsers when viewing debug information.
CVE-2026-27199
MEDIUM
[werkzeug] A path traversal vulnerability in the safe_join function allows Windows device names (like NUL) as filenames when preceded by path segments, causing file read operations to hang indefinitely when serving files through send_from_directory on Windows systems. This bypasses previous security filtering that didn't account for multi-segment paths.
CVE-2020-28724
MEDIUM
[werkzeug] Open redirect vulnerability in werkzeug before 0.11.6 via a double slash in the URL.
CVE-2020-25032
MEDIUM
[flask-cors] An issue was discovered in Flask-CORS (aka CORS Middleware for Flask) before 3.0.9. It allows ../ directory traversal to access private resources because resource matching does not ensure that pathnames are in a canonical format.
AIKIDO-2024-10084
MEDIUM
[Flask-Cors] A log injection vulnerability allows attackers to inject fake log entries by sending requests with CRLF sequences in the path, enabling log file corruption and covering attack tracks when debug logging is enabled.

@aikido-autofix aikido-autofix Bot added the security Label created by Aikido AutoFix label Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Label created by Aikido AutoFix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants