sql injection. What is the difference between " 'OR 1=1 #" and " ' OR 1=1 -- "? - sql-injection

There are several version of sql injection method, but I don't know why there are slightly difference exactly.
How can I know the difference among the environments?

TL;DR — the # form is usable only on MySQL. The -- form is usable on any brand of SQL.
Both # and -- are used to introduce comments. The purpose of both in an SQL injection attack is to make sure the rest of the line is ignored.
SELECT * FROM MyTable WHERE name = '$unsafe_variable' AND id = 12345
An SQL injection attack might be able to interfere with the $unsafe_variable but the query would still be limited to the one row with a specific id. But what if the SQL injection attack could effectively neutralize the second term?
SELECT * FROM MyTable WHERE name = '' OR 1=1 -- ' AND id = 12345
^^^^^^^^^^^^
Anything past the -- is a comment, so it will be ignored by the query. It doesn't matter that the comment contains content that looks like more SQL syntax.
The -- is the only comment syntax that is specified by standard ANSI SQL, and all SQL implementations should support this syntax.
But most if not all SQL implementations support other comment syntax, because developers are more familiar with using it. Notably the /* comment */ syntax, because it allows multi-line comments, and it's supported by many other programming languages.
Both -- comment or /* comment */ are supported by all SQL brands I checked:
MySQL
Oracle 10g
Microsoft SQL Server
PostgreSQL
SQLite
IBM DB2
Firebird
Informix
The # comment syntax is supported only by MySQL.
The { comment } syntax is supported only by Informix.

simply it is different syntax between DB engines “ OR 1=1 #” it works with mysql DB because comment there is using # but “ OR 1=1 — ” works with sql server BD becsuase comment there using -- for more details about sql injection methods samples check this link

Related

Is there such a thing as a "PostgreSQL-SQL-to-OtherDB-SQL" converter in PHP, or at all?

I use PostgreSQL exclusively. I have no plans to ever change this. However, I recognize that other people are not me, and they instead use MySQL, MS SQL, IBM SQL, SQLite SQL, Oracle SQL and ManyOthers SQL. I'm aware that they have different names in reality.
My queries look like:
SELECT * FROM table WHERE id = $1;
UPDATE table SET col = $1 WHERE col = $2;
INSERT INTO table (a, b, c) VALUES ($1, $2, $3);
My database wrapper functions currently support only PostgreSQL, by internally calling the pg_* functions.
I wish to support "the other databases" too. This would involve (the trivial part) to make my wrapper functions able to interact with the other databases by using the PHP functions for those.
The difficult part is to reconstruct the PostgreSQL-flavor SQL queries from the application into something that works identically yet will be understood by the other SQL database in use, such as MySQL. This obviously involves highly advanced parsing, analysis and final creation of the final query string. For example, this PostgreSQL SQL query:
SELECT * FROM table WHERE col ILIKE $1 ORDER BY random() LIMIT 1;
... will be turned into WeirdSQL like this:
SELECT * FROM table WHERE col ISEQUALTOKINDA %1 ORDER BY rnd() LIMIT 1;
I don't require support from any other input SQL flavor than PostgreSQL, but the output must be "all the big SQL database vendors".
Has anyone even attempted this? Or is it something that is never gonna happen as free software but might exist as a commercial offering? It sounds like it would be a thing. It would be insanely useful, and "crazier" projects have been attempted.
jOOQ is a Java library that aims to hide differences between databases. It has its own SQL grammar which tries to be compatible with everything (but parameter markers must be the JDBC ?), and generates DB-specific SQL from that.
There is an online translator, which generates the following from your query for Oracle:
select *
from table
where lower(cast(col as varchar2(4000))) like lower(cast(:1 as varchar2(4000)))
order by DBMS_RANDOM.RANDOM
fetch next 1 rows only
ODBC uses its own syntax on top on the database's syntax. ODBC drivers are required to convert ODBC parameter markers (?) to whatever the database uses, and to translate escape sequences for certain elements that are likely to have a non-standard syntax in the DB (time/GUID/interval literals, LIKE escape character, outer joins, procedure calls, function calls).
However, most escape sequences are optional, and this does not help with other syntax differences, such as the LIMIT 1.
ODBC drivers provide a long list of information about SQL syntax details, but it is the application's job to construct queries that conform to those restrictions, and not all differences can be described by this list. In practice, most ODBC applications restrict themselves to a commonly supported subset of SQL.

cakephp condition using '?' in the string [duplicate]

For detecting the existence of a key in a hstore, I need to run a query like this:
SELECT * FROM tbl WHERE hst ? 'foo'
However, that gives me a PDOException:
PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'
Is there any way to escape the question mark so PDO won't pick it up as a placeholder? I've tried with up to four backslashes, as well as a double question mark (??), but nothing seems to persuade PDO to leave the question mark alone.
Use the function call form. According to the system catalogs, the hstore ? operator uses the exist function:
regress=# select oprname, oprcode from pg_operator where oprname = '?';
oprname | oprcode
---------+---------
? | exist
(1 row)
so you can write:
SELECT * FROM tbl WHERE exist(hst,'foo');
(Personally I'm not a big fan of hstore's operator-centric design and documentation, I think it discards the useful self-documenting properties of a function based interface without any real benefit and I usually use its function calls rather than its operators. Just because you can define operators doesn't mean you should.)
I had the same problem when searching on JSONB data. The full question is here
SELECT * FROM post WHERE locations ? :location;
The workaround on PostgreSQL 9.5 is similar:
SELECT * FROM post WHERE jsonb_exists(locations, :location);
I also opened a ticket at PHP bug tracing system
Update
As Diabl0 mentioned, the proposed solution work but does not use the index.
Tested with:
CREATE INDEX tempidxgin ON post USING GIN (locations);
I suggest you disable PDO native prepared statement so question marks will be ignored:
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);

Is it possible to get explain plan with bind variables in DB2?

With Oracle, the syntax is:
explain plan for
select * from users WHERE user_name = :user_name AND user_dob = :user_dob
Is it possible to do the same in DB2? The statement below does not seem to work.
explain plan with snapshot for
select * from users WHERE user_name = :user_name AND user_dob = :user_dob
Thank you.
The answer may depend on your DB2 version and platform, which you chose not to share with us for some reason. This works fine on DB2 for LUW (v10.1, but I'm sure it would work with v9.7 and up):
$ db2 "explain plan with snapshot for select * from syscat.schemata where schemaname = :blah"
DB20000I The SQL command completed successfully.
You may want to try replacing named parameter markers with questions marks.
Apparently, the answer is in the IBM website, but it is not easy to make sense of.
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.admin.doc%2Fdoc%2Fr0000952.htm
FOR explainable-sql-statement
Specifies the SQL statement to be explained. This statement can be any
valid CALL, Compound SQL (Dynamic), DELETE, INSERT, MERGE, SELECT,
SELECT INTO, UPDATE, VALUES, or VALUES INTO SQL statement. If the
EXPLAIN statement is embedded in a program, the
explainable-sql-statement can contain references to host variables
(these variables must be defined in the program). Similarly, if
EXPLAIN is being dynamically prepared, the explainable-sql-statement
can contain parameter markers.
But it does not tell you what "parameter markers" are, so you have to go and search for it.

Using a straight sql statement in a progress application

What is the syntax to run a straight sql statement in a progress application?
SELECT count(distinct myField2) FROM myTable WHERE myField = myVariable);
I've figured out how to do this with a for each but I would still like to run this command.
Using a for each:
def var iTmpCount as int no-undo.
for each myTable no-lock where myField = myVariable break by myField2:
if first-of (myTable.myField2) then
iTmpCount = iTmpCount + 1.
end.
The 4GL has an ancient and deprecated implementation of SQL-89.
You can do some simple things successfully. It is sometimes helpful for an ad-hoc query.
The documentation is limited and, since it is a deprecated feature, it will never be improved or enhanced.
The 4GL is not a SQL tool and the embedded SQL support should not be used. Don't try to apply SQL thinking to 4GL, you will only regret it.
SQL-92 is supported via the ODBC & JDBC drivers. But that is outside the 4GL.

Syntax error at end of input in PostgreSQL

I have used the next SQL statement in both MySQL and PostgreSQL, but it fails in PostgreSQL
db.Query(`SELECT COUNT(*) as N FROM email WHERE address = ?`, email)
with this error:
pq: F:"scan.l" M:"syntax error at end of input" S:"ERROR" C:"42601" P:"50" R:"scanner_yyerror" L:"993"
What's the problem? The error messages in PostgreSQL are very cryptic.
You haven't provided any details about the language/environment, but I'll try a wild guess anyway:
MySQL's prepared statements natively use ? as the parameter placeholder, but PostgreSQL uses $1, $2 etc. Try replacing the ? with $1 and see if it works:
WHERE address = $1
The error messages in PostgreSQL are very cryptic.
In general, I've found that Postgres error messages are better than competing products (ahem, MySQL and especially Oracle), but in this instance you've managed to confuse the parser beyond sanity. :)
In golang for queries we have use
MySQL uses the ? variant
PostgreSQL uses an enumerated $1, $2, etc bindvar syntax
SQLite accepts both ? and $1 syntax
Oracle uses a :name syntax
You are using Go right?
try:
db.Query(`SELECT COUNT(*) as N FROM email WHERE address = $1`, email)
In my case, it was due to using a -- line comment where the program that was responsible for interacting with the database read in the multiple lines of my query all as one giant line. This meant that the line comment corrupted the remainder of the query. The fix was to use a /* block comment */ instead.