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 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ You can also import add-ons you have downloaded manually from https://github.com

Please see the [wiki](https://github.com/zaproxy/zap-extensions/wiki) for more details.

## Building
## Buildingh
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved

The add-ons are built with [Gradle], each add-on has its own project which is located under the `addOns` project/directory.

Expand Down
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=2
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
release=false
29 changes: 29 additions & 0 deletions addOns/llm/llm.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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")

}

187 changes: 187 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,187 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2014 The ZAP Development Team
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
*
* 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.CardLayout;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.io.File;
import java.nio.file.Files;
import javax.swing.ImageIcon;
import javax.swing.JTextPane;
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.parosproxy.paros.view.View;
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.addon.llm.ui.ImportDialog;
import org.zaproxy.zap.utils.FontUtils;
import org.zaproxy.zap.view.ZapMenuItem;

/**
* An example ZAP extension which adds a top level menu item, a pop up menu item and a status panel.
*
* <p>{@link ExtensionAdaptor} classes are the main entry point for adding/loading functionalities
* provided by the add-ons.
*
* @see #hook(ExtensionHook)
*/
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
public class ExtensionLlm extends ExtensionAdaptor {

// The name is public so that other extensions can access it
public static final String NAME = "ExtensionLlm";

// The i18n prefix, by default the package name - defined in one place to make it easier
// to copy and change this example
protected static final String PREFIX = "llm";

/**
* Relative path (from add-on package) to load add-on resources.
*
* @see Class#getResource(String)
*/
private static final String RESOURCES = "resources";

private ZapMenuItem menuExample;
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
private AbstractPanel statusPanel;
private ImportDialog importDialog;
private LlmReviewAlertMenu llmReviewAlertMenu;
private LlmOptionsParam llmOptionsParam;
private LlmOptionsPanel llmOptionsPanel;
private static final String[] ROOT = {};

private LlmAPI api;

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

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

@Override
public void hook(ExtensionHook extensionHook) {
super.hook(extensionHook);
this.llmOptionsParam = new LlmOptionsParam();
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved


if (hasView()) {
extensionHook.getHookMenu().addImportMenuItem(getMenuLLM());
extensionHook.getHookMenu().addPopupMenuItem(getCheckLlmMenu());
extensionHook.addOptionsParamSet(getOptionsParam());
// change to a message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please clarify what should be done ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deal with the comment, or remove it.

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() {
// The extension can be dynamically unloaded, all resources used/added can be freed/removed
// from core.
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

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

// In this example it's not necessary to override the method, as there's nothing to unload
// manually, the components added through the class ExtensionHook (in hook(ExtensionHook))
// are automatically removed by the base unload() method.
// If you use/add other components through other methods you might need to free/remove them
// here (if the extension declares that can be unloaded, see above method).
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
if (importDialog != null) {
importDialog.dispose();
}
}

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

@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;
}

}
60 changes: 60 additions & 0 deletions addOns/llm/src/main/java/org/zaproxy/addon/llm/LlmAPI.java
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2018 The ZAP Development Team
TmmmmmR marked this conversation as resolved.
Show resolved Hide resolved
*
* 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 net.sf.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.zaproxy.zap.extension.api.ApiAction;
import org.zaproxy.zap.extension.api.ApiException;
import org.zaproxy.zap.extension.api.ApiImplementor;
import org.zaproxy.zap.extension.api.ApiResponse;
import org.zaproxy.zap.extension.api.ApiResponseElement;

public class LlmAPI extends ApiImplementor {
private static final String PREFIX = "llm";

private static final String ACTION_HELLO_WORLD = "helloWorld";

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

public LlmAPI() {
this.addApiAction(new ApiAction(ACTION_HELLO_WORLD));
}

@Override
public String getPrefix() {
return PREFIX;
}

@Override
public ApiResponse handleApiAction(String name, JSONObject params) throws ApiException {
switch (name) {
case ACTION_HELLO_WORLD:
LOGGER.debug("hello world called");
break;

default:
throw new ApiException(ApiException.Type.BAD_ACTION);
}

return ApiResponseElement.OK;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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")
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"
+ "}";
}
}

Loading
Loading