Moderate severityNVD Advisory· Published Sep 4, 2024· Updated Sep 4, 2024
Flask-AppBuilder login form allows browser to cache sensitive fields
CVE-2024-45314
Description
Flask-AppBuilder is an application development framework. Prior to version 4.5.1, the auth DB login form default cache directives allows browser to locally store sensitive data. This can be an issue on environments using shared computer resources. Version 4.5.1 contains a patch for this issue. If upgrading is not possible, configure one's web server to send the specific HTTP headers for /login per the directions provided in the GitHub Security Advisory.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
flask-appbuilderPyPI | < 4.5.1 | 4.5.1 |
Affected products
1- Range: < 4.5.1
Patches
13030e881d2e4feat: add no cache directive to login forms (#2266)
3 files changed · +31 −1
flask_appbuilder/security/decorators.py+14 −0 modified@@ -30,6 +30,20 @@ P = ParamSpec("P") +def no_cache(view: Callable[..., Response]) -> Callable[..., Response]: + @functools.wraps(view) + def wrapped_view(*args, **kwargs) -> Response: + response = make_response(view(*args, **kwargs)) + response.headers[ + "Cache-Control" + ] = "no-store, no-cache, must-revalidate, max-age=0" + response.headers["Pragma"] = "no-cache" + response.headers["Expires"] = "0" + return response + + return wrapped_view + + def response_unauthorized_mvc(status_code: int) -> Response: response = make_response( jsonify({"message": str(FLAMSG_ERR_SEC_ACCESS_DENIED), "severity": "danger"}),
flask_appbuilder/security/views.py+4 −1 modified@@ -9,7 +9,7 @@ from flask_appbuilder.baseviews import BaseView from flask_appbuilder.charts.views import DirectByChartView from flask_appbuilder.fieldwidgets import BS3PasswordFieldWidget -from flask_appbuilder.security.decorators import has_access +from flask_appbuilder.security.decorators import has_access, no_cache from flask_appbuilder.security.forms import ( DynamicForm, LoginForm_db, @@ -520,6 +520,7 @@ class AuthDBView(AuthView): login_template = "appbuilder/general/security/login_db.html" @expose("/login/", methods=["GET", "POST"]) + @no_cache def login(self): if g.user is not None and g.user.is_authenticated: return redirect(self.appbuilder.get_url_for_index) @@ -543,6 +544,7 @@ class AuthLDAPView(AuthView): login_template = "appbuilder/general/security/login_ldap.html" @expose("/login/", methods=["GET", "POST"]) + @no_cache def login(self): if g.user is not None and g.user.is_authenticated: return redirect(self.appbuilder.get_url_for_index) @@ -568,6 +570,7 @@ class AuthOIDView(AuthView): oid_ask_for_optional: List[str] = [] @expose("/login/", methods=["GET", "POST"]) + @no_cache def login(self, flag=True) -> WerkzeugResponse: @self.appbuilder.sm.oid.loginhandler def login_handler(self):
tests/security/test_mvc_security.py+13 −0 modified@@ -63,6 +63,19 @@ class Model1View(ModelView): self.appbuilder.add_view(Model1View, "Model1", category="Model1") + def test_sec_login_no_cache(self): + """ + Test Security Login, no cache directives + """ + rv = self.client.get("/login/") + assert rv.status_code == 200 + assert ( + rv.headers.get("Cache-Control") + == "no-store, no-cache, must-revalidate, max-age=0" + ) + assert rv.headers["Pragma"] == "no-cache" + assert rv.headers["Expires"] == "0" + def test_sec_login(self): """ Test Security Login, Logout, invalid login, invalid access
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-fw5r-6m3x-rh7pghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-45314ghsaADVISORY
- github.com/dpgaspar/Flask-AppBuilder/commit/3030e881d2e44f4021764e18e489fe940a9b3636ghsax_refsource_MISCWEB
- github.com/dpgaspar/Flask-AppBuilder/security/advisories/GHSA-fw5r-6m3x-rh7pghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.