[Aikido] Fix 17 security issues in jinja2, flask, werkzeug and 2 more#20
Open
aikido-autofix[bot] wants to merge 1 commit into
Open
[Aikido] Fix 17 security issues in jinja2, flask, werkzeug and 2 more#20aikido-autofix[bot] wants to merge 1 commit into
aikido-autofix[bot] wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upgrade Jinja2, Flask, and Werkzeug to fix sandbox escapes, privilege escalation, session cookie leakage, and path traversal vulnerabilities. This update includes breaking changes that require manual migration.
runtime.txt) and upgrading to the specified package versions will cause multiple breaking changes:1. Python Version Incompatibility
Where your code is affected: Entire codebase, specifically
runtime.txt(line 1),requestbin/__init__.py(line 3),requestbin/models.py(line 56)Impact: Flask 2.0+ requires Python 3.6+, Werkzeug 2.0+ requires Python 3.6+, Jinja2 3.0+ requires Python 3.6+, and Flask-Cors 4.0+ requires Python 3.8+. The current Python 2.7.13 runtime is incompatible.
Remediation: Upgrade to Python 3.8 or higher and update all Python 2-specific code (cStringIO, xrange, print statements, etc.)
2. cStringIO Import (Python 2 only)
Where your code is affected:
requestbin/__init__.py(line 3)Impact:
from cStringIO import StringIOwill fail as cStringIO doesn't exist in Python 3.Remediation: Replace
from cStringIO import StringIOwithfrom io import BytesIOorfrom io import StringIOdepending on whether you need bytes or text3. xrange (Python 2 only)
Where your code is affected:
requestbin/models.py(line 56)Impact:
xrangedoesn't exist in Python 3, causing a NameError.Remediation: Replace
xrangewithrange4. werkzeug.contrib.fixers.ProxyFix Import
Where your code is affected:
requestbin/__init__.py(line 41)Impact:
werkzeug.contribmodule was removed in Werkzeug 1.0. ProxyFix moved to a new location.Remediation: Change
from werkzeug.contrib.fixers import ProxyFixtofrom werkzeug.middleware.proxy_fix import ProxyFix5. flask.escape Import
Where your code is affected:
requestbin/views.py(line 2)Impact:
escapewas removed from Flask in version 2.0 and should be imported from MarkupSafe instead.Remediation: Change
from flask import escapetofrom markupsafe import escape(though the function is imported but never used in the code, so it can also be removed)6. request.values Usage
Where your code is affected:
requestbin/models.py(line 76)Impact: In Werkzeug 2.0+,
request.valuesdoes not include form data for GET requests, and the behavior has changed.Remediation: Review the usage of
input.values[k]and consider usinginput.form.getlist(k)orinput.form[k]explicitly instead7. app.debug Direct Assignment
Where your code is affected:
requestbin/__init__.py(line 44)Impact: While not strictly breaking, directly setting
app.debugis deprecated in favor of usingapp.config['DEBUG'].Remediation: Replace
app.debug = config.DEBUGwithapp.config['DEBUG'] = config.DEBUGAll breaking changes by upgrading jinja2 from version 2.7 to 3.1.4 (CHANGELOG)
{% macro m(x, y=1, z) %}a syntax error. The previous behavior for this code was broken anyway (resulting in the default value being applied toy).importstatement cannot end with a trailing comma.indentfilter will not indent blank lines by default.finalizefunction is only applied to the output of expressions (constant or not), not static template data.Undefinedwhen omitting theelseclause in a{{ 'foo' if bar }}expression, regardless of the environment'sundefinedclass.urlizefilter recognizesmailto:links and takesextra_schemesto recognize other schemes. URLs without a scheme are linked ashttps://instead ofhttp://.Undefined.__contains__(in) raises anUndefinedErrorinstead of aTypeError.\n,\r\nand\ras line breaks. Other characters are left unchanged.Environment(enable_async=True).WithExtensionandAutoEscapeExtensionnow built-in,contextfilter/contextfunctionreplaced bypass_context,evalcontextfilter/evalcontextfunctionreplaced bypass_eval_context,environmentfilter/environmentfunctionreplaced bypass_environment.Markupandescapeshould be imported from MarkupSafe.Contextsubclasses is no longer supported. Overrideresolve_or_missinginstead ofresolve.unicode_urlencodeis renamed tourl_quote.groupbyfilter is case-insensitive by default, matching other comparison filters.All breaking changes by upgrading flask from version 0.10.1 to 2.2.5 (CHANGELOG)
TEMPLATES_AUTO_RELOADconfig key.send_filehas been removed.send_filenow fails loudly and doesn't fall back toapplication/octet-stream.JSONIFY_PRETTYPRINT_REGULARtoFalse.Flask.make_responseraisesTypeErrorinstead ofValueErrorfor bad response types.APPLICATION_ROOTto'/'by default.TRAP_BAD_REQUEST_ERRORSis enabled by default in debug mode.flask.ext,Flask.init_jinja_globals,Flask.error_handlers,Flask.request_globals_class,Flask.static_path,Request.module.Flask.loggerhas been simplified.LOGGER_NAMEandLOGGER_HANDLER_POLICYconfig was removed.SERVER_NAMEdoes not implicitly enable it.Request.get_jsonno longer accepts arbitrary encodings. Incoming JSON should be encoded using UTF-8 per RFC 8259, but Flask will autodetect UTF-8, -16, or -32.InternalServerErroror500will always be passed an instance ofInternalServerError. The original exception is now available ase.original_exceptionrather than being passed directly to the handler.Flask.loggertakes the same name asFlask.name(the value passed asFlask(import_name)). This reverts 1.0's behavior of always logging to"flask.app".(response, headers)tuple from a view, the headers replace rather than extend existing headers on the response.send_filesetsconditional=Trueandmax_age=Noneby default.Cache-Controlis set tono-cacheifmax_ageis not set, otherwisepublic..envand.flaskenvfiles.script_infoto app factory functions,config.from_jsonis replaced,jsonfunctions no longer take anencodingparameter,safe_joinis removed,total_secondsis removed, the same blueprint cannot be registered with the same name, the test client'sas_tupleparameter is removed.send_fileparameters have been removed,RequestContext.gproperty is removed.LocalStack.--eager-loading/--lazy-loadingoptions from theflask runcommand. The app is always eager loaded the first time, then lazily loaded in the reloader.All breaking changes by upgrading werkzeug from version 0.9.3 to 3.1.6 (CHANGELOG)
sslmodule instead ofOpenSSLfor the builtin server. OpenSSL contexts are not supported anymore, but insteadssl.SSLContextfrom the stdlib.wrappers.Request.methodis now always uppercase, eliminating inconsistencies of the WSGI environment.mimetypeparameters on request and response classes are now always converted to lowercase.generate_password_hashhave been changed to more secure ones.best_matchfor mime types.response.ageis parsed as atimedelta. Previously, it was incorrectly treated as adatetime.Authorization.qopis a string instead of a set, to comply with RFC 2617.Request.application.get_multion cache clients now returns lists all the time.MultiDictto capture all values for cookies with the same key.cookies[key]returns the first value rather than the last.MapandRulehave amerge_slashesoption to collapse multiple slashes into one, similar to how many HTTP servers behave. This is enabled by default.SharedDataMiddlewaredefaultfallback_mimetypeisapplication/octet-stream. If a filename looks like a text mimetype, theutf-8charset is added to it.datetimevalues are timezone-aware withtzinfo=timezone.utc.RequestandResponseclasses. Using the mixin classes is no longer necessary and will show a deprecation warning.Response.get_json()no longer caches the result, and thecacheparameter is removed.Response.freeze()generates anETagheader if one is not set. Theno_etagparameter is no longer used.Unauthorizedproduces oneWWW-Authenticateheader per value inwww_authenticate, rather than joining them into a single value.default_stream_factoryto match the order used when calling it.send_filesetsconditional=Trueandmax_age=Noneby default.Cache-Controlis set tono-cacheifmax_ageis not set, otherwisepublic.generate_password_hash. Increase PBKDF2 iterations to 260000 from 150000. Increase salt length to 16 from 8.Clientrequest methods always return an instance ofTestResponse. In addition to the normal behavior ofResponse, this class providesrequestwith the request that produced the response, andhistoryto track intermediate responses whenfollow_redirectsis used.__Secureprefixed cookies.LocalProxymatches 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, includingisinstance. Useissubclass(type(obj), LocalProxy)to check if an object is actually a proxy.LocalusesContextVaron Python 3.7+ instead ofthreading.local.request.valuesdoes not includeformfor GET requests.Map.build, list values do not filter outNoneor collapse to a single value. Passing aMultiDictdoes collapse single items.threadedorprocessesis enabled.append_slash_redirectis 308 instead of 301.Response.autocorrect_location_headeris disabled by default. TheLocationheader URL will remain relative, and exclude the scheme and domain, by default.Request.get_json()will raise a 400BadRequesterror if theContent-Typeheader is notapplication/json./it must set the class variablepart_isolating = False.Request.get_json()will raise a415 Unsupported Media Typeerror if theContent-Typeheader is notapplication/json, instead of a generic 400.part_isolatingdefaults toFalseif itsregexcontains a/.All breaking changes by upgrading flask-cors from version 3.0.2 to 3.0.9 (CHANGELOG)
always_send=True, and'*'is in the allowed origins, and a request is made without an Origin header, noAccess-Control-Allow-Originsheader 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)
always_send=True, and'*'is in the allowed origins, and a request is made without an Origin header, noAccess-Control-Allow-Originsheader will now be returned (previously this header was sent, but this was a bug)✅ 17 CVEs resolved by this upgrade
This PR will resolve the following CVEs:
xmlattrfilter 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._punctuation_re regexallows attackers to cause denial of service through specially crafted input with multiple wildcards. Mitigation includes using Markdown for user content formatting or implementing request timeouts and memory limits.