PHP代码审计系列基础文章(二)之XSS漏洞篇
字数 1334 2025-08-11 22:57:16

PHP代码审计:XSS漏洞详解与防御

1. XSS漏洞原理

XSS(Cross Site Scripting)中文名称为跨站脚本攻击,重点在于执行恶意JavaScript脚本而非跨站行为。漏洞成因是:

  • Web程序未对用户提交参数进行过滤直接输出到页面
  • 参数中的特殊字符被恶意闭合,导致原有HTML页面嵌入恶意脚本
  • 当用户浏览该页面时,嵌入的JavaScript代码会被执行

2. XSS分类与实例分析

2.1 反射型XSS

特点

  • 用户可控数据未被存储
  • 仅在单次请求中生效
  • 执行流程:浏览器 → 后端 → 浏览器

示例代码

<?php
highlight_file(__FILE__);
echo $_REQUEST['xss'];
?>

利用方式
攻击者构造恶意URL发送给受害者,受害者点击后脚本被执行。

2.2 存储型XSS

特点

  • 用户可控数据被存储至数据库
  • 可被持续读取,危害较高
  • 执行流程:浏览器 → 后端 → 数据库 → 后端 → 浏览器

示例场景

// 接收并存储用户输入
$content = $_POST['content'];
$sql = "INSERT INTO xss(content) VALUES('$content')";

// 从数据库读取并输出
$result = mysqli_query($conn, "SELECT content FROM xss");
$row = mysqli_fetch_assoc($result);
echo $row['content'];

2.3 DOM型XSS

特点

  • 特殊的反射型XSS
  • 通过JavaScript和DOM技术输出到HTML
  • 执行流程:URL → 浏览器

示例代码

function domxss(){
    var str = document.getElementById("text").value;
    document.getElementById("dom").innerHTML = 
        "<a href='"+str+"'>what do you see?</a>";
}

利用方式
通过闭合引号注入恶意脚本:

' onclick='alert(1)'

3. XSS审计关键函数

审计时应重点关注以下输出打印函数:

  1. print
  2. print_r
  3. echo
  4. printf
  5. sprintf
  6. die
  7. var_dump
  8. var_export

4. XSS审计注意事项

4.1 htmlspecialchars函数缺陷

htmlspecialchars()默认不对单引号转义,当输出在单引号属性中时可能被绕过:

$content = htmlspecialchars($_GET['text']);
?>
<input type='text' value='<?=$content?>'>

绕过方式
闭合单引号后添加事件处理:

' onclick='alert(1)

4.2 编解码问题

漏洞代码

$content = $_REQUEST['text']; // 浏览器自动URL解码
$cont = htmlspecialchars($content);
echo urldecode($cont); // 再次URL解码

绕过方式
对payload进行双重URL编码:

%253Cscript%253Ealert('xss')%253C/script%253E

解码过程:

  1. 浏览器解码:%3Cscript%3Ealert('xss')%3C/script%3E
  2. 通过htmlspecialchars过滤(无效)
  3. urldecode解码:<script>alert('xss')</script>

5. XSS防御措施

  1. 输入验证

    • 对用户输入进行严格的白名单验证
    • 过滤特殊字符:<, >, ", ', &
  2. 输出编码

    • 根据输出上下文选择合适的编码方式
    • HTML实体编码:htmlspecialchars($var, ENT_QUOTES)
    • JavaScript编码:json_encode()
  3. 内容安全策略(CSP)

    • 通过HTTP头限制脚本来源
    • 示例:Content-Security-Policy: default-src 'self'
  4. HttpOnly标志

    • 设置Cookie的HttpOnly属性防止被JavaScript读取
  5. 避免不安全的DOM操作

    • 避免使用innerHTML等直接插入HTML的方法
    • 使用textContentinnerText替代

6. 审计实践建议

  1. 遵循"见框就插"原则进行黑盒测试
  2. 重点关注输出函数和过滤逻辑
  3. 测试各种编码绕过可能性
  4. 检查是否根据输出上下文使用不同编码方式
  5. 验证CSP等防御措施是否生效

通过深入理解XSS原理和常见绕过方式,结合靶场实践,可以有效提升代码审计中识别和防御XSS漏洞的能力。

PHP代码审计:XSS漏洞详解与防御 1. XSS漏洞原理 XSS(Cross Site Scripting)中文名称为跨站脚本攻击,重点在于执行恶意JavaScript脚本而非跨站行为。漏洞成因是: Web程序未对用户提交参数进行过滤直接输出到页面 参数中的特殊字符被恶意闭合,导致原有HTML页面嵌入恶意脚本 当用户浏览该页面时,嵌入的JavaScript代码会被执行 2. XSS分类与实例分析 2.1 反射型XSS 特点 : 用户可控数据未被存储 仅在单次请求中生效 执行流程:浏览器 → 后端 → 浏览器 示例代码 : 利用方式 : 攻击者构造恶意URL发送给受害者,受害者点击后脚本被执行。 2.2 存储型XSS 特点 : 用户可控数据被存储至数据库 可被持续读取,危害较高 执行流程:浏览器 → 后端 → 数据库 → 后端 → 浏览器 示例场景 : 2.3 DOM型XSS 特点 : 特殊的反射型XSS 通过JavaScript和DOM技术输出到HTML 执行流程:URL → 浏览器 示例代码 : 利用方式 : 通过闭合引号注入恶意脚本: 3. XSS审计关键函数 审计时应重点关注以下输出打印函数: print print_r echo printf sprintf die var_dump var_export 4. XSS审计注意事项 4.1 htmlspecialchars函数缺陷 htmlspecialchars() 默认不对单引号转义,当输出在单引号属性中时可能被绕过: 绕过方式 : 闭合单引号后添加事件处理: 4.2 编解码问题 漏洞代码 : 绕过方式 : 对payload进行双重URL编码: 解码过程: 浏览器解码: %3Cscript%3Ealert('xss')%3C/script%3E 通过htmlspecialchars过滤(无效) urldecode解码: <script>alert('xss')</script> 5. XSS防御措施 输入验证 : 对用户输入进行严格的白名单验证 过滤特殊字符: < , > , " , ' , & 等 输出编码 : 根据输出上下文选择合适的编码方式 HTML实体编码: htmlspecialchars($var, ENT_QUOTES) JavaScript编码: json_encode() 内容安全策略(CSP) : 通过HTTP头限制脚本来源 示例: Content-Security-Policy: default-src 'self' HttpOnly标志 : 设置Cookie的HttpOnly属性防止被JavaScript读取 避免不安全的DOM操作 : 避免使用 innerHTML 等直接插入HTML的方法 使用 textContent 或 innerText 替代 6. 审计实践建议 遵循"见框就插"原则进行黑盒测试 重点关注输出函数和过滤逻辑 测试各种编码绕过可能性 检查是否根据输出上下文使用不同编码方式 验证CSP等防御措施是否生效 通过深入理解XSS原理和常见绕过方式,结合靶场实践,可以有效提升代码审计中识别和防御XSS漏洞的能力。