Skip to content

Commit

Permalink
Add web service example app (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
ursachec authored May 11, 2023
1 parent 80d3517 commit af3b1fa
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ gatherDependencies {
2. Run `gatherDependencies` task for the _SlimAndroid_ test project:

```
$ cd SlimAndroid
$ cd examples/springboot-kotlin-webgoat
$ gradle wrapper
$ ./gradlew gatherDependencies
$ find build/gatheredDependencies -name "*jar" | wc -l
Expand Down
37 changes: 37 additions & 0 deletions examples/springboot-kotlin-webgoat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
24 changes: 24 additions & 0 deletions examples/springboot-kotlin-webgoat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# springboot-kotlin-webgoat

Simple vulnerable Spring Boot Application written in Kotlin

## Run

```
$ ./gradlew bootRun
```

## Vulnerabilities

```
$ grep -R -A 1 vulnerability src
src/main/kotlin/ai/qwiet/springbootkotlinwebgoat/HelloController.kt: // vulnerability: XSS
src/main/kotlin/ai/qwiet/springbootkotlinwebgoat/HelloController.kt- return "Greetings ${username}!"
```

## Examples of HTTP endpoints querying

```
$ curl localhost:8080
Greetings from Spring Boot
```
39 changes: 39 additions & 0 deletions examples/springboot-kotlin-webgoat/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.springframework.boot") version "3.0.5"
id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.7.22"
kotlin("plugin.spring") version "1.7.22"
id("io.shiftleft.gather-dependencies") version "0.6"
}

group = "ai.qwiet"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
mavenCentral()
}

gatherDependencies {
configurationName.set("compileClasspath")
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}

tasks.withType<Test> {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
8 changes: 8 additions & 0 deletions examples/springboot-kotlin-webgoat/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
rootProject.name = "springboot-kotlin-webgoat"

pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ai.qwiet.springbootkotlinwebgoat

import org.springframework.http.HttpHeaders
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import java.io.InputStreamReader
import java.io.BufferedReader
import java.io.File


@RestController
class HelloController {
@GetMapping("/")
fun index(): String {
return "Greetings from Spring Boot!"
}

@GetMapping("/greet")
fun greet(@RequestParam("username") username: String): String {
// vulnerability: XSS
return "Greetings ${username}!"
}

fun parseParams(name: String, msg: String): Map<String, String?> {
val checkedName = name.takeUnless { it.contains('\\') }?.ifBlank { "default_name" }
val checkedMsg = msg.ifBlank { "default_msg" }
return mapOf("parsed_name" to checkedName, "parsed_msg" to checkedMsg)
}

@GetMapping("/exec")
fun exec(@RequestParam("cmd") cmd: String): ResponseEntity<String> {
var out = "NOP"
if (cmd != "nop") {
// vulnerability: Remote Code Execution
val proc = Runtime.getRuntime().exec(cmd)
val lineReader = BufferedReader(InputStreamReader(proc.getInputStream()));
val output = StringBuilder()
lineReader.lines().forEach { line ->
output.append(line + "\n")
}
out = "Did execute command `" + cmd + "`, got stdout:" + output;
}
return ResponseEntity(out, HttpStatus.OK)
}


@GetMapping("/touch_file")
fun touchFile(@RequestParam("name") name: String, @RequestParam("msg") msg: String): ResponseEntity<String> {
if (name == null || msg == null) {
return ResponseEntity("The `name` & `msg` parameters have to be set.", HttpStatus.OK)
} else {
val parsedParams = parseParams(name, msg)
val fullPath = "/tmp/http4kexample/" + parsedParams["parsed_name"]
val finalMsg = "MESSAGE: " + parsedParams["parsed_msg"]
// vulnerability: Directory Traversal
File(fullPath).writeText(finalMsg)
return ResponseEntity("Did write message `" + finalMsg + "` to file at `" + fullPath + "`", HttpStatus.OK)
}
}

@GetMapping("/debug")
fun debug(@RequestParam("url") url: String): ResponseEntity<String> {
val headers = HttpHeaders()
headers.add("Location", url)
// vulnerability: Open Redirect
return ResponseEntity(headers, HttpStatus.FOUND)
}


@GetMapping("/render_html")
fun renderHtml(@RequestParam("name") name: String): ResponseEntity<String> {
// vulnerability: XSS
val out = StringBuilder().append("<h1>Hello there, ").append("$name").append("!</h1>").toString()
return ResponseEntity(out, HttpStatus.OK)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ai.qwiet.springbootkotlinwebgoat

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class SpringbootKotlinWebgoatApplication

fun main(args: Array<String>) {
runApplication<SpringbootKotlinWebgoatApplication>(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ai.qwiet.springbootkotlinwebgoat

import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class SpringbootKotlinWebgoatApplicationTests {

@Test
fun contextLoads() {
}

}

0 comments on commit af3b1fa

Please sign in to comment.