"Manual" SQL injection- how does it work? - sql

I've seen it's possible to get into website's sql database just by typing certain sql lines into browser's address bar.How is this even possible? Shouldn't address bar only redirect us to website? How's that address bar can accept sql syntax? I'm total layman to browsers itselves, but it fascinates me that address bars offer vulnerabilites.

How is this even possible?
The application is executing arbitrary SQL that is read from the URL. Think http://example.com/search.php?query=SELECT%20....
Shouldn't address bar only redirect us to website?
That's exactly what it's doing. The vulnerability is in the website's handling of that URL.
How's that address bar can accept sql syntax?
The SQL query is just text that's part of a URL. The address bar doesn't know (or care) that your URL contains SQL.

Are you going to use the answer to this question for good, or for evil?
In any case, assume you have a url in the form
http://mysite.com/dosomething?email=$EMAIL
And you have some code that executes a query that looks like this:
SELECT fieldlist
FROM table
WHERE field = '$EMAIL';
Then this page explains how someone can manipulate the contents of EMAIL to execute essentially an arbitrary query:

SQL injection is a code injection technique, used to attack data driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker).
For example let's say that you have a textField that receives a value and then assign that value to variable username, then you have a statement that receives the valor, and it concatenates the value to a string representing your query like this:
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
let's say that the value that you are passing it's something like this ' or '1'='1 this example could be used to force the selection of a valid username because the evaluation of '1'='1' is always true. This only an example! check this site in order to learn more about it

Related

extract user name and password from url using regex and sql

in order to implement a custom sql function named getUserName and getPassword from an input url, im trying to find a way to extract the user name and password from a given url using regex.
the code will be executing on snowflake sql flavor language so my coding tools are limited to sql functions and regex supported by snowflake.
i can find the url scheme and the domain/host, get their indexes and length, and extract as substring every thing in between to get the user name and password, the problem is that it wont work with many edge cases, can you suggest better methods/code execution?
this is an example url:
http://UserName123:P#$$:\/\/0rd#domain.co.uk:34567/3.0.1/file_name.txt?pn1:pv1&pn2:pv2#ref
this is the current regex used to identify the url scheme and domain:
(^[a-z0-9.-]+:\/\/)|((?:#)([a-z0-9.-]+))
this is an sql example of getting the scheme:
SPLIT_PART(REGEXP_SUBSTR(A, '^[a-z0-9.-]+://', 1, 1, 'c'), ':', 0) as split
Username and password in a URL are bad practice. URLs, along with the query string (and thus the passwords) will show up in server log files or it can leak/get stolen another way.
So, redesign is needed and not a solution to this problem.
I hope you find it good to know now instead of after solving the problem.

Remove all rows from a table where an invalid "URL" has been entered

A somewhat odd Postgresql question for our highly specific use case. We have a table which accepts URLs as a part of a comment input from our users. This is on a highly trafficked site. We had some PHP code that was validating that users only entered correctly-formed URLs, if they included one in their comment (usually comment text does not include any URLs).
However, sadly, our PHP is old on an old server. So at some point the ereg logic we had became dysfunctional. Which means miscreant users have had a field day entering comments with badly formed URLs like the following:
l%20are%20generally%20included%20almost%20anyplace--even%20if%20your%20"yard"%20is%20bound%20to%20an%20outdoor%20patio%20or%20balcony.Adding%20water%20to%20your%20patio%20could%20be%20as%20simple%20as%20aiming%20a%20low%20dish%20of%20water%20designed%20for%20use%20in%20the%20form%20of%20birdbath.Any%20cursory%20container%20around%206%20in%20.wide%20and%20a%20half-inch%20deep%20will%20attempt%20to%20work.Pie%20pans,%20garbage%20can%20lids,%20or%20flo
Note that it's not a URL at all. Hence, our question: is there a Postgresql-only way, perhaps through some PL/SQL function or some stored function or something, that we can use to delete all these rubbish records from our database? We'd ideally not want to use a PHP program that went through the entire database and checked it against the valid URL pattern.
We'd like to execute this within PG itself. We can take the database offline to perform this task for as long as it takes.
Thank you!
SELECT * FROM table WHERE url_column !~* '(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?'
Try this query, validate the output en then you could create a DELETE query with this example.

SQL Injection Query

I am writing a report on SQL injection attacks. I've found an example on Owasp as shown bellow.
Since this is an example and to me, it seems as a simple query getting a row with the specific ID, does it do anything else or my assumption is correct?
String query = "SELECT * FROM accounts WHERE custID='" +
request.getParameter("id") + "'";
// Since this is an online example i don't know what getParameter("id") method does.
to me it seems as a simple query getting a row with specific ID
Thats the magic of injection. The query should only get a row that fits a certain criteria that comes from a request (like a GET or POST from html for example).
So request.getParameter("id") provides a parameter submitted by the user (or a very bad guy).
Usually whoever wrote that peace of code expected something like this:
id = 12
which would result in
SELECT * FROM accounts WHERE custID='12'
Now image what happens if the user (a bad one in this case) sends this instead:
id = 0'; DROP TABLE accounts; --
This would execute as
SELECT * FROM accounts WHERE custID='0'; DROP TABLE accounts; --'
Step-by-step:
Make sure the intended query executes without error (0)
End the query before the intended point (';)
Inject your malicous code (DROP TABLE accounts;)
Make sure everything that is left of the original query is treated as a comment (--)
The problem in the OWASP example isn't the query itself, but the fact that parameters that come from 'outside' (request.getParameter("id")) are used to generate a query, without escaping any potential control characters.
This style of writing code basically allows any user to execute code on your SQL-Server.
The problem with this query is that the SQL is created dynamically. Request.getparameter is probably just a function which returns the id of the row for the specific web request.
But if the webpage allows filling this parameter through a text box or the function is called directly from JavaScript any value can be set in id.
This could contain any SQL statement, which with the correct authentication, could even contain 'DROP Database'
request.getParameter("id")
will get a the parameter "id" from the http-request, e.g. for: http://test.com/?id=qwertz request.getParameter("id") will return "qwertz". SQL injection is possible in this case, since the value of this parameter wasn't checked at all and can contain anything

Performing an ASP.NET database search with StartsWith keyword

I have a query. I am developing a site that has a search engine. The search engine is the main function. It is a business directory site.
A present I have basic search sql that searches the database using the "LIKE" keyword.
My client has asked me to change the search function so instead of using the "Like" keyword they are after something along the lines of the "Startswith" keyword.
To clarify this need here is an example.
If somebody types "plu" for plumbers in the textbox it currently returns, e.g.,
CENTRE STATE PLUMBING & ROOFING
PLUMBING UNLIMITED
The client only wants to return the "PLUMBING UNLIMITED" because it startswith "plu", and doesn't "contain" "plu"
I know this is a weird and maybe silly request, however does anyone have any example SQL code to point me in the right direction on how to achieve this goal.
Any help would be greatly appreciated, thanks...
how about this:
SELECT * FROM MyTable WHERE MyColumn LIKE 'PLU%'
please note that the % sign is only on the right side of the string
example in MS SQL
Instead of:
select * from professions where name like '%plu%'
, use a where clause without the leading %:
select * from professions where name like 'plu%'
LIKE won't give you the performance you need for a really effective search. Looking into something like Lucence or your engine's Full Text Search equivalent.

Are sql injection attacks only a threat on a page that has a form?

I know it's a simple question, but in everything I've read, I've never seen this spelled out specifically.
If you do a query on a page, do you need to worry about SQL injection attacks? Or is it only a problem when you ask the user for input?
Thanks!
You don't have to have user input to suffer a SQL injection attack.
Let's say you have a product page that is called using a URL such as this:
product.aspx?ID=123
And in your code you have a query constructed such as this:
string sql = "SELECT * FROM Products WHERE ID = " + Request.Querystring["ID"];
Someone could call your page with this url:
product.aspx?ID=123;DROP Table Students;
And bam, you've just been had.
In addition to ANYTHING that can be passed in via a user, querystring, post, cookie, browser variable, etc. I think it is just good practice to always use parameters, even if you have the literals in your code. For example:
if(SomeCondition)
{
sql = "Select * from myTable where someCol = 'foo'";
}
else
{
sql = "Select * from myTable where someCol = 'bar'";
}
this may be injection safe, but your RDBMS will cache them as two different queries.
if you modiy it to this:
sql = "Select * from myTable where someCol = #myParam";
if(SomeCondition)
{
myCommand.Parameters.Add("#myParam").value = "foo";
}
else
{
myCommand.Parameters.Add("#myParam").value = "bar";
}
You achieve the same result but the RDBMS will only cache it as one query, substituting the parameter at runtime. I use it as a rule of thumb to ALWAYS use parameterized queries, just to keep things consistent, not to mention a slight cache improvement.
SQL injection is caused by unsanitized data. You should always always always sanitize data going into a database. Not just for SQL injection, but also for making your app just work.
For example, some systems won't use my name because it has a ' character in it, and their database is not sanitized. I did not enter my name, my name was taken from another database. Doesn't matter -- the data should be sanitized.
SQL Injection snippets can also come in from the QueryString (aka "URL arguments") passed in with the GET method instead.
As hinted by Billy O'Neal [single quote intended ;-) ], any piece of data that is not intrinsic to the program (or to its very trusted back-end), should be "sanitized". The Sanitizing term seems to imply to be a sophisticated process, but in effect it typically means little more than:
[may vary with your specific SQL server make]
remove (or escape) single quotes characters embedded within a string
watch from strings exceeded the length of the underlying SQL column (in particular if such length is readily long)
A possible reason for the idea that HTTP Forms would be the only source of SQL injection snippets is that a -valid- recommendation is to ensure that one gets the user-supplied submitted text from the Request's form exclusively. Several Web Application frameworks expose the HTTP request as an object which exposes, by default, all key-values pairs from either the QueryString, from a Form, or even from cookies, accessible as from a single hash. While this can be practical for applications that sometimes get the info from a form an sometimes from the querystring, this can facilitate the work of would-be-injectors, because it is easier to craft a URL than a Form. (But with the proper tool, one can also fake a POST request as well...)
No, there are several other cases. For example, you may have some of the variables as a querystring passed into a php page. The 'user' could modify that string to include some dodgy scripting.
http://en.wikipedia.org/wiki/SQL_injection includes a large section on the types of vulnerabilities and how to combat them effectively.
To summarize - any type of input from the user that is used in SQL queries is a potential target of sql injection
Also consider preventing against cross-site-scripting ("XSS").
SQL Injections is possible if you use any kind of data that comes from the browser. It could be form data, querystring data, cookie values, or even data from the request header.
The obvious and easy ways in is the form data and querystring data, but anything that comes from the browser could be spoofed.
Anything that the code takes as input from the HTTP request can be a SQL injection vector:
POST/PUT content
GET URL parameters
Cookies
At a higher level these show up as $_REQUEST or Page.Request values, session variable, it all depends on a miriad of factors. but ultimately, is not just POST forms. Although probably the most prvalent vector is form POST content and GET URL variables.
When the user can modify the values of the parameters of a query, then it can become a threat.
You need to worry about cross site scripting (XSS) attacks in this case if the data you are displaying on the page came from user submitted data.
ESCAPE INPUT, FILTER OUTPUT
As I concern you should never trust this variables: $_POST, $_GET, $_REQUEST, $_COOKIE even $_SERVER can contain malicious code. So ALWAYS make sure that inserted data match your expectation.
For example as an extra paranoid measure on validation email address you can encrypt email address with md5 like this:
"SELECT username FROM users WHERE MD5(email)='" . md5($_POST['email']) . "' AND active=1"
As a general rule parameterized queries should always be used.
It prevents malicious user input from being executed against your database (SQL injection attacks). [You should do user input validation as well to ensure that malicious code isn't rendered on the page and that JavaScript can be run against your server.]
It enables you to re-use your queries.
You can precompile your queries.
It organizes your input and makes it more readable. You might want to use the same parameter in more than one location.
It has better support for different data type such as dates, strings and the like. You won't run into problems with weird characters when you use parameterized queries.
In my use case I always generate parameter based queries. I have a wrapper that will always compile them so that if a second query gets executed in the same request path, it will run that much faster on the same connection. This takes a fair bit of work to setup, but is worth the performance gain in any medium to enterprise level system.
I agree that parameterisation is the best approach.
As an alternative (which might be easier to retro fit into your code, at least initially) doubling the single quotes in a string will prevent SQL Injection.
To take Neil N's example:
sql = "Select * From Products Where ID = " + Request.Querystring["ID"];
wrap the variable in a function that doubles the quotes, and wrap the varible with single quotes too.
sql = "Select * From Products Where ID = "
+ fnSQLSafeParam(Request.Querystring["ID"]);
The function would be something like (VBscript example):
Function fnSQLSafeParam(ByVal strStr)
If IsNull(strStr) or IsEmpty(strStr) then strStr = ""
fnSQLSafeParam = "'" & replace(Trim(CStr(strStr)), "'", "''") & "'"
End Function