开启慢日志需要注意三个关键点 1.多久算慢? 2.慢日志存放哪? 3.可以不可以关闭慢日志
抱着上面的问题我们来查找一下 多久算慢?show variables like 'long_query_time%';
系统默认的是10s 我们来改一下,改成2s行不行 set global long_query_time=2;
我们再看慢日志的开启状态和文件存放 show variables like 'slow_query_log%';
默认是关闭的,我们打开
set global slow_query_log=1;
select sleep(3);
查看慢日志
slow_query_log=1
slow_query_log_file=/usr/local/mysql/data/zhangguofudeMacBook-Pro-slow.log
long_query_time=2
use mysql;
create user 'acurd'@'%' identified by 'acurd';
grant all privileges on *.* to "acurd"@'%';
创建表
CREATE TABLE `user` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '管理员ID',
`name` varchar(20) NOT NULL COMMENT '管理员名称',
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '管理员密码',
PRIMARY KEY (`id`),
KEY `member_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='管理员表';
INSERT INTO `user` VALUES (1,'haha','123456'),(3,'123','sfdsaf');
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"html/template"
"log"
"net/http"
"strings"
)
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //获取请求的方法
if r.Method == "GET" {
t, _ := template.ParseFiles("sql-inject/login.html")
t.Execute(w, nil)
return
}
if r.Method == "POST" {
r.ParseForm()
fmt.Println("name:", r.Form["name"])
var name = strings.Join(r.Form["name"], "")
var password = strings.Join(r.Form["password"], "")
var id int
db, err := sql.Open("mysql", "acurd:acurd@tcp(127.0.0.1:3306)/test")
if err != nil {
log.Fatal(err)
}
sql:="SELECT id FROM user WHERE name = '" + name + "' AND password =" + password + ""
log.Println(sql)
err = db.QueryRow(sql).Scan(&id)
if err != nil {
w.Write([]byte("登录失败!"))
return
}
if id != 0 {
w.Write([]byte("登录成功!"))
return
} else {
w.Write([]byte("登录失败!"))
return
}
return
}
}
func main() {
http.HandleFunc("/login", login) //设置访问的路由 //设置访问的路由
err := http.ListenAndServe(":80", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Query_time: 10.015358 Lock_time: 0.007526 Rows_sent: 0
zhangguofu@zhangguofudeMacBook-Pro mysql $ cat /usr/local/mysql/data/zhangguofudeMacBook-Pro-slow.log
# Time: 2022-03-08T02:13:50.546820Z
# User@Host: acurd[acurd] @ localhost [127.0.0.1] Id: 63
# Query_time: 10.015358 Lock_time: 0.007526 Rows_sent: 0 Rows_examined: 38
SET timestamp=1646705620;
SELECT id FROM user WHERE name = 'haha' AND password =ELT(1,SLEEP(10));
SELECT id FROM user WHERE name = 'haha' AND password =3 or 1=1
这条SQL把库里所有的数据都查出来了 sqlStr:="SELECT id FROM user WHERE name = " + name + " AND password =" + password + ""
SELECT id FROM user WHERE name = 123 # AND password =some word
var sqln string; sqln="select sleep(10)"
,你说你声明的是字符串,但是MySQL执行的是字符串里面的内容。SELECT id FROM user WHERE name = 'haha' AND password ='ELT(1,SLEEP(10))'
sql:="SELECT id FROM user WHERE name = '" + name + "' AND password = '" + password + "'"
sql:="SELECT id FROM user WHERE name = ? AND password = ?"
log.Println(sql)
err = db.QueryRow(sql,name,password).Scan(&id)
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"html/template"
"log"
"net/http"
)
func article(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //获取请求的方法
if r.Method == "GET" {
r.ParseForm()
title := r.FormValue("title")
log.Println(title)
titleHtml:=template.HTML(title)//template默认是转义了,我们使用template.HTML 表示不转义
t, _ := template.ParseFiles("xss/article.html")
t.Execute(w, titleHtml)
return
}
}
func main() {
http.HandleFunc("/article", article) //设置访问的路由 //设置访问的路由
err := http.ListenAndServe(":80", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
<html>
<head>
<meta charset="utf-8" />
<title>sql注入</title>
<style>
form{
width: 30vw;
height: 30vh;
min-height: 300px;
margin: 10vh auto;
border: 1px solid;
border-radius: 4px;
}
form .username,.password{
display: block;
float: right;
}
div {
width: 300px;
height: 80px;
margin: 30px auto 0;
}
input label {
float: left;
display: inline-block;
}
input {
height: 30px;
}
.button {
width: 100px;
margin: auto;
clear: both;
display: block;
}
</style>
</head>
<body>
<form action="/article" method="get">
<div>
<label>标题: </label>
<input class="username" type="text" name="title">
</div>
<input class="button" type="submit" value="查询">
<p>搜索结果:{{.}}</p>
</form>
</body>
</html>
<script>alert("反射型 XSS 攻击")</script>
CREATE TABLE `an_article` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '文章id',
`title` varchar(100) NOT NULL COMMENT '标题',
`detail` varchar(1000) DEFAULT NULL COMMENT '内容',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文章表';
<!doctype html>
<html lang="en" content="wwwww">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<h4>{{.Title}}</h4>
<p>{{.Detail}}</p>
</body>
</html>
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"html/template"
"log"
"net/http"
"strings"
)
type Article struct {
Title template.HTML
Detail template.HTML
}
func article(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //获取请求的方法
db, err := sql.Open("mysql", "acurd:acurd@tcp(127.0.0.1:3306)/test")
if r.Method == "GET" {
sqlStr:="SELECT title,detail FROM an_article WHERE id=13"//13是带xss提交生成的id
var article Article
var title string
var detail string
err = db.QueryRow(sqlStr).Scan(&title,&detail)
article.Title=template.HTML(title)
article.Detail=template.HTML(detail)
log.Println(article)
t, err := template.ParseFiles("xss/article.html")
if err != nil{
log.Fatal(err)
}
err = t.Execute(w, article)
if err != nil{
log.Fatal(err)
}
return
}
if r.Method=="POST"{
if err != nil {
log.Fatal(err)
}
defer db.Close()
sqlStr := "INSERT INTO an_article (title,detail) VALUES (?,?)"
r.ParseForm()
fmt.Println("title:", r.Form["title"])
fmt.Println("detail:", r.Form["detail"])
var title = strings.Join(r.Form["title"], "")
var detail = strings.Join(r.Form["detail"], "")
res, _ := db.Exec(sqlStr, title, detail)
id,_:=res.LastInsertId()
fmt.Println(id)
}
}
func main() {
http.HandleFunc("/article", article) //设置访问的路由 //设置访问的路由
err := http.ListenAndServe(":80", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
<img src="pic.gif" onerror="alert('请点击图片查看')" alt="点击可查看" title="点击可查看" onclick="alert('叫点就点,你也是有蛮乖的!')">
</p><h4>xxxxxxx</h4>
截断了你的p标签,换行了一个h4<img src="pic.gif" onerror="alert('请点击图片查看')" alt="点击可查看" title="点击可查看" onclick="alert('叫点就点,你也是有蛮乖的!')">
控制输出,使用转义函数、标签过滤函数等 比如转义后的在html 并不是医html实体 ,而是字符串的形式出现的,当然不会被执行
对于一些富文本,我们可以采用白名单或者黑名单的方式,过滤非法字符串