Global Variable Leakage
April 11, 2022
from django.urls import re_path
from django.http import JsonResponse
leaky_variable = dict()
def victims_account(request):
"""Return personal data."""
leaky_variable["name"] = "I'm an unsuspecting user"
leaky_variable["routing number"] = 123456789
leaky_variable["account number"] = 123456789012
leaky_variable["account value"] = 12345678
return JsonResponse(leaky_variable)
def hackers_account(request):
"""Return hacker's data plus victim's data data."""
leaky_variable["name"] = "I'm a hacker"
return JsonResponse(leaky_variable)
urlpatterns = [
re_path(r'^victims-account/$', victims_account),
re_path(r'^hackers-account/$', hackers_account),
]
Overview of Vulnerability
Global variable leakage is class of vulnerabilities that can arise in web applications. It occurs when stateful server code leaks one user's data to a second user.
Background and Scope
I mentioned this to Django's security team in late 2019 after observing data leakage when running
pyplot on the back-end. However, this is neither a Django nor a Python-specific vulnerability. Any library in any language can potentially contain this type of vulnerability. The only requirement is that the calls to the library are able to read some type of information that was produced during a previous call. Even without explicitly declared global variables, leakage can still occur if any kind of data persistence (e.g. data stored in a database or in a temporary file). Because many libraries were never intended to be used in web apps, it's something to be aware of. As shown below, information leakage can occur with first-party code as well.
Implementation with Python and Django
The vulnerability is implemented by the Django code above. If data for two private accounts are accessed by the URLs
localhost/victims-account and
localhost/hackers-account, the attack is demonstrated by requesting both URLs sequentially. In this case, requesting
localhost/victims-account outputs the victim's account data:
"name": "I'm an unsuspecting user",
"routing number": 123456789,
"account number": 123456789012,
"account value": 12345678
A second request for
localhost/hackers-account then outputs data which includes information about both the hacker's and the victim's accounts.
"name": "I'm a hacker",
"routing number": 123456789,
"account number": 123456789012,
"account value": 12345678
Implementation with JavaScript and AWS Lambda
A 2021
AWS blog post describes this type of vulnerability and gives an example implementation using AWS Lambda and JavaScript. Look under the heading "Comparing the effect of global scope."