
(点击上方公众号,可快速关注)
究其原因,是fastjson漏洞频发,导致了公司内部需要频繁的督促各业务线升级fastjson版本,来防止安全问题。
fastjson在2020年频繁暴露安全漏洞,此漏洞可以绕过autoType开关来实现反序列化远程代码执行并获取服务器访问权限。
从2019年7月份发布的v1.2.59一直到2020年6月份发布的 v1.2.71 ,每个版本的升级中都有关于AutoType的升级,涉及13个正式版本。
fastjson中与AutoType相关的版本历史:
1.2.59发布,增强AutoType打开时的安全性 fastjson
1.2.60发布,增加了AutoType黑名单,修复拒绝服务安全问题 fastjson
1.2.61发布,增加AutoType安全黑名单 fastjson
1.2.62发布,增加AutoType黑名单、增强日期反序列化和JSONPath fastjson
1.2.66发布,Bug修复安全加固,并且做安全加固,补充了AutoType黑名单 fastjson
1.2.67发布,Bug修复安全加固,补充了AutoType黑名单 fastjson
1.2.68发布,支持GEOJSON,补充了AutoType黑名单
1.2.69发布,修复新发现高危AutoType开关绕过安全漏洞,补充了AutoType黑名单
1.2.70发布,提升兼容性,补充了AutoType黑名单
1.2.71发布,补充安全黑名单,无新增利用,预防性补充
相比之下,其他的json框架,如Gson和Jackson,漏洞数量少很多,高危漏洞也比较少,这是公司想要替换框架的主要原因。
本文主要讨论Gson替换fastjson框架的实战问题,所以在这里不展开详细讨论各种json框架的优劣,只给出结论。
经过评估,主要有Jackson和Gson两种json框架放入考虑范围内,与fastjson进行对比。
速度快
fastjson相对其他JSON库的特点是快,从2011年fastjson发布1.1.x版本之后,其性能从未被其他Java实现的JSON库超越。
使用广泛
fastjson在阿里巴巴大规模使用,在数万台服务器上部署,fastjson在业界被广泛接受。在2012年被开源中国评选为最受欢迎的国产开源软件之一。
测试完备
fastjson有非常多的testcase,在1.2.11版本中,testcase超过3321个。
每次发布都会进行回归测试,保证质量稳定。
使用简单
fastjson的API十分简洁。
容易使用 - jackson API提供了一个高层次外观,以简化常用的用例。
无需创建映射 - API提供了默认的映射大部分对象序列化。
性能高 - 快速,低内存占用,适合大型对象图表或系统。
干净的JSON - jackson创建一个干净和紧凑的JSON结果,这是让人很容易阅读。
不依赖 - 库不需要任何其他的库,除了JDK。
提供一种机制,使得将Java对象转换为JSON或相反如使用toString()以及构造器(工厂方法)一样简单。
允许预先存在的不可变的对象转换为JSON或与之相反。
允许自定义对象的表现形式
支持任意复杂的对象
输出轻量易读的JSON
同事撰写的性能对比源码:
https://github.com/zysrxx/json-comparison
本文不详细讨论性能的差异,毕竟这其中涉及了很多各个框架的实现思路和优化,所以只给出结论:
1.序列化单对象性能Fastjson > Jackson > Gson,其中Fastjson和Jackson性能差距很小,Gson性能较差
2.序列化大对象性能Jackson> Fastjson > Gson ,序列化大Json对象时Jackson> Gson > Fastjson,Jackson序列化大数据时性能优势明显
3.反序列化单对象性能 Fastjson > Jackson > Gson , 性能差距较小
4.反序列化大对象性能 Fastjson > Jackson > Gson , 性能差距较很小
Jackson适用于高性能场景,Gson适用于高安全性场景
对于新项目仓库,不再使用fastjson。对于存量系统,考虑到Json更换成本,由以下几种方案可选:项目未使用autoType功能,建议直接切换为非fastjson,如果切换成本较大,可以考虑继续使用fastjson,关闭safemode。业务使用了autoType功能,建议推进废弃fastjson。
企业项目或者说大型项目的特点:
代码结构复杂,团队多人维护。
承担重要线上业务,一旦出现严重bug会导致重大事故。
如果是老项目,可能缺少文档,不能随意修改,牵一发而动全身。
项目有很多开发分支,不断在迭代上线。
所以对于大型项目,想要做到将底层的fastjson迁移到gson是一件复杂且痛苦的事情,其实对于其他依赖的替换,也都一样。
我总结了如下几个在替换项目依赖过程中要特别重视的问题。
再怎么谨慎都不为过,如果你要更改的项目是非常重要的业务,那么一旦犯下错误,代价是非常大的。
并且,对于业务方和产品团队来说,没有新的功能上线,但是系统却炸了,是一件“无法忍受”的事情。
尽管你可能觉得很委屈,因为只有你或者你的团队知道,虽然业务看上去没变化,但是代码底层已经发生了翻天覆地的变化。
所以,谨慎点!
在依赖替换的过程中,需要做好项目的规划,比如分模块替换,严格细分排期。
把前期规划做好,开发和测试才能有条不紊的进行工作。
开发之间,需要提前沟通好开发注意事项,比如依赖版本问题,防止由多个开发同时修改代码,最后发现使用的版本不同,接口用法都不同这种很尴尬,并且要花额外时间处理的事情。
而对于测试,更要事先沟通好。一般来说,测试不会太在意这种对于业务没有变化的技术项目,因为既不是优化速度,也不是新功能。
但其实迁移涉及到了底层,很容易就出现BUG。要让测试团队了解更换项目依赖,是需要大量的测试时间投入的,成本不亚于新功能,让他们尽量重视起来。
上面说到测试团队需要投入大量工时,这些工时主要都用在项目功能的整体回归上,也就是回归测试。
当然,不只是业务回归测试,如果有条件的话,要做接口回归测试。
如果公司有接口管理平台,那么可以极大提高这种项目测试的效率。
打个比方,在一个模块修改完成后,在测试环境(或者沙箱环境),部署一个线上版本,部署一个修改后的版本,直接将接口返回数据进行对比。
一般来说是Json对比,网上也有很多的Json对比工具:
https://www.sojson.com/
正如上面描述的Gson和Fastjson性能对比,替换框架需要注意框架之间的性能差异,尤其是对于流量业务,也就是高并发项目,响应时间如果发生很大的变化会引起上下游的注意,导致一些额外的后果。
这里总结了两种json框架常用的方法,贴出详细的代码示例,帮助大家快速的上手Gson,无缝切换!
String jsonCase = "[{\"id\":10001,\"date\":1609316794600,\"name\":\"小明\"},{\"id\":10002,\"date\":1609316794600,\"name\":\"小李\"}]";
// fastjson
JSONArray jsonArray = JSON.parseArray(jsonCase);
System.out.println(jsonArray);
System.out.println(jsonArray.getJSONObject(0).getString("name"));
System.out.println(jsonArray.getJSONObject(1).getString("name"));
// 输出:
// [{"date":1609316794600,"name":"小明","id":10001},{"date":1609316794600,"name":"小李","id":10002}]
// 小明
// 小李
// Gson
JsonArray jsonArrayGson = gson.fromJson(jsonCase, JsonArray.class);
System.out.println(jsonArrayGson);
System.out.println(jsonArrayGson.get(0).getAsJsonObject().get("name").getAsString());
System.out.println(jsonArrayGson.get(1).getAsJsonObject().get("name").getAsString());
// 输出:
// [{"id":10001,"date":1609316794600,"name":"小明"},{"id":10002,"date":1609316794600,"name":"小李"}]
// 小明
// 小李
看得出,两者区别主要在get各种类型上,Gson调用方法有所改变,但是变化不大。
那么,来看下空对象反序列化会不会出现异常:
String jsonObjectEmptyCase = "{}";
// fastjson
JSONObject jsonObjectEmpty = JSON.parseObject(jsonObjectEmptyCase);
System.out.println(jsonObjectEmpty);
System.out.println(jsonObjectEmpty.size());
// 输出:
// {}
// 0
// Gson
JsonObject jsonObjectGsonEmpty = gson.fromJson(jsonObjectEmptyCase, JsonObject.class);
System.out.println(jsonObjectGsonEmpty);
System.out.println(jsonObjectGsonEmpty.size());
// 输出:
// {}
// 0
没有异常,开心。
看看空数组呢,毕竟[]感觉比{}更加容易出错。
String jsonArrayEmptyCase = "[]";
// fastjson
JSONArray jsonArrayEmpty = JSON.parseArray(jsonArrayEmptyCase);
System.out.println(jsonArrayEmpty);
System.out.println(jsonArrayEmpty.size());
// 输出:
// []
// 0
// Gson
JsonArray jsonArrayGsonEmpty = gson.fromJson(jsonArrayEmptyCase, JsonArray.class);
System.out.println(jsonArrayGsonEmpty);
System.out.println(jsonArrayGsonEmpty.size());
// 输出:
// []
// 0
两个框架也都没有问题,完美解析。
解析泛型是一个非常常用的功能,我们项目中大部分fastjson代码就是在解析json和Java Bean。
// 实体类
User user = new User();
user.setId(1L);
user.setUserName("马云");
// fastjson
List<User> userListResultFastjson = JSONArray.parseArray(JSON.toJSONString(userList), User.class);
List<User> userListResultFastjson2 = JSON.parseObject(JSON.toJSONString(userList), new TypeReference<List<User>>(){});
System.out.println(userListResultFastjson);
System.out.println("userListResultFastjson2" + userListResultFastjson2);
// 输出:
// userListResultFastjson[User [Hash = 483422889, id=1, userName=马云], null]
// userListResultFastjson2[User [Hash = 488970385, id=1, userName=马云], null]
// Gson
List<User> userListResultTrue = gson.fromJson(gson.toJson(userList), new TypeToken<List<User>>(){}.getType());
System.out.println("userListResultGson" + userListResultGson);
// 输出:
// userListResultGson[User [Hash = 1435804085, id=1, userName=马云], null]
可以看出,Gson也能支持泛型。
这一点fastjson和Gson有区别,Gson不支持直接将List写入value,而fastjson支持。
所以Gson只能将List解析后,写入value中,详见如下代码:
// 实体类
User user = new User();
user.setId(1L);
user.setUserName("马云");
// fastjson
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("user", user);
jsonObject1.put("userList", userList);
System.out.println(jsonObject1);
// 输出:
// {"userList":[{"id":1,"userName":"马云"},null],"user":{"id":1,"userName":"马云"}}
// Gson
JsonObject jsonObject = new JsonObject();
jsonObject.add("user", gson.toJsonTree(user));
System.out.println(jsonObject);
// 输出:
// {"user":{"id":1,"userName":"马云"},"userList":[{"id":1,"userName":"马云"},null]}
如此一来,Gson看起来就没有fastjson方便,因为放入List是以gson.toJsonTree(user)的形式放入的。
这样就不能先入对象,在后面修改该对象了。
(有些同学比较习惯先放入对象,再修改对象,这样的代码就得改动)
驼峰转换下划线依靠的是修改Gson的序列化模式,修改为
LOWER_CASE_WITH_UNDERSCORES
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
Gson gsonUnderScore = gsonBuilder.create();
System.out.println(gsonUnderScore.toJson(user));
// 输出:
// {"id":1,"user_name":"马云"}
下面整理了我们在公司项目迁移Gson过程中,踩过的坑,这些坑现在写起来感觉没什么技术含量。
但是这才是我写这篇文章的初衷,帮助大家把这些很难发现的坑避开。
这些问题有的是在测试进行回归测试的时候发现的,有的是在自测的时候发现的,有的是在上线后发现的,比如Swagger挂了这种不会去测到的问题。
不知道大家想过一个问题没有,如果你的项目里有缓存系统,使用fastjson写入的缓存,在你切换Gson后,需要用Gson解析出来。
所以就一定要保证两个框架解析逻辑是相同的,但是,显然这个愿望是美好的。
在测试过程中,发现了Date类型,在两个框架里解析是不同的方式。
fastjson:Date直接解析为Unix
Gson:直接序列化为标准格式Date
导致了Gson在反序列化这个json的时候,直接报错,无法转换为Date。
解决方案:
新建一个专门用于解析Date类型的类:
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.Date;
public class MyDateTypeAdapter extends TypeAdapter<Date> {
@Override
public void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.getTime());
}
}
@Override
public Date read(JsonReader in) throws IOException {
if (in != null) {
return new Date(in.nextLong());
} else {
return null;
}
}
}
接着,在创建Gson时,把他放入作为Date的专用处理类:
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class,new MyDateTypeAdapter()).create();
这样就可以让Gson将Date处理为Unix。
当然,这只是为了兼容老的缓存,如果你觉得你的仓库没有这方面的顾虑,可以忽略这个问题。
切换到Gson后,使用SpringBoot搭建的Web项目的接口直接请求不了了。
报错类似:
org.springframework.http.converter.HttpMessageNotWritableException
因为SpringBoot默认的Mapper是Jackson解析,我们切换为了Gson作为返回对象后,Jackson解析不了了。
解决方案:
application.properties里面添加:
#Preferred JSON mapper to use for HTTP message conversion
spring.mvc.converters.preferred-json-mapper=gson
这个问题和上面的SpringBoot异常类似,是因为在SpringBoot中引入了Gson,导致 swagger 无法解析 json。
采用类似下文的解决方案(添加Gson适配器):
http://yuyublog.top/2018/09/03/springboot%E5%BC%95%E5%85%A5swagger/
1.GsonSwaggerConfig.java
@Configuration
public class GsonSwaggerConfig {
//设置swagger支持gson
@Bean
public IGsonHttpMessageConverter IGsonHttpMessageConverter() {
return new IGsonHttpMessageConverter();
}
}
2.IGsonHttpMessageConverter.java
public class IGsonHttpMessageConverter extends GsonHttpMessageConverter {
public IGsonHttpMessageConverter() {
//自定义Gson适配器
super.setGson(new GsonBuilder()
.registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter())
.serializeNulls()//空值也参与序列化
.create());
}
}
3.SpringfoxJsonToGsonAdapter.java
public class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> {
@Override
public JsonElement serialize(Json json, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonParser().parse(json.value());
}
}
有时候,我们会在入参使用类似:
public ResponseResult<String> submitAudit(@RequestBody JsonObject jsonObject) {}
如果使用这种代码,其实就是使用Gson来解析json字符串。但是这种写法的风险是很高的,平常请大家尽量避免使用JsonObject直接接受参数。
在Gson中,JsonObject若是有数字字段,会统一序列化为double,也就是会把count = 0这种序列化成count = 0.0。
为何会有这种情况?简单的来说就是Gson在将json解析为Object类型时,会默认将数字类型使用double转换。
如果Json对应的是Object类型,最终会解析为Map<String, Object>类型;其中Object类型跟Json中具体的值有关,比如双引号的""值翻译为STRING。
我们可以看下数值类型(NUMBER)全部转换为了Double类型,所以就有了我们之前的问题,整型数据被翻译为了Double类型,比如30变为了30.0。
可以看下Gson的ObjectTypeAdaptor类,它继承了Gson的TypeAdaptor抽象类:
具体的源码分析和原理阐述,大家可以看这篇拓展阅读:
https://www.jianshu.com/p/eafce9689e7d
解决方案:
第一个方案:把入参用实体类接收,不要使用JsonObject
第二个方案:与上面的解决Date类型问题类似,自己定义一个Adaptor,来接受数字,并且处理。
这种想法我觉得可行但是难度较大,可能会影响到别的类型的解析,需要在设计适配器的时候格外注意。
这篇文章主要是为了那些需要将项目迁移到Gson框架的同学们准备的。
一般来说,个人小项目,是不需要费这么大精力去做迁移,所以这篇文章可能目标人群比较狭窄。
但文章中也提到了不少通用问题的解决思路,比如怎么评估迁移框架的必要性。其中需要考虑到框架兼容性,两者性能差异,迁移耗费的工时等很多问题。
收外国男骗中国妹子的炮?天朝竟有这样一帮「女权组织」 2018-03-19 INSIGHT视界 From 酷玩实验室 微信号:coollabs 其实我读书的时候 也曾经想过做一个女权主义者 但是后来发生了一些事情 让我选择了放弃 简单来说是这么一个事情:我发现 女权对于一些中国人来说是信仰 但是对另一些中国人来说是生意 所谓的“伪女权”“女权癌” 大概就是这么回事 尽管早就有这样的思想准备 但让我没想到的是 这两天,知乎上曝光了一件大事 还是让我三观震碎 我没想到,这些“伪女权” 竟然已经形成了黑色产业链 让人细思恐极—— 国内竟然有一群人 打着“女权主义”的名号 从事着组织卖淫的事情 在中国女生不知情的情况下 把她们卖给外国男人!事情是这样的:根据知乎用户伊利丹·怒风的爆料 他在知乎和一个伪女权主义者 吵了起来 一开始,他可能以为这只是一个 脑子比较轴的伪女权主义者 所以两人就吵了一通 本来,他以为就是撕个逼而已 没想到的是 这个伪女权主义者 可不是什么好惹的主 这个自称为“玛丽女王”的人 竟然在半个月中 持续不断地骚扰他 而最夸张的是 玛丽女王声称 自己有能力 让伊利丹的QQ号 在5天之内被封掉 到这里为止 伊利丹一直以为 他不过是碰到了一个杠精 但是万万没想到 5天之后 他的QQ号竟然真的被永久封禁了!说真的,这就有点吓人了 这个不起眼的玛丽女王 竟然还能操控别人的QQ账号被封?难不成,她真的背后有人?伊利丹这才意识到 自己好像惹到了一个组织 他去扒了扒这个玛丽女王的QQ空间 这才发现 自己简直捅出一个马蜂窝:这个人平时干的 竟然是把中国女生 卖给外国男人的皮肉生意!真的,我本来以为 我是一个见过不少套路的人 但没想到 这一套操作 真的是惊为天人 简单来说是这样的 首先,玛丽女王自称是“女权主义者” 但是实际上她的言论 宣传的却是 中国男人配不上中国女人 她甚至恶意辱骂中国男人 恨不得中国男人全部死光 连自己的爸爸都不放过 但是,这么做对她有什么好处呢?很简单 骂完中国男人以后 接下来她就说—— 既然中国男人这么差劲 那就找外国男人吧!于是,她就经常发布外国男人的介绍 看起来是一个热心的媒婆 还在各种QQ和微信群里 散播此类信息 但是看到这里 我们不难发现有点问题 看看其中这些不堪入目的措辞 这并不是普通的介绍男友啊!这简直是在拉皮条啊!果然,伊利丹发现 玛丽女王真的在 拉皮条的过程中 收外国男人的钱!下面是聊天记录实锤:而且,请注意—— 在这个过程中 她会收外国男人的钱 但是钱不给中国女生 却落到了她自己的腰包 于是一个诡异的情况出现了:中国妹子 并不知道收钱这回事 还以为是正常交友 而外国男人 却都交了钱 很可能认为自己是在买春!额,也就是说 在中国女孩不知情的情况下 她们被“卖”给了外国男人 而好处费 却全都进了玛丽女王的腰包... 我真的是没见过这种操作 这说轻了是骗炮 说重了,已经可以算是卖淫了吧?我想请熟悉刑法的朋友们看看 这个玛丽女王 至少应该算是个 介绍组织卖淫罪吧?而且,从伊利丹曝光的资料看来 这个组织规模不小 玛丽女王甚至把外国男生的信息 建了一个完整的表格 有详细的个人资料、照片 可以说 是一条非常完整的产业链 那如果按照这样操作 外国男人都是来嫖的 中国女生却不知道 还以为是要跟他们谈恋爱 那双方难道不会穿帮吗?恩,在这方面 玛丽女王早有对策 根据知乎一位 从事过这个产业的匿名用户提供的信息 针对这种情况 玛丽女王们 还会手把手地教外国男人 怎么快速摆脱女生的纠缠 怎么调教中国女生 怎么让女生觉得自己很可爱 可以说 各种套路一应俱全 甚至还可以开发票!看到这里 她们背后的产业就非常清楚了 这个玛丽女王 她根本就不是什么女权主义者 而是打着女权主义的口号 贩卖中国女生的人贩子 一方面 她们通过辱骂中国男人 吸引对外国男人感兴趣的中国女生 另一方面 她们向外国男人收钱 然后把中国女生卖给他们!图片来源:知乎@渭水徐工 而可怜的中国妹子们 还以为自己是在 追求男女平权 其实,不过是沦为了 这些老鸨的赚钱工具 伊利丹把这整个事情 写出来以后 在知乎、微博引起了巨大的关注 关于其中提到的 伊利丹的QQ被永久封禁的问题 腾讯经过核查 目前也有了结果:经调查,是玛丽女王利用伪造证据 恶意举报了伊利丹的QQ号 目前,腾讯已经将伊利丹的QQ解封 同时封禁了玛丽女王等人的 两个QQ账号 警方也就此事立案侦查了 相信很快就会有结果 这个事情算是告一段落了 但是在我看来 却有一件事让我无法释怀:为什么“女权主义”竟然会和 辱骂中国男性等同起来?为什么“和外国男人交友” 竟然还能演变成 一个免费的陪睡组织?我想,这个玛丽女王 也许只是一个 发现了恶性赚钱模式的生意人 但是在这背后隐藏的 其实是一个很深的问题:为什么有不少中国女人 越来越看不上中国男人 甚至觉得嫁给外国男人 是一种时尚?这里面的原因可能非常复杂 我这里先提供一个思路 供大家讨论:我发现 现在中国很多大型的女权组织 背后都有着西方势力的影子 她们打着女权的名号 为自己谋取暴利 为西方国家从事破坏活动 而那些真正为女性平权而奔走的人 却得不到应有的帮助 我之所以这样说 并不是信口开河 而是有充足的证据 有一个非常有名的民间女权组织 叫做“女权之声” 它一再声称 自己只是一个自发的民间组织 致力于促进男女平等的 它所有的微博账号、微信账号 全部都是由一个 叫做妇女传媒监测网络的创办的 而这个妇女传媒监测网络 有这么多媒体产品 那它的钱都是哪里来的呢?从她们介绍的合作组织里 我们可以清楚地找到 她们的资助者—— 竟然有西方的福特基金会 有人也许会问 收了西方的钱怎么了?中国的组织不能收西方的钱吗?然而,她们不只是收了西方的钱而已 女权之声组织里 有一个人叫做郑楚然 她除了女权运动之外 没有任何其他工作 表面上,是一个全职的女权工作者 在2015年的时候 她还因为寻衅滋事 被警察拘留过30多天 甚至在她被拘留的时候 希拉里还借题发挥 指责中国侵犯人权、压制民主 一个中国的小小民间组织的首领 在互联网上的粉丝还没有我多 竟然能得到希拉里这个级别的关注?我真的是惊掉了下巴 这样看来 我离希拉里也不是很远了??而不止是希拉里 这样一个明明思想上毫无建树的人 却被西方媒体BBC评为了 全球百大思想家 图:郑楚然在王宝强事件中发表的言论 除此以外 更让人匪夷所思的 是她们平时就喜欢攻击政府 甚至于,她们还会试图分裂我们国家 比如,女权之声这个组织里 著名的女权斗士洪理达 就曾经转发著名的港独媒体 Hong Kong Free Press的言论 甚至曾公开发表过 支持藏独、港独、台独的言论 她也经常和郑楚然混在一起 我很想不通 如果她们真的只是单纯的女权主义者 为何要发表分裂国家的言论?为何要支持藏独、港独、台独?我只能说,这大概就叫 拿人家的手短,吃人家的嘴软吧 以前,我在接触中国的女权组织时 我就觉得很奇怪 她们都喜欢声称 自己是不盈利的非政府组织 但是她们无论是宣传 还是组织各类活动 都需要大量的钱 如果她们真的不盈利 那这些钱都是哪里来的呢?而这些外国的金主 他们也更加不可能是什么慈善组织 大发善心来给中国人投钱 每一分投出去的钱 一定都是要有回报的 那么,他们的回报是什么呢?他们给中国的“女权组织”投钱 能得到什么利益呢?联想到中国网络上 如火如荼的对中国男人的讨伐 我只能说,细思恐极 我绝不是危言耸听 因为我们就看不远的邻国日本 近些年来日本对于西方的崇拜 可谓深入骨髓 已经到了崇洋媚外的程度 而这其中 当然也包括对白人男性的崇拜 甚至在2016年一个瑞士白人 发了一个视频,赤裸裸的说 “在东京,只要你是白人, 做什么都可以” 视频里面他在日本便利店 随意的亲吻不认识的收银员女孩 在酒吧把不认识的日本女孩 按向自己的裤裆 而日本女孩回应的却是谄媚的笑容 我想,并不会有那么多中国人 真正被西方伪女权主义控制 但是,我们要警惕的是 别在你自己都没有察觉的时候 被别有用心的人洗了脑 更有甚者 别在你自己都不知道的情况下 被别人卖给了外国男人 还去帮他数钱 本文系授权发布,From 酷玩实验室,微信号:coollabs,欢迎分享到朋友圈,未经许可不得转载,INSIGHT视界 诚意推荐 Forwarded from Official Account 酷玩实验室 酷玩实验室 Learn More Scan QR Code via WeChat to follow Official Account 采集文章采集样式近似文章查看封面