HTTP防劫持方案

2023-05-16

DNS污染检测
被改标题
被挂黑链
被入侵
检测网站是否被劫持
网站打开速度检测
网站是否被黑
域名是否被墙      网站监控 http://www.iis7.com/b/wzjk/?inviteCode=496

HTTP劫持是在使用者与其目的网络服务所建立的专用数据通道中,监视特定数据信息,提示当满足设定的条件时,就会在正常的数据流中插入精心设计的网络数据报文,目的是让用户端程序解释”错误”的数据,并以弹出新窗口的形式在使用者界面展示宣传性广告或者直接显示某网站的内容。

什么是HTTP劫持

在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理。后续做法往往分为2种,1种是类似DNS劫持返回302让用户浏览器跳转到另外的地址,还有1种是在服务器返回的 HTML 数据中插入 js 或 dom 节点,从而使网页中出现自己的广告等等垃圾信息。
看图你就懂了一切(虽然被劫持我也很绝望)
Alt text

URL Loading System

官方文档


   

1

2

3


   

The URL loading system is a set of classes and protocols that allow your app to access

content referenced by a URL. At the heart of this technology is the NSURL class, which

lets your app manipulate URLs and the resources they refer to.

 

官方配图About the URL Loading System
Alt text

NSURLCache

NSURLCache 为 URL 请求提供了内存中以及磁盘上的综合缓存机制。 作为基础类库 URL Loading System 的一部分,任何通过 NSURLConnection 加载的请求都将被 NSURLCache 处理。

当一个请求完成得到来自服务器的Response,在本地保存作为cache。下一次同一个请求再发起时,本地保存的Response就会马上返回,不需要连接服务器。NSURLCache 会 自动 且 透明 地返回回应。

在NSURLConnection加载系统中,缓存被设计为request对象的一个属性,由NSURLRequest对象的cachePolicy属性指定。而在NSURLSession加载系统中,缓存被设计为 NSURLSessionConfiguration对像的一个属性,该属性所指定的策略被该session的所有request所共享。

作为一个Cache,它头文件中提供的方法并不复杂,就是基本的增删查改,(其中增和改可以算是一个功能,没有就增,改就是覆盖)。主要方法仅六个:


   

1

2

3

4

5

6

7

8

9

10


   

// 初始化方法

- (instancetype)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger)diskCapacity diskPath:(nullable NSString *)path;

// 查询方法

- (nullable NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;

// 存储方法

- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;

// 删除方法

- (void)removeCachedResponseForRequest:(NSURLRequest *)request;

- (void)removeAllCachedResponses;

- (void)removeCachedResponsesSinceDate:(NSDate *)date NS_AVAILABLE(10_10, 8_0);

 

当然,在项目中为了方便,我们一般都会实现一个子类,当系统调用URLCache的增删改查方法时,由子类来接管系统的URLCache功能。
NSURLCache的缓存策略,以及和HTTP header之间的关系,可以参考NSHipster NSURLCache文章

js签名防注入

这个方法主要用于资讯类App,就像文章开头那样的情况
步骤如下:
(1).发版前,在 bundle 中存一份最新的前端js文件
(2).后台在返回 js 文件 URL 的时候,对 js 文件内容进行 SHA-256 ,得到的 hash 值拼接到 js 的文件名中
(3).请求 js 资源文件时,在NSURLCache中的- (NSCachedURLResponse )cachedResponseForRequest:(NSURLRequest )request方法中拦截请求
(4).拦截请求之后,判断本地是否有缓存,如果有,则直接返回缓存文件包装成 response
(5).下载 js 资源时,走NSURLProtocol 代理方法- (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data,对 data 进行SHA-256签名比对,如果签名一致,将 data 通过;如果签名不一致,代表 js 被污染,直接丢弃,从bundle取出本地预存的 js 文件返回回来。

基本逻辑如下(需要用到上文中NSURLCache实现的子类)
URLCache实现文件中:


   

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


   

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {

NSString* ua = [request valueForHTTPHeaderField:@"User-Agent"];

if (!EmptyString(ua) && [ua lf_containsSubString:@"AppleWebKit"]) {

if ([CacheManager shouldVerifyHashCode:request]) { //包含64位hashcode的js css文件

// 取本地JS缓存

NSData *resultData = [CacheManager getJSCache];

if (resultData) {

NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:nil expectedContentLength:resultData.length textEncodingName:nil];

return [[NSCachedURLResponse alloc] initWithResponse:response data:resultData];

} else {

return nil;

}

}

return [super cachedResponseForRequest:request];

}

- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request {

NSString* ua = [request valueForHTTPHeaderField:@"User-Agent"];

if ([CacheManager shouldVerifyHashCode:request] && [ua lf_containsSubString:@"AppleWebKit"]) {

// 将请求回来的,并且通过验证的新js放到缓存中

[[CacheManager defaultManager] storeCachedResponse:cachedResponse forRequest:request])

return;

}

[super storeCachedResponse:cachedResponse forRequest:request];

}

 

自定义的NSURLProtocol子类:


   

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19


   

// 初始化方法

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {

NSString *ua = [request valueForHTTPHeaderField:@"User-Agent"];

if ([CacheManager shouldVerifyHashCode:request] && [ua lf_containsSubString:@"AppleWebKit"]) {

// 拦截js请求

return YES;

}

return NO;

}

// 收到请求返回data的代理方法

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

if([data verifySHA256Success]) {

[self.client URLProtocol:self didLoadData:data];

} else {

localData = [CacheManager bundleCacheFromUrl:url];

[self.client URLProtocol:self didLoadData:localData];

}

}

 

这里不用担心不能更新js文件,因为当后台的 js 文件有更新时,新 js 文件的签名就会发生变化,js 文件的URL也就自然变化,于是本地请求的时候,缓存是无法命中的,所以,也就会直接走下载 js 的那个路径。

缺点如下:
(1).在发生 js 劫持的时候,只能使用本地 js,可能会比最新版本 js 落后
(2).js 文件必须是由自己的服务端提供,并控制,才好对 js 进行签名,所以适用范围略窄
作为这个方案的扩充,可以考虑再次利用NSURLProtocol,当发现 js 被污染,重定向URL,此URL由服务端返回一个加密的 js 文件,对称加密,密钥插入在 js 的密文中,本地解密 js 文件,就可以保证得到最新的,安全的 js 文件了。

总结

本文总结的是HTTP的防劫持,其实现在苹果也建议我们使用HTTPS,是啊,如果大家都使用了HTTPS哪还有这么多事呢,但是苹果框架下的URL Loading System需要我们研究的东西还是比较多的,长路漫漫,Fighting~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTTP防劫持方案 的相关文章

  • 使用意图过滤器从 URL 打开 Android 应用程序不起作用

    我有一个 Android 应用程序 人们用它来替代网站 因此 当用户遇到网站的 URL 时 我想为他们提供在我的应用程序中而不是在浏览器中 打开 URL 的选项 换句话说 我希望出现弹出窗口 让他们在我的应用程序和浏览器 可能还有其他应用程
  • 从 Django 基于类的视图的 form_valid 方法调用特殊(非 HTTP)URL

    如果你这样做的话 有一个 HTML 技巧 a href New SMS Message a 点击新短信打开手机的本机短信应用程序并预 先填写To包含所提供号码的字段 在本例中为 1 408 555 1212 以及body与提供的消息 Hel
  • 如何自定义解析错误的 HTTP 400 响应?

    我编写了一个 REST API 服务 要求所有响应均为 JSON 但是 当 Go HTTP 请求解析器遇到错误时 它会返回 400 作为纯文本响应 而不会调用我的处理程序 例子 gt curl i H Authorization Basic
  • 当 REST 中的资源不支持操作时,HTTP 状态代码 404 或 501

    我有一个 REST 服务 根据正在查看的资源类型 我有某些可用的操作 So Resource1支持Operation1 and Operation2 eg Resource1 Operation1 Resource1 Operation2
  • REST URL 结构建议

    我正在尝试为我正在开发的网站的愿望清单部分敲定一个宁静的网址结构 这是一个非常简单的模型 用户可以有许多愿望清单 每个愿望清单可以包含许多产品 目前我有明显的 CRUD URL 来操作愿望清单本身 GET account wishlists
  • 从express.js 中删除所有标头

    我正在创建一个页面 其中有一些数据可以由另一个设备解析 我曾经使用 php 执行此操作 但现在将其移至 Node js 我需要从页面中删除所有标题 这样我就只有我的输出 此输出是对 GET 请求的响应 此刻我有 HTTP 1 1 200 O
  • 身份验证中的随机数使用

    在基于摘要的身份验证中 随机数由服务器生成 然而 在基于 OAuth 的身份验证中 随机数是由客户端生成的 我想知道是否有人知道差异的原因 随机数用于使请求唯一 在没有随机数的身份验证方案中 恶意客户端可以生成一次请求并重放多次 即使计算成
  • 在 Ubuntu 12.04 上的 Apache 上配置 SVN 服务器

    我正在尝试通过 HTTP 访问现有的 Subversion 服务器 我的dav svn conf文件看起来像
  • OkHttp如何获取Json字符串?

    Solution 这是我这边的一个错误 正确的方法是响应 body string 以外响应 body toString 我使用 Jetty servlet URL 是http 172 16 10 126 8789 test path jso
  • Perl:LWP::UserAgent 对于重定向 URL 始终返回代码 200

    我有一个简单的 url 它执行 302 临时错误 移至另一页 我尝试在 URL 返回代码 200 表示 OK 时检索它 并在返回 200 以外的其他内容时停止 My code my ua LWP UserAgent gt new env p
  • Angular JS 在调用新的 $http 之前取消 $http 调用

    在 Angular JS 1 1 5 中 您可以取消之前启动的 http 调用 这两个link1 https stackoverflow com questions 16962232 in angularjs how to stop ong
  • HTTP部分上传、断点续传的标准方法

    我正在开发 http 客户端 服务器框架 并寻找处理部分上传的正确方法 与使用带有 Range 标头的 GET 方法进行下载相同 但是 HTTP PUT 并不打算恢复 据我所知 PATCH 方法不接受 Range 标头 有没有办法通过 HT
  • Angular2 中 Http 的 Promise 与 Observable? [复制]

    这个问题在这里已经有答案了 本质上 正如标题所说 是否有任何理由使用可观察的承诺 https stackoverflow com questions 37364973 angular 2 promise vs observable为了进行
  • 多个客户端如何同时连接到服务器上的一个端口(例如 80)? [复制]

    这个问题在这里已经有答案了 我了解端口工作原理的基础知识 但是 我不明白的是多个客户端如何同时连接到端口 80 我知道每个客户端都有一个唯一的 对于他们的机器 端口 服务器是否从可用端口回复客户端 并简单地声明回复来自 80 这是如何运作的
  • Access-Control-Allow-Origin值跨站缓存

    我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点 只要客户端从不访问这两个站点 它似乎就可以工作 但如果它们这样做 就会出现缓存 跨站点问题 Allow cross origin location eot
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 网站(Google 和/或您)应如何处理 Accept-Language 标头?

    很长一段时间以来 我对谷歌在以下情况下的行为并不满意 并且在无意中注意到之后80 其他人 https stackoverflow com questions 1011167 what are common ui misconceptions
  • 谁添加“_”单下划线查询参数?

    我有一个在 Apache 上运行的 PHP 服务器 我收到很多类似这样的请求 10 1 1 211 02 Sep 2010 16 14 31 0400 GET request 1283458471913 action get list HT
  • 对于一般不成功的请求(不是错误),适当的 HTTP 状态代码响应是什么?

    我正在创建一个 RESTful API 它将处理许多用户交互 包括使用存储的信用卡下订单 如果订单成功 我将返回 200 OK 如果订单请求格式错误或无效 我将返回 400 Bad Request 但如果订单实际处理过程中出现问题 我该怎么
  • 如何在 PHP 中使用 file_get_contents 获取图像的 MIME 类型

    我需要获取图像的 MIME 类型 但我只有图像的正文file get contents 是否有可能获取 MIME 类型 是的 你可以这样得到它 file info new finfo FILEINFO MIME TYPE mime type

随机推荐

  • Spark+Python函数总结

    Spark 43 Python函数总结 整理自 https www cnblogs com yangzhang home p 6058076 html https blog csdn net nanruoanhao article deta
  • Spark + Python入门

    Spark 43 Python实践入门 整理自 xff1a https www cnblogs com yangzhang home p 6056133 html http spark apache org docs latest quic
  • Numpy函数总结

    Numpy函数总结 整理自 https www jianshu com p 83c8ef18a1e8 基础属性 引入模块 gt gt gt import numpy as np 创建一个list并转化为numpy数组 创建简单的列表 gt
  • pip提速方法

    Author Gary Date 2019 4 12 方法1 在pip参数中添加镜像源地址 豆瓣 xff1a http pypi douban com simple 清华 xff1a https pypi tuna tsinghua edu
  • 使ssh可以以root用户直接登录

    出于安全考虑 ubuntu默认不允许root远程登录 解决方案 安装openssh软件 sudo apt install y openssh server 编辑 SSH 的文件 sudo nano etc ssh sshd config 将
  • 安装Arduino以及ESP8266开发环境

    安装Arduino以及ESP8266开发环境 Author Gary 更新日期 2018 11 20 1 下载安装ArduinoIDE 没什么好说的 xff0c 下载地址 xff1a https www arduino cc en Main
  • 使用Screen来管理终端

    使用Screen来管理终端 转载整理自 xff1a https blog csdn net u013901768 article details 81189348 需要使程序一直运行的情况下 xff0c 可以采用开机自启动的方式 这里为了便
  • 终端关闭后让程序继续运行

    更新 实测此方法有问题 xff0c ctrl 43 z后进程会停止运行 xff0c 即使挂起了也没用了 xff0c 如需挂起后还能继续执行请参考https blog csdn net m0 37340681 article details
  • HiveDDL

    一 数据类型 1 基本数据类型 Hive数据类型 Java数据类型 长度 例子 TINYINT byte 1byte有符号整数 20 SMALINT short 2byte有符号整数 20 INT int 4byte有符号整数 20 BIG
  • Linux解除端口占用-kill进程总结

    Linux解除端口占用 需要解除端口占用时 xff0c 可以通过端口或者进程名查找进程 xff0c 再通过该进程的pid来杀掉该进程 xff1b 也可以通过进程名直接杀死进程 方法1 根据端口查找进程 sudo lsof i lt 端口号
  • Matplot学习总结

    数据可视化库Matplotlib学习总结 更新日期 20181109 安装 需要先安装numpy pip install numpy pip install matplotlib 如果下载速度慢可以参考 https blog csdn ne
  • 使用GDB调试Android Native层代码

    Author Gary Date 2019 2 21 转载整理自 xff1a https wladimir tm4pda github io porting debugging gdb html https www cnblogs com
  • Shell总结

    Author Gary Date 2019 2 22 转载整理自 xff1a http www runoob com linux linux shell variable html bin bash 是一个约定的标记 xff0c 它告诉系统
  • Android I/O截获

    Author Gary Date 2019 3 15 系统版本 Android 6 0 1 r1 Android I O截获 xff0d xff0d 将Android系统中的汇编系统调用封装为C函数 由于项目要求 xff0c 需要拦截And
  • Android添加内核系统调用

    Author Gary Date 2019 4 30 Android版本 Android 6 0 1 r1 内核版本 Linux 3 10 40 手机 Nexus 6 参考资料 http android blogs rice edu 201
  • Ubuntu Linux 安装 .7z 解压和压缩文件

    转载自 https blog csdn net zqlovlg article details 8033456 安装方法 xff1a sudo apt get install p7zip 解压文件 xff1a 7zr x manager 7
  • SSH设置超时时间

    转载自 https blog csdn net cheng830306 article details 21796865 ssh连接超时问题解决方案 xff1a 1 修改server端的etc ssh sshd config ClientA
  • Win10+RTX2060安装TensorFlow+Keras

    Win10 43 RTX2060安装TensorFlow 43 Keras Author Gary Date 2019 6 8 参考资料 https blog csdn net qq 32728345 article details 815
  • Radix Tree总结

    Date 2019 6 19 主要转载自 https www cnblogs com mingziday p 3969269 html https blog csdn net qq 22613757 article details 9104
  • HTTP防劫持方案

    DNS污染检测 被改标题 被挂黑链 被入侵 检测网站是否被劫持 网站打开速度检测 网站是否被黑 域名是否被墙 网站监控 http www iis7 com b wzjk inviteCode 61 496 HTTP劫持是在使用者与其目的网络