Skip to content

Commit

Permalink
fix(mpt-v1): prevent leak of information through template resolution …
Browse files Browse the repository at this point in the history
…endpoint (#3706) (#3708)

(cherry picked from commit ef080b1)

Co-authored-by: Daniel Peach <daniel.peach@armory.io>
  • Loading branch information
mergify[bot] and danielpeach committed Jun 1, 2020
1 parent 6881ee1 commit e2475fe
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 0 deletions.
6 changes: 6 additions & 0 deletions orca-web/orca-web.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

apply from: "$rootDir/gradle/groovy.gradle"
apply from: "$rootDir/gradle/kotlin.gradle"
apply plugin: 'io.spinnaker.package'

ext {
Expand Down Expand Up @@ -92,6 +93,11 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.hamcrest:hamcrest-core:1.3")
testImplementation("com.netflix.spinnaker.keiko:keiko-mem:$keikoVersion")

testImplementation(project(":orca-api-tck"))
testImplementation("dev.minutest:minutest")
testImplementation("io.strikt:strikt-core")
testImplementation("io.mockk:mockk")
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ package com.netflix.spinnaker.orca.controllers

import com.netflix.spinnaker.kork.web.exceptions.InvalidRequestException
import com.netflix.spinnaker.orca.pipelinetemplate.PipelineTemplateService
import com.netflix.spinnaker.orca.pipelinetemplate.exceptions.TemplateLoaderException
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.converter.PipelineTemplateConverter
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.TemplateConfiguration.TemplateSource
import groovy.util.logging.Slf4j
import javax.servlet.http.HttpServletResponse
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
Expand Down Expand Up @@ -51,4 +55,10 @@ class PipelineTemplateController {
String convertPipelineToPipelineTemplate(@RequestBody Map<String, Object> pipeline) {
new PipelineTemplateConverter().convertToPipelineTemplate(pipeline)
}

@ExceptionHandler(TemplateLoaderException)
static void handleTemplateLoaderException(TemplateLoaderException tle, HttpServletResponse response) {
log.error("Could not load pipeline template from source: {}", tle.message)
response.sendError(HttpStatus.BAD_REQUEST.value(), "Could not load pipeline template from source")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2020 Armory, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.orca.controllers

import com.netflix.spinnaker.orca.api.test.OrcaFixture
import com.netflix.spinnaker.orca.api.test.orcaFixture
import com.sun.net.httpserver.HttpServer
import dev.minutest.junit.JUnit5Minutests
import dev.minutest.rootContext
import java.net.InetSocketAddress
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
import strikt.api.expect
import strikt.assertions.isNotNull

class PipelineTemplateServiceSpec : JUnit5Minutests {

fun tests() = rootContext<Fixture> {
orcaFixture {
Fixture()
}

context("pipeline template controller") {
test("does not leak information about the endpoints it searches if it can't deserialize the response into a template") {
val resp = subject.get("/pipelineTemplate") {
param("source", "http://localhost:${server.address.port}")
}.andReturn().response

expect {
that(resp.errorMessage)
.isNotNull()
.assert("should not include the content of the private endpoint") {
when {
it.contains("Private message - don't read me!") -> fail()
else -> pass()
}
}
}
}
}
}

@AutoConfigureMockMvc
private inner class Fixture : OrcaFixture() {

@Autowired
lateinit var subject: MockMvc

var server: HttpServer = HttpServer.create(InetSocketAddress(0), 0).apply {
createContext("/") {
it.responseHeaders.set("Content-Type", "text/plain")
it.sendResponseHeaders(200, 0)
it.responseBody.write("Private message - don't read me!".toByteArray())
it.responseBody.close()
}
start()
}
}
}

0 comments on commit e2475fe

Please sign in to comment.