• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Sql Injection Myths and Fallacies

Sql Injection Myths and Fallacies




The most massive crime of identity theft in history was perpetrated in 2007 by exploiting an SQL Injection vulnerability. This issue is one of the most common and most serious threats to web application security. In this presentation, you'll see some common myths busted and you'll get a better understanding of defending against SQL injection.



Total Views
Views on SlideShare
Embed Views



51 Embeds 6,073

http://ovm-kassel.eu 2737
http://ovm-kassel.net 1692
http://www.websdeveloper.com 325
http://www.slideshare.net 247
http://dll.lv 234
http://nwlinux.com 215
http://my.bergersoft.net 156
http://demlaip.wordpress.com 58
http://kyaiz.wordpress.com 43
http://kerika.net 42
http://www.berejeb.com 42
http://khishigee.miniih.com 36
http://localhost 36
http://www.khishigee.miniih.com 33
http://www.matsuyuku.com 30
https://twitter.com 26
http://a0.twimg.com 13
https://groupereflect.bluekiwi.net 11
http://sjaswinder.blogspot.com 9
http://gsmental.blogspot.in 8
http://www.ovsa.fr 8
http://lernen20.de 7
http://www.techgig.com 7
http://www.devetdesign.com 7
http://lernmix.de 6
http://www.linkedin.com 5
http://translate.googleusercontent.com 5
http://chirag.dreamworldsolutions.com 3
http://localhost:49234 3
http://gsmental.blogspot.com 3
http://www.scoop.it 2
http://hml-monqi.monqi.com.br 2
https://twimg0-a.akamaihd.net 2
http://sjaswinder.blogspot.in 2
http://www.google.com 2
http://chandresh.dreamworldsolutions.com 1
http://www.blogger.com 1
http://paper.li 1
http://www.miniih.com 1
https://devbbapp3.nku.edu 1
https://drive.jolicloud.com 1
http://rbucky.com 1
http://lms.ipa.edu.sa 1 1
http://buckycomputing.net 1
http://webcache.googleusercontent.com 1
http://www.tumblr.com 1
https://si0.twimg.com 1
http://mayur.dreamworldsolutions.com 1
http://bharat.dreamworldsolutions.com:8085 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-NoDerivs LicenseCC Attribution-NonCommercial-NoDerivs LicenseCC Attribution-NonCommercial-NoDerivs License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.


19 of 9 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • While I agree with the limitations of parameters (can't be used for table names, ordering etc) it feels like it's a different level of 'not a fix' to the others (such as escaping). Unless I'm wrong - and I'm *not* a database expert - query parameters really are *the* way to go in situations where they're applicable (i.e. when you don't need to dynamically choose the table name, build a list etc). There aren't all the 'gotchas' to be really careful with that there are with escaping (which always feels like a losing battle to me).

    Of course there are other benefits of query parameters anyway - simpler to read SQL and avoiding error-prone conversions (especially for date/time types) for example.

    Is this a fair statement, or are there downsides to query parameters beyond the limitations? The good part of the limitations is that when you bump into them, you *know* you've bumped into them, because the query simply doesn't work - so with query parameters you're either working safely, or you're broken. Again, that's assuming I'm not missing something.
    Are you sure you want to
    Your message goes here
  • the 20th slide, story of my life
    Are you sure you want to
    Your message goes here
  • very good
    Are you sure you want to
    Your message goes here
  • Awesome PPT and very knowledgeable
    Are you sure you want to
    Your message goes here
  • Slide 27 - Why does QueryAnyTable have a table_name IN parameter when we pass the 'SELECT * FROM' to the procedure? Won't that execute 'SELECT * FROM SELECT * FROM ...' ?
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    Sql Injection Myths and Fallacies Sql Injection Myths and Fallacies Presentation Transcript

    • SQL InjectionMyths and Fallacies Bill Karwin, Percona Inc.
    • Me• Software developer• C, Java, Perl, PHP, Ruby• SQL maven• Percona Consultant and Trainer• Author of SQL Antipatterns: Avoiding the Pitfalls of Database Programming www.percona.com
    • What is SQL Injection?http://example.com/show.php?bugid=1234SELECT * FROM Bugs WHERE bug_id = $_GET[bugid] user input www.percona.com
    • What is SQL Injection?http://example.com/show.php?bugid=1234 OR TRUESELECT * FROM Bugs WHERE bug_id = 1234 OR TRUE unintended logic www.percona.com
    • Worse SQL Injectionhttp://example.com/changepass.php?acctid=1234 &pass=xyzzyUPDATE Accounts SET password = SHA2($password) WHERE account_id = $account_id www.percona.com
    • Worse SQL Injectionhttp://example.com/changepass.php?acctid=1234 OR TRUE &pass=xyzzy), admin=(1 changes account to administratorUPDATE Accounts SET password = SHA2(xyzzy), admin=(1) WHERE account_id = 1234 OR TRUE changes password for all accounts www.percona.com
    • Myths and Fallacies MYTH Based on a grain of truth, but derives a wrong conclusionFALLACY Based on a false assumption, but derives a logical conclusion www.percona.com
    • Myth MYTH“SQL Injection is an oldproblem―so I don’t have to worry about it.” www.percona.com
    • Identity Theft• 130 million credit card numbers• Albert Gonzalez used SQL Injection to install his code onto credit-card servers• Sentenced 20 years in March 2010• Cost to victim company Heartland Payment Systems: $12.6 million • http://www.miamiherald.com/2009/08/22/1198469/from-snitch-to-cyberthief-of-the.html • http://www.cio.com/article/492039/Security_Breach_Cost_Heartland_12.6_Million_So_Far www.percona.com
    • Ruby on Rails 3.x• June 1, 2012.• Ruby on Rails 3.2.5 releases fix for a critical SQL injection vulnerability.• Applications using ActiveRecord in Ruby on Rails 3.0 and later were vulnerable.• Fixes released in RoR 3.1.5 and 3.0.13 as well.• http://news.softpedia.com/news/Critical-SQL-Injection-Vulnerability-Fixed-with-Ruby-on-Rails-3-2-5-273202.shtml www.percona.com
    • LinkedIn.com• June 4, 2012.• Russian hackers posted 6.5 million user credentials acquired from LinkedIn.com.• The means of attack is still unconfirmed, but...• A class action lawsuit against LinkedIn over this breach alleges that the attackers exploited an SQL injection vulnerability.• http://www.zdnet.com/blog/identity/linkedin-hit-with-5-million-class-action-suit/548 www.percona.com
    • Yahoo! Voices• July 12, 2012.• 453,000 email addresses and passwords leaked.• The perpetrators claimed they exploited union-based SQL injection.• http://arstechnica.com/security/2012/07/yahoo-service-hacked/• http://gnahackteam.wordpress.com/2012/06/08/union-based-basic-sql-injection/ www.percona.com
    • Myth MYTH “Escaping inputprevents SQL injection.” www.percona.com
    • Escaping & Filteringhttp://example.com/changepass.php?acctid=1234 OR TRUE &pass=xyzzy), admin=(1 backslash escapes special charactersUPDATE Accounts SET password = SHA2(xyzzy), admin=(1) WHERE account_id = 1234 coerced to integer www.percona.com
    • Escaping & Filtering Functions<?php$password = $_POST["password"]; $password_escaped = mysql_real_escape_string($password);$id = (int) $_POST["account"];$sql = "UPDATE Accounts SET password = SHA2(‘{$password_escaped}’) WHERE account_id = {$id}";mysql_query($sql); www.percona.com
    • Escaping & Filtering Functions<?php$password = $_POST["password"]; $password_quoted = $pdo->quote($password);$id = filter_input(INPUT_POST, "account", FILTER_SANITIZE_NUMBER_INT);$sql = "UPDATE Accounts SET password = SHA2( {$password_quoted} ) WHERE account_id = {$id}";$pdo->query($sql); www.percona.com
    • Identifiers and Keywords<?php no API to support delimited identifiers$column = $_GET["order"]; $column_delimited = $pdo->FUNCTION?($column);$direction = $_GET["dir"];$sql = "SELECT * FROM Bugs ORDER BY {$column_delimited} {$direction}";$pdo->query($sql); keywords get no quoting www.percona.com
    • Myth MYTH“If some escaping is good, more must be better.” www.percona.com
    • Overkill?<?php real function from a user’s projectfunction sanitize($string){ $string = strip_tags($string); $string = htmlspecialchars($string); $string = trim(rtrim(ltrim($string))); $string = mysql_real_escape_string($string); return $string; }$password = sanitize( $_POST["password"] );mysql_query("UPDATE Users SET password = $password WHERE user_id = $user_id"); www.percona.com
    • “FIRE EVERYTHING!!” www.percona.com
    • Just the One Will Do<?php$password = mysql_real_escape_string( $_POST["password"] );mysql_query("UPDATE Users SET password = $password WHERE user_id = $user_id"); www.percona.com
    • Myth MYTH“I can write my own escaping function.” www.percona.com
    • Please Don’t• addslashes() isn’t enough in a multibyte world• Example: • http://example.org/login.php?account=%bf%27 OR x=x • $account = addslashes($_REQUEST(“account”)); • Function sees a single-quote (%27) and inserts backslash (%5c). Result: %bf%5c%27 OR x=x single-quote valid multi-byte character in GBK: www.percona.com
    • Grant Access to Any Account• Interpolating: SELECT * FROM Accounts WHERE account = {$account} AND password = {$passwd}• Results in: SELECT * FROM Accounts WHERE account = OR x= x AND password = xyzzy • http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string • http://bugs.mysql.com/bug.php?id=8378 www.percona.com
    • Solutions• Use driver-provided escaping functions: • mysql_real_escape_string() • mysqli::real_escape_string() • PDO::quote()• Use API functions to set the client character set: • mysql_set_charset() • mysqli::set_charset() • http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html• Use UTF-8 instead of GBK, SJIS, etc. www.percona.com
    • Myth MYTH“Unsafe data comes fromusers―if it’s already in the database, then it’s safe.” www.percona.com
    • Not Necessarily$sql = "SELECT product_name FROM Products"; $prodname = $pdo->query($sql)->fetchColumn();$sql = "SELECT * FROM Bugs WHERE MATCH(summary, description) AGAINST ({$prodname})"; not safe input www.percona.com
    • Fallacy FALLACY“Using stored procedures prevents SQL Injection.” www.percona.com
    • Static SQL in Procedures filtering by data type is a good thingCREATE PROCEDURE FindBugById (IN bugid INT) BEGIN SELECT * FROM Bugs WHERE bug_id = bugid; ENDCALL FindByBugId(1234) www.percona.com
    • Dynamic SQL in ProceduresCREATE PROCEDURE BugsOrderBy (IN column_name VARCHAR(100), IN direction VARCHAR(4)) BEGIN interpolating arbitrary SET @query = CONCAT( strings = SQL injection SELECT * FROM Bugs ORDER BY , column_name, , direction); PREPARE stmt FROM @query; EXECUTE stmt; ENDCALL BugsOrderBy(date_reported, DESC) www.percona.com
    • Worthy of TheDailyWTFCREATE PROCEDURE QueryAnyTable (IN table_name VARCHAR(100)) BEGIN SET @query = CONCAT( SELECT * FROM , table_name); PREPARE stmt FROM @query; EXECUTE stmt; ENDCALL QueryAnyTable( (SELECT * FROM ...) )http://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspx www.percona.com
    • Myth MYTH“Conservative SQL privileges limit the damage.” www.percona.com
    • Denial of ServiceSELECT * FROM Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs 100 bugs = 1 trillion rows www.percona.com
    • Denial of ServiceSELECT * FROM Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs ORDER BY 1 still requires only SELECT privilege www.percona.com
    • Just Asking for Ithttp://www.example.com/show.php? query=SELECT%20*%20FROM %20Bugs www.percona.com
    • Fallacy FALLACY “It’s just an intranetapplication―it doesn’t need to be secure.” www.percona.com
    • Just Ask This Manager www.percona.com
    • What Stays on the Intranet?• You could be told to give business partners access to an internal application UPDATE Accounts SET password = SHA2($password) WHERE account_id = $account_id www.percona.com
    • What Stays on the Intranet?• Your casual code could be copied & pasted into external applications UPDATE Accounts UPDATE Accounts SET password = SET password = SHA2($password) SHA2($password) WHERE account_id WHERE account_id = $account_id = $account_id www.percona.com
    • What Stays on the Intranet?• It’s hard to argue for a security review or rewrite for a “finished” application $$ $ ? UPDATE Accounts SET password = SHA2($password) WHERE account_id = $account_id www.percona.com
    • Myth MYTH “My frameworkprevents SQL Injection.” www.percona.com
    • ORMs Allow Custom SQL• Dynamic SQL always risks SQL Injection, for example Rails ActiveRecord: Bugs.all( :joins => "JOIN Accounts ON reported_by = account_id", any custom SQL can carry SQL injection :order => "date_reported DESC" ) www.percona.com
    • Whose Responsibility?• Security is the application developer’s job• No database, connector, or framework can prevent SQL injection all the time www.percona.com
    • Fallacy FALLACY“Query parameters do quoting for you.” www.percona.com
    • Interpolating Dynamic Values• Query needs a dynamic value: SELECT * FROM Bugs WHERE bug_id = $_GET[bugid] user input www.percona.com
    • Using a Parameter• Query parameter takes the place of a dynamic value: SELECT * FROM Bugs WHERE bug_id = ? parameter placeholder www.percona.com
    • How the Database Parses It SELECT expr-list * simple- bugsquery FROM table bug_id WHERE expr equality = ? parameter placeholder www.percona.com
    • How the Database Executes It SELECT expr-list * simple- bugsquery FROM table bug_id WHERE expr equality = 1234 parameter value www.percona.com
    • Interpolation SELECT expr-list * bug_id simple- bugsquery FROM table equality = 1234 WHERE expr OR TRUE SQL injection www.percona.com
    • Parameterization SELECT expr-list * simple- bugsquery FROM table bug_id WHERE expr equality = 1234 OR TRUE no parameter can change the tree www.percona.com
    • Sequence of Prepare & Execute Client Server prepare query convert to machine- send SQL readable form parse query optimize query execute query send parameters repeat with bind parameters different parameters execute query return results www.percona.com
    • Myth MYTH“Query parameters prevent SQL Injection.” www.percona.com
    • One Parameter = One ValueSELECT * FROM Bugs WHERE bug_id = ? www.percona.com
    • Not a List of ValuesSELECT * FROM Bugs WHERE bug_id IN ( ? ) www.percona.com
    • Not a Table NameSELECT * FROM ? WHERE bug_id = 1234 www.percona.com
    • Not a Column NameSELECT * FROM Bugs ORDER BY ? www.percona.com
    • Not an SQL KeywordSELECT * FROM Bugs ORDER BY date_reported ? www.percona.com
    • Interpolation vs. ParametersScenario Example Value Interpolation Parametersingle value ‘1234’ SELECT * FROM Bugs SELECT * FROM Bugs WHERE bug_id = $id WHERE bug_id = ?multiple ‘1234, 3456, 5678’ SELECT * FROM Bugs SELECT * FROM Bugsvalues WHERE bug_id IN ($list) WHERE bug_id IN ( ?, ?, ? )table name ‘Bugs’ SELECT * FROM $table NO WHERE bug_id = 1234column name ‘date_reported’ SELECT * FROM Bugs NO ORDER BY $columnother syntax ‘DESC’ SELECT * FROM Bugs NO ORDER BY date_reported $direction www.percona.com
    • Solution SOLUTIONWhitelist Maps www.percona.com
    • Example SQL Injectionhttp://www.example.com/? order=date_reported&dir=ASC<?php unsafe inputs$sortorder = $_GET["order"]; $direction = $_GET["dir"]; SQL Injection$sql = "SELECT * FROM Bugs ORDER BY {$sortorder} {$direction}";$stmt = $pdo->query($sql); www.percona.com
    • Fix with a Whitelist Map application SQL identifiers request values and keywords<?php$sortorders = array("DEFAULT" => "bug_id", "status" => "status", "date" => "date_reported" );$directions = array( "DEFAULT" => "ASC", "up" => "ASC", "down" => "DESC" ); www.percona.com
    • Map User Input to Safe SQL<?phpif (isset( $sortorders[ $_GET["order"] ])) { $sortorder = $sortorders[ $_GET["order"] ]; } else { $sortorder = $sortorders["DEFAULT"]; } www.percona.com
    • Map User Input to Safe SQL PHP 5.3 syntax<?php$direction = $directions[ $_GET["dir"] ] ?: $directions["DEFAULT"]; www.percona.com
    • Interpolate Safe SQLhttp://www.example.com/?order=date&dir=up<?php whitelisted values$sql = "SELECT * FROM Bugs ORDER BY {$sortorder} {$direction}";$stmt = $pdo->query($sql); www.percona.com
    • Benefits of Whitelist Maps• Protects against SQL injection in cases where escaping and parameterization doesn’t help.• Decouples web interface from database schema.• Uses simple, declarative technique.• Works independently of any framework. www.percona.com
    • Fallacy FALLACY “Queries parametershurt SQL performance.” www.percona.com
    • Simple Query Profiled Elapsed 0.004 0.003 0.002 0.001MySQL MySQLi MySQLi Prep 0 PDO PDO Prep www.percona.com
    • Complex Query Profiled Elapsed 1.56 1.17 0.78 0.39MySQL MySQLi MySQLi Prep 0 PDO PDO Prep www.percona.com
    • Myth MYTH“A proxy/firewall solution prevents SQL injection.” www.percona.com
    • Oracle Database Firewall• Reverse proxy between application and Oracle • Whitelist of known SQL queries • Learns legitimate queries from application traffic • Blocks unknown SQL queries • Also supports Microsoft SQL Server, IBM DB2, Sybase ASE, SQL Anywhere• http://www.oracle.com/technetwork/database/database-firewall/overview/index.html www.percona.com
    • GreenSQL• Reverse proxy for MySQL, PostgreSQL, Microsoft SQL Server• Detects / reports / blocks “suspicious” queries: • Access to sensitive tables • Comments inside SQL commands • Empty password • An ‘or’ token inside a query • An SQL expression that always returns true• http://www.greensql.net/about www.percona.com
    • Still not Perfect• Vipin Samar, Oracle vice president of Database Security: • “Database Firewall is a good first layer of defense for databases but it wont protect you from everything,” • http://www.databasejournal.com/features/oracle/article.php/3924691/article.htm• GreenSQL Architecture • “GreenSQL can sometimes generate false positive and false negative errors. As a result, some legal queries may be blocked or the GreenSQL system may pass through an illegal query undetected.” • http://www.greensql.net/about www.percona.com
    • Limitations of Proxy Solutions• False sense of security; discourages code review• Gating factor for emergency code deployment• Constrains application from writing dynamic SQL• Doesn’t stop SQL injection in Stored Procedures www.percona.com
    • Fallacy FALLACY “NoSQL databases areimmune to SQL injection.” www.percona.com
    • “NoSQL Injection”http://www.example.com?column=password<?php any string-interpolation$map = new MongoCode("function() { of untrusted content emit(this." . $_GET["column"] . ",1); is Code Injection } ");$data = $db->command( array( "mapreduce" => "Users", "map" => $map ) ); www.percona.com
    • NoSQL Injection in the Wild• Diaspora wrote MongoDB map/reduce functions dynamically from Ruby on Rails: • def self.search(query) Person.all($where => "function() { return this.diaspora_handle.match(/^#{query}/i) || this.profile.first_name.match(/^#{query}/i) || this.profile.last_name.match(/^#{query}/i); }") end did query come from • http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/ a trusted source? www.percona.com
    • Myths and Fallacies• I don’t have to worry anymore • My app doesn’t need security• Escaping is the fix • Frameworks are the fix• More escaping is better • Parameters quote for you• I can code an escaping • Parameters are the fix function • Parameters make queries slow• Only user input is unsafe • SQL proxies are the fix• Stored procs are the fix • NoSQL databases are the fix• SQL privileges are the fix there is no single silver bullet— use all defenses when appropriate www.percona.com
    • SQL Antipatternshttp://www.pragprog.com/titles/bksqla/ www.percona.com
    • New York, October 1-2, 2012London, December 3-4, 2012Santa Clara, April 22-25, 2013 www.percona.com/live
    • License and Copyright Copyright 2010-2012 Bill Karwin www.slideshare.net/billkarwin Released under a Creative Commons 3.0 License: http://creativecommons.org/licenses/by-nc-nd/3.0/ You are free to share - to copy, distribute and transmit this work, under the following conditions: Attribution. Noncommercial. No Derivative Works.You must attribute this work You may not use this work You may not alter, transform, to Bill Karwin. for commercial purposes. or build upon this work. www.percona.com