Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLM Integration #5861

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions addOns/llm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 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/).

## Unreleased

- First version.

2 changes: 2 additions & 0 deletions addOns/llm/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
version=0.0.1
release=false
27 changes: 27 additions & 0 deletions addOns/llm/llm.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
description = "An extension to leverage LLM within ZAP."

zapAddOn {
addOnName.set("LLM Extension")

manifest {
author.set("Abdessamad TEMMAR")
}
}

crowdin {
configuration {
val resourcesPath = "org/zaproxy/addon/${zapAddOn.addOnId.get()}/resources/"
tokens.put("%messagesPath%", resourcesPath)
tokens.put("%helpPath%", resourcesPath)
}
}

dependencies {

zapAddOn("automation")
zapAddOn("commonlib")

testImplementation(project(":testutils"))
implementation("dev.langchain4j:langchain4j:0.35.0")
implementation("dev.langchain4j:langchain4j-azure-open-ai:0.35.0")
}
156 changes: 156 additions & 0 deletions addOns/llm/src/main/java/org/zaproxy/addon/llm/ExtensionLlm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 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.addon.llm;

import java.awt.event.KeyEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.extension.AbstractPanel;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.parosproxy.paros.extension.SessionChangedListener;
import org.parosproxy.paros.model.Session;
import org.zaproxy.addon.llm.ui.ImportDialog;
import org.zaproxy.addon.llm.ui.LlmReviewAlertMenu;
import org.zaproxy.addon.llm.ui.settings.LlmOptionsPanel;
import org.zaproxy.addon.llm.ui.settings.LlmOptionsParam;
import org.zaproxy.zap.view.ZapMenuItem;

/**
* An extension for ZAP that enables researchers to leverage Language Learning Models (LLMs) to
* augment the functionalities of ZAP.
*
* <p>{@link ExtensionAdaptor} classes are the main entry point for adding/loading functionalities
* provided by the add-ons.
*
* @see #hook(ExtensionHook)
*/
public class ExtensionLlm extends ExtensionAdaptor {

private static final Logger LOGGER = LogManager.getLogger(ExtensionLlm.class);

public static final String NAME = "ExtensionLlm";
protected static final String PREFIX = "llm";
private static final String[] ROOT = {};

private ZapMenuItem menuLLM;
private AbstractPanel statusPanel;
private ImportDialog importDialog;
private LlmReviewAlertMenu llmReviewAlertMenu;
private LlmOptionsParam llmOptionsParam;
private LlmOptionsPanel llmOptionsPanel;

public ExtensionLlm() {
super(NAME);
setI18nPrefix(PREFIX);
}

@Override
public void hook(ExtensionHook extensionHook) {
super.hook(extensionHook);

if (hasView()) {
extensionHook.getHookMenu().addImportMenuItem(getMenuLLM());
extensionHook.getHookMenu().addPopupMenuItem(getCheckLlmMenu());
extensionHook.addOptionsParamSet(getOptionsParam());
getView().getOptionsDialog().addParamPanel(ROOT, getOptionsPanel(), true);

extensionHook.addSessionListener(
new SessionChangedListener() {
@Override
public void sessionAboutToChange(Session session) {
if (importDialog != null) {
importDialog.clearFields();
}
}

@Override
public void sessionChanged(Session session) {}

@Override
public void sessionScopeChanged(Session session) {}

@Override
public void sessionModeChanged(Control.Mode mode) {}
});
}
}

@Override
public boolean canUnload() {
return true;
}

@Override
public void unload() {
super.unload();

if (importDialog != null) {
importDialog.dispose();
}
}

private ZapMenuItem getMenuLLM() {
if (menuLLM == null) {
menuLLM =
new ZapMenuItem(
"llm.topmenu.import.importOpenAPI",
getView().getMenuShortcutKeyStroke(KeyEvent.VK_J, 0, false));
menuLLM.setToolTipText(
Constant.messages.getString("llm.topmenu.import.importOpenAPI.tooltip"));
menuLLM.addActionListener(
e -> {
if (importDialog == null) {
importDialog = new ImportDialog(getView().getMainFrame(), this);
}
importDialog.setVisible(true);
});
}
return menuLLM;
}

@Override
public String getDescription() {
return Constant.messages.getString(PREFIX + ".desc");
}

private LlmReviewAlertMenu getCheckLlmMenu() {
if (llmReviewAlertMenu == null) {
llmReviewAlertMenu = new LlmReviewAlertMenu(this);
}
return llmReviewAlertMenu;
}

private LlmOptionsPanel getOptionsPanel() {
if (llmOptionsPanel == null) {
llmOptionsPanel = new LlmOptionsPanel();
}
return llmOptionsPanel;
}

public LlmOptionsParam getOptionsParam() {
if (llmOptionsParam == null) {
llmOptionsParam = new LlmOptionsParam();
}
return llmOptionsParam;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 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.addon.llm.communication;
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved

import dev.langchain4j.model.output.structured.Description;

public class Confidence {

@Description(
"The level of confidence, typically represented as a percentage or a descriptive term")
kingthorin marked this conversation as resolved.
Show resolved Hide resolved
private Integer level;

@Description("A textual explanation for the assigned confidence level")
private String explanation;

// Constructor
public Confidence(Integer level, String explanation) {
this.level = level;
this.explanation = explanation;
}

// Getter for level
public Integer getLevel() {
return level;
}

// Setter for level
public void setLevel(Integer level) {
this.level = level;
}

// Getter for explanation
public String getExplanation() {
return explanation;
}

// Setter for explanation
public void setExplanation(String explanation) {
this.explanation = explanation;
}

@Override
public String toString() {
return "Confidence {\n"
+ "level="
+ level
+ "\n"
+ ", explanation='"
+ explanation
+ "\n"
+ "}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 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.addon.llm.communication;

import dev.langchain4j.model.output.structured.Description;
import java.util.Map;

public class HttpRequest {

@Description("HTTP method such as GET, POST, PUT, DELETE, etc.")
private String method;

@Description("hostname of the request")
private String hostname;

@Description("Full URL of the request based on the hostname and base URL fields")
private String url;

@Description("Query parameters in key-value pairs")
private Map<String, String> queryParams;

@Description("HTTP headers in key-value pairs")
private Map<String, String> headers;

@Description("Body of the request, typically used with POST or PUT methods")
private String body;

public HttpRequest(
String method,
String hostname,
String url,
Map<String, String> queryParams,
Map<String, String> headers,
String body) {
this.method = method;
this.hostname = hostname;
this.url = url;
this.queryParams = queryParams;
this.headers = headers;
this.body = body;
}

public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

public String geturl() {
return url;
}

public void seturl(String url) {
this.url = url;
}

public String getHostname() {
return hostname;
}

public void setHostname(String hostname) {
this.hostname = hostname;
}

public Map<String, String> getQueryParams() {
return queryParams;
}

public void setQueryParams(Map<String, String> queryParams) {
this.queryParams = queryParams;
}

public Map<String, String> getHeaders() {
return headers;
}

public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}

public String getBody() {
return body;
}

public void setBody(String body) {
this.body = body;
}

@Override
public String toString() {
return "url = " + this.url;
}
}
Loading