Skip to content

Commit

Permalink
🐛 json text 전체를 clean 시키면 json 구조가 망가질 수 있기 때문에 String 필드만 필터링 처리
Browse files Browse the repository at this point in the history
  • Loading branch information
allbegray committed Apr 3, 2023
1 parent 02ba33a commit 61906d4
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 4 deletions.
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
}

group = 'herbaccara'
version = '0.0.5'
version = '0.0.6'
sourceCompatibility = '17'

publishing {
Expand Down Expand Up @@ -49,6 +49,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot:3.0.0'
implementation 'org.springframework.boot:spring-boot-autoconfigure:3.0.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.0'

implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.3'
}

tasks.withType(KotlinCompile) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package herbaccara.xss

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import jakarta.servlet.ServletInputStream
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletRequestWrapper
Expand All @@ -9,6 +11,7 @@ import java.io.BufferedReader

class XssHttpServletRequestWrapper(
request: HttpServletRequest,
private val objectMapper: ObjectMapper,
private val safelist: Safelist,
private val jsonContentTypes: List<String> = listOf("application/json")
) : HttpServletRequestWrapper(request) {
Expand Down Expand Up @@ -39,8 +42,9 @@ class XssHttpServletRequestWrapper(
val stream = super.getInputStream()
if (jsonContentTypes.contains(super.getContentType())) {
return stream.use {
val text = it.reader().readText().let(::clean)
CachedServletInputStream(text.byteInputStream())
val obj = objectMapper.readValue<Any>(it.reader().readText())
val json = objectMapper.writeValueAsString(obj)
CachedServletInputStream(json.byteInputStream())
}
}
return stream
Expand Down
13 changes: 12 additions & 1 deletion src/main/kotlin/herbaccara/xss/filter/XssServletFilter.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package herbaccara.xss.filter

import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import herbaccara.xss.XssHttpServletRequestWrapper
import herbaccara.xss.annotation.DisabledXssFilter
import herbaccara.xss.annotation.XssFilter
import herbaccara.xss.jackson.StringStdDeserializer
import herbaccara.xss.safelist.SafelistSupplier
import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
Expand Down Expand Up @@ -53,7 +56,15 @@ class XssServletFilter(
}

if (safelist != null) {
filterChain.doFilter(XssHttpServletRequestWrapper(request, safelist), response)
val objectMapper = jacksonObjectMapper().apply {
registerModule(
SimpleModule().apply {
addDeserializer(String::class.java, StringStdDeserializer(safelist))
}
)
}

filterChain.doFilter(XssHttpServletRequestWrapper(request, objectMapper, safelist), response)
return
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/kotlin/herbaccara/xss/jackson/StringStdDeserializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package herbaccara.xss.jackson

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import org.jsoup.Jsoup
import org.jsoup.safety.Safelist

class StringStdDeserializer(private val safelist: Safelist) : StdDeserializer<String>(String::class.java) {

override fun deserialize(p: JsonParser, ctxt: DeserializationContext): String? {
return p.text?.let { Jsoup.clean(it, safelist) }
}
}
43 changes: 43 additions & 0 deletions src/test/kotlin/herbaccara/xss/JsonTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package herbaccara.xss

import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import herbaccara.xss.jackson.StringStdDeserializer
import org.jsoup.safety.Safelist
import org.junit.jupiter.api.Test

class JsonTest {

@Test
fun test() {
val objectMapper = jacksonObjectMapper().apply {
findAndRegisterModules()
registerModule(
SimpleModule().apply {
addDeserializer(String::class.java, StringStdDeserializer(Safelist.none()))
}
)
}

// val json = """
// ["<script>1</scritp>", "<img>2"]
// """.trimIndent()

val json = """
{
"foo" : "<script>1</scritp>",
"bar" : "<img>2",
"asd" : null
}
""".trimIndent()

// val clean = Jsoup.clean(json, Safelist.none())
// println(clean)
//
// objectMapper.readTree(json)

val readValue = objectMapper.readValue<Any>(json)
println(readValue)
}
}

0 comments on commit 61906d4

Please sign in to comment.