WoW BlueTracker Home | RSS | News | Contact
Recent | Search | Archive | CS Posts
Poster: Iriel at 2006-10-13 11:19:46
Subject: Guide to Secure Execution and Tainting
Secure Execution and Tainting

The User Interface API's for Wow 2.0 have been updated to prevent scripted automation of decision making using the same code security model that protects the movement functions in prior releases. This means that several more of the API functions have been protected against execution from insecure code.

A number of common WoW UI coding practices (most notably hooking) can easily cause problems in this model, preventing players from casting spells or performing actions, so I hope to explain how the security model works for developers in order for you to avoid these problems, as well as introducing some new Blizzard features to make existing ideas work under the new constraints.

Secure execution and "Tainting"

When WoW starts executing lua code, the execution starts off 'secure', and able to run protected functions. Execution remains secure until it encounters 'taint' - which is an indicator that a function or object came from an untrusted (AddOn or /script) source. The basic idea is that execution becomes 'tainted' as soon as it reads tainted data or executes tainted code, and any data written by a tainted execution is itself tainted. Protected functions refuse to operate when called from an execution path that is not secure.

When the UI first loads, all code and data from Blizzard signed FrameXML and AddOns (plus their saved variables) is secure, and all code and data from user provided AddOns (plus their saved variables) is tainted.

What can be tainted?

All lua values and references can be tainted - local variables, global
variables, table keys, table values:

* When new values are created (e.g. local x = 2) then they inherit the current taint of their execution path.
* When code accesses secure values, the resulting value will be tainted by the current execution path (but the original value remains clean).
* When code accesses tainted values, the resulting value will remain tainted and the execution path is also tainted.
* When code sets global values, the resulting value has the taint of the execution path.

Function closures can also be tainted, executing a function closure applies its
taint to the current environment.

Hooking and the hooksecurefunc function

The taint model is the reason that 'hooking' as it is commonly done today can easily break lots of UI functionality, trying to hook a function that is used by secure code causes a tainted function to be called in the middle of an otherwise secure execution path, this then taints the execution path so that nothing following the hook can use secure functions - don't be too dismayed however, we've been given a tool to get around this.

The new hooksecurefunc API function allows AddOn code to 'post hook' a secure global function, that is run another function after the original one has been run. So for example you could track calls to CastSpellByName using hooksecurefunc("CastSpellByName", mySpellCastTracker). The API replaces the original global function with its own secure hook function that calls the original function, saves its return values away, and then calls your hook function with the same arguments as the original function (any return values from your hook function are thrown away) and then it returns the return values from the original.

The 'special' feature of this secure hook is that when your hook function is executed, it executes with the taint that was present at the time the hook was created, and when your hook function is done that taint is discarded and the original secure (or possibly tainted - you cannot use hooksecurefunc to REMOVE taint, just avoid it) execution mode is restored.


UI and Macros Forum MVP - Understand GC!
Poster: Slouken at 2006-10-13 11:38:06
Subject: Re: Guide to Secure Execution and Tainting
Great explanation, thanks Iriel!
Poster: Slouken at 2006-10-18 02:45:23
Subject: Re: Guide to Secure Execution and Tainting

Q u o t e:
I have a quick question concerning the macro interface. I am assuming that "taint" can be introduced in a macro just like in a mod, but does it effect items outside a /script line? ex:

/script {series of lua commands}
/target Myshuna
/cast Spellname(Spellrank)

Will the "unsecure" code in the /script line break the macro thereafter, or are those commands executed as if they were simply part of the macro, and all the "taint" stays in the /script portion?

The "taint" stays in the /script portion.
Poster: Slouken at 2006-10-18 20:07:22
Subject: Re: Guide to Secure Execution and Tainting
FYI, the raid header template allows you to sort by id, by grouping, by class, and by name, and they dynamically update as players are moved in combat..

Please correct me if I missed anything, Esamynn...
Poster: Slouken at 2006-12-08 12:02:29
Subject: Re: Guide to Secure Execution and Tainting
The jump function changed names. I don't recall the new name offhand, something like JumpOrAscend() ...
Poster: Slouken at 2007-02-23 10:39:30
Subject: Re: Guide to Secure Execution and Tainting

Q u o t e:
been getting taint errors from the code below. any ideas?

-- SpellBookFrame

function HIC_ProcessSpellInterface()
local f = getglobal("SpellBookFrame")
if (f) then
if (not (f:IsMouseWheelEnabled() and f:HasScript("OnMouseWheel"))) then
f:SetScript("OnMouseWheel", HIC_Spell_OnMouseWheel)

function HIC_Spell_OnMouseWheel(frame, d)
if (not HICConfig.MWEnabled) then
local currentPage, maxPages = SpellBook_GetCurrentPage();
if (maxPages > 1) then
if (arg1 == -1) then
if (currentPage < maxPages) then
HIC_Debug("SpellBook Next Page")
if (currentPage > 1) then
HIC_Debug("SpellBook Previous Page")

swatter claims that my addon is calling castspell from non secure path and give me a line no which I traced to the following which is from spellbookframe.lua

function SpellButton_OnClick(drag) 

local id = SpellBook_GetSpellID(this:GetID());
if ( id > MAX_SPELLS ) then
if ( arg1 ~= "LeftButton" and SpellBookFrame.bookType == BOOKTYPE_PET ) then
ToggleSpellAutocast(id, SpellBookFrame.bookType);
CastSpell(id, SpellBookFrame.bookType);

Is SpellBookFrame.bookType getting changed inside NextPageButton_OnClick() ?

Is this thread News or Fluff? You Decide!
- OR -
What are you talking about?

View all recent official Blue Posts

WoW Blue Tracker: Archiving World of Warcraft Blue Posts
since March 2005
Home | RSS | News | Contact
Recent | Search | Archive | CS Posts

Why Ads?