By Sebastiaan de Jonge, published on Tuesday, September 14, 2010 at 06:34

In this article I will explain how to bypass the table restriction that was made for CONTENT objects. This restriction is made for security reasons, however I wonder how useful it is since it's so easy to bypass.

The Restriction

By default we can only select data from the following tables.

  • pages
  • tt_*
  • tx_*
  • ttx_*
  • fe_*
  • user_*
  • static_*

Which will be enough in most cases, since we normally wouldn't need anything from sys_* or be_* tables. But what if we would like to select all languages for example? There's no harm in there, is there?

With this restriction it would mean we would have to create an extension to display a simple language menu.

The workaround

Bypassing this restriction is actually not so hard, we can do something that exploiters of SQL injections often do.. We can use a UNION SELECT.

Basically we can select something from an allowed table, e.g. pages, make sure that returns no results and simply add a UNION SELECT to get the data we actually want.

An example

So let's try this out, let's select all the records from sys_language with TypoScript. We will get some code like the following:

temp.languages = CONTENT
temp.languages {
        table = pages
        select.selectFields = uid,title
        select.pidInList = 0
        select.where = 1=2 UNION SELECT uid,title FROM sys_language WHERE 1;--
        renderObj = COA
        renderObj {
                10 = HTML
                10.value.field = uid
                20 = HTML
                20.value.field = title
                20.value.wrap = &nbsp;<strong>|</strong>
                wrap = <li></li>
        }
        wrap = <ul>|</ul>
}

As you see, I used pages as a dummy table. I will select everything from the pages table, where 1 equals 2. This will ensure I have no results. After that inside the WHERE clause of the select, I add my UNION SELECT. This is where I simply get the data from sys_language.

When using a UNION SELECT, make sure the amour of columns (selectFields) is the same on both selects. Otherwise you will get query errors.

Is this restriction really needed?

I'm a little curious about the opinions of people here. Since this 'restriction' is easy to bypass, is it really necessary for it to be there in the first place? I would say no, but perhaps you think otherwise…

Update

2010-09-15 16:00: Sorry for temporary disabling this article. There was a little discussion going on wether this was a security issue inside TYPO3 or not. Today I got an answer to my question from Oliver Klee. The TYPO3 security team agrees that this is NOT a security issue.

The reason for that is that on a normal installation, only an administrative user has access to TypoScript templates. Administrative users already have access to this data, so it doesn't provide them with any advantage.

Comments

Pim Broens
Pim Broens - Tuesday, September 14, 2010 at 09:13

Don't know if the actual question is, necessary or not. Might it should be: good enough or not?The restriction is there for a reason, but when used correct nothing should be wrong.

Usually the person creating the SQL / TS has access to the database and is otherwise able to create an extension to get the data anyway.

So in my opinion it should be changed, either to a better check, not even allowing UNION SELECTS etc. with security risks tables. Or change it by removing the check and thus enabling the use of these CONTENT to it's full potential.

Sengchheang CHHUN
Sengchheang CHHUN - Wednesday, January 15, 2014 at 05:13

Also something like andWhere = 1 = 1 OR (pid = 0).