With the release of TYPO3 v.4.4 a small but powerful feature was introduced to make displaying content with queries in Typoscript both safer and more flexible. Not too many people have noticed the extra possibilities the use of markers in the properties of the 'select' property give us.
If you wanted to render content based on values in query parameters in the URL the possibilities were quite limited.
Some properties of 'select' only accept (a list of) integer or string values without stdWrap support.
For properties where you can insert external data the construction makes this piece of Typoscript vulnerable for SQL-injections.
The value of each property can contain one or more markers, just like markers in an HTML template. The value of each marker is defined in a special section named 'markers' which gives full stdWrap support to each marker. Before replacing the marker with its value the value is quoted and escaped if necessary to prevent SQL-injections.
Examples are perhaps the best way to explain the features:
10 = CONTENT
10 {
table = tx_myext_tags
select {
selectFields = name, uid
pidInList = 73
where = name = ###sword###
max = 1
markers {
sword.data = GP:tx_myext_pi1|sword
}
}
renderObj = TEXT [...]
}
When the URL contains &tx_myext_pi1[sword]=two%20words this will result in a query
SELECT name,uid
FROM tx_myext_tags
WHERE name='two words' AND pid IN (73)
AND deleted=0 and hidden=0 LIMIT 1;
Suppose we have an evil visitor who starts some investigation by using &tx_myext_pi1[sword]=' or 'x'='x (or properly encoded '%20or%20'x'%3D'x ). If the old situation was:
andWhere.dataWrap = name='{GP:tx_myext_pi1|sword}'
the query would become:
SELECT name,uid
FROM tx_myext_tags
WHERE name='' or 'x'='x' AND pid IN (73)
AND deleted=0 and hidden=0 LIMIT 1;
It's not a dramatic query yet, but you can see that it was modified in a way which was not meant originally.
With the use of markers the query variable sword is properly quoted (and escaped) before it replaces the marker:
SELECT name,uid
FROM tx_myext_tags
WHERE name='\' or \'x\'=\'x' AND pid IN (73)
AND deleted=0 and hidden=0 LIMIT 1;
The query will most likely give no results, but the text the visitor entered is now completely harmless.
Now the URL contains a list of uids: &tx_myext_pi1[display]=1,53,951 (or properly encoded: 1%2C53%2C951).
10 = CONTENT
10 {
table = my_ext_table
select {
uidInList = ###displayids###
markers {
displayids.data = GP:tx_myext_pi1|display
displayids.commaSeparatedList = 1
}
}
}
Because normally the list of uids would be seen as a string this would lead to WHERE uid IN ('1,53,951') , which is of course not what we want. Setting .commaSeparatedList to 1 will indicate that this marker value must be interpreted as a comma separated list of values. Now each value in the list will be checked and if necessary quoted and escaped:
WHERE uid IN (1,53,951)
If it were a list of string (a,b,c) this would result in
WHERE column IN ('a','b','c')
Also note that we are now able to dynamically set the property uidInList. This is also possible for other properties of 'select' which have no stdWrap support directly.
If you display content in Typoscript using the CONTENT object with TYPO3 4.4 or newer you should always use markers to insert data into properties. The advantages are:
No comments yet. Be the first to comment on this!