EducationSoftwareStrategy.com
StrategyCommunity

Knowledge Base

Product

Community

Knowledge Base

TopicsBrowse ArticlesDeveloper Zone

Product

Download SoftwareProduct DocumentationSecurity Hub

Education

Tutorial VideosSolution GalleryEducation courses

Community

GuidelinesGrandmastersEvents
x_social-icon_white.svglinkedin_social-icon_white.svg
Strategy logoCommunity

© Strategy Inc. All Rights Reserved.

LegalTerms of UsePrivacy Policy
  1. Home
  2. Topics

KB483609: FreeForm SQL that contains text Prompt: Parameterized vs non-Parameterized


Qinyi Chen

Quality Engineer, Principal • Strategy


After enabling Parameterized Queries on Database connections, we might notice that a FreeForm SQL report which uses Text Prompt fails to work. This is likely caused by single quotes around the text prompt in the FreeForm SQL and after removing those, the report should work fine with Parameterized Queries. In this article, we will use examples to compare the different behaviors and present some approaches to modify the existing reports so that they work alongside parameterized queries.

When parameterized queries is turned OFF


Many users may have created their project a long time ago and had the option turned off. When it is off, the behavior is straightforward. The Engine takes whatever text input a user supplies and simply concatenates it in the query, sends the query to the warehouse and retrieves the result back.
However, such an approach is not only bad for performance, but also a security risk, as it is extremely vulnerable to SQL injection.
Let's play the role of a report designer who creates a Freeform SQL report to pull out all the Customers by searching Customer last name and expects the user to provide last names as prompt answers before running the report.

Step 1:


Create a Report in Developer, choose Freeform Sources and Create Freeform SQL report. 

ka0PW0000000hEfYAI_0EM2R000000lyjL.jpeg

Step 2:


Define the query and mapping to pull the data. It is important to notice the single quotes in the brackets. 

ka0PW0000000hEfYAI_0EM2R000000lyjQ.jpeg

Step 3:


Right-Click in between the single quotes and select Add New Prompt. It indicates the Engine to trigger a text prompt when the report executes. 

ka0PW0000000hEfYAI_0EM2R000000lyjV.jpeg

Choose Value prompt -> Text prompt. Leave the rest by default and save it.

Step 4:


The report may look like this:

ka0PW0000000hEfYAI_0EM2R000000lyja.jpeg

Step 5:


Define the mapping of return values to attribute Customer:

ka0PW0000000hEfYAI_0EM2R000000lyjf.jpeg

Step 6:


Save the Report and execute it. Give a sample answer, Smith and click Finish.
The report retrieves all the customers with last name Smith.

ka0PW0000000hEfYAI_0EM2R000000lyjk.jpeg
ka0PW0000000hEfYAI_0EM2R000000lyjp.jpeg

Try to View SQL and we can see the text Smith is embedded in the query.

ka0PW0000000hEfYAI_0EM2R000000lyju.jpeg

If the user checks the SQL Trace, they can see a query like this was sent to the warehouse, and the parameter is sent directly in the query:

select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME  from lu_customer where CUST_LAST_NAME in ('Smith')

Due to security reasons, such a Prompt will not accept multiple answers, as the user will NOT be able to put in Smith’,’Wood and expect a query to look like:
select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME  from lu_customer where CUST_LAST_NAME in (‘Smith’,’Wood’).

When parameterized queries is turned ON


Many users choose to enable parameterized queries for security and performance reasons. After enabling parameterized queries, a revision of the Freeform SQL reports may be necessary.
Please see this page about how to enable Parameterized queries.
https://community.Strategy.com/s/article/KB438401-Security-Fix-in-10-5-Secure-Freeform-SQL-report-s-text-prompt?language=en_US
After enabling parameterized queries, if the user executes the report created above, the execution will fail.

ka0PW0000000hEfYAI_0EM2R000000lykE.jpeg

To fix the issue, the user needs to manually edit the free form query and remove the single quotes.

ka0PW0000000hEfYAI_0EM2R000000lykO.jpeg

If the user checks the SQL Trace, they can see a query like this was sent to the warehouse:
Before removing the quotes:

select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME  from lu_customer where CUST_LAST_NAME in ('?') --Failed

After removing the quotes:
select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME  from lu_customer where CUST_LAST_NAME in (?)  --Success

The parameter will not show up in the log for security reasons and it is expected.
The above case is how a typical FFSQL report with text prompts is designed. There are some other variations that users may have designed. For example, a report designer may have created an FFSQL with a LIKE function and a prompt that expects only partial filtering text, surrounded by % signs.

ka0PW0000000hEfYAI_0EM4W000001LDm3.jpeg

To fix a case like this, both the report designer needs to remove '% and %' around the text prompt, and the user needs to supply the % signs in the prompt answers. There might be more variants of this case and to summarize, when Parameterized Queries is on, 1) the text prompt should not be quoted anymore, 2) all the content used to be inside the quotes should be provided together as the answer to the prompt.
After the modification the new FFSQL definition should be:

ka0PW0000000hEfYAI_0EM4W000001LDoO.jpeg

Assuming users used to answer the prompt with 2006, now they should answer the prompt with %2006%.
 

But why?


To explain the change, we must start with the fundamental difference between these 2 options.
When parameterized queries are disabled, the Data Engine treats the entire query as strings. 


String 1 = “select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME  from lu_customer where CUST_LAST_NAME in ('” 
String 2 = [Prompt Answer]
String 3 = “')”

After receiving the Prompt Answer, Engine parses the String to ensure its safety, then concatenates String 1, String 2 and String 3 into a complete query. Then send this query to the warehouse. And if the SQL Trace log is turned on, the user will see the whole query in it.
When the parameterized queries are enabled, the Data Engine will prepare a statement with placeholders, and then send it and the prompt answer separately. The prompt answer is no longer a String but a variable. Most modem database system can take the statement together with the parameters and compile the complete query on their side. Therefore, on the Engine side, as shown in the SQL Trace, users can only see the placeholders.
With the parameterized queries turned on and a pair of single quotes around the prompt, the Data Engine cannot resolve the answer or prepare the statement, and the report will fail. Therefore, the user who has a predefined freeform SQL with text Prompt needs to modify their query.
Another great advantage of using parameterized queries is the prompt now allows multiple answers.
For example, using the above report, if a user wants to search for customers whose last name is Smith or Wood, answering the prompt: 'Smith','Wood'. Note that each answer is quoted by single quotes and linked by a comma. The syntax here is very strict. No space is allowed after the comma.

ka0PW0000000hEfYAI_0EM2R000000lykn.jpeg
ka0PW0000000hEfYAI_0EM2R000000lyks.jpeg

Since when the value is surrounded by a pair of single quotes, the Engine will take it as a string value and removes the single quotes, if the search term does include single quotes, the user will have to use 2 single quotes. For example, one of the Customer’s Last name is ‘Smith’, if the user answers the prompt with ‘Smith’, the Engine will only look for Last name Smith. The user must answer the prompt with ''Smith’' to ensure the correct value is returned.

ka0PW0000000hEfYAI_0EM2R000000lykx.jpeg

View SQL

As mentioned, when SQL Trace is enabled, users can see the different behavior between Parameterized vs non-Parameterized. But how does the View SQL look like?

Before execution

Before the report is executed, users will always see the placeholder ? at the prompt value. The only difference is whether there are single quotes around the ?, which is the difference in the report freeform queries.
With parameterized queries turned off:

ka0PW0000000hEfYAI_0EM2R000000lymK.jpeg

With parameterized queries turned on:

ka0PW0000000hEfYAI_0EM2R000000lymF.jpeg

After execution

After the execution, with Parameterized queries turned off, users will see the prompt answer directly:

ka0PW0000000hEfYAI_0EM2R000000lylv.jpeg

After the execution, with Parameterized queries turned on, users will still see the ? in the query, but followed by the parameters that the Engine parsed from Prompt input:

ka0PW0000000hEfYAI_0EM2R000000lymP.jpeg

When there are multiple values, there are multiple placeholders and parameters separated into lines.

ka0PW0000000hEfYAI_0EM2R000000lylR.jpeg

Another scenario when redefining the Freeform SQL definition may be necessary: 
For example, if the existing Freeform SQL report has multiple insert statements, the report execution will fail if parameterized query is turned on.

ka0PW0000000hEfYAI_0EM4W000001JeUY.jpeg

The following error is returned:
Error: QueryEngine encountered error: OdbcPreparedStatement::Prepare failed. 

ka0PW0000000hEfYAI_0EM4W000001JeUT.jpeg

The reason for this error is that a parameterized query must contain exactly one SQL statement. This is to prevent SQL injection attacks, which frequently attempts to append an unexpected SQL after a valid SQL statement. 
To fix this report, it must be redesigned to be 3 separate Freeform SQL reports, each with 1 INSERT SQL. For example: 
 

ka0PW0000000hEfYAI_0EM4W000001JeUd.jpeg

Now the report will execute properly. 
It should be noted that when using statements that modify the contents of a database, such as INSERT, the best practice is to use Transaction Services reports. A Transaction Services report can have multiple SQL statements in one report, and combine them into one logical transaction, meaning all the statements will either succeed or fail. This makes the query much more robust. For more information, see Creating a Transaction Services Report.
Reference
More comprehensive document: community.Strategy.com/s/article/KB438401-Security-Fix-in-10-5-Secure-Freeform-SQL-report-s-text-prompt?language=en_US
How to enable SQL Trace: https://community.Strategy.com/s/article/KB13189-How-to-trace-the-SQL-generated-by-Strategy-Engine?language=en_US
 
 


Comment

0 comments

Details

Knowledge Article

Published:

September 13, 2019

Last Updated:

February 13, 2024