summaryrefslogtreecommitdiff
path: root/sandbox
diff options
context:
space:
mode:
authorMS <ms@taler.net>2023-01-05 16:03:42 +0100
committerMS <ms@taler.net>2023-01-05 16:03:42 +0100
commit571b2f9c1be786dc7ba46cdf589be515db12bb4d (patch)
treec69ba4152350b6126c3650e1e4d338351bd6dc2e /sandbox
parent252d91c515c6a788a547bc10b91c5fa288ef31c0 (diff)
downloadlibeufin-571b2f9c1be786dc7ba46cdf589be515db12bb4d.tar.gz
libeufin-571b2f9c1be786dc7ba46cdf589be515db12bb4d.tar.bz2
libeufin-571b2f9c1be786dc7ba46cdf589be515db12bb4d.zip
UUID sanitization.
Detect a malformed UUID before using it in a database query. That avoids a 500 response in favor of a 400.
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt13
-rw-r--r--sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt43
2 files changed, 33 insertions, 23 deletions
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
index e28770f7..50d1a96d 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
@@ -218,11 +218,18 @@ fun circuitApi(circuitRoute: Route) {
circuitRoute.get("/cashouts/{uuid}") {
val user = call.request.basicAuth()
val operationUuid = call.getUriComponent("uuid")
+ // Parse and check the UUID.
+ val maybeUuid = try {
+ UUID.fromString(operationUuid)
+ } catch (e: Exception) {
+ val msg = "The cash-out UUID is invalid: $operationUuid"
+ logger.debug(e.message)
+ logger.debug(msg)
+ throw badRequest(msg)
+ }
// Get the operation from the database.
val maybeOperation = transaction {
- CashoutOperationEntity.find {
- uuid eq UUID.fromString(operationUuid)
- }.firstOrNull()
+ CashoutOperationEntity.find { uuid eq maybeUuid }.firstOrNull()
}
if (maybeOperation == null) {
val msg = "Cash-out operation $operationUuid not found."
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 2b39819e..d1f88b43 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -20,18 +20,12 @@
package tech.libeufin.sandbox
import UtilError
-import com.fasterxml.jackson.core.JsonParseException
-import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.core.util.DefaultIndenter
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
-import com.fasterxml.jackson.databind.DeserializationFeature
-import com.fasterxml.jackson.databind.JsonMappingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
-import com.fasterxml.jackson.databind.exc.MismatchedInputException
import com.fasterxml.jackson.module.kotlin.KotlinFeature
import com.fasterxml.jackson.module.kotlin.KotlinModule
-import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.subcommands
@@ -42,7 +36,6 @@ import com.github.ajalt.clikt.parameters.types.int
import execThrowableOrTerminate
import io.ktor.server.application.*
import io.ktor.http.*
-import io.ktor.serialization.*
import io.ktor.serialization.jackson.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
@@ -55,9 +48,7 @@ import io.ktor.server.routing.*
import io.ktor.server.util.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.cors.routing.*
-import io.ktor.util.*
import io.ktor.util.date.*
-import kotlinx.coroutines.*
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.statements.api.ExposedBlob
@@ -1173,13 +1164,19 @@ val sandboxApp: Application.() -> Unit = {
return@get
}
post("/withdrawal-operation/{wopid}") {
- val wopid: String = ensureNonNull(call.parameters["wopid"])
+ val arg = ensureNonNull(call.parameters["wopid"])
+ val maybeWithdrawalUUid = try {
+ java.util.UUID.fromString(arg)
+ } catch (e: Exception) {
+ logger.debug(e.message)
+ throw badRequest("Withdrawal operation UUID was invalid: $arg")
+ }
val body = call.receive<TalerWithdrawalSelection>()
val transferDone = transaction {
val wo = TalerWithdrawalEntity.find {
- TalerWithdrawalsTable.wopid eq java.util.UUID.fromString(wopid)
+ TalerWithdrawalsTable.wopid eq maybeWithdrawalUUid
}.firstOrNull() ?: throw SandboxError(
- HttpStatusCode.NotFound, "Withdrawal operation $wopid not found."
+ HttpStatusCode.NotFound, "Withdrawal operation $maybeWithdrawalUUid not found."
)
if (wo.confirmationDone) {
return@transaction true
@@ -1211,24 +1208,30 @@ val sandboxApp: Application.() -> Unit = {
return@post
}
get("/withdrawal-operation/{wopid}") {
- val wopid: String = ensureNonNull(call.parameters["wopid"])
- val wo = transaction {
+ val arg = ensureNonNull(call.parameters["wopid"])
+ val maybeWithdrawalUuid = try {
+ java.util.UUID.fromString(arg)
+ } catch (e: Exception) {
+ logger.debug(e.message)
+ throw badRequest("Withdrawal UUID invalid: $arg")
+ }
+ val maybeWithdrawalOp = transaction {
TalerWithdrawalEntity.find {
- TalerWithdrawalsTable.wopid eq java.util.UUID.fromString(wopid)
+ TalerWithdrawalsTable.wopid eq maybeWithdrawalUuid
}.firstOrNull() ?: throw SandboxError(
HttpStatusCode.NotFound,
- "Withdrawal operation: $wopid not found"
+ "Withdrawal operation: $arg not found"
)
}
val demobank = ensureDemobank(call)
var captcha_page = demobank.captchaUrl
if (captcha_page == null) logger.warn("CAPTCHA URL not found")
val ret = TalerWithdrawalStatus(
- selection_done = wo.selectionDone,
- transfer_done = wo.confirmationDone,
- amount = wo.amount,
+ selection_done = maybeWithdrawalOp.selectionDone,
+ transfer_done = maybeWithdrawalOp.confirmationDone,
+ amount = maybeWithdrawalOp.amount,
suggested_exchange = demobank.suggestedExchangeBaseUrl,
- aborted = wo.aborted,
+ aborted = maybeWithdrawalOp.aborted,
confirm_transfer_url = captcha_page
)
call.respond(ret)