PDF-XSS

前言:

PDF文件是一種復雜的文檔格式,由一系列對象組成,包括字體、圖像、頁面內容等。PDF文件支持嵌入JavaScript代碼,這使得PDF文件不僅可以顯示靜態內容,還可以執行動態操作。這種特性被攻擊者利用來嵌入惡意腳本代碼。

攻擊者通過在PDF文件中嵌入惡意JavaScript代碼,使得當用戶打開該PDF文件時,惡意代碼會在用戶的瀏覽器或PDF閱讀器中執行。

pdf-xss制作:

python代碼如下:

from PyPDF2 import PdfReader, PdfWriter
# 創建一個新的 PDF 文檔
output_pdf = PdfWriter()
# 添加一個新頁面
page = output_pdf.add_blank_page(width=72, height=72)
# 添加js代碼
output_pdf.add_js("app.alert('xss');")
# 將新頁面寫入到新 PDF 文檔中
with open("alert.pdf", "wb") as f:output_pdf.write(f)

執行后會將腳本植入到pdf中,對應的pdf分析

?

當我們打開對應的pdf文件,可以看到彈出了對應的xss對話框

修復:

代碼修復也很簡單,就是要處理JavaScript方法,對應的處理的點如下

  • 識別并移除/Names/JavaScript結構
  • 處理嵌套字典中的JavaScript
  • 處理數組中的JavaScript動作
  • 遞歸檢查所有可能的位置

對應的java代碼如下

package org.example;import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;import java.io.File;
import java.io.IOException;
import java.util.List;public class Main {public static void main(String[] args) {String inputFile = "alert.pdf";String outputFile = "safe-output.pdf";try {removeJavaScript(inputFile, outputFile);System.out.println("PDF中的JavaScript已徹底移除!");} catch (IOException e) {System.err.println("處理失敗: " + e.getMessage());}}public static void removeJavaScript(String inputPath, String outputPath) throws IOException {PDDocument document = Loader.loadPDF(new File(inputPath));try {// 1. 處理文檔級JavaScriptprocessDocumentLevelJS(document);// 2. 處理頁面級JavaScriptprocessPagesJS(document);// 3. 保存處理后的文檔document.save(outputPath);} finally {document.close();}}// 處理文檔級的JavaScriptprivate static void processDocumentLevelJS(PDDocument document) {// 獲取文檔目錄PDDocumentCatalog catalog = document.getDocumentCatalog();COSDictionary catalogDict = catalog.getCOSObject();// 處理文檔開放動作catalog.setOpenAction(null);// 專門處理Names字典中的JavaScriptprocessNamesDictionaryJS(catalogDict);// 移除標準JS和AAremoveDictJavaScript(catalogDict);}// 專門處理Names字典中的JavaScriptprivate static void processNamesDictionaryJS(COSDictionary dict) {if (dict.containsKey(COSName.NAMES)) {COSDictionary namesDict = dict.getCOSDictionary(COSName.NAMES);if (namesDict != null) {// 檢查JavaScript字典if (namesDict.containsKey(COSName.JAVA_SCRIPT)) {namesDict.removeItem(COSName.JAVA_SCRIPT);System.out.println("已移除文檔級的Named JavaScript字典");// 如果Names字典變空(即沒有其他條目了),則移除整個Names字典if (namesDict.size() == 0) { // 修改這里:使用size()==0代替isEmpty()dict.removeItem(COSName.NAMES);}}}}}// 處理頁面級JavaScriptprivate static void processPagesJS(PDDocument document) throws IOException {for (PDPage page : document.getPages()) {// 處理頁面級JavaScriptCOSDictionary pageDict = page.getCOSObject();removeDictJavaScript(pageDict);// 處理頁面注釋List<PDAnnotation> annotations = page.getAnnotations();for (PDAnnotation annotation : annotations) {removeAnnotationJavaScript(annotation);}}}// 移除注釋中的JavaScriptprivate static void removeAnnotationJavaScript(PDAnnotation annotation) {COSDictionary dict = annotation.getCOSObject();removeDictJavaScript(dict);}// 核心方法:移除COSDictionary中的JavaScriptprivate static void removeDictJavaScript(COSDictionary dict) {// 1. 直接移除所有JavaScript項dict.removeItem(COSName.JS);// 2. 檢查并移除標準動作中的JavaScriptif (dict.containsKey(COSName.A)) {COSDictionary actionDict = dict.getCOSDictionary(COSName.A);if (isJavaScriptAction(actionDict)) {dict.removeItem(COSName.A);}}// 3. 檢查并移除附加動作中的JavaScriptif (dict.containsKey(COSName.AA)) {COSDictionary aaDict = dict.getCOSDictionary(COSName.AA);removeAllJavaScriptFromDict(aaDict);}// 4. 處理Names字典(針對嵌套的Names字典)processNamesDictionaryJS(dict);}// 檢查是否為JavaScript動作private static boolean isJavaScriptAction(COSDictionary actionDict) {// JavaScript動作的標識:/S 為 /JavaScriptreturn COSName.JAVA_SCRIPT.equals(actionDict.getCOSName(COSName.S)) ||actionDict.containsKey(COSName.JS);}// 徹底清除字典中的所有JavaScriptprivate static void removeAllJavaScriptFromDict(COSDictionary dict) {// 遍歷所有條目for (COSName key : dict.keySet().toArray(new COSName[0])) {COSBase value = dict.getItem(key);// 1. 直接移除JavaScript項if (value == COSName.JS || key == COSName.JS) {dict.removeItem(key);}// 2. 處理嵌套的JavaScript字典else if (value instanceof COSDictionary) {COSDictionary subDict = (COSDictionary) value;if (isJavaScriptAction(subDict)) {dict.removeItem(key);} else {// 遞歸處理嵌套字典removeAllJavaScriptFromDict(subDict);}}// 3. 處理數組中的JavaScriptelse if (value instanceof COSArray) {processArrayForJavaScript((COSArray) value);}}}// 處理數組中的JavaScriptprivate static void processArrayForJavaScript(COSArray array) {for (int i = 0; i < array.size(); i++) {COSBase element = array.get(i);if (element instanceof COSDictionary) {COSDictionary dict = (COSDictionary) element;if (isJavaScriptAction(dict)) {array.remove(i); // 從數組中移除JavaScript字典i--; // 調整索引}}}}
}

上述代碼具體的執行邏輯如下:?

  1. ?完整遍歷?:

    • 文檔級 (1次)
    • 頁面級 (每頁1次)
    • 注釋級 (每個注釋1次)
    • 潛在嵌套結構 (無限遞歸深度)
  2. ?腳本檢測?:

    • 檢測到JS項的PDF對象:直接移除
    • 檢測到A/AA項中的JS動作:移除整個動作項
    • 檢測到Names中的JS:移除整個JS子字典
  3. ?資源清理?:

    • 移除后的空容器會被清理
    • 只移除腳本相關項,保留其他內容

對應的執行完成的和開始的對比

?統一為1.6版本的pdf格式

如此便可以去除pdf文件中的js腳本代碼,后續最好再head中添加

CSP和X-Content-Type-Options: ?nosniff

可以進一步防御xss攻擊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88203.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88203.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88203.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 表關聯關系詳解

MySQL 表關聯關系詳解 本文檔詳細列舉了MySQL中常見的表關聯關系場景以及對應的SQL語句示例。 1. 一對一關系 (One-to-One) 場景&#xff1a;用戶表和用戶詳情表 一個用戶對應一個用戶詳情通常用于將大表拆分&#xff0c;提高查詢性能 -- 創建用戶表 CREATE TABLE users (…

kubernetes(k8s)集群部署(超詳細)

k8s部署 kubernetes集群圖例kubernetes 安裝倉庫初始化1、創建云主機2、初始化私有倉庫kube-master安裝1、防火墻相關配置2、配置yum倉庫(跳板機)3、安裝軟件包(master)4、鏡像導入私有倉庫5、Tab鍵設置6、安裝代理軟件包7、配置內核參數8、使用kubeadm部署9、驗證安裝結果計算…

「Flink」算子主要方法介紹

背景&#xff1a; 上期文章主要講了Flink項目搭建的一些方法&#xff0c;其中對于數據流的處理很大一部分是通過算子來進行計算和處理的&#xff0c;算子也是Flink中功能非常龐大&#xff0c;且很重要的一部分。 算子介紹&#xff1a; 算子在Flink的開發者文檔中是這樣介紹的…

3405. 統計恰好有 K 個相等相鄰元素的數組數目

3405. 統計恰好有 K 個相等相鄰元素的數組數目 給你三個整數 n &#xff0c;m &#xff0c;k 。長度為 n 的 好數組 arr 定義如下&#xff1a; arr 中每個元素都在 閉 區間 [1, m] 中。恰好 有 k 個下標 i &#xff08;其中 1 < i < n&#xff09;滿足 arr[i - 1] arr…

Spring AI 項目實戰(十):Spring Boot + AI + DeepSeek 構建智能合同分析技術實踐(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰(一):Spring AI 核心模塊入門2Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼)3Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼)4

impala中時間戳轉(DATE)指定格式的字符串

注意i&#xff1a;注意大小寫 timestamp\date–>string SELECT now(),from_timestamp(now(),yyyyMMdd);string->timestamp SELECT 20230710,to_timestamp(20230710,yyyyMMdd);日期加減 select 20231201,from_timestamp(date_add(to_timestamp(20231201,yyyyMMdd),1),…

百度下拉框出詞技術解密:72小時出下拉詞軟件原理分享

如何才能刷下拉詞&#xff1f;這個問題一直是企業做流量時最糾結的問題&#xff0c;百度下拉詞作為百度搜索體驗中的一項智能化功能&#xff0c;極大地方便了用戶快速完成搜索&#xff0c;也成為了企業在搜索引擎優化&#xff08;SEO&#xff09;策略中的重要流量入口。通過研究…

上海人工智能實驗室明珠湖會議首開,解答AI前沿疑問,推進科學智能

在通用人工智能&#xff08;AGI&#xff09;探索如火如荼的當下&#xff0c;如何加速突破&#xff1f;如何凝練關鍵問題、孕育顛覆性創新&#xff1f;2025年6月13日&#xff0c;上海人工智能實驗室主任、首席科學家&#xff0c;清華大學惠妍講席教授周伯文在首屆明珠湖會議&…

BeyondCompare安裝(永久免費使用+全網最詳細版)

一.下載&#xff1a; 官網下載&#xff08;速度較慢&#xff09;&#xff1a; https://www.scootersoftware.com/download.php 阿里云盤&#xff08;不限速&#xff09; https://www.alipan.com/s/WaG1z54BQ2U 二.安裝&#xff08;無腦下一步即可&#xff09; 三.永久免費…

如何用AI開發完整的小程序<7>—讓AI微調UI排版

上一節我們介紹了如何讓AI修改整體UI視覺效果。 不過有時候AI調整的并不理想&#xff0c;一些UI的布局還是需要微調。 比如已經實現的這個開始頁面&#xff0c;我覺得標題太高了&#xff0c;這時候可以自己調&#xff0c;也可以讓AI單獨調&#xff0c;下面詳細介紹。 一、手動…

64-Oracle Redo Log

小伙伴們&#xff0c;關于數據庫的redo log相信大家都操作很多次了,且這是OCM考試必考內容。Oracle Redo Log是一種特殊的日志文件&#xff0c;用于完整地記錄數據庫中所有數據變更的詳細信息。當數據庫執行插如、更新或刪除等更新操作&#xff0c;這些操作并不會立刻寫入數據庫…

hive集群優化和治理常見的問題答案

Hive 集群優化與治理常見問題答案合集 &#x1f42d;1. Q&#xff1a;Hive中如何優化大表Join操作&#xff1f; A&#xff1a; 使用Map Join&#xff08;小表Join大表時&#xff09;避免Reduce階段。啟用自動Map Join&#xff08;設置hive.auto.convert.jointrue&#xff09;…

C#采集電腦硬件(CPU、GPU、硬盤、內存等)溫度和使用狀況

這是采集出來的Json&#xff0c;部分電腦&#xff08;特別是筆記本&#xff09;無法獲取到&#xff1a; {"HardwareList": [{"Name": "MITX-6999","Type": "主板","Sensors": [],"WmiReport": null}, …

C3新增特性

? 一、選擇器&#xff08;Selectors&#xff09; 1. 屬性選擇器 [attr^value]: 匹配屬性值以特定字符串開頭的元素。[attr$value]: 匹配屬性值以特定字符串結尾的元素。[attr*value]: 匹配屬性值包含特定字符串的元素。 2. 子元素和兄弟元素選擇器 :nth-child(n): 匹配父元…

報錯 @import “~element-ui/packages/theme-chalk/src/index“;

報錯 import "~element-ui/packages/theme-chalk/src/index"; 具體報錯報錯原因 具體報錯 SassError: Can’t find stylesheet to import. import “~element-ui/packages/theme-chalk/src/index”; src\views\login\theme\element-variables.scss 8:9 root stylesh…

ESLint從入門到實戰

引言 作為前端開發者&#xff0c;你是否遇到過這樣的情況&#xff1a;團隊成員寫出的代碼風格各異&#xff0c;有人喜歡用分號&#xff0c;有人不用&#xff1b;有人用雙引號&#xff0c;有人用單引號&#xff1b;代碼評審時總是在糾結這些格式問題而不是業務邏輯&#xff1f;…

vue3實現markdown文檔轉HTML并可更換樣式

vue3實現markdown文檔轉HTML 安裝marked npm install marked<template><!-- 后臺可添加樣式編輯器 --><div class"markdown-editor" :class"{ fullscreen: isFullscreen, preview-mode: isPreviewMode }"><div class"editor-c…

Temu 實時獲取商品動態:一個踩坑后修好的抓數腳本筆記

Temu 作為一個增長迅猛的購物平臺&#xff0c;其商品價格、庫存等信息&#xff0c;對許多做運營分析的小伙伴來說非常有參考價值。 我在寫這個小工具的時候&#xff0c;踩了很多坑&#xff0c;特別記錄下來&#xff0c;希望對你有用。 初版代碼&#xff1a;想當然的“直接來一下…

【軟考高級系統架構論文】論數據分片技術及其應用

論文真題 數據分片就是按照一定的規則,將數據集劃分成相互獨立、 正交的數據子集,然后將數據子集分布到不同的節點上。通過設計合理的數據分片規則,可將系統中的數據分布在不同的物理數據庫中,達到提升應用系統數據處理速度的目的。 請圍繞“論數據分片技術及其應用”論題…

VR飛奪瀘定橋沉浸式歷史再現?

當你戴上 VR 設備開啟這場震撼人心的 VR 飛奪瀘定橋體驗&#xff0c;瞬間就會被拉回到 1935 年那個戰火紛飛的 VR 飛奪瀘定橋的歲月&#xff0c;置身于瀘定橋的西岸 。映入眼簾的是一座由 13 根鐵索組成的瀘定橋&#xff0c;它橫跨在波濤洶涌的大渡河上&#xff0c;橋下江水咆哮…