简单来说就是,攻击者通过一些技术手段欺骗用户通过浏览器去访问一个,自己已经认证过(登陆过,留下过登录验证信息)的网站,进行一系列操作(例如:发邮件,发消息,甚至财产操作和转账),所以被访问的网站会认为是真正的用户操作而去运行。
简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求是用户自愿发出的。
假设:
假如把1000元钱转账给shx的链接为:
https://www.bank.com/withdraw?amount=1000&for=shx
那么,一个恶意攻击者top可以在另外一个网站上设置如下链接:
https://www.bank.com/withdraw?amount=1000&for=top
如果用户登陆过账号不久,登录信息尚未过期,并且被攻击者骗取打开此链接,那么shx就有可能会损失1000元钱。
①检查Referer字段:
HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通过此字段获取发送请求的网址,并传递给服务器端,这时候服务器就能识别出是否为恶意访问。
这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。
②添加校验token:
由于CSRF的本质是利用存储在浏览器中的验证数据欺骗用户去访问攻击者设置的地址,只要用户提供的验证数据不存储在浏览器中,并且攻击者无法伪造验证数据作为效验,那么攻击者就无法运行CSRF攻击。
所以这种验证数据一般是由服务器生成,将其放在请求的返回值中,其内容是一个伪随机码,当客户端提交数据时,将这个伪随机码一并提交上去做校验。
当用户正常访问时,客户端能接受并返回这个随机码,而通过CSRF传来的欺骗性攻击中,攻击者无法事先得知或伪造这个伪随机码,服务器就会因为token的值为空或者错误,拒绝这个可疑请求。
③在 HTTP 头中自定义属性并验证:
这种方法本质也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
XSS攻击通常是指利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,当HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。
①由于XSS攻击在用户当前使用的应用程序中执行,用户将会看到与其有关的个性化信息,如账户信息或“欢迎回来”消息,克隆的Web站点不会显示个性化信息。
②通常,在钓鱼攻击中使用的克隆Web站点一经发现,就会立即被关闭。
③许多浏览器与安全防护软件产品都内置钓鱼攻击过滤器,可阻止用户访问恶意的克隆站点。
④如果客户访问一个克隆的Web网银站点,银行一般不承担责任。但是,如果攻击者通过银行应用程序中的XSS漏洞攻击了银行客户,则银行将不能简单地推卸责任。
①持久型跨站:最直接的危害类型,跨站代码存储在服务器(数据库)。
②非持久型跨站:反射型跨站脚本漏洞,最普遍的类型。用户访问服务器-跨站链接-返回跨站代码。
③DOM跨站(DOM XSS):DOM(document object model文档对象模型),客户端脚本处理逻辑导致的安全问题。
基于DOM的XSS漏洞是指受害者端的网页脚本在修改本地页面DOM环境时未进行合理的处置,而使得攻击脚本被执行。在整个攻击过程中,服务器响应的页面并没有发生变化,引起客户端脚本执行结果差异的原因是对本地DOM的恶意篡改利用。
①盗用cookie,获取敏感信息。
②利用植入Flash,通过crossdomain权限设置进一步获取更高权限;或者利用Java等得到类似的操作。
③利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
④利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。
⑤在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS攻击的效果。
①不信任用户提交的任何内容,对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、REFER、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤。尽量采用POST而非GET提交表单;对“<”,“>”,“;”,“””等字符做过滤;任何内容输出到页面之前都必须加以en-code,避免不小心把htmltag显示出来。
②实现Session 标记(session tokens)、CAPTCHA(验证码)系统或者HTTP引用头检查,以防功能被第三方网站所执行,对于用户提交信息的中的img等link,检查是否有重定向回本站、不是真的图片等可疑操作。
③cookie 防盗。避免直接在cookie中泄露用户隐私,例如email、密码,等等;通过使cookie和系统IP绑定来降低cookie泄露后的危险。这样攻击者得到的cookie没有实际价值,很难拿来直接进行重放攻击。
④确认接收的内容被妥善地规范化,仅包含最小的、安全的Tag(没有JavaScript),去掉任何对远程内容的引用(尤其是样式表和JavaScript),使用HTTPonly的cookie。
ab是:
ApacheBench命令的缩写。
ab的原理:
ab命令会创建多个并发访问线程,模拟多个访问者同时对某一个URL地址进行访问。(它的测试目标是基于url的,因此,它既可以用来测试安排车的负载压力,也可以测试Nginx、lighthttp、Tomcat、IIS等其他web服务器的压力)
ab命令注意事项:
ab命令对发出负载的计算机要求很低,它既不会占用很高的CPU,也不会占用很多内存。但却会给目标服务器造成巨大负载,其原理类似cc攻击。自己测试使用一定要注意,负责一次上太多负载。可能会造成目标服务器资源耗完,严重时甚至导致死机。
使用:
在windows系统下cmd进入Apache安装路径,在bin目录下有一个ab.exe可执行文件,执行ab命令(注意:直接双击是无法正确运行的),直接键入ab回车,可以看到帮助提示。
ab常用参数:
-n:总共请求执行次数,缺省是1;
-c:并发数,缺省是1;
-t:测试所进行的总时间,单位是秒,缺省是50000s;
-p:POST时的数据文件;
-w:以HTML表的格式输出;
例如:把<替换成<>,把>替换成><,不管谁在前都会影响下一次。
let newStr= oldStr.replace(/<|"|=|\/|>/g, str => { let return_str = str; switch (str) { case "<": return_str = `<>`; case ">": return_str = `><`; break; } return return_str; });
进入dir目录
cd dir
返回上一级
cd ..
返回上两级
cd ../..
返回根目录
cd /
返回最近一次访问目录
cd -
查看当前访问路径
pwd
将test目录或文件压缩成一个名为newzip的压缩文件,可在名称前加上路径
zip newzip.zip test
查看当前目录内容
ls
查看目录中的隐藏文件
ls -a
创建名为dir的目录
mkdir dir
删除名为dir的目录或文件
rm -rf dir
移动dir目录到指定url路径
mv dir url
复制dir目录下所有内容到dir2目录中,其中dir和dir2都可以是目录所在路径。
备注:如果复制目录则必须需要加-r参数,才能将目录中的所有内容都复制过去,复制文件则不需要加-r参数。
cp -r dir dir2
查看当前目录下所有目录或者文件的大小(但不包括目录下的大小)和权限信息。
单位:B,以下两种相同
ls -ll
ls -l
单位:KB
ls -lh
查看当前所在目录权限以及大小(但不包括目录下的大小),加h单位是KB,不加则为B。
ls -ld
查看当前所有目录和文件的总大小(包括目录下面内容的大小),单位自动,视情况使用KB、MB、GB等。
du -sh
查看名为dir的目录或文件大小(包括目录下面内容的大小),单位自动,视情况使用KB、MB、GB等。
du -sh dir
查看当前目录下所有一级目录或文件各自的大小
--max-depth指定最大深度,0就是只计算查看当前目录下的内容。
如果想查询到当前目录的二级子目录,则可以将0改为1,三级子目录则改为2,以此类推……
du -h --max-depth=0 *
如果是1,则会把这几个目录下的二级子目录和文件都计算展示出来。
查看file文件内容,正向查看文件。
cat file
查看file文件内容,反向查看文件。
tac file
打开一个file文件
vim file
打开文件后编辑文件
I
使用I进入编辑模式后退出编辑
ESC
按ESC退出编辑后使用,保存并退出编辑窗口
:wq
按ESC退出编辑后使用,保存但不退出编辑窗口
:w
按ESC退出编辑后使用,强制性保存但不退出编辑窗口
:w!
按ESC退出编辑后使用,将修改保存到另外的file中,当file文件不存在时自动创建
:w file
按ESC退出编辑后使用,强制性保存并退出编辑窗口
:wq!
按ESC退出编辑后使用,不保存退出并退出编辑窗口
:q
按ESC退出编辑后使用,不保存强制退出并退出编辑窗口
:q!
按ESC退出编辑后使用,放弃所有修改,从上次保存的开始编辑:
:e!
查看当前目录下的权限信息
备注:
文件最前方有十个字符。
第一个代表文件类型,-代表是普通文件,d代表是目录。
后面九个代表权限一共分成3组,每3个一组,分别是所有者、所属组、其他人。
ls -l
给dir目录或文件设置777权限。
权限数字表示:
r=4,w=2,x=1。
例如:
rwxrw-r--:三个一组,rwx权限分别对应421,相加得7,rw-对应42相加,r--对应4。
chmod 777 dir
给dir目录以及他下面文件和目录设置777权限,R必须大写。
chmod -R 777 dir
给dir目录或文件的所有者单独加一个读的权限
u:所有者, g:所属组,o:其他人,a:所有。
+:添加权限,-减少权限,=直接赋值成这个权限。
chmod u+r dir
查看80端口占用情况
lsof -i tcp:80
netstat 命令用于显示网络状态
#查看TCP和Socket的网络信息,并显示正在使用Socket的程序识别码(pid)和程序名称 netstat --tcp --listening --program #等同于:netstat -t -l -p
kill 命令用于杀死指定pid的进程(假设Websocket进程的pid为123456)
kill 123456 #杀死进程 kill -KILL 123456 #强制杀死进程 kill -9 123456 #彻底杀死进程(是操作系统从内核级别强制杀死一个进程) kill -15 123456 可以理解为操作系统发送一个通知告诉应用主动关闭.
拼合命令:杀死指定(9502)端口进程
kill -15 `netstat -nlp | grep :9502 | awk '{print $7}' | grep -o '[0-9]*'`
持久化启动python3的Django项目
nohup python3 manage.py runserver 0.0.0.0:80 >>log_app.out>&1 &
持久化启动某个程序,log_app.out 为日志文件,&1是保存标准输出内容的意思,最后&后台运行的意思
nohup 启动命令 >>log_app.out>&1 &
根据 文件或目录名称 搜索
find 【搜索目录】【-name或者-iname】【搜索字符】:-name和-iname的区别一个区分大小写,一个不区分大小写
eg:在/etc 目录下搜索名字为init的文件或目录
find /etc -name init (精准搜索,名字必须为 init 才能搜索的到) find /etc -iname init (精准搜索,名字必须为 init或者有字母大写也能搜索的到) find /etc -name *init (模糊搜索,以 init 结尾的文件或目录名) find /etc -name init??? (模糊搜索,? 表示单个字符,即搜索到 init___)
mysqladmin --version 验证mysql
mysql -h主机地址 -u用户名 -p 连接mysql
show engines 查看数据库支持的引擎
show variables like '%storage_engine%' 查看当前使用的数据库引擎
MySQL每个数据库都会在data目录下生成一个目录,里面有*.frm、*.myi、*.myd和*.opt文件。
*.frm--表定义,是描述表结构的文件。
*.MYD--"D"数据信息文件,是表的数据文件。
*.MYI--"I"索引信息文件,是表数据文件中任何索引的数据树。
*.opt--记录数据库选项,数据库的字符集。
增:返回添加记录的id,删和修返回影响的条数,查返回查询出来的结果集。
MySQL数据库版本:
5.X:
5.0-5.1:早期产品的延续,升级维护
5.2-5.3:不常用
5.4-5.X:MySQL整合了三方公司的新存储引擎,以前的版本都是mysql自己单干。(现在主要是用5.5和5.7)
连接层:提供与客户端连接的服务
服务层:1.提供各种接口。2.提供SQL优化器:MySQL QUery Optimizer
引擎层:提供了各种存储数据的方式(InnoDB MyISAM)
存储层:存储数据
InnoDb:事务有限,适合高并发操作;行锁
MyISAM:性能优先
内置很多实用工具,例如:josn美化、时间戳转化工具、思维导图、网页性能检测、二维码生成/解码、代码压缩工具、MArkdown工具、页面取色工具、简易postman…………
可以改变页面的编码格式。
可以根据具体网站和对应的元素进行屏蔽,可以选择任意元素进行屏蔽,不仅限于广告。
可以查看各大网商的历史价格变化曲线,自动生成在商品详情页上,鼠标移动上去自动显示。
可以通过s(减小)和d(增加)页面视频的播放速度,实测后发现包括一些学习视频,不能快进的也可以!
理由:可以跟踪每行代码的git提交修改记录。
最好用的翻译软件,选中代码Ctrl+shift+Y翻译代码,Ctrl+shift+O打开翻译器。
由于某些原因,导致部分代码没有写,但又怕忘记,可以以//todo为开始写注释,后期想要查找时,可以使用快捷键alt+6查看项目中那些文件使用了//todo。
ajax也分很多种,本人用的最多的是jQuery的Ajax,这篇文章就大概说一下相关的知识点。
首先下面是常用的ajax使用方式,其中的参数也是经常用到的:
$.ajax({ type:"post/get", url:"url", async:true/fasle, dataType:"json", processData:"true", contentType:"application/x-www-form-urlencoded", data:{ value_name:value }, success:function (data,status,ajaxclass) { //处理返回的数据 }, error:function () { //ajax失败时执行的方法 } })
type:
传值类型,分为POST和GET两种,不区分大小写,默认为GET。
实际上put、delete等传值方式也能使用,但仅部分浏览器支持。
url:
发送请求的地址
async:
是否异步,不写该属性时默认true。(异步是多线程,同步是单线程)
设置为true时,所有请求为异步。设置为false时,所有请求未同步。
注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。
data:
发送到请求地址的数据,将自动转换为请求字符串格式。
单个值可直接写。例如name,接口可以接受到name这个值。
多个值用json格式。{参数名:值,参数名:值,……}的形式,或者直接写变量名{变量1,变量2,变量3,……}。
success:
当请求运行成功时的回调函数,并返回根据 dataType 参数进行处理后的数据。
参数一:data(这里参数名称任意)即为返回的值
参数二:status(这里参数名称任意)返回ajax的执行状态,这里返回success
参数三:ajaxclass(这里参数名称任意)返回当前ajax对象的一些数据。
error:
当请求运行失败时的回调函数,一般用作请求地址响应失败时给予用户报错提示。
dataType:
请求返回后要处理成的数据类型。常用值:
"xml": 返回 XML 文档,可用 jQuery 处理。
"html": 返回纯文本 HTML 信息;包含的 script 标签会在插入 dom 时执行。
"script": 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了 "cache" 参数。注意:在远程请求时(不在同一个域下),所有 POST 请求都将转为 GET 请求。(因为将使用 DOM 的 script标签来加载)
"json": 返回 JSON 数据 。
"jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
"text": 返回纯文本字符串
processData:
参数值为true或false,默认为true
一般情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是一个字符串),都会处理转化成一个查询字符串,以配合默认内容类型“application/x-www-form-urlencoded”。
如果发送DOM树信息或其他不希望转换的信息,则需要设置为false。
此属性在使用FormData进行data传值时属性值必须为false
contentType:
默认值“application/x-www-form-urlencoded”,是发送信息至请求地址时内容编码类型。
此属性在使用FormData进行data传值时属性值必须为false。
end,waiting for update……
相关知识扩充:
①如果不加此参数,会出现不可预知的错误!
比如某些加了安全控件的系统,不加此参数,会直接报错403,服务器认为你的此次请求是在攻击系统。
②当ajax上传文件时,我们查看Request headers:
这时会发现content-Type这个的参数是multipart/form-data后面还会有boundary再接着一串随机字符串。
前面的参数我们并不陌生,这是form表单上传文件必须的参数,而后面的参数是当我们上传文件时,系统会自动生成一堆随机字符串,也叫分界符,目的是为了防止文件中出现分隔符导,最终致请求地址的服务器无法正确解析文件的起始位置。
换言之就是,文件传输中本质还是文件流传输(其实也就是字符代码的传输),这样就需要与其他非文件参数进行区分,而boundary生成的这个复杂随机字符串就是为了将文件流与其他参数区分开来,而将contentType设为false是为了防止jQuery对数据进行二次编码,从而失去分界符,最终导致请求地址的服务器无法正常解析文件。
按默认值也就是true,会将上传的数据转换为字符上传,而当上传文件的时候,则不需要把其转换为字符串,因此就要关闭此转换功能,也就是设置为false。
HEAD是一个指针,通常情况下它可以将它与当前分支等同(其实它是指向当前分支)
HEAD 表示当前版本,也就是最新的提交。上一个版本就是 HEAD^ ,上上一个版本就是 HEAD^^ ,往上100个版本写100个 “ ^ ” 比较容易数不过来,所以写成 HEAD~100 。HEAD~2 相当于 HEAD^^ 。
git实际上分为三个仓库,本地工作区,中间暂存区,远端仓库。
git add .
作用:把修改和添加的文件提交到暂存区,但不包括删除的文件。
git add -u
作用:把修改和删除的文件提交到暂存区,但不包括新文件
git add -a
作用:提交所有变化
撤销操作:当提交代码时不小心添加了错误文件,可以通过git reset HEAD进行撤销上次的全部提交,git reset HEAD ./../index.php 用来撤销某个文件。
git commit -m “message”
作用:简要说明提交的改动。
git diff
作用:查看当前工作区和版本库里最新版本的区别。
git pull
作用:从仓库或者本地的分支拉取并且整合代码。
git pull origin master
作用:拉取远程分支并且整合代码。
合并出现问题时可以通过git reset --merge进行回退
git push
作用:把改动提交到当前分支上
git branch
作用:查看所有本地分支
git branch -r
作用:查看所有远程分支
git branch -a
作用:查看所有分支
git checkout
作用:检出(切换)分支
git fetch
作用:当git branch -a 查看不到新的分支,git fetch更新一下分支信息后就可以看见新分支了。
git merge
作用:将其他分支合并到当前分支
git reset HEAD
作用:拉取最新一次提交到版本库的文件到暂存区,单独拉取某个文件用git reset HEAD -- index.php,然后git checkout可以拉取暂存区文件到本地仓库,同样的git checkout -- index.php可以从暂存区单独拉取一个文件到本地仓库。
git reset --hard 版本号
作用:拉取指定版本的文件到暂存区。
注意:如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法。
恢复之前版本
git revert -n 版本号
注意:创建一个新的版本为之前提交的某个版本,可以先用git log 查看所有提交记录。
git revert HEAD~3
作用:撤销HEAD指针之前的第3个提交,并且生成一个新的提交。
注意:如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。
局部:
git config user.name “用户名”
git config user.passsword “密码”
git config user.email “邮箱”
全局:
git config --global user.name “用户名”
git config --global user.passsword “密码”
git config --global user.email “邮箱”
查看设置:
git config --list
有时拉取代码失败可能需要当前克隆仓库的账号密码,使用以下命令:
git clone --bare http://username:password@gitlab.300.cn/package1/myProject.git
其中:
①如果username使用的是邮箱,那么@符号要用%40代替,例如:123@qq.com,要写成123%40qq.com
代码:
git add 我是修改内容.text
gitcommit --amend
解释:
【amend】袖中,会对最新一条commit进行修正,会把当前的commit和暂存区的内容合并起来后创建一个新的commit,用这个新的commit把当前commit替换掉
代码:
git add 我是忘提交的文件.text git commit -amend --no-edit
解释:
他表示提交信息不会更改,在git上仅为一次提交。
代码:
git reset --hard HEAD^ git pull
解释:
HEAD表示HEAD^往回数一个位置的commit,HEAD^表示你要恢复到哪个commit。因为你要撤销最新的一个commit(也就是当前未提交的内容),所以你要恢复到它上一次commit,也就是HEAD^。那么使用git reset --hard HEAD^就会恢复到上次提交前的样子,这时候再git pull把最后一次commit拉取下来,这样刚写完的修改就被撤销了(注意:一旦撤销到某个版本,那么这个版本之后的记录会全部消失,例如撤销到倒数第二次提交,那么最后一次提交记录就会彻底消失)。
代码:
git revert HEAD
解释:
将代码回退到上一个版本,并生成一个新的提交记录,原历史记录不变。 实际上它commit了一条与上一个版本相反的内容,相互抵消,达到撤销的效果。
connect('127.0.0.1', 6379, 30); //设置连接密码 $redis->auth('junyi'); //获取出售的数量,默认为空 $kuchun = $redis->get('kucun'); //秒杀数量 $total = 100; if ($kuchun < $total) { //监控售出数量是否变动,一旦中途变动就会打断redis事务 $redis->watch('kucun'); //开启事务 $redis->multi(); //设置售出数量+1 $redis->set("kucun", $kuchun + 1); //执行事务 $result = $redis->exec(); if ($result) { //剩余数量 $number = $total - ($kuchun + 1); //$openid 用户id $openid = $number; $redis->hset("list", "user_" . $openid, $kuchun); //获取抢购成功的用户 $data = $redis->hgetall('list'); var_dump($data); var_dump($number); } else { var_dump('手气很差哦,再试一下!'); } } else { var_dump('已经被抢光了'); } }
connect('127.0.0.1', 6379); for ($i = 1; $i rPush("goods_list", $i); } } //秒杀 function kill() { //假设这是是用户的uid $uuid = md5(uniqid('user') . time()); //创建连接redis对象 $redis = new \Redis(); //连接到服务器127.0.0.1,端口号6379,默认连接时间300,密码为空 $redis->connect('127.0.0.1', 6379); //监控列表中的值是否变动 $redis->watch("goods_list"); //开启事务 $redis->multi(); //从左边开始删除一个元素,并把删除的值赋给$goodsId if ($goodsId = $redis->lPop("goods_list")) { //秒杀成功,将幸运用户存在集合中 $redis->hSet("buy_order", $uuid, $goodsId); //执行事务 $redis->exec(); } else { //秒杀失败,将失败用户计数,默认从0开始+1 $redis->incr("fail_user_num"); } echo "SUCCESS"; }