当前位置:网站首页>SQL injection details

SQL injection details

2022-06-25 04:27:00 Life is sweet and good luck is good

One : What is? sql Inject

SQL Injection means web The application does not judge or filter the validity of the user's input data , Attackers can web Add extra... At the end of a predefined query statement in the application SQL sentence , Implement illegal operation without the administrator's knowledge , In this way, the database server is cheated to execute any unauthorized query , So we can get the corresponding data information


  Two :SQL The general idea of injection attack  

  1: Look for SQL Injection location

  2: Judge the server type and background database type

  3: For different server and database characteristics SQL Injection attack


  3、 ... and :SQL Inject attack instance

String sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";

-- When you enter the user name and password above , above SQL Statement becomes :
SELECT * FROM user_table WHERE username=
'’or 1 = 1 -- and password='’

"""
-- analysis SQL sentence :
-- After the condition username=”or 1=1  The user name is equal to  ”  or 1=1  Then this condition is bound to succeed ;

-- And then add two -, This means annotating , It annotates the following statements , Let them not work , This sentence will always be -- Can execute correctly , Users easily cheat the system , Get legal status .
-- It's more gentle , If it's execution 
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
-- The consequences can be imagined …
"""

Four : How to defend SQL Inject

   Be careful : Where there is SQL Injection of vulnerability procedures , It's because the program has to accept variables or URL Parameters passed , And this variable or parameter is made up of SQL Part of the statement , For user input or parameters passed , We should always be vigilant , This is in the field of security 「 External data is not trusted 」 Principles , throughout Web All kinds of attacks in the field of security , Most of it is because developers violate this principle , So it's natural to think of , From the detection of variables 、 Filter 、 Verification starts , Make sure the variables are what the developers expect .

  1、 Check variable data type and format

   If your SQL The statement is similar to where id={$id} This form , Everything in the database id It's all numbers , Then it should be SQL Before being executed , Check to make sure that the variable id yes int type ; If it's an acceptance email , Then we should check and strictly ensure that the variable must be in mailbox format , Other types like date 、 Time and so on is also a truth . Sum up : As long as it's a variable with a fixed format , stay SQL Statement before execution , Should be strictly in accordance with the fixed format to check , Make sure the variable is in the format we expect , This can be largely avoided SQL Injection attack .
   such as , We are going to accept username In the parameter example , Our product design should be at the beginning of user registration , There is a user name rule , such as 5-20 Characters , It can only be written by upper and lower case letters 、 Numbers and some security symbols , Does not contain special characters . At this point we should have a check_username Function to perform a unified check . however , There are still many exceptions that cannot be applied to this criterion , For example, the article publishing system , Comment system must allow users to submit arbitrary string scenarios , This requires other solutions such as filtering .

  2、 Filter special symbols

   For variables whose fixed format cannot be determined , Be sure to filter or escape special symbols .

  3、 Bound variable , Use precompiled statements   

  MySQL Of mysqli The driver provides support for precompiled statements , Different programming languages , There are different ways to use precompiled sentences

   actually , Binding variables using precompiled statements is a precaution SQL The best way to inject , Use precompiled SQL Sentence semantics will not change , stay SQL In the sentence , Variables are marked with question marks ? Express , No matter how powerful a hacker is , Can't change SQL Structure of statement


  5、 ... and : What is? sql precompile

  1: What is a precompiled sentence  

   Usually one of our sql stay db Receiving the final execution return can be divided into the following three processes :

    1.    Lexical and semantic analysis
    2.    Optimize sql sentence , Make an implementation plan
    3.    Execute and return results

   We call this common sentence Immediate Statements.  

   But in many cases , One of our sql Statements may be executed repeatedly , Or only individual values are different each time ( such as query Of where Clause values are different ,update Of set Clause values are different ,insert Of values Values are different ).
   If every time you need to go through the above word French meaning analysis 、 Statements to optimize 、 Make an implementation plan, etc , Then the efficiency is obviously not good .

   The so-called precompiled statement is to replace the values in such statements with placeholders , It can be regarded as taking sql Statement templating or parameterization , This kind of sentence is called Prepared Statements perhaps Parameterized Statements
   The advantage of precompiled sentences is that they can be summed up as : A compilation 、 Multiple runs , The process of analysis and optimization is omitted ; In addition, precompiled statements can prevent sql Inject .
   Of course, in terms of optimization , Most of the time, the best execution plan is not just to know sql The template of the statement determines , It is often necessary to estimate the cost through the specific value .

  1.2:MySQL Precompiled function of

   Be careful MySQL The old version (4.1 Before ) Server precompile is not supported , But based on the general situation of the industry's production environment , Basically, we can think of MySQL Support server precompile .

   So let's see MySQL The use of precompiled statements in .
  (1) Build table First of all, we have a test sheet t, The structure is as follows :

mysql> show create table t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `a` int(11) DEFAULT NULL,
  `b` varchar(20) DEFAULT NULL,
  UNIQUE KEY `ab` (`a`,`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

 (2) compile

   We're going to go through  PREPARE stmt_name FROM preparable_stm To precompile a sql sentence

mysql> prepare ins from 'insert into t select ?,?';
Query OK, 0 rows affected (0.00 sec)
Statement prepared

 (3) perform

   We go through EXECUTE stmt_name [USING @var_name [, @var_name] ...] To execute precompiled statements

mysql> set @a=999,@b='hello';
Query OK, 0 rows affected (0.00 sec)
 
mysql> execute ins using @a,@b;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0
 
mysql> select * from t;
+------+-------+
| a    | b     |
+------+-------+
|  999 | hello |
+------+-------+
1 row in set (0.00 sec)

You can see , The data has been successfully inserted into the table .

  MySQL The scope of the precompiled statement in is session level , But we can pass max_prepared_stmt_count Variable to control the global maximum storage of precompiled statements .

mysql> set @@global.max_prepared_stmt_count=1;
Query OK, 0 rows affected (0.00 sec)
 
mysql> prepare sel from 'select * from t';
ERROR 1461 (42000): Can't create more than max_prepared_stmt_count statements (current value: 1)

When the number of precompiles has reached the threshold, you can see MySQL The error shown above will be reported .

   (4) Release
   If we want to release a precompiled statement , You can use {DEALLOCATE | DROP} PREPARE stmt_name The grammar of :

mysql> deallocate prepare ins;
Query OK, 0 rows affected (0.00 sec)

6、 ... and : Why? PrepareStatement Can prevent sql Inject

   The principle is that precompile Methods , First the SQL Statement can be compiled by the set of parameters controlled by the client , Generate the corresponding temporary variable set , Then use the corresponding setting method , Assign values to the elements in the temporary variable set , The mutator setString(), Mandatory type checking and security checking are performed on the incoming parameters , So we avoid SQL The generation of Injection . Here is a detailed analysis

 (1): Why? Statement Will be sql Inject

   because Statement The reason for being sql It's because SQL The sentence structure has changed . such as :

"select*from tablename where username='"+uesrname+  
"'and password='"+password+"'"

   In user input 'or true or' after sql Sentence structure changes .

select*from tablename where username=''or true or'' and password=''

   In this way, the user name and password should be judged to match before accounting , But after the change, it becomes the logical relationship of or , Whether the user name and password match or not, the return value of this expression is always true;

 (2) Why? Preparement Can prevent SQL Inject .

   because Preparement Style is

select*from tablename where username=? and password=?

   The SQL Statement will be precompiled with the database before getting user input , In this way, no matter what the user enters, the judgment of user name and password is always a logical relationship of union , Prevented SQL Inject

   Simple summary , The reason why parameterization can prevent injection is that , A statement is a statement , Parameters are parameters , The value of the parameter is not part of the statement , The database only runs according to the semantics of the statement , As for running with an ordinary backpack or a monster , It won't affect the route , It's just the difference between running faster and running slower .


  7、 ... and :mybatis How to prevent SQL Injected   

  1、 Let's first look at the following two sql The difference between sentences :

<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = #{username,jdbcType=VARCHAR}
and password = #{password,jdbcType=VARCHAR}
</select>

 

<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = ${username,jdbcType=VARCHAR}
and password = ${password,jdbcType=VARCHAR}
</select>

mybatis Medium # and $ The difference between :

  1、# Treat the incoming data as a string , A double quotation mark will be added to the automatically passed in data .
Such as :where username=#{username}, If the value passed in is 111, So it's resolved into sql The value of time is where username="111", If the value passed in is id, Then it resolves to sql by where username="id". 
  2、$ Generate the incoming data directly in the sql in .
Such as :where username=${username}, If the value passed in is 111, So it's resolved into sql The value of time is where username=111;
If the value passed in is ;drop table user;, Then it resolves to sql by :select id, username, password, role from user where username=;drop table user;
  3、# To a great extent sql Inject ,$ Method cannot prevent Sql Inject .
  4、$ Method is generally used for incoming database objects , For example, pass in the table name .
  5、 Generally available # Don't use it. $, If you have to use “${xxx}” Such a parameter , Do a good job of filtering by hand , To prevent sql Injection attack .
  6、 stay MyBatis in ,“${xxx}” Parameters in this format will directly participate in SQL compile , So we can't avoid injection attacks . But when it comes to dynamic table names and column names , Only use “${xxx}” Such a parameter format . therefore , Such parameters need to be handled manually in the code to prevent injection .
【 Conclusion 】 Writing MyBatis The mapping statement of , Use as far as possible “#{xxx}” This format . If you have to use “${xxx}” Such a parameter , Do a good job of filtering by hand , To prevent SQL Injection attack .

mybatis How to prevent sql Injected

  MyBatis Framework as a semi-automatic persistence layer framework , Its SQL We have to write the sentences by ourselves , This time, of course, we need to prevent SQL Inject . Actually ,MyBatis Of SQL Is a person with “ Input + Output ” The function of , Similar to the structure of a function , Refer to the two examples above . among ,parameterType Represents the input parameter type ,resultType Represents the parameter type of the output . In response to the above , If we want to prevent SQL Inject , It's natural to work on input parameters . Used in the above code # The input parameters are in SQL The spliced part of , After passing in the parameters , Print out the execution of SQL sentence , Will see SQL That's true :

select id, username, password, role from user where username=? and password=?

   No matter what parameters you enter , Print out the SQL It's all like this . This is because MyBatis Precompile is enabled , stay SQL Before execution , I'll put the above SQL Send to database for compilation ; Execution time , Use compiled SQL, Replace placeholders “?” That's all right. . because SQL Injection only works on the compilation process , So this is a good way to avoid SQL Injection problem .

  【 Underlying implementation principle 】MyBatis How to do SQL Precompiled ? In fact, at the bottom of the frame , yes JDBC Medium PreparedStatement Class is working ,PreparedStatement It's something we're familiar with Statement Subclasses of , Its objects contain compiled SQL sentence . such “ Get ready ” It's not just a way to improve security , And execute the same... Many times SQL when , Can improve efficiency . as a result of SQL Compiled , You don't need to compile it again

 

Information :https://www.cnblogs.com/shenbuer/p/7875419.html

  http://www.cnblogs.com/mmzs/p/8398405.html

原网站

版权声明
本文为[Life is sweet and good luck is good]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206250220556024.html