Python全栈之路系列之MySQL SQL注入
SQL注入
是一种代码注入技术,过去常常用于攻击数据驱动性的应用,比如将恶意的SQL代码注入到特定字段用于实施拖库攻击等。
SQL注入
的成功必须借助应用程序的安全漏洞,例如用户输入没有经过正确地过滤(针对某些特定字符串)或者没有特别强调类型的时候,都容易造成异常地执行SQL语句。
SQL注入
是网站渗透中最常用的攻击技术,但是其实SQL注入可以用来攻击所有的SQL数据库。
SQL注入的实现
创建SQLdb
数据库
CREATE DATABASE SQLdb;
创建user_info
表
1
2
3
4
5
6
|
CREATE TABLE `user_info` (
`
id
`
int
(
11
) NOT NULL AUTO_INCREMENT,
`username` varchar(
32
) DEFAULT NULL,
`password` varchar(
32
) DEFAULT NULL,
PRIMARY KEY (`
id
`)
) ENGINE
=
InnoDB DEFAULT CHARSET
=
utf8;
|
插入一条用户数据
测试的用户名是ansheng
,密码as
1
|
insert into user_info(username,password) values(
"ansheng"
,
"as"
);
|
Python代码
app.py
文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import
tornado.ioloop
import
tornado.web
import
pymysql
class
LoginHandler(tornado.web.RequestHandler):
def
get(
self
,
*
args,
*
*
kwargs):
self
.render(
'login.html'
)
def
post(
self
,
*
args,
*
*
kwargs):
username
=
self
.get_argument(
'username'
,
None
)
pwd
=
self
.get_argument(
'pwd'
,
None
)
conn
=
pymysql.connect(host
=
'127.0.0.1'
, port
=
3306
, user
=
'root'
, passwd
=
'as'
, db
=
'sqldb'
)
cursor
=
conn.cursor()
temp
=
"select username from user_info where username='%s' and password = '%s'"
%
(username, pwd,)
effect_row
=
cursor.execute(temp)
result
=
cursor.fetchone()
conn.commit()
cursor.close()
conn.close()
if
result:
self
.write(
'登录成功'
)
else
:
self
.write(
'登录失败'
)
application
=
tornado.web.Application([
(r
"/login"
, LoginHandler),
])
if
__name__
=
=
"__main__"
:
application.listen(
8888
)
tornado.ioloop.IOLoop.instance().start()
|
HTML代码
login.html
与app.py
文件在同级
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!DOCTYPE html>
<html lang
=
"en"
>
<head>
<meta charset
=
"UTF-8"
>
<title>Title<
/
title>
<
/
head>
<body>
<form action
=
"/login"
method
=
"post"
>
<
input
type
=
"text"
name
=
"username"
placeholder
=
"用户名"
/
>
<
input
type
=
"text"
name
=
"pwd"
placeholder
=
"密码"
/
>
<
input
type
=
"submit"
/
>
<
/
form>
<
/
body>
<
/
html>
|
演示效果
打开浏览器,输入地址http://127.0.0.1:8888/login
填写内容如下:
用户名:asas ' or 1 = 1-- asd
密码:随便填写一串字母
如图:
当点击提交
的时候是否会跳转到登陆成功页面?如果你的代码和我一样,那么就会跳转到登陆成页面
。
为什么出现这种问题?
出现这个问题的主要原因就是因为我们使用了字符串拼接
的方式来进行SQL指令的拼接。
SQL指令拼接代码
1
|
temp
=
"select username from user_info where username='%s' and password = '%s'"
%
(username, pwd,)
|
这是一个正常的SQL拼接出来的结果
1
|
select username
from
user_info where username
=
'ansheng'
and
password
=
'as'
|
这是一个非正常的SQL拼接出来的结果
select username from user_info where username='asas' or 1 = 1 -- asd' and password = 's'
聪明的你是否已经看到其中的玄机了呢?--
如何防止?
通过Python
的pymysql
模块来进行SQL
的执行,在pymysql
模块内部会自动把”'
“(单引号做一个特殊的处理,来预防上述的错误
1
2
3
|
......
effect_row
=
cursor.execute(
"select username from user_info where username='%s' and password = '%s'"
, (username, pwd))
......
|
本文转自 Edenwy 51CTO博客,原文链接:http://blog.51cto.com/edeny/1925919,如需转载请自行联系原作者