者:公子
出处: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小时内与您取得联系。