0x00、什么是URL

URL全称为Uniform Resource Locator,中文名称是统一资源定位符。顾名思义,一条语法正确的URL对应了服务器上某个资源。

为什么要研究URL?因为URL是整个Web的入口,搞清楚URL的解析机制及出现的问题,是Web安全最基础的问题。

0x01、URL的结构

这是一个标准的URL格式

下面对每个部分进行详细的说明

位置 作用 是否可选
scheme: 协议名称 必选
:// 层级URL标记符 必选
login:password@ 访问资源凭证信息 可选
address 服务器地址 必选
:port 端口号 可选
/path 资源层级文件路径 必选
?query_string 查询参数 可选
#fragment 片段ID 可选

1、协议名称

协议是由一个不区分大小写的字符串构成的,表示获取资源时候使用的协议。

官方认证的URL由IANA维护,不仅如此浏览器还会自己支持一些伪协议,这些都会带来一些安全问题,后面会专门说协议。

2、层级URL

一般都有,目前所知mailto协议是不需要这个的,后面会学习下RFC,遇到类似的会补充到这里。

3、访问资源凭证信息

在URL中这个属于可选的,主要是在身份认证的时候使用。如果没有提供身份信息,默认匿名的方式获取数据。

4、服务器地址

对完整的URL来说,服务器地址必须是一个完整的域名、IPV4地址或者IPV6地址。

因为大多数应用都依赖C语言库,所以支持接收八进制、十六进制的写法

下面的几个例子是等同的,一般可以在绕过某些的东西的时候使用

上面的写法可以拿出来看看

对于119.23.22.125来说,可以看成32位二进制数组成,8位为一组

每组都换成16进制就变成上面第二种写法

对16进制的ip进行8进制转码后,前置加上一个0就变成了第三种写法

如果组合型的,可以前八位用16进制转置,后面24位用8进制转换后,前置加上一个0就变成了第四种写法

如果把第四种后面8进制数(16进制也可以)转成10进制,就变成了第五种写法

5、端口号

服务器端口是可选的,一般在连接非标准端口时用到。基本上浏览器所支持的协议都是以TCP/UDP方式传输的。
服务器上所有应用都是以端口号进行区别的,这代表我们可以用浏览器通过改写端口的方式访问原本浏览器不支持的服务协议。

6、资源层级文件路径

从类UNIX继承过来的路径,可以使用绝对路径和相对路径。
即支持 ../ 和 ./ 可以用这些进行绕过读配置。

7、查询参数

这串字符串中可以包含任意需要传递的参数和值,把相关参数传给前面的文件路径指定的文件

8、片段ID

片段ID主要用于客户端,不会传送数据给服务端。实际应用中,主要是用在HTML的锚点,用于页面定位。
但现在可以用于存储一些临时数据,存储客户端需要的各种状态信息。

0x02、编码和保留字符

1、谈谈编码和保留字符

看到这个标题第一个反应是什么是编码,什么是保留字符?
然后第二个反应就是为什么要编码,为什么要有保留字符。

如果说一个东西不能通过原生的方式进行传输,需要类似编码之类的操作,首先能够想到的就是这种传输方式在特定场景下并不适用。
比如数据包过大,容易出现丢数据;比如传输的信息比较机密,不适合明文传输;比如传输过程中出现特定字符冲突等等。

那么URL里为什么要编码呢?这就不得不提保留字符这个东西了。

通过前面URL的标准格式可以看出,一些特定的符号限定了URL的格式,那么如果我要传输的内容中出现了同样的字符怎么办?总不能让人不用吧。

所以就提出了编码和保留字符,保留字符就是指这些容易跟某些用于语义分隔发生冲突的字符。为了使用这些字符,就用编码的形式对这些保留字符进行区分。

RFC规定了一种使用方法,又称为URL编码,或者百分号编码。

URL编码用一个百分号(%)和该字符的ASCII码对应的2位16进制数字进行替换原来的保留字符。

2、如何编码

所以现在我们再来看看需要编码的字符

第一种就是不安全字符,放在URL中会改变原本的意思

因为这些符号和markdown冲突了,所以这里的表格就直接上图了

第二种就是非ASCII编码字符

一般这样的都是先把非ASCII字符(例如中文),编码成ASCII字符集,然后再进行URL编码。

0x03、常见URL协议

主要分为4种URL协议

协议 分类
http 浏览器本身支持的协议
https 浏览器本身支持的协议
ftp 浏览器本身支持的协议
gopher 浏览器本身支持的协议
mailto 第三方插件应用协议
rstp 第三方插件应用协议
daap 第三方插件应用协议
javascript 未封装伪协议
data 未封装伪协议
view-source 封装过的伪协议