Skip to content

Commit

Permalink
Merge branch 'feature/kotlin-scripting' into feature/kotlin-script
Browse files Browse the repository at this point in the history
  • Loading branch information
kberg committed Jun 12, 2020
2 parents 24fdb78 + 911eca6 commit b170258
Show file tree
Hide file tree
Showing 11 changed files with 332 additions and 0 deletions.
8 changes: 8 additions & 0 deletions addOns/kotlin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog
All notable changes to this add-on will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Alpha

- Kotlin scripting for the JVM
27 changes: 27 additions & 0 deletions addOns/kotlin/kotlin.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import org.zaproxy.gradle.addon.AddOnStatus

plugins {
kotlin("jvm") version "1.3.50"
}

version = "1"
description = "Allows Kotlin to be used for ZAP scripting - templates included"

zapAddOn {
addOnName.set("Kotlin Scripting")
addOnStatus.set(AddOnStatus.ALPHA)
zapVersion.set("2.9.0")

manifest {
author.set("StackHawk Engineering")
}
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable")
implementation("org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable")
implementation("org.jetbrains.kotlin:kotlin-script-util")

testImplementation(project(":testutils"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2020 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.zaproxy.zap.extension.kotlin

import org.apache.log4j.Logger
import org.parosproxy.paros.control.Control
import org.parosproxy.paros.extension.Extension
import org.parosproxy.paros.extension.ExtensionAdaptor
import org.parosproxy.paros.extension.ExtensionHook
import org.parosproxy.paros.view.View
import org.zaproxy.zap.ZAP
import org.zaproxy.zap.control.ExtensionFactory
import org.zaproxy.zap.extension.script.ExtensionScript
import javax.swing.ImageIcon

class ExtensionKotlin : ExtensionAdaptor(NAME) {


companion object {
val NAME = "ExtensionKotlin"
val TEAM_NAME = "StackHawk Engineering"
val KOTLIN_ICON: ImageIcon? = if (View.isInitialised()) ImageIcon(
ExtensionKotlin::class.java.getResource(
"/org/zaproxy/zap/extension/kotlin/resources/kotlin.png")) else null

val EXTENSION_DEPENDENCIES: List<Class<out Extension>> = listOf(ExtensionScript::class.java)
private val LOGGER: Logger = Logger.getLogger(ExtensionKotlin::class.java)
}

init {
order = 9999

}

override fun hook(extensionHook: ExtensionHook?) {
super.hook(extensionHook)

LOGGER.info("Hooking Kotlin Scripting Extension")

val zapJar = ZAP::class.java.protectionDomain.codeSource.location.file

LOGGER.info("Loading Kotlin engine...")
val cl = ExtensionFactory.getAddOnLoader()
cl.urLs.forEach { LOGGER.info(it) }
extScript
.registerScriptEngineWrapper(
KotlinEngineWrapper(KotlinScriptEngineFactory(cl, zapJar.toString())))
LOGGER.info("Kotlin engine loaded.")

}

private val extScript: ExtensionScript by lazy {
Control.getSingleton()
.extensionLoader
.getExtension(ExtensionScript.NAME) as ExtensionScript
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2020 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.zaproxy.zap.extension.kotlin

import org.fife.ui.rsyntaxtextarea.SyntaxConstants
import org.parosproxy.paros.Constant
import org.parosproxy.paros.extension.Extension
import org.zaproxy.zap.extension.script.DefaultEngineWrapper
import javax.script.ScriptEngine
import javax.script.ScriptEngineFactory
import javax.swing.ImageIcon

class KotlinEngineWrapper(scriptEngineFactory: ScriptEngineFactory): DefaultEngineWrapper(scriptEngineFactory) {

override fun getExtensions(): MutableList<String> {
return mutableListOf("kts")
}

override fun getIcon(): ImageIcon? {
return ExtensionKotlin.KOTLIN_ICON
}

override fun getEngine(): ScriptEngine {
return super.getEngine()
}

override fun getSyntaxStyle(): String {
return SyntaxConstants.SYNTAX_STYLE_NONE
}

fun getAuthor(): String {
return ExtensionKotlin.TEAM_NAME
}

fun getDescription(): String {
return Constant.messages.getString("kotlin.desc")
}

fun getDependencies(): List<Class<out Extension>> {
return ExtensionKotlin.EXTENSION_DEPENDENCIES
}

override fun isRawEngine(): Boolean {
return false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2020 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.zaproxy.zap.extension.kotlin

import org.jetbrains.kotlin.cli.common.repl.KotlinJsr223JvmScriptEngineFactoryBase
import org.jetbrains.kotlin.cli.common.repl.ScriptArgsWithTypes
import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngine
import org.jetbrains.kotlin.script.jsr223.KotlinStandardJsr223ScriptTemplate
import java.io.File
import javax.script.Bindings
import javax.script.ScriptContext
import javax.script.ScriptEngine
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContextOrStdlib

class KotlinScriptEngineFactory(private val classLoader: ClassLoader,
private val zapJar: String? = null) : KotlinJsr223JvmScriptEngineFactoryBase() {
override fun getScriptEngine(): ScriptEngine {
val clJars = scriptCompilationClasspathFromContextOrStdlib("kotlin-stdlib",
wholeClasspath = true,
classLoader = classLoader)
val jars = if (zapJar != null) {
clJars + File(zapJar)
} else {
clJars
}
return KotlinJsr223JvmLocalScriptEngine(
this,
jars,
KotlinStandardJsr223ScriptTemplate::class.qualifiedName!!,
{ ctx, types ->
ScriptArgsWithTypes(arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)), types ?: emptyArray())
},
arrayOf(Bindings::class)
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

kotlin.desc = Allows Kotlin to be used for ZAP scripting
kotlin.options.title = Kotlin
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

import org.apache.commons.httpclient.URI
import org.parosproxy.paros.network.HttpHeader
import org.parosproxy.paros.network.HttpMessage
import org.parosproxy.paros.network.HttpRequestHeader
import org.zaproxy.zap.authentication.AuthenticationHelper
import org.zaproxy.zap.authentication.GenericAuthenticationCredentials

val PARAM_TARGET_URL = "targetUrl"

fun authenticate(
helper: AuthenticationHelper,
paramsValues: Map<String, String>,
credentials: GenericAuthenticationCredentials): HttpMessage {

println("Kotlin auth template")

println("TARGET_URL: ${paramsValues[PARAM_TARGET_URL]}")
val msg = helper.prepareMessage()
msg.requestHeader = HttpRequestHeader(HttpRequestHeader.GET, URI(paramsValues[PARAM_TARGET_URL], true),
HttpHeader.HTTP11)
println("msg: $msg ${msg.requestHeader.headers.size}")
msg.requestHeader.headers.forEach { println(it) }
helper.sendAndReceive(msg)
return msg
}

fun getRequiredParamsNames(): Array<String> {
return arrayOf(PARAM_TARGET_URL)
}

fun getOptionalParamsNames(): Array<String> {
return arrayOf()
}

fun getCredentialsParamsNames(): Array<String> {
return arrayOf("username", "password")
}

fun getLoggedInIndicator(): String {
return "Sign Out"
}

fun getLoggedOutIndicator(): String {
return "Sign In"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

println("KaaKaawwtlin!!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2020 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.zaproxy.zap.extension.kotlin

import org.junit.jupiter.api.BeforeAll
import org.zaproxy.zap.testutils.AbstractVerifyScriptTemplates
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import javax.script.Compilable

class KotlinScriptTest : AbstractVerifyScriptTemplates() {

companion object {
lateinit var se: Compilable
@BeforeAll
@JvmStatic
fun setUp() {
se = KotlinScriptEngineFactory(Thread.currentThread().contextClassLoader).scriptEngine as Compilable
}
}

override fun getScriptExtension(): String? {
return ".kts"
}

override fun parseTemplate(template: Path?) {
val reader = Files.newBufferedReader(template, StandardCharsets.UTF_8)
val s = se.compile(reader)
s.eval()
}
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var addOns = listOf(
"jruby",
"jsonview",
"jython",
"kotlin",
"onlineMenu",
"openapi",
"plugnhack",
Expand Down

0 comments on commit b170258

Please sign in to comment.