jeudi 26 avril 2018

Testing Scala Play behaviour when posting XXE XML

I am trying to test my Scala Play application through a Unit Test, but the behaviour I am experiencing in my test is different to the behaviour I experience when sending a POST request to my route through Postman.

I am trying to test that the Scala Play application will handle any XML which contains DTD, as I am trying to prove that I am protected against XXE attacks. According to James Roper, Play was patched to reject XML containing DTD by default due to potential vulnerabilities.

My problem is that when I hit my route, I get a 400: Bad Request error as expected due to the Play application catching the DTD. However, when I try to hit the route through my Unit Tests, I get a 200: Ok, so the tests are behaving differently to the actual Play Application.

Here is my Controller code:

def handlePost(): Action[NodeSeq] = Action.async(parse.xml) {
  implicit request =>
    Future.successful(Ok(request.body))
}

At some point behind the scenes, POSTing to this Controller seems to fail at Action.async(parse.xml). I have also swapped out request.body with some other random XML to verify that it fails before even touching the request body in my code.

My test case:

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
    }
  }
}

I have two questions:

  1. Does anyone know how to influence my tests to behave more like my application?

OR

  1. I am aware that XML.loadString is also vulnerable and am aware of how to fix it. Is my test misbehaving at this line, and if so, is there an alternative way to blindly pass XML to my test method without evaluating it and interpreting the DTD?

Aucun commentaire:

Enregistrer un commentaire