What programming language is this code from? - sql

I am looking at some SQL code:
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
I know in php it uses $_GET or $_POST to retrieve the values entered in a form so I am just wondering what is the language the first statement is written in that is retrieving the values?

I'm going to answer this definitively. No, not the language question, but the actual, important part of that code snippet.
Do Not Open Yourself To SQL Injection Attacks.
That code puts in the text contents of UserId directly into the SQL statement. Which means that someone can enter something like:
UserId=-1 or (1=1)
... and get the entire table. Or:
UserId=-1; NewSQLStatementStartsHere
... and start running malicious SQL statements on your server.
Never inject raw values into SQL. Always use parameterized values. SQL Injection Attack is still the #1 cause of security vulnerabilities in software.

Related

Why do Parameterized queries allow for moving user data out of string to be interpreted?

From https://en.wikipedia.org/wiki/Code_injection#Preventing_problems
To prevent code injection problems, utilize secure input and output handling, such as:
Using APIs that, if used properly, are secure against all input characters. Parameterized queries (also known as "Compiled queries", "prepared statements", "bound variables") allows for moving user data out of string to be interpreted. Additionally Criteria API[7] and similar APIs move away from the concept of command strings to be created and interpreted.
I was wondering how and why "parameterized queries (also known as "Compiled queries", "prepared statements", "bound variables") allows for moving user data out of string to be interpreted" and prevent or mitigate code injection problems?
Can you also provide some examples in explanation?
Thanks.
Compiled queries use special syntax that the database understands. They usually add placeholders for parameters such as in:
select * from applicant where name = ?
select * from applicant where name = :name
The exact syntax depends on the specific technology: JDBC, ODBC, etc.
Now, once those queries are sent to the database (without the specific parameter values), the database "saves" them. Later on (usually in the same database session), you can run them many times, by just providing the parameter values each time.
SQL Injection Safety
They are also safe against SQL injection. For example, if in the previous query instead of a simple value such as Mary you used the value x'; delete from applicant; -- the database will work safely. It would run something like:
select * from applicant where name = 'x; delete from applicant; --'
This query won't probably find anything and will be safe.
If instead you didn't use compiled query, but just decided to concatenate the SQL as a string you would do something like:
String sql = "select * from applicant where name = '" + param1 + "'";
And would end up with the UNSAFE query:
select * from applicant where name = 'x'; delete from applicant; --
This one would run two queries. The second one will delete all the information from your table. Probably not what you want.

i have a query problems

Can anyone tell me what is wrong with this query:
$query = "INSERT INTO ideas_tbl (idea, desc) VALUES ('$idea', '$desc')";
As #GordonLinoff mentioned in a comment the problem is desc is a SQL keyword. Used like that, the SQL server might see it as a piece of syntax, not a column name, and get confused. The list of SQL keywords is different from server to server, but here's a good baseline list from SQLite.
There's two solutions. First is to quote the column with ". Some databases will use ` (MySQL) or [] (Microsoft), but " is the SQL standard. The non-conforming databases can be configured to support the " standard, for example, MySQL has ANSI_QUOTES.
This also means either escaping the quote, or my preferred option, using balanced quoting operators (assuming this is Perl).
$query = qq[INSERT INTO ideas_tbl (idea, "desc") VALUES ('$idea', '$desc')];
I don't like this option because it means every time that column is used you have to remember to quote it. The better option is to rename the column to something else like "description".
Now let's talk about your security hole. Because you've put variables straight into the query string your code is vulnerable to a SQL Injection Attack. This is one of the most common security holes. If $idea or $desc come from user input, a clever person can craft some data that can jump out of the quotes and be interpreted as more SQL. This can also happen innocently, like if $desc = "Our prices can't be beat!"
You could do all sorts of quoting, but to fully defeat it, and to speed up your code a bit, use prepared statements and bind parameters. Here I am assuming this is Perl using DBI.
my $sth = $dbh->prepare(q{
INSERT INTO ideas_tbl
(idea, description)
VALUES (?, ? )
};
$sth->execute($idea, $desc);
The other advantage is now you can reuse this statement handle avoiding the overhead of having to recompile it. Like if you were looping through a list of ideas.
for my $idea (#ideas) {
$sth->execute( $idea->{idea}, $idea->{desc} );
}
Finally, I suspect you didn't get an error message when your query failed which is why you're asking the question. Unfortunately DBI doesn't treat SQL errors as errors by default. If you forget the or die after every query you won't get an error.
To avoid this, turn on RaiseError either when you connect (best) or afterwards.
my $dbh = DBI->connect($dsn, $user, $pass, { RaiseError => 1 });
or
$dbh->RaiseError(1);
Now all failed queries will raise an error. No need to remember to put or die "Something failed because $DBI::errstr" on every query.

What are "parameters" and how do they prevent SQL injections? [duplicate]

This question already has answers here:
How does SQLParameter prevent SQL Injection?
(4 answers)
How does the SQL injection from the "Bobby Tables" XKCD comic work?
(13 answers)
Closed 8 years ago.
I'm very early on in learning SQL, but I've encountered the topic of SQL injections, and understand that parameters are probably the best way to prevent them. But I couldn't find any explanation of what they actually ARE.
So, for instance, in this code in ASP.NET (from w3schools):
txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = #0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("#0",txtUserID);
command.ExecuteReader();
What dos the "command.parameters.addwithvalue" actually do?
I'm sorry if this is a stupid question, but I couldn't find the answer to it - everywhere I look they just say "use parameters" but don't explain what that actually means...
Thanks!
actually you need to make prepared statement to stop sql injection , another thing is you need to escape the query or add slashed before single quotes in order to qvoid SQL Injection
Form w3schools
"Some web developers use a "blacklist" of words or characters to
search for in SQL input, to prevent SQL injection attacks.
This is not a very good idea. Many of these words (like delete or
drop) and characters (like semicolons and quotation marks), are used
in common language, and should be allowed in many types of input.
(In fact it should be perfectly legal to input an SQL statement in a
database field.)
The only proven way to protect a web site from SQL injection attacks,
is to use SQL parameters.
SQL parameters are values that are added to an SQL query at execution
time, in a controlled manner.
ASP.NET Razor Example
txtUserId = getRequestString("UserId"); txtSQL = "SELECT * FROM Users
WHERE UserId = #0"; db.Execute(txtSQL,txtUserId);
Note that parameters are represented in the SQL statement by a #
marker.
The SQL engine checks each parameter to ensure that it is correct for
its column and are treated literally, and not as part of the SQL to be
executed. Another Example txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address"); txtCit =
getRequestString("City"); txtSQL = "INSERT INTO Customers
(CustomerName,Address,City) Values(#0,#1,#2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);"

cgi generic sql injection problems

I was scanning a site when the following vulnerability popped up: CGI Generic SQL Injection
nessus sais that An attacker may exploit this flaw to bypass authentication, read confidential data, modify the remote database, or even take control of the remote operating system.
So i continued reading and found out that the vulnerability sits in this piece of code:
Using the POST HTTP method, Nessus found that :
The following resources may be vulnerable to SQL injection :
The '_codeTextBox' parameter of the /LoginTeacherForm.aspx CGI :
/LoginTeacherForm.aspx [loginButton=Login&_VIEWSTATE=dDwtMTU2NDIxMDkwN
Ts7Pg%3d%3d&btnChangePassword=Wijzig%20Pincode&_pinCodeTextBox=&_codeTex
tBox='+convert(int,convert(varchar,0x7b5d))+']
-------- output --------
Exception Details: System.Data.SqlClient.SqlException: String or
binary data would be truncated.
The statement has been terminated.
But i'm wondering how an attacker can exploit this vulnerability, because when i paste that piece of code it just give me the error.
So my question is how would an attack be able to actually hack into the site and bypass login etc. (Educational purpose only of course)
It looks like a false positive caused by the Nessus request causing your page to insert too long a string into a field. Nessus has detected the error was a SQL server error and has said that it may be a SQL injection vulnerability.
To test yourself try the request with _codeTextBox= set to a single quote to see if you still get a SqlException. If so amend this to two single quotes and if the error then goes away you are probably vulnerable.
The error System.Data.SqlClient.SqlException indicates an error in your SQL query statement. This implies that value stored in the _codeTextBox parameter is not validated or otherwised sanitized before being put into the query.
This would have varying implications depending on the query and logic surrounding its return value. It is impossible to determine the worst case scenario without a thorough understanding of the web application. Suffice it to say, this issue should be fixed by the developer. Fortunately, it is usually easy to fix once identified.
In this case, it looks like the _codeTextBox parameter is being passed to the convert function. I doubt anyone could exploit this. But, this indicates insecure coding practices that probably appear in other areas that Nessus is not aware of. Read below for more info.
I see this most often when the programmer simply concatenates the values with the SQL query string:
Unsafe Example (java) (Source OWASP)
String query = "SELECT account_balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}
Since the value simply gets appended to the end of the query, the user can change query to do something nefarious like login as any user or view all transactions. In the above example, the user could change the customer name parameter to something like '' or 1=1 or worse.
Expected query:
SELECT account_balance FROM user_data WHERE user_name = someuser
Bad query:
SELECT account_balance FROM user_data WHERE user_name = '' OR 1=1
OWASP recommends the following defensive measures. Your situation will dictate what is appropriate:
Primary Defenses:
Use of Prepared Statements (Parameterized Queries)
Use of Stored Procedures
Escaping all User Supplied Input
Additional Defenses:
Also Enforce: Least Privilege
Also Perform: White List Input Validation
You really need to check out OWASP's site and read more about SQL injection.

PDO prepare statements: Do we need to escape?

public function receiveDomainNames($keyword)
{
try
{
$stmt = $this->_dbh->prepare("SELECT d.someField FROM domain d WHERE d.someField LIKE :keyword");
$someField = '%'.$keyword.'%';
Do we need to escape $keyword on this case?
On php manual we can read:
If an application exclusively uses prepared statements, the developer can
be sure that no SQL injection will
occur (however, if other portions of
the query are being built up with
unescaped input, SQL injection is
still possible).
Is this the case on your opinion, are, on this case, build up unescaped input (no prior treatment has been made to our $keyword parameter) ?
Thanks in advance,
MEM
Given the above SQL statement, I see no rational possibility of a SQL injection.
What the warning about "other parts" would be a SQL query like:
$binds = array(":id"=>$_GET['id']);
$myPDO->prepare("SELECT {$_GET['columns']} FROM {$_GET{['table']} WHERE id = :id");
$statement = $myPDO->execute($binds);
The example is a worst case/explicit example of what they mean, that naively someone might think since they're escaping the where argument, that everything is safe.
With your example above, there is no un-escaped input so you're safe.
If an application exclusively uses prepared statements, the developer
can be sure that no SQL injection will occur (however, if other
portions of the query are being built up with unescaped input, SQL
injection is still possible).
I'd figure variables you create shouldn't have to be escaped because you know what they're doing.
Only escape content gotten from the user, such as $_COOKIE, $_POST, $_GET and other parameters such as the URL.