Тестирование поведения Scala Play при публикации DTD / XXE XML - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь протестировать свое приложение Scala Play с помощью юнит-теста, но поведение, которое я испытываю в своем тесте, отличается от поведения, которое я испытываю при отправке запроса POST на мой маршрут через Postman.

Я пытаюсь проверить, что приложение Scala Play будет обрабатывать любой XML, содержащий DTD, так как я пытаюсь доказать, что я защищен от XXE-атак. Согласно Джеймсу Роперу , Play был исправлен для отклонения XML, содержащего DTD по умолчанию из-за потенциальных уязвимостей.

Моя проблема в том, что когда я нажимаю на свой маршрут, я получаю ошибку 400: Bad Request, как и ожидалось, из-за того, что приложение Play перехватывает DTD. Однако, когда я пытаюсь пройти маршрут через мои юнит-тесты, я получаю 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
    }
  }
}

У меня два вопроса:

  1. Кто-нибудь знает, как повлиять на мои тесты, чтобы они больше походили на мое приложение?

OR

  1. Я знаю, что XML.loadString также уязвим и знаю, как это исправить. Мой тест ведет себя неправильно в этой строке, и если так, есть ли альтернативный способ слепой передачи XML в мой метод теста без его оценки и интерпретации DTD?

1 Ответ

0 голосов
/ 26 апреля 2018

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