掌握基础,突破网络:输入与输出基础
1. 客户端验证 vs 服务器端验证
客户端验证发生在数据发送到服务器之前,通常在浏览器中使用JavaScript或HTML规则进行。服务器端验证则发生在请求到达后端之后,确保数据是安全、正确且经过授权的。客户端检查能提升用户体验,但服务器端验证才是真正的安全层。
客户端验证
- 运行环境:在浏览器中运行,检查如必填字段、格式和长度等基本规则。
- 作用:增强可用性,但通过修改请求或禁用脚本可以轻易绕过。
- 渗透测试相关性:
- 绝不信任其安全性——攻击者可以编辑或移除验证。
- 可用于识别仅在客户端强制执行的隐藏字段或逻辑。
- 💡示例:使用JavaScript在表单中阻止“负数金额”,一旦攻击者手动编辑请求,此验证便失效。
服务器端验证
- 运行环境:在服务器上运行,在处理数据前决定什么是可接受的或应被拒绝的。
- 作用:无论客户端发送什么,都必须强制执行严格的规则。
- 渗透测试相关性:
- 缺失或弱验证会导致SQL注入(SQLi)、跨站脚本(XSS)、命令注入和逻辑绕过。
- 渗透测试人员通过模糊测试输入,来观察服务器接受或拒绝什么。
- 💡示例:即使浏览器阻止了特殊字符,渗透测试人员仍可以向服务器端发送这些字符来测试注入漏洞。
2. 数据编码基础
编码将数据转换为安全或可传输的格式,以便浏览器和服务器能正确解释。不同类型的编码可以防止破坏HTML、URL或脚本的结构,并确保特殊字符得到安全处理。渗透测试人员必须能识别和解码编码数据,以理解攻击方式、绕过过滤器或识别注入点。
HTML编码
- 定义:用安全表示法替换特殊的HTML字符,防止它们作为代码执行。
- 示例:
<变为<,>变为>。 - 渗透测试相关性:
- 用于通过中和危险字符来防止XSS。
- 弱的HTML编码可能导致注入的脚本被执行。
- 💡示例:
- 输入:
<script>alert(1)</script> - 编码后:
<script>alert(1)</script>
- 输入:
URL编码
- 定义:对字符进行编码,使其能安全地出现在URL中。空格、符号和Unicode字符被替换为
%序列。 - 渗透测试相关性:
- 用于绕过过滤器、破坏解析器以及对端点进行模糊测试。
- 在测试基于URL的注入或路径遍历时是必需的。
- 💡示例:
/search?q=test value→/search?q=test%20value
Base64编码
- 定义:将二进制或文本数据转换为ASCII字符(A–Z, a–z, 0–9, +, /)。这不是加密——任何人都可以轻松解码。
- 渗透测试相关性:
- 常用于在API、cookie、JWT载荷或参数中隐藏数据。
- 渗透测试人员解码Base64以检查隐藏信息,或修改后重新编码。
- 💡示例:
admin:1234→YWRtaW46MTIzNA==
Unicode编码
- 定义:使用Unicode代码点表示字符(例如,
<用\u003C表示)。有助于在不同系统间一致地显示符号和语言。 - 渗透测试相关性:
- 用于XSS绕过、过滤绕过和WAF规避。
- 恶意载荷可能隐藏在混合或编码的unicode格式中。
- 💡示例:
<script>→\u003Cscript\u003E
3. 净化与转义
净化和转义是两种核心技术,用于在将用户输入发送到浏览器或数据库之前安全地处理它。它们通过确保危险字符被移除或变得无害,来帮助防止注入(XSS、SQLi、命令注入)。理解两者对于评估应用程序处理不可信数据的安全性至关重要。
净化
- 定义:修改或移除用户输入中不安全的部分。通常会剥离或中和可能造成危害的字符、标签或模式。
- 渗透测试相关性:
- 过于严格的净化可能破坏功能;过于宽松的净化则会导致漏洞。
- 攻击者测试替代载荷、编码或嵌套输入以绕过过滤器。
- 净化依赖于上下文——为HTML净化与为SQL净化是不同的。
- 💡示例:在将输入存储到数据库之前移除
<script>标签。
转义
- 定义:将特殊字符转换为安全表示法,使其被视为文本而非代码。它防止输入突破其预期上下文(HTML、JavaScript、SQL等)。
- 渗透测试相关性:
- 正确的转义通过确保像
<和"这样的字符不会变成可执行代码来阻止XSS。 - 输入必须根据其出现的位置进行转义:HTML、属性、URL或JS上下文。
- 渗透测试人员测试那些转义缺失或不一致的地方。
- 正确的转义通过确保像
- 💡示例:将
<转义为<,使其在页面上显示为文本而非执行。
4. 文件上传处理基础
文件上传允许用户向服务器发送文件(图像、PDF、文档)以供存储或处理。由于上传的文件直接来自用户,必须将其视为不可信的输入。安全的文件上传处理确保只接受安全的文件、正确存储文件且绝不以代码形式执行文件。
文件类型验证
- 定义:服务器检查文件扩展名、MIME类型或文件签名以确保允许上传。然而,扩展名和MIME类型很容易被伪造。
- 渗透测试相关性:
- 绕过尝试包括将
.php重命名为.jpg.php或修改头信息。 - 弱验证可能导致远程代码执行(RCE)。
- 绕过尝试包括将
- 💡示例:上传伪装成
image.jpg的shell.php。
文件大小限制
- 定义:服务器限制文件大小以防止资源耗尽或拒绝服务攻击。大文件可能压垮存储或处理管道。
- 渗透测试相关性:渗透测试人员测试最大限制并上传超大文件以检查系统的抗DoS能力。
- 💡示例:向一个预期接收
<10MB文件的系统上传一个5GB的文件。
存储位置
- 定义:上传的文件应存储在Web根目录之外,这样它们就不能被直接执行或访问。访问应由应用程序控制,而不是文件路径。
- 渗透测试相关性:
- 存储在公共目录中的文件如果被服务器解释,可能会被执行。
- 路径遍历攻击可能暴露内部目录。
- 💡示例:可直接访问
/uploads/image.jpg→ 测试上传的脚本是否可执行。
重命名与净化
- 定义:服务器必须将上传的文件重命名为安全的、随机的名称。净化文件名可以防止注入或路径遍历。
- 渗透测试相关性:
- 文件名注入(
../../etc/passwd)可能泄露系统文件。 - 净化不充分可能导致覆盖现有文件。
- 文件名注入(
- 💡示例:
- 原始名:
../../../malicious.php - 净化后:
upload_12345.jpg
- 原始名:
内容扫描
- 定义:一些应用程序会扫描文件内容以查找恶意载荷。这增加了一层额外的保护。
- 渗透测试相关性:渗透测试人员尝试多态文件、混淆的载荷或基于元数据的漏洞利用。
- 💡示例:一个嵌入了PHP代码的
.jpg文件。
到这里就结束了——接下来预告:后端应用流程 下次见 🙌,
Abinesh