Skip to content

Commit

Permalink
Implemented Proxy Request Highlighter
Browse files Browse the repository at this point in the history
  • Loading branch information
lokiuox committed Nov 24, 2023
1 parent 1079e55 commit 15d576a
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/main/kotlin/inql/Config.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package inql

import burp.Burp
import burp.api.montoya.core.HighlightColor

class Config private constructor() {
companion object {
Expand Down Expand Up @@ -48,6 +49,8 @@ class Config private constructor() {
"report.poi.custom_scalars" to true,
"report.poi.custom_keywords" to "",
"logging.level" to "WARN",
"proxy.highlight_enabled" to true,
"proxy.highlight_color" to HighlightColor.BLUE.displayName(),
)

private val hooks = hashMapOf<String, (Any) -> Unit>(
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/inql/InQL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,15 @@ class InQL : TabbedPane(), SavesAndLoadData {

// Initialize ExternalToolsService to make it ready to spawn the webserver and register the interceptor when they are needed
ExternalToolsService.init(this)

// If enabled, start request highlighter
if (this.config.getBoolean("proxy.highlight_enabled") == true) {
ProxyRequestHighlighter.start()
}
}

fun unload() = runBlocking {
// this@InQL.saveToProjectFile()
ProxyRequestHighlighter.stop()
this@InQL.gqlspection.unload()
}

Expand Down
91 changes: 91 additions & 0 deletions src/main/kotlin/inql/ProxyRequestHighlighter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package inql

import burp.Burp
import burp.api.montoya.core.HighlightColor
import burp.api.montoya.proxy.ProxyHttpRequestResponse
import com.google.gson.Gson
import com.google.gson.JsonObject
import inql.graphql.Utils
import kotlinx.coroutines.*


class ProxyRequestHighlighter private constructor(){
companion object {
private lateinit var instance: ProxyRequestHighlighter
public fun start() {
if (!this::instance.isInitialized) {
this.instance = ProxyRequestHighlighter()
} else {
Logger.error("Cannot start Request Highlighter more than once, something's wrong")
throw Exception("Cannot start Request Highlighter more than once, something's wrong")
}
}

public fun stop() {
if (this::instance.isInitialized) this.instance.stop()
}
}

private var pollingDelay = 1000L // 1 sec
private val color: HighlightColor = HighlightColor.highlightColor(Config.getInstance().getString("proxy.highlight_color"))
private val pollingScope = CoroutineScope(Dispatchers.IO)
private val coroutineScope = CoroutineScope(Dispatchers.Default)
private val gson = Gson()

private var oldIdx = 0
private val newIdx = {
Burp.Montoya.proxy().history().size - 1
}

init {
this.oldIdx = this.newIdx()

this.pollingScope.launch {
this@ProxyRequestHighlighter.poll()
}

Logger.debug("Proxy Request Highlighter started")
}

private fun stop() {
this.pollingScope.cancel()
this.coroutineScope.cancel()
}
private suspend fun poll() {
while (true) {
delay(this.pollingDelay)

val newIdx = this.newIdx()
// If no new requests have arrived, skip a cycle
if (newIdx == this.oldIdx) continue

// Else, spawn a coroutine for each new requests
Logger.debug("Spawning coroutines for requests ${this.oldIdx+1}-$newIdx")
for (idx in this.oldIdx+1..newIdx) {
this.coroutineScope.launch { this@ProxyRequestHighlighter.handleRequest(Burp.Montoya.proxy().history()[idx]) }
}
this.oldIdx = newIdx
}
}

private fun handleRequest(req: ProxyHttpRequestResponse) {
if (!Utils.isGraphQLRequest(req.finalRequest())) return

req.annotations().setHighlightColor(this.color)
var operationName: String? = null
try {
operationName = this.gson.fromJson(req.finalRequest().bodyToString(), JsonObject::class.java).get("operationName").asString
} catch (_: Exception) {
// Do nothing
}

val note: String = if (operationName.isNullOrEmpty()) {
"GraphQL"
} else {
"GraphQL: $operationName"
}

req.annotations().setNotes(note)
}

}

0 comments on commit 15d576a

Please sign in to comment.