Skip to content

Commit dfdf5e1

Browse files
authored
Merge branch 'master' into phg/objectMapper-v2
2 parents 9f3fb0c + 41efbab commit dfdf5e1

File tree

59 files changed

+1024
-266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1024
-266
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,11 @@ Existing open-source tools for REST API fuzzing, with at least 100 stars on GitH
227227
[Fuzz-lightyear](https://github.com/Yelp/fuzz-lightyear),
228228
[ResTest](https://github.com/isa-group/RESTest),
229229
[Restler](https://github.com/microsoft/restler-fuzzer),
230+
[Schemathesis](https://github.com/schemathesis/schemathesis)
230231
and
231-
[Schemathesis](https://github.com/schemathesis/schemathesis).
232+
[WuppieFuzz](https://github.com/TNO-S3/WuppieFuzz).
232233

233-
All these tools are _black-box_, i.e., they do not analyze the source-code of the tested APIs to generate more effective test data.
234+
Apart from WuppieFuzz, all these tools are _black-box_, i.e., they do not analyze the source-code of the tested APIs to generate more effective test data.
234235
As we are the authors of EvoMaster, we are too biased to compare it properly with those other black-box tools.
235236
However, different independent studies (e.g., in [2022](https://arxiv.org/abs/2204.08348) and [2024](https://arxiv.org/abs/2410.12547)) shows that EvoMaster is among the best performant.
236237
Furthermore, if your APIs are running on the JVM (e.g., written in Java or Kotlin), then EvoMaster has clearly an advantage, as it supports _white-box_ testing.

core-tests/e2e-tests/spring/spring-rest-h2-v1/src/test/java/org/evomaster/e2etests/spring/examples/resource/db/ResourceDependencyDBEMTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void testRunEM(boolean heuristicsForSQLAdvanced) throws Throwable {
2929
runTestHandlingFlakyAndCompilation(
3030
"ResourceEM",
3131
"org.db.resource.ResourceEM" + (heuristicsForSQLAdvanced ? "Complete" : "Partial"),
32-
1_000,
32+
2_000,
3333
true,
3434
(args) -> {
3535
// disable taint analysis

core-tests/e2e-tests/spring/spring-rest-mysql/src/test/kotlin/org/evomaster/e2etests/spring/rest/likecondition/LikeConditionEMTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class LikeConditionEMTest : RestTestBase() {
3737
.apply {
3838
assertTrue(isNotEmpty())
3939
forEach {
40-
assertEquals("${RegexGene.DATABASE_REGEX_PREFIX}foo%", it.sourceRegex)
40+
assertEquals("foo%", it.sourceRegex)
4141
}
4242
}
4343

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.foo.rest.examples.spring.openapi.v3.security.ssrf.uri
2+
3+
import io.swagger.v3.oas.annotations.Operation
4+
import io.swagger.v3.oas.annotations.responses.ApiResponse
5+
import io.swagger.v3.oas.annotations.responses.ApiResponses
6+
import org.springframework.boot.SpringApplication
7+
import org.springframework.boot.autoconfigure.SpringBootApplication
8+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
9+
import org.springframework.http.ResponseEntity
10+
import org.springframework.web.bind.annotation.GetMapping
11+
import org.springframework.web.bind.annotation.RequestMapping
12+
import org.springframework.web.bind.annotation.RequestParam
13+
import org.springframework.web.bind.annotation.RestController
14+
import java.net.HttpURLConnection
15+
import java.net.URI
16+
17+
@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
18+
@RequestMapping(path = ["/api"])
19+
@RestController
20+
open class SSRFUriApplication {
21+
22+
companion object {
23+
@JvmStatic
24+
fun main(args: Array<String>) {
25+
SpringApplication.run(SSRFUriApplication::class.java, *args)
26+
}
27+
}
28+
29+
@Operation(
30+
summary = "GET endpoint to fetch data from remote source",
31+
description = "Can be used to fetch data from remote source."
32+
)
33+
@ApiResponses(
34+
value = [
35+
ApiResponse(responseCode = "200", description = "Successful response"),
36+
ApiResponse(responseCode = "204", description = "No data to fetch"),
37+
ApiResponse(responseCode = "400", description = "Invalid request"),
38+
ApiResponse(responseCode = "500", description = "Invalid server error")
39+
]
40+
)
41+
@GetMapping(path = ["/uri"])
42+
open fun uriTest(@RequestParam dataSource: String): ResponseEntity<String> {
43+
if (dataSource != null) {
44+
return try {
45+
val uri = URI(dataSource)
46+
if (uri.scheme == "http") {
47+
val connection = uri.toURL().openConnection() as HttpURLConnection
48+
connection.requestMethod = "GET"
49+
connection.connectTimeout = 1000
50+
51+
if (connection.responseCode == 200) {
52+
return ResponseEntity.status(200).body("OK")
53+
}
54+
ResponseEntity.status(204).body("Unable to fetch.")
55+
}
56+
ResponseEntity.status(204).body("Unable to fetch.")
57+
} catch (e: Exception) {
58+
ResponseEntity.status(204).body("Unable to fetch.")
59+
}
60+
}
61+
62+
return ResponseEntity.badRequest().body("Invalid request")
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.foo.rest.examples.spring.openapi.v3.security.ssrf.uri
2+
3+
import com.foo.rest.examples.spring.openapi.v3.SpringController
4+
5+
class SSRFUriController: SpringController(SSRFUriApplication::class.java)

core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/security/existenceleakage/SecurityExistenceLeakageNoExistenceEMTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class SecurityExistenceLeakageNoExistenceEMTest : SpringTestBase(){
2626

2727
runTestHandlingFlakyAndCompilation(
2828
"SecurityExistenceLeakageNoExistenceEM",
29-
6000
29+
10_000
3030
) { args: MutableList<String> ->
3131

3232
setOption(args, "security", "true")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.evomaster.e2etests.spring.openapi.v3.security.ssrf.uri
2+
3+
import com.foo.rest.examples.spring.openapi.v3.security.ssrf.uri.SSRFUriController
4+
import org.evomaster.core.EMConfig
5+
import org.evomaster.core.problem.rest.data.HttpVerb
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 SSRFUriEMTest: SpringTestBase() {
12+
13+
companion object {
14+
@BeforeAll
15+
@JvmStatic
16+
fun init() {
17+
val config = EMConfig()
18+
config.instrumentMR_NET = false
19+
initClass(SSRFUriController(), config)
20+
}
21+
}
22+
23+
@Test
24+
fun testSSRFUri() {
25+
runTestHandlingFlakyAndCompilation(
26+
"SSRFUriGeneratedTest",
27+
30,
28+
) { args: MutableList<String> ->
29+
30+
// If mocking enabled, it'll spin new services each time when there is a valid URL.
31+
setOption(args, "externalServiceIPSelectionStrategy", "NONE")
32+
33+
setOption(args, "security", "true")
34+
setOption(args, "ssrf", "true")
35+
setOption(args, "vulnerableInputClassificationStrategy", "MANUAL")
36+
setOption(args, "schemaOracles", "false")
37+
38+
val solution = initAndRun(args)
39+
40+
assertTrue(solution.individuals.isNotEmpty())
41+
assertTrue(solution.hasSsrfFaults())
42+
43+
assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/api/uri", "OK")
44+
}
45+
}
46+
}

core-tests/e2e-tests/spring/spring-rest-postgres/src/test/kotlin/org/evomaster/e2etests/spring/rest/postgres/likecondition/LikeConditionEMTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class LikeConditionEMTest : RestTestBase() {
4141
.apply {
4242
assertTrue(isNotEmpty())
4343
forEach {
44-
assertEquals("${RegexGene.DATABASE_REGEX_PREFIX}foo%", it.sourceRegex)
44+
assertEquals("foo%", it.sourceRegex)
4545
}
4646
}
4747

core-tests/integration-tests/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.evomaster.core.EMConfig
55
import org.evomaster.core.problem.enterprise.SampleType
66
import org.evomaster.core.problem.rest.data.RestCallAction
77
import org.evomaster.core.problem.rest.data.RestIndividual
8+
import org.evomaster.core.problem.rest.service.RestIndividualBuilder
89
import org.evomaster.core.problem.rest.service.fitness.AbstractRestFitness
910
import org.evomaster.core.problem.rest.service.sampler.AbstractRestSampler
1011
import org.evomaster.core.problem.rest.service.SecurityRest
@@ -54,6 +55,8 @@ abstract class IntegrationTestRestBase : RestTestBase() {
5455

5556
fun getEMConfig() = injector.getInstance(EMConfig::class.java)
5657

58+
fun getBuilder() = injector.getInstance(RestIndividualBuilder::class.java)
59+
5760
/**
5861
* Create and evaluate an individual
5962
*/

core-tests/integration-tests/core-it/src/test/kotlin/org/evomaster/core/problem/rest/aiclassification/AIModelsCheck.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.evomaster.core.problem.rest.aiclassification
22

33
import bar.examples.it.spring.aiclassification.allornone.AllOrNoneController
4-
import bar.examples.it.spring.aiclassification.multitype.MultiTypeController
54
import com.google.inject.Inject
65
import org.evomaster.core.problem.enterprise.SampleType
76
import org.evomaster.core.problem.rest.IntegrationTestRestBase
@@ -245,7 +244,7 @@ class AIModelsCheck : IntegrationTestRestBase() {
245244
val overAllMetrics = aiGlobalClassifier.estimateOverallMetrics()
246245
println("Overall Accuracy: ${overAllMetrics.accuracy}")
247246
println("Overall Precision400: ${overAllMetrics.precision400}")
248-
println("Overall Recall400: ${overAllMetrics.recall400}")
247+
println("Overall Recall400: ${overAllMetrics.sensitivity400}")
249248
println("Overall F1Score400: ${overAllMetrics.f1Score400}")
250249
println("Overall MCC: ${overAllMetrics.mcc}")
251250

0 commit comments

Comments
 (0)