Skip to content

Commit 95ba399

Browse files
authored
Merge pull request #1554 from WebFuzzing/http-invalid-location
http oracle invalid location
2 parents c77e797 + bd4abdc commit 95ba399

15 files changed

Lines changed: 595 additions & 3 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.base
2+
3+
import org.springframework.boot.SpringApplication
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
6+
import org.springframework.http.ResponseEntity
7+
import org.springframework.web.bind.annotation.GetMapping
8+
import org.springframework.web.bind.annotation.PathVariable
9+
import org.springframework.web.bind.annotation.PutMapping
10+
import org.springframework.web.bind.annotation.RequestMapping
11+
import org.springframework.web.bind.annotation.RestController
12+
13+
@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
14+
@RequestMapping(path = ["/api/resources"])
15+
@RestController
16+
open class HttpInvalidLocationApplication {
17+
18+
companion object {
19+
@JvmStatic
20+
fun main(args: Array<String>) {
21+
SpringApplication.run(HttpInvalidLocationApplication::class.java, *args)
22+
}
23+
24+
private val data = mutableMapOf<Int, String>()
25+
26+
fun reset(){
27+
data.clear()
28+
}
29+
}
30+
31+
32+
@GetMapping(path = ["/{id}"])
33+
open fun get(@PathVariable("id") id: Int): ResponseEntity<String> {
34+
val value = data[id] ?: return ResponseEntity.status(404).build()
35+
return ResponseEntity.status(200).body(value)
36+
}
37+
38+
39+
@PutMapping(path = ["/{id}"])
40+
open fun put(
41+
@PathVariable("id") id: Int
42+
): ResponseEntity<Any> {
43+
44+
val isNew = !data.containsKey(id)
45+
data[id] = "$id"
46+
47+
// bug: Location header points to a different id than the one
48+
// actually stored, so a follow-up GET on it will return 404
49+
50+
val status = if (isNew) 201 else 200
51+
return ResponseEntity.status(status)
52+
.header("Location", "/api/resources/${id + 1000}")
53+
.build()
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.fullpath
2+
3+
import org.springframework.boot.SpringApplication
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
6+
import org.springframework.http.ResponseEntity
7+
import org.springframework.web.bind.annotation.GetMapping
8+
import org.springframework.web.bind.annotation.PathVariable
9+
import org.springframework.web.bind.annotation.PutMapping
10+
import org.springframework.web.bind.annotation.RequestMapping
11+
import org.springframework.web.bind.annotation.RestController
12+
import org.springframework.web.servlet.support.ServletUriComponentsBuilder
13+
14+
@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
15+
@RequestMapping(path = ["/api/resources"])
16+
@RestController
17+
open class HttpInvalidLocationFullPathApplication {
18+
19+
companion object {
20+
@JvmStatic
21+
fun main(args: Array<String>) {
22+
SpringApplication.run(HttpInvalidLocationFullPathApplication::class.java, *args)
23+
}
24+
25+
private val data = mutableMapOf<Int, String>()
26+
27+
fun reset(){
28+
data.clear()
29+
}
30+
}
31+
32+
33+
@GetMapping(path = ["/{id}"])
34+
open fun get(@PathVariable("id") id: Int): ResponseEntity<String> {
35+
val value = data[id] ?: return ResponseEntity.status(404).build()
36+
return ResponseEntity.status(200).body(value)
37+
}
38+
39+
40+
@PutMapping(path = ["/{id}"])
41+
open fun put(
42+
@PathVariable("id") id: Int
43+
): ResponseEntity<Any> {
44+
45+
val isNew = !data.containsKey(id)
46+
data[id] = "$id"
47+
48+
val location = ServletUriComponentsBuilder
49+
.fromCurrentContextPath()
50+
.path("/api/resources/{id}")
51+
.buildAndExpand(id + 1000)
52+
.toUri()
53+
54+
val status = if (isNew) 201 else 200
55+
return ResponseEntity.status(status)
56+
.header("Location", location.toString())
57+
.build()
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.locationget
2+
3+
import org.springframework.boot.SpringApplication
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
6+
import org.springframework.http.ResponseEntity
7+
import org.springframework.web.bind.annotation.GetMapping
8+
import org.springframework.web.bind.annotation.PathVariable
9+
import org.springframework.web.bind.annotation.PutMapping
10+
import org.springframework.web.bind.annotation.RequestMapping
11+
import org.springframework.web.bind.annotation.RestController
12+
13+
@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
14+
@RequestMapping(path = ["/api/resources"])
15+
@RestController
16+
open class HttpInvalidLocationGetApplication {
17+
18+
companion object {
19+
@JvmStatic
20+
fun main(args: Array<String>) {
21+
SpringApplication.run(HttpInvalidLocationGetApplication::class.java, *args)
22+
}
23+
24+
fun reset(){
25+
}
26+
}
27+
28+
29+
@GetMapping(path = ["/{id}"])
30+
open fun get(@PathVariable("id") id: Int): ResponseEntity<String> {
31+
return ResponseEntity.status(200).header("Location", "/api/resources/${id + 1000}/notfound").body("Resource with id $id")
32+
}
33+
34+
@GetMapping(path = ["/{id}/notfound"])
35+
open fun getNotFound(@PathVariable("id") id: Int): ResponseEntity<String> {
36+
return ResponseEntity.status(404).body("Not found")
37+
}
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.notvalidpath
2+
3+
import org.springframework.boot.SpringApplication
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
6+
import org.springframework.http.ResponseEntity
7+
import org.springframework.web.bind.annotation.GetMapping
8+
import org.springframework.web.bind.annotation.PathVariable
9+
import org.springframework.web.bind.annotation.PutMapping
10+
import org.springframework.web.bind.annotation.RequestMapping
11+
import org.springframework.web.bind.annotation.RestController
12+
13+
@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
14+
@RequestMapping(path = ["/api/resources"])
15+
@RestController
16+
open class HttpInvalidLocationNotValidApplication {
17+
18+
companion object {
19+
@JvmStatic
20+
fun main(args: Array<String>) {
21+
SpringApplication.run(HttpInvalidLocationNotValidApplication::class.java, *args)
22+
}
23+
24+
private val data = mutableMapOf<Int, String>()
25+
26+
fun reset(){
27+
data.clear()
28+
}
29+
}
30+
31+
32+
@GetMapping(path = ["/{id}"])
33+
open fun get(@PathVariable("id") id: Int): ResponseEntity<String> {
34+
val value = data[id] ?: return ResponseEntity.status(404).build()
35+
return ResponseEntity.status(200).body(value)
36+
}
37+
38+
39+
@PutMapping(path = ["/{id}"])
40+
open fun put(
41+
@PathVariable("id") id: Int
42+
): ResponseEntity<Any> {
43+
44+
val isNew = !data.containsKey(id)
45+
data[id] = "$id"
46+
47+
// bug: Location header points to a different id than the one
48+
// actually stored, so a follow-up GET on it will return 404
49+
50+
val status = if (isNew) 201 else 200
51+
return ResponseEntity.status(status)
52+
.header("Location", "/somePathThatDoesNotExist")
53+
.build()
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation
2+
3+
import com.foo.rest.examples.spring.openapi.v3.SpringController
4+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.base.HttpInvalidLocationApplication
5+
6+
7+
class HttpInvalidLocationController: SpringController(HttpInvalidLocationApplication::class.java){
8+
9+
override fun resetStateOfSUT() {
10+
HttpInvalidLocationApplication.reset()
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.fullpath
2+
3+
import com.foo.rest.examples.spring.openapi.v3.SpringController
4+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.base.HttpInvalidLocationApplication
5+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.notvalidpath.HttpInvalidLocationNotValidApplication
6+
7+
8+
class HttpInvalidLocationFullPathController: SpringController(HttpInvalidLocationFullPathApplication::class.java){
9+
10+
override fun resetStateOfSUT() {
11+
HttpInvalidLocationFullPathApplication.reset()
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.locationget
2+
3+
import com.foo.rest.examples.spring.openapi.v3.SpringController
4+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.base.HttpInvalidLocationApplication
5+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.locationget.HttpInvalidLocationGetApplication
6+
7+
8+
class HttpInvalidLocationGetController: SpringController(HttpInvalidLocationGetApplication::class.java){
9+
10+
override fun resetStateOfSUT() {
11+
HttpInvalidLocationGetApplication.reset()
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.notvalidpath
2+
3+
import com.foo.rest.examples.spring.openapi.v3.SpringController
4+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.base.HttpInvalidLocationApplication
5+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.notvalidpath.HttpInvalidLocationNotValidApplication
6+
7+
8+
class HttpInvalidLocationNotValidController: SpringController(HttpInvalidLocationNotValidApplication::class.java){
9+
10+
override fun resetStateOfSUT() {
11+
HttpInvalidLocationNotValidApplication.reset()
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.evomaster.e2etests.spring.openapi.v3.httporacle.invalidlocation
2+
3+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.HttpInvalidLocationController
4+
import org.evomaster.core.problem.enterprise.DetectedFaultUtils
5+
import org.evomaster.core.problem.enterprise.ExperimentalFaultCategory
6+
import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase
7+
import org.junit.jupiter.api.Assertions.assertEquals
8+
import org.junit.jupiter.api.Assertions.assertTrue
9+
import org.junit.jupiter.api.BeforeAll
10+
import org.junit.jupiter.api.Test
11+
12+
class HttpInvalidLocationEMTest : SpringTestBase(){
13+
14+
companion object {
15+
@BeforeAll
16+
@JvmStatic
17+
fun init() {
18+
initClass(HttpInvalidLocationController())
19+
}
20+
}
21+
22+
23+
@Test
24+
fun testRunEM() {
25+
26+
runTestHandlingFlakyAndCompilation(
27+
"HttpInvalidLocationEM",
28+
20
29+
) { args: MutableList<String> ->
30+
31+
setOption(args, "security", "false")
32+
setOption(args, "schemaOracles", "false")
33+
setOption(args, "httpOracles", "true")
34+
setOption(args, "useExperimentalOracles", "true")
35+
36+
val solution = initAndRun(args)
37+
38+
assertTrue(solution.individuals.size >= 1)
39+
40+
val faults = DetectedFaultUtils.getDetectedFaultCategories(solution)
41+
assertTrue({ ExperimentalFaultCategory.HTTP_INVALID_LOCATION in faults })
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.evomaster.e2etests.spring.openapi.v3.httporacle.invalidlocation
2+
3+
import com.foo.rest.examples.spring.openapi.v3.httporacle.invalidlocation.fullpath.HttpInvalidLocationFullPathController
4+
import org.evomaster.core.problem.enterprise.DetectedFaultUtils
5+
import org.evomaster.core.problem.enterprise.ExperimentalFaultCategory
6+
import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase
7+
import org.junit.jupiter.api.Assertions.assertTrue
8+
import org.junit.jupiter.api.BeforeAll
9+
import org.junit.jupiter.api.Test
10+
11+
class HttpInvalidLocationFullPathEMTest : SpringTestBase(){
12+
13+
companion object {
14+
@BeforeAll
15+
@JvmStatic
16+
fun init() {
17+
initClass(HttpInvalidLocationFullPathController())
18+
}
19+
}
20+
21+
22+
@Test
23+
fun testRunEM() {
24+
25+
runTestHandlingFlakyAndCompilation(
26+
"HttpInvalidLocationFullPathEM",
27+
20
28+
) { args: MutableList<String> ->
29+
30+
setOption(args, "security", "false")
31+
setOption(args, "schemaOracles", "false")
32+
setOption(args, "httpOracles", "true")
33+
setOption(args, "useExperimentalOracles", "true")
34+
35+
val solution = initAndRun(args)
36+
37+
assertTrue(solution.individuals.size >= 1)
38+
39+
val faults = DetectedFaultUtils.getDetectedFaultCategories(solution)
40+
assertTrue({ ExperimentalFaultCategory.HTTP_INVALID_LOCATION in faults })
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)