者:公子
出處:https://segmentfault.com/a/1190000024526176
pire.Office 7.7.6 已發布。本次更新帶來了一些新功能,如:Spire.Doc 在使用新引擎轉換 Word 到 PDF 時支持保留文本方向;Spire.PDF 支持創建標簽 PDF 文件;Spire.XLS 支持在導出 DataTable 時,設置是否保持數據的數字格式;Spire.Presentation 支持裁切幻燈片圖片。此外,該版本還成功修復了許多已知問題。詳情請閱讀以下內容。
該版本涵蓋了最新版的Spire.Doc,Spire.PDF,Spire.XLS,Spire.Email,Spire.DocViewer, Spire.PDFViewer,Spire.Presentation,Spire.Spreadsheet, Spire.OfficeViewer, Spire.DocViewer, Spire.Barcode, Spire.DataExport。
版本信息如下:
獲取Spire.Office 7.7.6請點擊:
Spire.Office for .NET | 下載
新功能:
//Note:At present, in order to ensure the validity of the output tagged PDF file, it is necessary to add the valid license of Spire.PDF for .net to remove the red warning watermark.
//Spire.License.LicenseProvider.SetLicenseKey("valid license key");
//Create a pdf document
PdfDocument doc = new PdfDocument();
//Add page
doc.Pages.Add();
//Set tab order
doc.Pages[0].SetTabOrder(TabOrder.Structure);
//Create PdfTaggedContent
PdfTaggedContent taggedContent = new PdfTaggedContent(doc);
taggedContent.SetLanguage("en-US");
taggedContent.SetTitle("test");
//Set font
PdfTrueTypeFont font = new PdfTrueTypeFont(new System.Drawing.Font("Times New Roman", 10), true);
PdfSolidBrush brush = new PdfSolidBrush(Color.Black);
//Append elements
PdfStructureElement article = taggedContent.StructureTreeRoot.AppendChildElement(PdfStandardStructTypes.Document);
PdfStructureElement paragraph1 = article.AppendChildElement(PdfStandardStructTypes.Paragraph);
PdfStructureElement span1 = paragraph1.AppendChildElement(PdfStandardStructTypes.Span);
span1.BeginMarkedContent(doc.Pages[0]);
PdfStringFormat format = new PdfStringFormat(PdfTextAlignment.Justify);
doc.Pages[0].Canvas.DrawString("Spire.PDF for .NET is a professional PDF API applied to creating, writing, editing, handling and reading PDF files.",
font, brush, new Rectangle(40, 0, 480, 80), format);
span1.EndMarkedContent(doc.Pages[0]);
PdfStructureElement paragraph2 = article.AppendChildElement(PdfStandardStructTypes.Paragraph);
paragraph2.BeginMarkedContent(doc.Pages[0]); doc.Pages[0].Canvas.DrawString("Spire.PDF for .NET can be applied to easily convert Text, Image, SVG, HTML to PDF and convert PDF to Excel with C#/VB.NET in high quality.",
font, brush, new Rectangle(40, 80, 480, 60), format);
paragraph2.EndMarkedContent(doc.Pages[0]);
PdfStructureElement figure1 = article.AppendChildElement(PdfStandardStructTypes.Figure);
//Set Alternate text
figure1.Alt = "replacement text1";
figure1.BeginMarkedContent(doc.Pages[0], null);
PdfImage image = PdfImage.FromFile(@"E-logo.png");
doc.Pages[0].Canvas.DrawImage(image, new PointF(40, 200), new SizeF(100, 100));
figure1.EndMarkedContent(doc.Pages[0]);
PdfStructureElement figure2 = article.AppendChildElement(PdfStandardStructTypes.Figure);
//Set Alternate text
figure2.Alt = "replacement text2";
figure2.BeginMarkedContent(doc.Pages[0], null);
doc.Pages[0].Canvas.DrawRectangle(PdfPens.Black, new Rectangle(300, 200, 100, 100));
figure2.EndMarkedContent(doc.Pages[0]);
//Save to file
String result = "CreateTaggedFile_result.pdf";
doc.SaveToFile(result);
doc.Close();
//Note:At present, in order to ensure the validity of the output PDF/UA file, it is necessary to add the valid license of Spire.PDF for .net to remove the red warning watermark.
//Spire.License.LicenseProvider.SetLicenseKey("valid license key");
//Create a pdf document
PdfDocument doc = new PdfDocument();
//Add page
doc.Pages.Add();
//Set tab order
doc.Pages[0].SetTabOrder(TabOrder.Structure);
//Create PdfTaggedContent
PdfTaggedContent taggedContent = new PdfTaggedContent(doc);
taggedContent.SetLanguage("en-US");
taggedContent.SetTitle("test");
//Set PDF/UA1 identification
taggedContent.SetPdfUA1Identification();
//Set font
PdfTrueTypeFont font = new PdfTrueTypeFont(new System.Drawing.Font("Times New Roman", 10), true);
PdfSolidBrush brush = new PdfSolidBrush(Color.Black);
//Append elements
PdfStructureElement article = taggedContent.StructureTreeRoot.AppendChildElement(PdfStandardStructTypes.Document);
PdfStructureElement paragraph1 = article.AppendChildElement(PdfStandardStructTypes.Paragraph);
PdfStructureElement span1 = paragraph1.AppendChildElement(PdfStandardStructTypes.Span);
span1.BeginMarkedContent(doc.Pages[0]);
PdfStringFormat format = new PdfStringFormat(PdfTextAlignment.Justify);
doc.Pages[0].Canvas.DrawString("Spire.PDF for .NET is a professional PDF API applied to creating, writing, editing, handling and reading PDF files.",
font, brush, new Rectangle(40, 0, 480, 80), format);
span1.EndMarkedContent(doc.Pages[0]);
PdfStructureElement paragraph2 = article.AppendChildElement(PdfStandardStructTypes.Paragraph);
paragraph2.BeginMarkedContent(doc.Pages[0]);
doc.Pages[0].Canvas.DrawString("Spire.PDF for .NET can be applied to easily convert Text, Image, SVG, HTML to PDF and convert PDF to Excel with C#/VB.NET in high quality.",
font, brush, new Rectangle(40, 80, 480, 60), format);
paragraph2.EndMarkedContent(doc.Pages[0]);
PdfStructureElement figure1 = article.AppendChildElement(PdfStandardStructTypes.Figure);
//Set Alternate text
figure1.Alt = "replacement text1";
figure1.BeginMarkedContent(doc.Pages[0], null);
PdfImage image = PdfImage.FromFile(@"E-logo.png");
doc.Pages[0].Canvas.DrawImage(image, new PointF(40, 200), new SizeF(100, 100));
figure1.EndMarkedContent(doc.Pages[0]);
PdfStructureElement figure2 = article.AppendChildElement(PdfStandardStructTypes.Figure);
//Set Alternate text
figure2.Alt = "replacement text2";
figure2.BeginMarkedContent(doc.Pages[0], null);
doc.Pages[0].Canvas.DrawRectangle(PdfPens.Black, new Rectangle(300, 200, 100, 100));
figure2.EndMarkedContent(doc.Pages[0]);
//Save to file
String result = "CreatePDFUAFile_result.pdf";
doc.SaveToFile(result);
doc.Close();
問題修復:
新功能:
功能調整:
問題修復:
新功能:
ExportTableOptions options = new ExportTableOptions();
options.KeepDataFormat = false;
DataTable table = sheet.ExportDataTable(1, 1, sheet.LastDataRow, sheet.LastDataColumn, options);
問題修復:
問題修復:
新功能:
SlidePicture slidePicture = (SlidePicture)presentation.Slides[0].Shapes[0];
slidePicture.Crop(float x, float y, float width, float height);
presentation.Slides[0].Shapes[0].InsertPicture(Stream stream)
x00 前言
在過去幾周中,FortiGuard Labs一直在研究帶有SVG(Scalable Vector Graphics)圖像的Web應用。根據研究結果,我們找到了Web應用中的一些常見問題。在本文中,我們簡要介紹了SVG的特點以及針對SVG圖像的常見攻擊面。
根據之前的研究結果,我們梳理了一些常見的SVG攻擊方式,如下所示:
0x01 SVG簡介
SVG的全稱為 Scalable Vector Graphics(可縮放矢量圖),是一種基于XML的二維矢量圖格式,支持交互性及動畫展示。SVG圖像及具體行為由XML文本文件定義,可以通過任何文本編輯器以及繪圖軟件來創建并編輯。目前所有主流web瀏覽器都支持渲染SVG圖像。
來觀察一個示例,更好理解SVG圖像。如下圖所示,我們編寫了一些代碼來渲染SVG圖像:
圖1. simple.svg代碼片段
將該圖像保存為simple.svg,然后直接打開,或者將其包含在img/image/object/embed HTML標簽中,如下圖所示:
圖2. 通過代碼渲染圖像
圖1代碼渲染生成的圖像如圖2所示,這是rect元素,瀏覽器會在x, y (100, 100)(即寬度和高度)位置渲染一個紅色矩形。
0x02 使用SVG的攻擊場景
雖然SVG提供了較大的靈活性,可以方便創建更多的動態web內容,但同時也引入了一些安全風險。在下文中,我們將討論一些常見的攻擊向量,我們在互聯網上的一些主流站點上都觀察到過這些攻擊方式。
跨站腳本
我們可以通過腳本方式來訪問并修改SVG文檔的任何內容,這與HTML操作方式類似。默認的腳本語言為ECMAScript(與JavaScript密切相關),每個SVG元素及屬性都對應已定義的DOM(Document Object Model,文檔對象模型)對象。相關腳本被封裝在<script>元素中。
這意味著如果web服務器允許用戶上傳任意SVG圖像,就存在XSS(跨站腳本)安全風險。如下所示,我們將腳本存放在圖像中:
圖3. xss.svg代碼片段
將該圖像保存為xss.svg,然后直接打開,如下圖所示:
圖4. 直接訪問該文件觸發XSS
如果將該文件鏈接到某個HTML頁面,訪問該頁面也可以觸發,如下圖所示:
圖5. 通過鏈接文件觸發XSS
JavaScript代碼會在瀏覽器上下文中執行,這意味著攻擊者可以使用該文件執行惡意行為,比如竊取用戶隱私信息等。
HTML注入
在某些情況下,XSS payload會被服務端過濾,然而我們依然能夠通過SVG圖像的特定功能來注入HTML代碼。如前文所述,SVG是基于XML的一種矢量圖,因此我們無法簡單將HTML內容放入其中,不然會破壞XML的語法。
為了避免這種情況,SVG提供了一個foreignObject元素,可以用來包含來自其他XML命名空間的元素。在瀏覽器上下文中,這部分數據很可能采用(X)HTML形式。
來看一下html.svg圖像:
圖6. html.svg代碼片段
當我們在foreignObject內添加一個body標簽以及XHTML命名空間時,可以使用xmlns屬性來聲明命名空間。采用這種方式,瀏覽器會將body標簽及其所有子標簽解析為屬于XHTML的元素。因此,我們可以將來自SVG的任意XHTML代碼渲染到頁面中:
圖7. HTML注入漏洞
這種方式可以運行任意HTML代碼,意味著我們可以簡單從SVG圖像中發起類似釣魚、繞過同源策略、CSRF之類的攻擊。
XML實體:Billion Laughs Attack
由于SVG是基于XML的矢量圖,因此可以支持Entity(實體)功能。Entity可以用來定義特殊字符的快捷方式,也可以聲明成內部或外部實體。
我們可以通過如下方式聲明內部Entity:
<!ENTITY entity-name "entity-value">
通過如下方式聲明外部Entity:
<!ENTITY entity-name SYSTEM "URI/URL">
如果解析文件的XML解析器存在脆弱性,那么我們就可以濫用外部Entity功能來泄露內部數據。由于現在大家主要使用的都是現代瀏覽器,因此我們假設可用的解析器都經過fuzzer的嚴格測試,因此沒那么容易被攻擊。在這個前提下,這里我們主要討論如何濫用內部Entity。
entity.svg的內部實現如下所示:
圖8. entity.svg代碼片段
如上圖所示,我們在第2行定義lab這個Entity,然后在SVG元素中調用該實體。結果如圖9所示:
圖9. lab實體被加載到頁面
一切非常順利,來嘗試另一個例子:entity_2.svg,如下圖所示:
圖10. entity_2.svg代碼片段
結果如下:
圖11. lab2實體被加載到頁面
如上圖所示,這里的文本內容被重復渲染,這表明我們可以使用Entity標簽發起“ Billion Laughs ”攻擊。
“ Billion Laughs ”攻擊是一種DoS(拒絕服務)攻擊,目標是XML文檔解析器。這種攻擊也被稱之為XML炸彈或者指數實體攻擊。
圖12. billion_laughs.svg代碼片段
我們的瀏覽器在解析這個 billion_laughs.svg數據時,只花了4~5秒就能正常響應。這是因為大多數現代瀏覽器已經能夠能應付這種攻擊,可以在渲染過程中解決該問題,因此不會造成安全風險。
拒絕服務:新型SVG “Billion Laughs”攻擊
在上一節中,我們發現“ Billion Laughs ”攻擊可以延緩瀏覽器的處理速度,瀏覽器需要4~5秒才能應付該攻擊。不幸的是,攻擊者還可以通過SVG圖像,發起另一種“ Billion Laughs ”攻擊,繞過這些防御措施。
這一次我們使用xlink:href來代替XML Entity。來看一下 xlink_laughs.svg所使用的payload:
圖13. xlink_laughs.svg代碼片段
xlink:href屬性以IRI(國際資源標識)方式定義了對某個資源的引用,該鏈接的具體含義需根據使用該鏈接的每個元素的上下文來決定。
<use>元素從SVG文檔中獲取節點,然后將其復制到其他位置。
我們現在a0中定義circle元素,然后在a1、a2、a3……中通過xlink:href屬性調用<use>元素,通過這種方式反復克隆circle。結果如下圖所示:
圖14. 在解析惡意SVG時,通過xlink:href發起“ Billion Laugh”攻擊
需要注意的是,在最壞的情況下,大多數現代瀏覽器在嘗試解析網站上的這張SVG圖像時可能會發生崩潰,或者至少會出現無響應情況。
有趣的是,我們在測試某些開源SVG/XML過濾器時,發現這些過濾器并不能正確捕捉到圖13所示的SVG圖像。因此,這種錯誤格式的SVG圖像也可能造成DoS效果。
0x03 總結
SVG圖像更像HTML,而不單單是一張簡單的圖像。因此,我們建議web開發者盡可能不要以對象或者iframe形式加載任何SVG。Web管理員同樣應當限制可以上傳到站點的文件類型。
此外,任何不可信的SVG圖像在被上傳到服務端前都必須經過過濾處理,可以采取如下操作:
我們使用一些瀏覽器來直接打開這些惡意SVG文件,對比結果如下圖所示:
大家可以訪問我們的Github倉庫下載本文使用的SVG樣本。
0x04 參考資料
[1] W3C, “Scalable Vector Graphics” https://www.w3.org/TR/SVG2/ (02 September, 2019)
[2] OWASP, “The Image that called me” https://www.owasp.org/images/0/03/Mario_Heiderich_OWASP_Sweden_The_image_that_called_me.pdf (02 September, 2019)
[3] Blackhat, “Exploiting Browsers without Image Parsing Bugs” https://www.blackhat.com/docs/us-14/materials/us-14-DeGraaf-SVG-Exploiting-Browsers-Without-Image-Parsing-Bugs.pdf (02 September, 2019)
原文鏈接:https://www.anquanke.com/post/id/190651
*請認真填寫需求信息,我們會在24小時內與您取得聯系。