Use of threading.local() ... what is the risk?

1,474 views
Skip to first unread message

Micah Carrick

unread,
Sep 10, 2011, 7:40:15 PM9/10/11
to django...@googlegroups.com
I have read https://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser and numerous other discussions about the use of threading.local() yet I still see it being employed in various projects.

I have recently implemented a referral system in which the use of threading.local() makes the app very portable and very simple as I can simply use the post_save signal (which cannot access the session). What I'm doing...

1. When a user first gets to the site, middleware stores the referral ID found in the URL and puts it into a session variable. 
2. The session variable is copied to a threading.local() variable on every request. 
3. A handler for the post_save on the User model checks this threading.local() variable, finds the User the referral code belongs to, and associates the referral user with the referred user in referral model. This handler also creates the referral code for the new user.

I like this approach because there is no need to think about the referral system in the views, forms, or models of the auth system. I haven't deployed this because of the big threading.local() warnings.

So this referral code is the only thing vulnerable here. This code is a uniquely generated code which is associated with a User. What risks does this pose and why?

Russell Keith-Magee

unread,
Sep 14, 2011, 8:33:35 AM9/14/11
to django...@googlegroups.com

The biggest reason to avoid the use of threadlocals is a very simple
architectural one: It doesn't matter how you rename it to make it more
palatable; a threadlocal is a global variable. Global variables
increase coupling, decrease cohesion, and make it harder to test a
system. For this reason alone, threadlocals should be avoided.

Aside from the basic engineering risk of building a system based on
global variables, there is also a potential risk associated with data
leakage. If you're building a system using global variables, you're
making yourself vulnerable to situations where you put data in a
location where it can be seen across threads. If this happens, you've
just opened a big security hole in your app, because a user on one
thread can observe the state of another user.

Now, I will admit that it's entirely possible to use threadlocals in a
completely "safe" manner, without any data leakage. The extent to
which this is a problem in practice depends entirely on exactly what
you're doing, and how you do it.

At the end of the day, it comes down to this: If you don't use global
state, the data leakage problem *can't* exist, and you get easier to
test code as a bonus. If you *do* use global state, leakage problems
*might* exist, you need to be vigilant to ensure that they don't, and
your code is harder to test anyway.

For my money, avoiding threadlocals is a no-brainer.

Yours,
Russ Magee %-)

Reply all
Reply to author
Forward
0 new messages