解决 jsonP 安全问题
jsonp安全性防范,分为以下几点:
1、防止callback参数意外截断js代码,特殊字符单引号双引号,换行符均存在风险
2、防止callback参数恶意添加标签(如script),造成XSS漏洞
3、防止跨域请求滥用,阻止非法站点恶意调用
针对第三点,我们可以通过来源refer白名单匹配,以及 cookieToken 机制来限制
而前两点,传统的做法分为以下几种:
1、纯手工过滤特殊字符,引号尖括号等,一旦发现潜在恶意字符则服务端拒绝,返回错误。
此种方式较为严格,但是随之而来的问题是失败率会有所提升,尤其对于对外开发者。
而且JS中恶意字符的变形十分多,此方式需要枚举所有非法字符,可能存在疏漏。
我们不应该将潜在的恶意字符都一概屏蔽,因为确实有些需求需要传入并存储这些字符。
2、对于callback参数作严整的格式检查,或强制约定指定格式。基本可以彻底解决安全问题,
但同样是对调用端不是完全透明,使用者需要额外去知晓相关限制和约定,可能会造成不必要的沟通成本。
3、返回包体添加header头部,强制指定MIME类型,避免按HTML方式解析,防止XSS漏洞。
这似乎是个很完美的解决方案。
但是十分诡异的是,在某些版本的火狐浏览器下,直接访问MIME类型为JAVASCRIPT的请求时,浏览器仍然会按照HTML解析。
或许是该浏览器设计的缺陷,但它忽略了我们设置的header。无法保证所有浏览器严格按照MIME类型解析。
我们的关注点一直在于如何限制用户输入,但是请从另外一个层面去考虑该问题,或许就会豁然开朗。
我们先了解一下JS本身的特性。
JSONP的本质是构造全局回调函数,之后加载script标签触发回调函数。
通常我们使用函数可以这么写
function test(){}test();
而在全局的函数也就默认是window的成员。也可以显示书写为
window.test = function(){};window.test();
而JS中对象的成员是可以使用字符串索引的方式访问的,故进一步改造为
window['test']=function(){};window['test']();
现在有注意到么,如此一来我们已经把函数名已经完全限制在了字符串上下文,
理论上只要做好了防注入工作,callback参数是不可能跳出字符串上下文意外执行代码的。
以PHP为例,单字符串防止注入甚至可以直接使用json_encode该字符串实现。
window['alert("123");abc']();
上面的callback参数虽然有注入的风险,可以由于callback参数严格限制在字符串内部,仅会作为文本,不会意外执行
但仍然存在xss漏洞问题
看下面例子
window['<script>alert(123);</script>']();
我们虽然已经保证了<script>严格限制在引号内部,不会造成js注入,但是直接在浏览器中输入该jsonp请求仍会按照HTML解析,产生XSS
漏洞,即便设置了header也很难防范。
在进一步,我们只需要保证浏览器内不会明文出现<>标签,那么问题便可彻底解决。
基本思路是在服务端做一次urlencode。而在output输出decodeURIComponent(‘#####’)来规避显示尖括号。
Urlencode过的字符串,只可能包含字母数字%,也顺便解决了注入的问题
最终附上一段简短的代码。根本解决jsonp的安全问题
<?php header('Content-type: text/javascript'); //加上此句可以消除chrome的警告
$callback = urlencode($_GET['callback']);
echo "window[decodeURIComponent('{$callback}')]({ret:0,msg:’OK’});"
请求1:http://www.test.com/a.php?callback=alert(123);abc
响应1:window[decodeURIComponent('alert(123)%3Babc')]({ret:0,msg:'OK'});
请求2:http://www.test.com/a.php?callback=<script>alert(123);</script>
响应2:window[decodeURIComponent('%3Cscript%3Ealert(123)%3B%3C%2Fscript%3E')]({ret:0,msg:'OK'});
上述几个例子都可以证明jsonp安全漏洞已被彻底规避,即便存在尝试注入的恶意参数,仍能最大限度保证程序完全正常工作触发回调。
附上源码
<html>
<head>
<title>GoJSONP</title>
</head>
<body>
<script type="text/javascript">
function jsonhandle(data){
console.table(data);
}
</script>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.3.1.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
// var url = "http://www.project.com/project/l.php?callback=alert('123');jsonhandle";
var url = "http://www.project.com/project/l.php?callback=jsonhandle";
var obj = $('<script><\/script>');
obj.attr("src",url);
$("body").append(obj);
});
</script>
</body>
</html>
<?php
header('Content-type: text/javascript'); //加上此句可以消除chrome的警告
//xss
// $callback = $_GET['callback'];
// echo "$callback({ret:0,msg:'ok'});"
//safe
$callback = urlencode($_GET['callback']);
echo "window[decodeURIComponent('{$callback}')]({ret:0,msg:'OK'});"
?>
解决 jsonP 安全问题的更多相关文章
- java 22 - 13 多线程之解决线程安全问题的实现方式2
上一章说了,解决线程安全问题的实现方式1是使用同步代码块 同时也知道了,同步代码块的锁对象是任意对象:(Object obj ; Demo d;)这些都行 那么,现在来说解决线程安全问题的实现方式2 ...
- java 22 - 12 多线程之解决线程安全问题的实现方式1
从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢? 导致出现问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 上一章的程序,上面那3条都具备, ...
- 如何解决 Java 安全问题?
如何解决 Java 安全问题,目前的应对策略都十分笨拙,往往适得其反.幸运的是,有一种新的方法可以将安全机制嵌入 Java 执行平台--或者更具体地说,嵌入 Java 虚拟机中,进而规避一些「Big ...
- java线程安全问题以及使用synchronized解决线程安全问题的几种方式
一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...
- Lock锁方式解决线程安全问题
在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...
- java并发之如何解决线程安全问题
并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务. 而Java并发则由多线程实现的. 在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中.(当然这是比 ...
- Java之解决线程安全问题的方式三:Lock锁
import java.util.concurrent.locks.ReentrantLock; /** * 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增 * * 1. 面试题:sy ...
- 静态同步方法和解决线程安全问题_Lock锁
静态的同步方法锁对象是谁?不能是thisthis是创建对象之后产生的,静态方法优先于对象静态方法的锁对象是本类的cLass属性-->class文件对象(反射) 卖票案例出现了线程安全问题 卖出了 ...
- 解决线程安全问题_同步方法和解决线程安全问题_Lock锁
解决线程安全问题_同步方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 卖票案例出现了线程安全的问题 * ...
随机推荐
- XPath学习
一.基本语法 1.以 / 斜线开始,该路径表示到一个元素下的绝对路径 2.如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系) 3.星号 * 表示选择所有由 ...
- php imagemagick库安装使用
imagemagick介绍: ImageMagick® is a software suite to create, edit, compose, or convert bitmap images. ...
- 详解HTTP中GET与POST的区别,不是你看过的标准答案!
防吐槽声明:本文适合程序员新人,自认阅文无数.技术超叼的大神不用看. GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含 ...
- cdojQ - 昊昊爱运动 II
地址:http://acm.uestc.edu.cn/#/contest/show/95 题目: Q - 昊昊爱运动 II Time Limit: 3000/1000MS (Java/Others) ...
- 菩提树下的杨过.Net 的《hadoop 2.6全分布安装》补充版
对菩提树下的杨过.Net的这篇博客<hadoop 2.6全分布安装>,我真是佩服的五体投地,我第一次见过教程能写的这么言简意赅,但是又能比较准确表述每一步做法的,这篇博客主要就是在他的基础 ...
- Visual Studio各版本区别
Visual Studio 是微软公司推出的开发环境,Visual Studio 可以用来创建 Windows 平台下的 Windows 应用程序和网络应用程序,也可以用来创建网络服务.智能设备应用程 ...
- HDU4628
/*状态转移f[i]=min(f[i],f[j]+f[i^j]); 就是j状态+i^j状态=i状态,f[i]记录的是从i删除1要的最小步数*/ #include<string.h> #in ...
- Django学习笔记之Ajax入门
AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JS ...
- 【Flask】Flask Cookie操作
### 什么是cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第 ...
- iptables配置顺序-两条规则会忽略后边的
oracle在centos本机能够正常访问,关闭防火墙也能够远程访问,但是一旦开启防火墙则不能远程访问 尝试添加规则iptables -A INPUT -m state --state NEW -m ...