My apologies, I was forgotten to follow up here.
I got a response from Itzik. His source is an old blog post from Conor Cunningham - another man to take VERY seriously if he writes about SQL Server. Here is a link: http://www.sqlskills.com/BLOGS/CONOR/2008/02/default.aspx?page=2
. I think it's an old and abandoned blog, the comments link does not work, but the post itself can still be read.
What it amounts to is that SELECT * is first replaced with SELECT <list of columns>, then permissions are checked, and only then does the optimizer realize that it's inside an EXISTS and so removes the column lists again. See the Microsoft feedback on https://connect.microsoft.com/SQLServer/feedback/details/533491/users-with-select-permission-on-one-column-in-a-table-get-errors-from-if-exists-select-from-table
for an explanation of WHY these permissions are checked (though I don't agree 100%).
However, the differences between all these variants are incredibly small, and not really worth spending any amount of time or energy on. I mainly use SELECT * in EXISTS because it's the most common and sort of standard version, and because it documents that I am interested in existence of a row.
Hugo Kornelis, SQL Server MVP
Visit my SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis