Open Source for you

Stay Away from SQL Injections

-

SQL injection is a common hacking technique that places malicious code in SQL statements, via Web page input. It can destroy your database. Three SQL injection vulnerabil­ities and their remedies are discussed in this article.

SQL injection is a code injection technique that exploits the security vulnerabil­ity of the connected database layer of an applicatio­n. This vulnerabil­ity allows poorly filtered user inputs with undesirabl­e escape characters embedded within SQL statements to get executed by the database server. User inputs with an inappropri­ate data type also create an SQL injection vulnerabil­ity problem. Unfiltered user input through a Web page is a common source of this type of security breach, as it makes the database accessible to hackers to gain control over it. This security loophole generally occurs when one programmin­g or scripting language is embedded inside another. SQL injection vulnerabil­ity is also known as SQL insertion attack.

SQL injection typically occurs when a user-supplied input, like the name, is purposeful­ly modified to a specific MySQL statement to get executed within the Web database. For example, a user form for user name may be designed to enter the user’s name for credential verificati­on. But instead of a simple alphanumer­ic literal string, a user may provide a string to delete a table, as shown in Figure 1.

With this form input entry, the server will drop the entire user’s table. This is an example of how commanding and hazardous an SQL injection can be and shows the necessity of regular database backups.

Here I shall discuss only three of the SQL injection features and their possible remedies. These are: bypassing query logic, retrieving protected data and multiple query injections. All these vulnerabil­ities are internal to SQL and intrinsic to embedded programmin­g structures but arise mainly due to careless coding. Proper systematic goal-oriented design methodolog­y can reduce the chance of these to a great extent and make the database secure from external attacks.

Retrieving hidden data

SQL injection can be demonstrat­ed directly on SQL database prompt. For example, if we consider an SQL query to browse a user table for a user name, and assign a user name variable string as: “HelloWorld” or 1=1-‘, the SQL SELECT statement: set @id1 := “HelloWorld”, @id2 :=”1=1--” ; select * from users where username= @id1 or @id2;

…it will display all records from the user’s table irrespecti­ve of the value of the user name field. Even if the user name ‘HelloWorld’ is absent in the user table, all the records will still be displayed.

Retrieving hidden data: Web page mode

The above vulnerabil­ity can be explored through a Web-based login module to bypass a user’s name pattern matching restrictio­n. For example, if there is a login form login.html as shown below: login.html

/>

…then a PHP Web page program login.php may be written to exploit the SQL injection loophole of the SQL query. The purpose of this code is to read the user’s name from the users’ table of the database. This code has four parts. Initially, it establishe­s a connection to a MySQL database customer; then it reads the variable user name from the login.html Web form and performs the first query to read a particular user’s name from the database table users. Subsequent­ly, this section of the code displays all the records with the user name = $umame. The third section performs another query to display the same user’s name but with restrictio­n status. In a normal situation, this section will display all records having the user name =$uname, provided the record satisfies the condition status=1. Lastly, it closes the database connection and returns the control to the system.

Step 1: Open a database customer. connect_error) { die(“Connection failed: “. $conn->connect_error); } else{ echo “Connected successful­ly
”; }

Step 2: Read the POST variable user name from the Web form and perform the SQL select query. $uname = $_POST[‘username’] ; #1. Read unrestrict­ed records $sql = “SELECT * FROM users WHERE username = ‘”. $uname; $result = mysqli_query($conn,$sql); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo “
id: “. $row[“userid”]. “- Name: “. $row[“username”]. ““. $row[“status”]. “
”; } } else { echo “0 results
”; }

Step 3: Perform the select query with restrictio­n status. Field status will allow only those records that have status=1. # 2 Read restricted records $sql = “SELECT * FROM users WHERE username = ‘”. $uname. “and status = 1”; $result = mysqli_query($conn,$sql); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo “
id: “. $row[“userid”]. “- Name: “. $row[“username”]. ““. $row[“status”]. “
”; } } else { echo “0 results”; }

Step 4: Close the connection and the PHP Web page login.php. $conn->close(); ?>

With this code snippet, one can use the given Web based form to exploit the SQL injection technique to bypass the user name verificati­on clause of the SQL query statement. The query statement: $sql = “SELECT * FROM users WHERE username = ‘”. $uname;

…can inject a string into the statement to browse the entire table and display all the records of the table. To make the query TRUE for all the situations one can enter the string ‘or 1=1 (Figure 2) instead of a valid user’s name. Since 1=1 is always true and the connecting logical operator is OR, it will make the query TRUE for all the records and the subsequent for-loop will fetch all the records from the table users (Figure 3). If proper precaution is not taken, this type of injection can make the database vulnerable to hackers.

Retrieving restricted data: Web page mode

To retrieve restricted records as shown in the second query, it is required to bypass the restrictio­n status = 1 clause of the query statement. This can be done by commenting the restrictio­n with an SQL injection statement parker ‘-- (Figure 4), where ‘parker’ is a valid user’s name. String ‘-- will make the rest of the line commented and the query will display all records with the user name = parker (Figure 5).

Prevention: Both the above-mentioned injections can be prevented by restrictin­g the input field length to a given suitable number and allowing an alphanumer­ic field value, as shown in the following code snippet: if (preg_match(“/^\w{6,20}$/”, $_POST[‘username’])) { $sql = “SELECT * FROM users WHERE username=’”.$uname.”’”; echo $sql; $result = mysqli_query($conn,$sql); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo “
id: “. $row[“userid”]. “- Name: “. $row[“username”]. ““. $row[“status”]. “
”; } } else { echo “0 results
”; } } else { } echo “
username not accepted
”;

The regular expression pattern matching function preg_match() will filter out any non-alphanumer­ic character within the input string and will allow a string of length 6 to 20 characters only. For an input field value ‘parker’, the above filter and the subsequent query string will generate a query string as: SELECT * FROM users WHERE username=’parker’ …and will produce the following browsing list: id: 115 - Name: parker 1 id: 135 - Name: parker 0

Multiple query restrictio­n

One dangerous SQL injection menace is the multiple query statement in single query execution. This injection is harmful in the sense that one can inject a destructiv­e data manipulati­on query along with a simple SELECT query statement. One can add multiple SQL statements with a SELECT statement as follows: “parker’; DELETE FROM users;”;

A multiple query statement can be injected into a Web based PHP routine through an HTML form as used earlier. The form can read multiple query statements and pass them into the server-side routines. Here is an example of multiple query injection by a Web form and its form routine. For clarity, the entire code is given. Those who are interested can experiment with this code for further study. connect_error) { die(“Connection failed: “. $conn->connect_error); } else{ echo “Connected successful­ly
”; } // ********************** Main Body ***************************** $uname = $_POST[‘username’]; $sql = “SELECT * FROM users WHERE username=’”.$uname; if ($conn -> multi_query($sql)) { do { // Store first result set if ($result = $conn -> store_result()) { while ($row = $result -> fetch_row()) { //Display only first two fields printf(“%s,%s\n”, $row[0],$row[1]);echo “
”; } $result -> free_result(); } // Mark the end of each record set

 ??  ??
 ??  ??
 ??  ??

Newspapers in English

Newspapers from India