发布时测试 Scala Play 行为 DTD/XXE XML
Testing Scala Play behaviour when posting DTD/XXE XML
我正在尝试通过单元测试来测试我的 Scala Play 应用程序,但是我在测试中遇到的行为与我在通过 Postman 向我的路由发送 POST 请求时遇到的行为不同。
我正在尝试测试 Scala Play 应用程序是否可以处理任何包含 DTD 的 XML,因为我正在尝试证明我可以免受 XXE 攻击。根据 James Roper,Play 被修补为拒绝 XML 由于潜在漏洞而默认包含 DTD。
我的问题是,当我到达我的路线时,由于 Play 应用程序捕获 DTD,我收到了预期的 400: Bad Request
错误。但是,当我尝试通过我的单元测试走路线时,我得到了 200: Ok
,因此测试的行为与实际的 Play 应用程序不同。
这是我的控制器代码:
def handlePost(): Action[NodeSeq] = Action.async(parse.xml) {
implicit request =>
Future.successful(Ok(request.body))
}
在幕后的某个时候,POST连接到此控制器似乎在 Action.async(parse.xml)
失败。我还将 request.body
换成其他一些随机 XML 以验证它是否在我的代码中触及请求正文之前失败。
我的测试用例:
class RoutesSpec extends PlaySpec with GuiceOneAppPerSuite {
"The POST route" must {
"not handle XXE XML" in {
val xml: Elem = scala.xml.XML.loadString(
"""<?xml version="1.0" encoding="utf-8"?>
|<!DOCTYPE foo [
|<!ELEMENT foo (bar)>
| <!ELEMENT bar (#PCDATA)>
|]>
|<foo>
| <bar>string</bar>
|</foo>
""".stripMargin)
val Some(result) = route(app, FakeRequest(POST_REQUEST, "/my-route")
.withXmlBody(xml))
status(result) mustEqual 400 // currently returns 200
}
}
}
我有两个问题:
- 有谁知道如何影响我的测试,使其表现得更像我的应用程序?
或
- 我知道
XML.loadString
也容易受到攻击,并且知道如何修复它。我的测试是否在这一行行为不当,如果是这样,是否有另一种方法可以盲目地将 XML 传递给我的测试方法而不对其进行评估和解释 DTD?
scala.xml.Unparsed
似乎可以完成这项工作。我认为是 scala.xml.XML.loadString
中的漏洞让我感到困惑。
class RoutesSpec extends PlaySpec with GuiceOneAppPerSuite {
"The POST route" must {
"not handle XXE XML" in {
val xml = scala.xml.Unparsed(
"""<?xml version="1.0" encoding="utf-8"?>
|<!DOCTYPE foo [
|<!ELEMENT foo (bar)>
| <!ELEMENT bar (#PCDATA)>
|]>
|<foo>
| <bar>string</bar>
|</foo>
""".stripMargin)
val Some(result) = route(app, FakeRequest(POST_REQUEST, "/my-route")
.withXmlBody(xml))
status(result) mustEqual 400
contentAsString(result) mustBe """{"statusCode":400,"message":"bad request"}"""
}
}
}
我正在尝试通过单元测试来测试我的 Scala Play 应用程序,但是我在测试中遇到的行为与我在通过 Postman 向我的路由发送 POST 请求时遇到的行为不同。
我正在尝试测试 Scala Play 应用程序是否可以处理任何包含 DTD 的 XML,因为我正在尝试证明我可以免受 XXE 攻击。根据 James Roper,Play 被修补为拒绝 XML 由于潜在漏洞而默认包含 DTD。
我的问题是,当我到达我的路线时,由于 Play 应用程序捕获 DTD,我收到了预期的 400: Bad Request
错误。但是,当我尝试通过我的单元测试走路线时,我得到了 200: Ok
,因此测试的行为与实际的 Play 应用程序不同。
这是我的控制器代码:
def handlePost(): Action[NodeSeq] = Action.async(parse.xml) {
implicit request =>
Future.successful(Ok(request.body))
}
在幕后的某个时候,POST连接到此控制器似乎在 Action.async(parse.xml)
失败。我还将 request.body
换成其他一些随机 XML 以验证它是否在我的代码中触及请求正文之前失败。
我的测试用例:
class RoutesSpec extends PlaySpec with GuiceOneAppPerSuite {
"The POST route" must {
"not handle XXE XML" in {
val xml: Elem = scala.xml.XML.loadString(
"""<?xml version="1.0" encoding="utf-8"?>
|<!DOCTYPE foo [
|<!ELEMENT foo (bar)>
| <!ELEMENT bar (#PCDATA)>
|]>
|<foo>
| <bar>string</bar>
|</foo>
""".stripMargin)
val Some(result) = route(app, FakeRequest(POST_REQUEST, "/my-route")
.withXmlBody(xml))
status(result) mustEqual 400 // currently returns 200
}
}
}
我有两个问题:
- 有谁知道如何影响我的测试,使其表现得更像我的应用程序?
或
- 我知道
XML.loadString
也容易受到攻击,并且知道如何修复它。我的测试是否在这一行行为不当,如果是这样,是否有另一种方法可以盲目地将 XML 传递给我的测试方法而不对其进行评估和解释 DTD?
scala.xml.Unparsed
似乎可以完成这项工作。我认为是 scala.xml.XML.loadString
中的漏洞让我感到困惑。
class RoutesSpec extends PlaySpec with GuiceOneAppPerSuite {
"The POST route" must {
"not handle XXE XML" in {
val xml = scala.xml.Unparsed(
"""<?xml version="1.0" encoding="utf-8"?>
|<!DOCTYPE foo [
|<!ELEMENT foo (bar)>
| <!ELEMENT bar (#PCDATA)>
|]>
|<foo>
| <bar>string</bar>
|</foo>
""".stripMargin)
val Some(result) = route(app, FakeRequest(POST_REQUEST, "/my-route")
.withXmlBody(xml))
status(result) mustEqual 400
contentAsString(result) mustBe """{"statusCode":400,"message":"bad request"}"""
}
}
}