sql注入:

所谓sql注入,就是通过把sql命令插入到表单中或页面请求的查询字符串中,最终达到欺骗服务器执行恶意的sql命令。具体来说,它是利用现有的应用程序,将(恶意的)sql命令注入到后台数据库引擎执行的能力,它也可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者的意图去执行sql语句。比如先前的很多影视网站泄露VIP会员密码大多数就是通过Web表单递交查询字符串爆出的。

(1)现在我们有一个sql_user表,表结构如下:

from django.db import models
from django.core import validators class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=24)
telephone = models.CharField(max_length=11, validators=[validators.RegexValidator(r"1[345678]\d{9}")]) class Meta:
db_table = 'sql_user'

(2)然后我们使用原生sql语句实现以下需求:

(1)实现一个根据用户id获取用户详情的视图,示例代码如下:
from django.http import HttpResponse
from django.db import connection
from django.shortcuts import render def index(request):
cursor = connection.cursor()
user_id = request.GET.get('id')
context = {} if user_id:
cursor.execute("select id,username from sql_user where id=%s"%user_id)
users = cursor.fetchall()
for user in users:
print(user)
context['users'] = users
return render(request, 'sql.html', context=context)
else:
return HttpResponse('该用户不存在!!!')
(2)正常情况,用户可以使用查询字符串的形式访问该网页,并且查询用户的详情,可以输入:http://127.0.0.1:8000/sql/?id=2, 这样的话,就会返回给用户数据库中id为2的用户详情。可是,如果用户在这个时候,进行sql注入,比如,输入:http://127.0.0.1:8000/sql/?id=2 or 1=1,很显然,1=1这样的条件是永远为True的,这样的话,就会返回给用户数据库中存在的所有用户的数据,就会造成用户信息的泄露。
(3)根据用户名提取用户相关的信息,示例代码如下:
from django.http import HttpResponse
from django.db import connection
from django.shortcuts import render def index(request):
cursor = connection.cursor()
username = request.GET.get('username')
context = {}
if username:
cursor.execute("select id, username from sql_user where username='%s'"%username)
users = cursor.fetchall()
for user in users:
print(user)
context['users'] = users
return render(request, 'sql.html', context=context)
else:
context['users'] = '您输入的用户不存在!'
return render(request, 'sql.html', context=context)
注意,如果在执行sql语句的时候没有在%s两边用单引号包裹,那么在输入url的时候一定要将username对应的值加上单引号http://127.0.0.1:8001/sql/?username='孤烟逐云',否者的话,会报错:“OperationalError at /sql/(1054, "Unknown column '孤烟逐云' in 'where clause'")”。但是,如果我们在执行sql语句的时候,在%s两边加上单引号,那么在url中输入查询字符串的时候,就不用加单引号了。
正常情况下,我们应该输入:http://127.0.0.1:8001/sql/?username=孤烟逐云 ,网页就会返回给我们查询到的用户的详情。但是,如果我们不遵循设计者的意愿,输入http://127.0.0.1:8001/sql/?username=孤烟逐云' or '1=1很显然,这个结果永远为True 。那么,就会给用户返回数据库中所有的用户信息,并且此时不管你输入的username是否存在数据库中,也不管你后面输入的是1=4还是1=3都会返回数据库中所有的信息。其实此时已经破坏了网页的结构。

sql注入防御:

通过传递一些恶意代码来破坏原有的sql语句以便达到自己的目的。那么我们该如何防御sql注入呢? 归类起来主要有以下几点:

(1)永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双引号进行转换等。
(2)永远不要使用动态拼接sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取,比如:
sql = "select id, username from sql_user where username=%s"
cursor.execute(sql, (username,))
<!--参数化的形式execute(sql语句,(参数,)),其中参数后面的逗号表示execute()传入的是一个元组。-->
(3)永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
(4)不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
(5)应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始信息进行包装。

在Django中如何防御sql注入:

(1)使用ORM来做数据的增删改查,因为ORM使用的是参数化的形式执行sql语句。
(2)如果要执行原生sql语句,那么建议不要使用拼接的sql,而是使用参数化的形式。

159.SQL注入的实现和防御措施的更多相关文章

  1. SQL注入之代码层防御

    [目录] 0x0 前言 0x1 领域驱动的安全 1.1 领域驱动的设计 1.2 领域驱动的安全示例 0x2 使用参数化查询 2.1 参数化查询 2.2 Java中的参数化语句 2.3 .NET(C#) ...

  2. SQL注入原理&分类&危害&防御

    SQL是什么? 结构化查询语句 SQL注入是什么? 是一种将SQL 语句插入或添加到用户输入的参数中,这些参数传递到后台服务器,加以解析并执行 造成注入的原因/原理? 1.对用户输入的参数没有进行严格 ...

  3. SQL注入的那些面试题总结

    一.知识储备类 1.SQL与NoSQL的区别? SQL:关系型数据库 NoSQL:非关系型数据库 存储方式:SQL具有特定的结构表,NoSQL存储方式灵活 性能:NoSQL较优于SQL 数据类型:SQ ...

  4. 注入攻击(SQL注入防御)

    正确的防御SQL注入 sql注入的防御不是简单只做一些用户输入的escape处理,这样是不够的,只是提高了攻击者的门槛而已,还是不够安全. 例如 mysql_real_escape_string()函 ...

  5. SQL注入(SQL Injection)案例和防御方案

    sql注入(SQL Injection):就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. SQL注入攻击的主要危害包括:非法读取.篡 ...

  6. 程序员常用的3大Web安全漏洞防御解决方案:XSS、CSRF及SQL注入(图文详解)

    https://blog.csdn.net/ChenRui_yz/article/details/86489067 随着互联网的普及,网络安全变得越来越重要,程序员需要掌握最基本的web安全防范,下面 ...

  7. Web安全之SQL注入(原理,绕过,防御)

    首先了解下Mysql表结构 mysql内置的information_schema数据库中有三个表非常重要1 schemata:表里包含所有数据库的名字2 tables:表里包含所有数据库的所有的表,默 ...

  8. 防御sql注入

    1. 领域驱动安全 领域驱动安全是一种代码设计方法.其思想是将一个隐式的概念转化为显示,个人认为即是面向对象的方法,将一个概念抽象成一个类,在该类中通过方法对类的属性进行约束.是否是字符串,包含什么字 ...

  9. web安全之sql注入的防御

    自动把引号转义     1.防御sql注入的基本原则           任何时候不应该改变用户的输入                    比如用户输入单引号,那输出也要是单引号.   几种基本的防 ...

随机推荐

  1. ELK学习003:Elasticsearch启动常见问题

    一.Caused by: java.lang.RuntimeException: can not run elasticsearch as root 这个错误,是因为使用root用户启动elastic ...

  2. springboot快速创建项目框架

    一.项目框架准备 1.1 新建maven空项目,并在pom中引入依赖 <parent> <groupId>org.springframework.boot</groupI ...

  3. 简单的OO ALV显示ALV及下载

    REPORT OO_ALV. CLASS OO_ALV DEFINITION. PUBLIC SECTION. METHODS:GET_DATA IMPORTING AMOUNT TYPE I,&qu ...

  4. 使用expect实现自动交互,shell命令行自动输入

    背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...

  5. 发布开源项目到Jcenter

    前言 为了将阿里云短信开箱即用发布到Jcenter仓库,前前后后花费了1天半的时间,把端午节都搭进去了.终于今天收到了Jcenter的消息,自己发布的包被添加到了Jcenter仓库,也算给开源社区做了 ...

  6. MySQL基础篇(02):从五个维度出发,审视表结构设计

    本文源码:GitHub·点这里 || GitEE·点这里 一.数据场景 1.表结构简介 任何工具类的东西都是为了解决某个场景下的问题,比如Redis缓存系统热点数据,ClickHouse解决海量数据的 ...

  7. [大数据技术]Kettle报OPTION SQL_SELECT_LIMIT=DEFAULT错误的解决办法

    百度得到的解决方式都是说mysql通过jdbc链接的时候会进行测试’SET OPTION SQL_SELECT_LIMIT=DEFAULT’,但是5.6以后的版本弃用了set的方式. 我用的MySQL ...

  8. MariaDB(MySQL)创建、删除、选择及数据类型使用详解

    一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行 ...

  9. 【sklearn】特征选择和降维

    1.13 特征选择 sklearn.feature_selection模块中的类可以用于样本集上的特征选择/降维,以提高估计器的精度值,或提高其应用在高维数据集上的性能. 1.13.1 删除低方差的特 ...

  10. 【sklearn决策树算法】DecisionTreeClassifier(API)的使用以及决策树代码实例 - 鸢尾花分类

    决策树算法 决策树算法主要有ID3, C4.5, CART这三种. ID3算法从树的根节点开始,总是选择信息增益最大的特征,对此特征施加判断条件建立子节点,递归进行,直到信息增益很小或者没有特征时结束 ...