大模型安全(三十四):核心技术栈之Selenium/Playwright自动化与反爬对抗

摘要:

面对现代前端框架(Vue/React)构建的复杂Web应用,传统的HTTP客户端已无法满足深度扫描的需求。本文将深入探讨浏览器自动化技术在安全工具中的应用。我们将对比Selenium与Playwright的架构差异,解释为何Playwright凭借其原生异步(Async)、无头模式(Headless)和网络拦截(Network Interception)能力成为安全开发的首选。通过Python实战,我们将构建一个动态攻击面扫描器:它不仅能模拟用户登录,还能Hook浏览器网络层以提取隐藏API,并利用JS执行能力验证DOM型XSS漏洞。最后,我们将简要探讨如何通过Stealth模式隐藏浏览器指纹,对抗反爬虫检测。

关键词:Playwright, Selenium, 浏览器自动化, 动态爬虫, DOM XSS, 网络拦截, 反爬虫, 自动化测试


正文

1. 选型之争:Selenium vs. Playwright

在Python爬虫和自动化测试领域,Selenium统治了很长时间,但Playwright(微软出品)正在迅速取代它。

特性 Selenium Playwright 安全开发视角
通信协议 WebDriver (HTTP JSON) WebSocket (CDP) Playwright 速度更快,延迟更低。
异步支持 较弱 (第三方库支持) 原生 AsyncIO Playwright 完美融入我们的异步扫描框架。
网络控制 有限 (需配合代理) 极其强大 Playwright 可直接拦截/修改 请求和响应包。
环境配置 需手动配 Driver
install
自动管理
Playwright 部署更友好。
反爬对抗 容易被识别 支持 Stealth 插件 Playwright 更容易伪装成真人。

结论:写简单的自动化脚本用 Selenium;开发高性能安全工具、扫描器、红队Bot,首选 Playwright。

2. 安全开发中的“浏览器能力”

对于黑客工具来说,浏览器不仅仅是用来渲染页面的,它是用来HookExploit的:

DOM XSS 验证:只有在浏览器里真的执行了 JS,才能确认
location.hash
里的 Payload 是否触发了
alert(1)

API 发现:很多 API 接口只在用户点击按钮后才通过 AJAX 加载,静态爬虫看不到。

会话劫持模拟:自动提取
LocalStorage

Cookies

3. Python实战:构建动态漏洞验证器

我们将使用
playwright
的异步 API,构建一个能够自动登录拦截流量的扫描器原型。

环境准备

Bash



pip install playwright
playwright install chromium # 安装浏览器内核

代码实现:

Python



import asyncio
from playwright.async_api import async_playwright
import json
 
class DynamicScanner:
    def __init__(self, target_url, username=None, password=None):
        self.url = target_url
        self.creds = {"username": username, "password": password}
        self.found_apis = set()
        self.dom_xss_candidates = []
 
    async def _intercept_network(self, route):
        """
        网络拦截钩子:记录所有后台 API 调用
        """
        request = route.request
        # 过滤出 JSON 接口或 敏感文件
        if request.resource_type in ["fetch", "xhr"] or ".json" in request.url:
            self.found_apis.add(f"[{request.method}] {request.url}")
            # 进阶:在这里可以修改请求头,进行越权测试
        
        # 继续请求
        await route.continue_()
 
    async def run_scan(self):
        print(f"[*] 启动浏览器引擎,目标: {self.url}")
        
        async with async_playwright() as p:
            # 启动浏览器 (headless=False 可以看到界面,调试用)
            # args=['--disable-blink-features=AutomationControlled'] 是基础的反爬绕过
            browser = await p.chromium.launch(headless=True, args=['--disable-blink-features=AutomationControlled'])
            
            # 创建上下文 (相当于一个独立的隐身窗口)
            context = await browser.new_context(
                user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
            )
            page = await context.new_page()
 
            # 1. 挂载网络拦截器
            await page.route("**/*", self._intercept_network)
 
            # 2. 访问页面
            try:
                await page.goto(self.url, wait_until="networkidle")
            except Exception as e:
                print(f"[-] 访问失败: {e}")
                return
 
            # 3. 自动登录逻辑 (简单模拟)
            if self.creds['username']:
                print("[*] 尝试自动登录...")
                # 智能查找输入框 (Playwright 的选择器非常强大)
                if await page.locator("input[type='password']").count() > 0:
                    await page.fill("input[name*='user']", self.creds['username'])
                    await page.fill("input[type='password']", self.creds['password'])
                    await page.click("button[type='submit']")
                    await page.wait_for_load_state("networkidle")
                    print("[+] 登录提交完成。")
 
            # 4. DOM XSS 检测 (模拟)
            # 注入一个 Payload 到 URL Fragment
            # 假设页面有逻辑: document.write(location.hash)
            xss_payload = "#<img src=x onerror=window.xss_triggered=true>"
            await page.goto(self.url + xss_payload)
            
            # 检查 JS 变量是否被定义 (这证明 Payload 被执行了)
            is_xss = await page.evaluate("() => window.xss_triggered === true")
            if is_xss:
                print(f"[!!!] 发现 DOM XSS 漏洞!Payload 执行成功。")
            
            # 5. 提取敏感数据 (LocalStorage / Cookies)
            cookies = await context.cookies()
            local_storage = await page.evaluate("() => JSON.stringify(localStorage)")
            
            print(f"
[+] 会话信息提取:")
            print(f"    Cookies: {len(cookies)} 个")
            print(f"    LocalStorage 长度: {len(local_storage)}")
 
            await browser.close()
 
        print("
[+] 扫描结束,发现的 API 接口:")
        for api in self.found_apis:
            print(f"    {api}")
 
# --- 运行 ---
if __name__ == "__main__":
    # 使用 httpbin 或本地靶场测试
    target = "https://httpbin.org/forms/post" 
    scanner = DynamicScanner(target, "admin", "123456")
    asyncio.run(scanner.run_scan())

代码亮点解析


page.route
:这是Playwright的大杀器。它不仅能监听,还能篡改请求。例如,你可以编写代码自动把所有请求头的
User-Agent
改成 iPhone,或者在所有 POST 请求中自动插入 SQL 注入 Payload。


page.evaluate
:它允许你在浏览器上下文中执行任意 JS。这是检测 DOM XSS 的唯一可靠方法(通过判断
window
对象的状态变化)。

异步设计:整个扫描过程是异步的,这意味着你可以同时启动 10 个
DynamicScanner
扫描 10 个不同的网站,效率极高。

4. 对抗技术:反爬虫与“幽灵模式” (Syllabus 8.2.1)

当你使用 Selenium/Playwright 时,浏览器会默认注入一个
navigator.webdriver = true
的属性。许多 WAF 和反爬脚本会检测这个属性,一旦发现就直接封禁。

防御绕过(Stealth Techniques)

去除特征:在启动时通过
args
禁用自动化特征。

Stealth 插件:对于 Python,可以使用
playwright_stealth
库。

Python



# pip install playwright-stealth
from playwright_stealth import stealth_async
 
# 在 page 创建后,访问页面前调用
await stealth_async(page)
# 这会自动抹除 webdriver 属性,伪造 WebGL 指纹,模拟真实的硬件并发数等
5. 总结

Playwright 是现代 Web 安全工具开发的必修课,它让我们拥有了“像用户一样操作,像黑客一样思考”的能力。

结合 AsyncIO,我们可以构建出既能处理复杂逻辑(JS渲染),又能保持高吞吐量的扫描器。

在面对高防御目标时,务必结合 Stealth 技术隐藏自动化特征。

掌握了请求(Httpx)解析(lxml)和渲染(Playwright),我们已经具备了处理任何 Web 页面的能力。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
-混世小仙女si的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容