AS400 library/file (member) JDBC query - sql

Using JDBC (with jt400 driver / connection, naming=system) I'm running these SQL statements:
"CREATE ALIAS QTEMP/SOURCETEMP FOR " + library + "/" + file + " (" + member + ")"
"SELECT SRCDTA FROM QTEMP/SOURCETEMP"
"DROP ALIAS QTEMP/SOURCETEMP"
This works. However, when the member String has a . in it this confuses everthing.
Is there any way of dealing with this?
Thanks.

You can escape any .'s by changing eg:
member = "foo.bar"
to
member = "\"FOO.BAR\""
ie capital letters enclosed within double quotes.

Somewhere in here there are details on how library(members) are handled.
Your problem seeems to be the basic member name is leant to be up eight chars and anything after a '.' is interpreted as a type (somewaht like .html, .jpg .exe etc)
however you can only store one type of data in a library object. So if your first member was premier.stuff than all the other member must have ".stuff" as a suffix if supplied.
The official 400-eze for a member is:
member
Different sets of data, each with the same format, within one database file.
You could probably get away with deleting everything after the first period from your member name.
Sorry if this isn't too clear but when the iSeries was designed they ignored every OS designed up till that point and started again from scratch. The results take some getting used too.

Related

How do I prevent my SQL statements from SQL injection when using CLR/C++ with multiple variables?

I am having a major problem where I do not know how to prevent SQL injection when writing SQL statements in CLR/C++
Below is the code
String^ sqlstr = "SELECT * FROM ";
sqlstr += tableName + " WHERE " + field + " = " + fieldEntity;
I need to be able to input correct SQL Injection preventions to this statement.
Background code
class database
{
protected:
string fieldEntity;
string tableName;
string field;
...
____
OleDbDataReader^ openData(String^ fieldEntity, String^ field, String^ tableName)
{
String^ sqlstr = "SELECT * FROM ";
sqlstr += tableName + " WHERE " + field + " = " + fieldEntity;
...
___
OleDbDataReader^ reader2 = testData.openData(effectID, "effectID", "effectOnUser");
while (reader2->Read())
{
Object^ dHealthptr = reader2["effectOnHealth"];
Object^ dTirednessptr = reader2["effectOnTiredness"];
Object^ dHappinessptr = reader2["effectOnHappiness"];
...
There are two ways to prevent SQL Injection and the environment of SQLCLR does not change this:
The preferred mechanism is by using parameterized queries. Different languages and libraries go about this in different ways, but at the very least you should be able to use prepared statements. Please note that this does not apply to scenarios that could not accept a variable, such as with tableName and field in your code.
Please see:
Issuing a Parameterized Query
Using Stored Procedures
Sanitize the inputs:
Bare minimum, and by far the most common, requirement is to escape single quotes by doubling them (i.e. ' becomes '')
Additionally (below is a quote from a related answer of mine on DBA.StackExchange):
There is a lesser known type of attack in which the attacker tries to fill up the input field with apostrophes such that a string inside of the Stored Procedure that would be used to construct the Dynamic SQL but which is declared too small can't fit everything and pushes out the ending apostrophe and somehow ends up with the correct number of apostrophes so as to no longer be "escaped" within the string. This is called SQL Truncation and was talked about in an MSDN magazine article titled "New SQL Truncation Attacks And How To Avoid Them", by Bala Neerumalla, but the article is no longer online. The issue containing this article — the November, 2006 edition of MSDN Magazine — is only available as a Windows Help file (in .chm format). If you download it, it might not open due to default security settings. If this happens, then right-click on the MSDNMagazineNovember2006en-us.chm file and select "Properties". In one of those tabs there will be an option for "Trust this type of file" (or something like that) which needs to be checked / enabled. Click the "OK" button and then try opening the .chm file again.
So, be sure to properly size the string input parameters. You don't need VARCHAR(500) for a column that is declared as VARCHAR(25). Please see my answer on DBA.StackExchange for more details and examples:
Why does SQL Injection not happen on this query inside a stored procedure?
For tableName and field variables, those are being used as SQL identifiers in your query. You can't use either common method of query parameters or escaping. You just have to make sure to whitelist the values for those variables. In other words, check them against known identifiers of tables and columns in your database.
For the other variable fieldEntity, I suppose this should be used like a constant value in your SQL query. You can protect this from SQL injection by using a query parameter.
I don't know CLR, but there are lots of examples of using SQL query parameters in C++ or C#.
https://owasp.org/www-project-cheat-sheets/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html

Can you print variables that are dynamically generated?

I am trying to setup a program that takes user input for database ddl generation. I have it working to the point where it can ask a user for the name of the table, the number of columns and any attributes that might be needed. The problem comes when I try to print a string that includes the variables used for the column names. Due to trying to let users have as many columns as they want I used variables similar to this newvar(number that increases every time you enter a column name). This works fine and I can get the values if i do send %newvar1% but it doesn't work to do send newvar%increasing number%. I need to know if this is possible or if I'm just missing something obvious. Also I don't have the code with me but I can post it once I get back to my main computer.
I have tried quite a few things like, send %newvar%%number%, send newvar%number%, othervar = newvar%number% send %othervar%.
I'll show some once I have access to it in about 2 hours.
I expect to be able to output names for increasing variables using an ever increasing number. Class is starting I'll clarify some things later.
You can use a lone percent % beginning the first argument for the send command to achieve what you want. This will make everything after it to be evaluated (up to the next comma). Here is an example:
f1::
newvar1 := "This " , newvar2 := "is just a " , newvar3 := "test."
Loop , 3
Send , % newvar%A_Index%
Return
See: https://www.autohotkey.com/docs/Language.htm#-expression

String within externally saved Qlik Sense expression

I have a small issue, so here's a bit of background:
We are developing a Qlik Sense application and we normally write our expressions to an external script. We save these as variables, and then evaluate the variables in the application. The advantage of this is a) we can use better version control with GIT, and b) we can separate the queries from the application if we ever need to change platforms in future.
My Problem:
I have come across a situation where we need to concat a string to the result of an expression, which can be done easily in the application, but when you save the expression to an external file the single quotes around the expression interfere with the single quotes around the string.
I tried
using double quotes for the string only, but qlik doesn't evaluate it correctly.
same goes for the expression using double quotes only.
escaping the single quote inside the expression, eg. "\'" but same story.
What I was thinking of doing next was changing the quote to a rogue character so qlik would ignore it as text, then replacing it with a quote later so qlik would then try to evaluate it.
Example Code:
SET variable = 'if(isnull(month),'Month: ' & date(now(), 'MMM-YYYY'),'Month: ' & only({$<year={2016}, month={6}>}month)';
After some further research I found that Qlik has its own way of escaping characters without using the "\" character. I was able to solve this issue by escaping the inner single quotes like this:
SET variable = 'if(isnull(month),''Month: '' & date(now(), ''MMM-YYYY''),''Month: '' & only({$<year={2016}, month={6}>}month)';
Feels like a pretty silly oversight now, but hopefully this will save someone some time in the future.

VisualBasic OleDb accessing Excel spreadsheet, can't set column in query using parameter?

I'm working in Visual Basic and using OleDb to access an Excel spreadsheet. I'm importing the data from the sheet into my DataGridView, and that works fine, but now I'm working on filtering. For the most part it works great, but I'm trying to use parameters ("#p1" and so on), and I'm getting a very strange issue.
I can have the following (excluding a bunch of irrelevant stuff before, in between, and after)
query = query & "Project" & " LIKE #Gah1"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "%House%")
and it gives me the results I'm looking for. But I can't seem to get a parameter for the name of the column itself, for example
query = query & "#Gah1" & " LIKE #Gah2"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "Project")
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah2", "%House%")
does not work (and I've tried enclosing Project in different brackets and stuff in different ways, can't get it to work). I've found plenty of examples on using parameters, but none that use them to give the column name.
I'm guessing the parameter changes how the string is represented, seeing as you don't need to have the ' ' around string literals.
Is it not possible to give column names in parameter? If you can, what do I need to do?
Well it won't let me post comment, so here
a) Oops, no, I guess not
b) The string query that I end up sending in my test query here is
"select * from [Bid Summary$] where #Gah1 LIKE #Gah2"
I can post the procedure if absolutely need be, but it isn't the problem because the whole thing works perfectly fine if I replace #Gah1 with Project or [Project], so I just showed the lines that I change.
I'm very new to parameterized queries, can you explain how to avoid query strings using it? If there's a better way to do what I'm doing I'm happy to use it =)
And thanks for response and edit
I use combination of string methods and parameters, like this:
//replace field name in a query template
query = String.Format("select * from [Bid Summary$] where {0} LIKE ?", "#Gah1");
//set value (name is in OleDb parameter ignored, so it could be null)
MyCommand.SelectCommand.Parameters.AddWithValue(null, "%House%");
Note: There is possibility of a sql injection, so be sure about origin of field name (not from user input).

What characters are allowed in Oracle bind param placeholders?

Could anyone please point me to where the characters allowed for a bind variable name are listed? I've spent several hours digging through Oracle SQL docs to no avail.
I mean ":id" in the following:
SELECT * FROM mytable WHERE id = :id
E.g. can a dot be used there like ":some.id"? Will it function exactly like the version without the dot?
These pages both state bind variables must be "legal Oracle identifiers"
The documentation I found doesn't specifically say that a dot can
be part of a legal identifer. I was able to use a dot in both
a table name and as a bind variable name, but it looks like it is
not recommended.
PAGES THAT HAVE BIND VARIABLE NAMING CONVENTIONS
(These pages state a bind variable must be a legal identifier):
http://www.utoug.org/i/doc/concept_bind_var.htm
http://docs.oracle.com/cd/E23903_01/doc.41/e21674/concept_ses_val.htm#BEIEGCCC
PAGE THAT DESCRIBES LEGAL IDENTIFIERS:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements008.htm
I could not find anything on this page that says that a dot is a legal
part of an identifier (E.G. table or bind variable name) except in a DB link.
Even though $ and # are legal, they are not even recommended, so "."
may work but is obviously not recommended (not even mentioned as legal on
this page)
Bind variable names must correspond to an item name.
Bind variable names are not case-sensitive.
Bind variable names cannot be longer than 30 characters (that is, they must be a valid Oracle identifier).
I know that a valid ORACLE identifer (based on ORACLE's definition
of a legal identifier) cannot start with a number,
and can have SOME special characters like $ and . but if there are
special characters the identifier MUST be in double quotes.
I was able to get an identifier with a dot to work in a bind
variable, but I had to put double quotes around the bind
variable when the bind variable had a dot in it.
create or replace function F0416B
RETURN VARCHAR2
is
V_STMT VARCHAR2(1999);
V_RESULT VARCHAR2(1999);
BEGIN
V_STMT := 'INSERT INTO TEST0411(FIELD1, FIELD2) VALUES ( :"A.1" , :"A.2")';
EXECUTE IMMEDIATE V_STMT USING 'AS201', 'AS202';
RETURN 'INSERT-OK';
COMMIT;
EXCEPTION
WHEN OTHERS THEN RETURN SQLERRM;
END;
#This may work but according to the above documentation a period/dot
in a bind variable or other object name is not legal/recommended...
#This is the sentence on the ORACLE schema object naming page that is
telling me this:
Nonquoted identifiers can contain only alphanumeric characters from your database character set and the underscore (_), dollar sign ($), and pound sign (#). Database links can also contain periods (.) and "at" signs (#). Oracle strongly discourages you from using $ and # in nonquoted identifiers.
I also had trouble finding the official Oracle doc for this: http://docs.oracle.com/cd/E14072_01/appdev.112/e10646/oci04sql.htm#i420655
On top of that, it turns out that you can quote placeholders (:"_normallyinvalid") and then most of the rules listed in the preceding link stop being relevant. I couldn't find any Oracle doc offering this suggestion; just hints around the internet.