tags:

views:

308

answers:

3

Is there an injection safe way to call via the axpata business connector

string salesId = someObject.Text;

IAxaptaRecord salesLine = ax.CreateRecord("SalesLine");
salesLine.ExecuteStmt("select * from %1 where %1.SalesId == '" + salesId + "'");

If someObject.Text is set to the following, i am then vulnerable to x++ code injection:

"SomeSalesOrder' || %1.SalesId == 'SomeOtherOrder"

Is there a way to parametrize the query, or would it be better to write all of the data access code directly in x++, and then call that from COM?

A: 

you should do a replace on ' to \' e.g.

string salesId = someObject.Text.Replace("'", "\\'");
Luke Schafer
I am looking for a parametrization method handled by the framework to handle all edge cases, not just the example I gave
holz
You could create an extension method for IAxaptaRecord that is something like 'ExecuteParametizedStmt(string query, params object[])this would accept the query in a format expected by string.Format and build it that way, after performing the required work on the variables (such as escaping)
Luke Schafer
The whole issue is handling escaping correctly. If the query was "select * from %1.Id == {0}" (where {0} should be an int), and then "42 || 1 == 1" is passed in, injection will still occur after I have escaped it with the method you gave.I don't know all of the edge cases of x++ injection here, so i don't want to write my own escaping method. Because if I do, chances are I would miss something, and I would only find out about it after it is too late. This is for a public facing web app with lots of confidential information, so i need to be 100% that there is no risk of injection.
holz
By default simple queries use placeholders, but if you want to be 100% sure you should use the ForcePlaceholders keyword for joined queries. This is the X++ way to write parametrized queries. You can also take a look at the "Microsoft Dynamics AX Server Configuration Utility" where you can configure the default behavior for complex queries.
Velislav Marinov
+1  A: 

There is no way to be sure you have covered all cases ...

Using ExecuteStmt is most likely the wrong approach. You should write your select or whatever in an Axapta method (with parameters) then call that method.

Jan B. Kjeldsen
Given you don't use literals, the default behaviour for simple queries is to use placeholders (parametrized queries), which is considered safe. For complex queries (joins) the only way to be sure is to use the ForcePlaceholders hint in joins.
Velislav Marinov
A: 

Holz,

You can use parametrized SELECT statements with the forcePlaceholder keyword. This is the default behavior in X++, but since this behavior can be overriden for complex joins, it's good idea to implicitly specify the forcePlaceholder hint.

As parametrized SELECTs impose some additional overhead, and don't allow optimiziation on the actual values of the parameters, you may want to consider using views, or axapta queries instead.

Regards, Velislav Marinov

Velislav Marinov
`forceplaceholders` will not solve the problem stated in the question.The use of literals in X++ as values do not pose a problem, as values are quoted by the kernel.
Jan B. Kjeldsen
You are wrong. ForcePlaceholders creates parametrized query, while ForceLiterals is vulnerable to SQL injection. Check the security whitepaper by MS.
Velislav Marinov
Security white paper: http://download.microsoft.com/download/b/6/e/b6e77418-cde2-4ed4-a920-60d7f2d17757/Microsoft%20Dynamics%20AX%20Writing%20Secure%20X++%20Code.docThe question was about the use of direct SQL through the Business Connector, which is a bad thing.The `forceliterals`/`forceplaceholders` is another issue. Forceliteral is an issue if the kernel quoting can be circumvented, which may be difficult to disprove.
Jan B. Kjeldsen
I agree that using direct sql is bad no matter whether through the BC or not. Your advice, which I support, was to use X++ methods, and my addition to that, was that the 'ForceLiterals' hint is vulnerable to SQL injection. My comment was based on the following recommendations from the same security paper: •Use safer alternatives for executing SQL: for example, use the Query class, Views, or X++ Select statements.•Do not use the forceLiterals keyword in X++ Select statements.•Do not set Query.literals(true).
Velislav Marinov