- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
要求:当我将以下请求传递给我的应用程序时,
1)如何对这种存在风险的输入xml进行XML验证
2) 如何在 libxml2 中禁用 XXE,即不应该解析 ENTITY 字段
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY foo SYSTEM "file:///etc/issue">
]><TRANSACTION>
<FUNCTION_TYPE>LINE_ITEM</FUNCTION_TYPE>
<COMMAND>ADD</COMMAND>
<COUNTER>3</COUNTER>
<MAC>qof2EtycqT9YMcmOfKowpyXVbRpgM/7rncS3liK4JOs=</MAC>
<MAC_LABEL>P_206</MAC_LABEL>
<RUNNING_TAX_AMOUNT>0.00</RUNNING_TAX_AMOUNT>
<RUNNING_TRANS_AMOUNT>1.00</RUNNING_TRANS_AMOUNT>
<LINE_ITEMS>
<MERCHANDISE>
<LINE_ITEM_ID>1</LINE_ITEM_ID>
<DESCRIPTION>&foo;</DESCRIPTION>
<QUANTITY>1</QUANTITY>
<UNIT_PRICE>5.00</UNIT_PRICE>
<EXTENDED_PRICE>5.00</EXTENDED_PRICE>
</MERCHANDISE>
</LINE_ITEMS>
</TRANSACTION>
据我所知,从 libxml2 2.9 版开始,XXE 已默认禁用。但我们目前使用的是 2.7.7 版本。
Enum xmlParserOption 不应在 libxml2 中定义以下选项:
XML_PARSE_NOENT:扩展实体并用替换文本替换它们XML_PARSE_DTDLOAD:加载外部DTD
直到现在,我一直在使用 xmlParseMemory
函数来解析内存中的 XML block 并构建树。此函数不采用任何参数来设置 xmlParserOption。
然后我更改为 xmlReadMemory
函数,它也与 xmlParseMemory
函数做同样的事情,但采用不同的参数。
docPtr = xmlReadMemory(szXMLMsg, iLen, "noname.xml", NULL, XML_PARSE_RECOVER);
我仍然观察到 ENTITY 字段正在被解析。谁能帮帮我?如果您需要更多信息,请告诉我。
感谢您的宝贵时间。
问候
普拉文
最佳答案
如果您不指定XML_PARSE_NOENT
,ENTITY
声明仍会被解析,但实体不会被替换。此外,文件 /etc/issue
不会打开,您可以使用 strace
进行验证。因此,为了防止 XXE,您只需不传递 XML_PARSE_NOENT
解析器选项即可。
选项的名称有点误导,XML_PARSE_NOENT
表示不应在已解析的文档中创建任何实体节点。因此,每个实体都被扩展了。更好的名称应类似于 XML_PARSE_EXPAND_ENTITIES
。
如果你真的想确定或者你想扩展实体来细粒度地控制要加载的 URL,你可以使用 xmlSetExternalEntityLoader
安装你自己的外部实体加载器。 .如果您的处理程序总是返回 NULL,那么您就安全了。但请注意,外部实体加载器用于加载各种外部资源,因此完全禁用它可能会破坏其他内容(例如 XIncludes 或 XSLT 样式表)。
编辑: 我不知道为什么在您的案例中实体被替换了。这是一个测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
static xmlNodePtr
find_node(xmlNodePtr parent, const char *name) {
for (xmlNodePtr cur = parent->children; cur != NULL; cur = cur->next) {
if (cur->type == XML_ELEMENT_NODE
&& xmlStrcmp(cur->name, (const xmlChar*)name) == 0
) {
return cur;
}
}
fprintf(stderr, "Element '%s' not found\n", name);
abort();
return NULL;
}
int
main(int argc, char **argv) {
static const char buf[] =
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE foo [\n"
"<!ENTITY foo SYSTEM \"file:///etc/issue\">\n"
"]><TRANSACTION>\n"
"<FUNCTION_TYPE>LINE_ITEM</FUNCTION_TYPE>\n"
"<COMMAND>ADD</COMMAND>\n"
"<COUNTER>3</COUNTER>\n"
"<MAC>qof2EtycqT9YMcmOfKowpyXVbRpgM/7rncS3liK4JOs=</MAC>\n"
"<MAC_LABEL>P_206</MAC_LABEL>\n"
"<RUNNING_TAX_AMOUNT>0.00</RUNNING_TAX_AMOUNT>\n"
"<RUNNING_TRANS_AMOUNT>1.00</RUNNING_TRANS_AMOUNT>\n"
"<LINE_ITEMS>\n"
"<MERCHANDISE>\n"
"<LINE_ITEM_ID>1</LINE_ITEM_ID>\n"
"<DESCRIPTION>&foo;</DESCRIPTION>\n"
"<QUANTITY>1</QUANTITY>\n"
"<UNIT_PRICE>5.00</UNIT_PRICE>\n"
"<EXTENDED_PRICE>5.00</EXTENDED_PRICE>\n"
"</MERCHANDISE>\n"
"</LINE_ITEMS>\n"
"</TRANSACTION>\n";
xmlDocPtr doc = xmlReadMemory(buf, sizeof(buf), "noname.xml", NULL,
XML_PARSE_RECOVER);
xmlNodePtr trans = find_node((xmlNodePtr)doc, "TRANSACTION");
xmlNodePtr items = find_node(trans, "LINE_ITEMS");
xmlNodePtr merch = find_node(items, "MERCHANDISE");
xmlNodePtr desc = find_node(merch, "DESCRIPTION");
for (xmlNodePtr cur = desc->children; cur != NULL; cur = cur->next) {
if (cur->type == XML_ENTITY_REF_NODE) {
printf("entity ref node\n");
}
else {
printf("other node of type: %d\n", cur->type);
}
}
xmlFreeDoc(doc);
return 0;
}
如果我编译
gcc -std=c99 -O2 -I/usr/include/libxml2 so.c -lxml2 -o so
然后运行,结果是
entity ref node
关于c - 如何在 libxml2in C 中禁用 XXE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22930043/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!