java - 如何保护球衣服务器上的 xml 请求?
问题描述
我目前有一个使用 jersey-server 1.1 框架创建的简单 xml 端点(示例)。它使用以下表示法使用和生成 XML:
@POST
@Path("/post")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response getEmployee(Employee employee) {
return Response.status(Status.OK).entity(employee).build();
}
但是端点容易受到 XXE 攻击。(示例)它也可以让我的服务器使用这个符号来请求任何端点......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY % a SYSTEM "file:///etc/passwd">
%a;
]>
我想要一种保护服务器的方法,并且不允许它调用其他服务器/向攻击者提供文件。
有没有办法做到这一点,因为包括 XML 读取在内的所有内容都来自框架本身?@Consumes(MediaType.APPLICATION_XML)
我认为我可以做到这一点的唯一方法是以某种方式在请求正文上使用正则表达式和过滤器?阻止DOCTYPE
,请求并返回错误SYSTEM
,ENTITY
但我想知道是否有更简单的方法来执行此操作并覆盖的默认行为@Consumes(MediaType.APPLICATION_XML)
?
解决方案
我将仅解决 XXE 问题,因为该问题对于要解决的其他特定身份验证/授权问题并不完全清楚。
从Blaise 使用基本 JAXB 防止 XXE 的方法开始,需要做的是获得对提供的 XML 的较低级别的访问。好东西泽西开箱即用地支持这一点。一种方法是Employee
用StreamSource
.
首先掌握现有的
JAXBContext
:private final @Context Providers providers; //full list of all providers available
修改您的界面以接受 a
StreamSource
以便您可以访问原始传入 XML:@POST @Path("/post") @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public Response getEmployee(StreamSource employeeStreamSource)
配置 JAXBContext 解组器以忽略 DTD:
public Response getEmployee(StreamSource employeeStreamSource){ //we try to get a hold of the JAXBContext ContextResolver<JAXBContext> jaxbResolver = provider.getContextResolver(JAXBContext.class, MediaType.APPLICATION_XML_TYPE); JAXBContext jaxbContext= null; if(null != jaxbResolver) { jaxbContext = jaxbResolver.getContext(Employee.class); } if(null == jaxbContext) { jaxbContext = JAXBContext.newInstance(Employee.class); } XMLInputFactory xif = XMLInputFactory.newFactory(); xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); //Don't blindly parse entities xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); //suppress DTD XMLStreamReader xsr = xif.createXMLStreamReader(employeeStreamSource); //beging parsing incoming XML Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Employee employee= (Employee) unmarshaller.unmarshal(xsr); //manually unmarshal return Response.status(Status.OK).entity(employee).build(); }
推荐阅读
- javascript - 以 HTML 格式获取网络摄像头视频并通过 socketio 发送到烧瓶服务器
- cassandra - 不同 Cassandra 版本之间的多 DC 复制
- python - 引用 pandas to_csv
- java - Android ImageButton在更改片段后停止触发
- html - Why browser cannot display url that downloads base64
- go - RLock 已评估但未使用!为什么会出现这样的错误?
- php - 将日期时间保存到 DB codeigniter 总是 1970
- kotlin - Beam JdbcIO.readAll 似乎没有返回结果
- java - 在 Android 中结合 OpenGL ES 渲染和 UI 元素
- python - 替换 torch.cdist() 函数以消除 GPU 内存不足运行时错误