Skip to content

Commit

Permalink
[backend] Fix Cross-site Scripting (XSS) & Fix Server-Side Request Fo…
Browse files Browse the repository at this point in the history
…rgery
  • Loading branch information
RomuDeuxfois committed Jan 9, 2025
1 parent 354cec4 commit 1002ad4
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 4 deletions.
110 changes: 106 additions & 4 deletions openbas-api/src/main/java/io/openbas/rest/executor/ExecutorApi.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.openbas.rest.executor;

import static io.openbas.database.model.User.ROLE_ADMIN;
import static io.openbas.utils.AgentUtils.AVAILABLE_ARCHITECTURES;
import static io.openbas.utils.AgentUtils.AVAILABLE_PLATFORMS;
import static io.openbas.service.EndpointService.JFROG_BASE;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -14,6 +16,10 @@
import io.openbas.rest.helper.RestBehavior;
import io.openbas.service.EndpointService;
import io.openbas.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -138,11 +144,44 @@ public Executor registerExecutor(
}

// Public API
@Operation(
summary = "Retrieve OpenBAS Agent Executable",
description =
"Downloads the OpenBAS agent executable for a specified platform and architecture.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved the executable."),
@ApiResponse(
responseCode = "400",
description = "Invalid platform or architecture specified."),
})
@GetMapping(
value = "/api/agent/executable/openbas/{platform}/{architecture}",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody ResponseEntity<byte[]> getOpenBasAgentExecutable(
@PathVariable String platform, @PathVariable String architecture) throws IOException {
@Parameter(
description =
"Target platform for the agent installation (e.g., windows, linux, mac). Case insensitive.",
required = true)
@PathVariable
String platform,
@Parameter(
description =
"Target architecture for the agent installation (e.g., x86_64, arm64). Case insensitive.",
required = true)
@PathVariable
String architecture)
throws IOException {
platform = Optional.ofNullable(platform).map(String::toLowerCase).orElse("");
architecture = Optional.ofNullable(architecture).map(String::toLowerCase).orElse("");

if (!AVAILABLE_PLATFORMS.contains(platform)) {
throw new IllegalArgumentException("Platform invalid : " + platform);
}
if (!AVAILABLE_ARCHITECTURES.contains(architecture)) {
throw new IllegalArgumentException("Architecture invalid : " + architecture);
}

InputStream in = null;
String resourcePath = "/openbas-agent/" + platform + "/" + architecture + "/";
String filename = "";
Expand Down Expand Up @@ -170,11 +209,46 @@ public Executor registerExecutor(
}

// Public API
@Operation(
summary = "Retrieve OpenBAS Agent Package",
description =
"Downloads the OpenBAS agent package for the specified platform and architecture.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "Successfully retrieved the agent package."),
@ApiResponse(
responseCode = "400",
description = "Invalid platform or architecture specified."),
})
@GetMapping(
value = "/api/agent/package/openbas/{platform}/{architecture}",
value = "/{platform}/{architecture}",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody ResponseEntity<byte[]> getOpenBasAgentPackage(
@PathVariable String platform, @PathVariable String architecture) throws IOException {
@Parameter(
description =
"Target platform for the agent package (e.g., windows, linux, mac). Case insensitive.",
required = true)
@PathVariable
String platform,
@Parameter(
description =
"Target architecture for the agent package (e.g., x86, x64, arm). Case insensitive.",
required = true)
@PathVariable
String architecture)
throws IOException {
platform = Optional.ofNullable(platform).map(String::toLowerCase).orElse("");
architecture = Optional.ofNullable(architecture).map(String::toLowerCase).orElse("");

if (!AVAILABLE_PLATFORMS.contains(platform)) {
throw new IllegalArgumentException("Platform invalid : " + platform);
}
if (!AVAILABLE_ARCHITECTURES.contains(architecture)) {
throw new IllegalArgumentException("Architecture invalid : " + architecture);
}

byte[] file = null;
String filename = null;

Expand Down Expand Up @@ -208,9 +282,37 @@ public Executor registerExecutor(
}

// Public API
@Operation(
summary = "Retrieve OpenBAS Agent Installer Command",
description =
"Generates the installation command for the OpenBAS agent for the specified platform and token.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "Successfully generated the install command."),
@ApiResponse(responseCode = "400", description = "Invalid platform specified."),
@ApiResponse(responseCode = "404", description = "Token not found."),
})
@GetMapping(value = "/api/agent/installer/openbas/{platform}/{token}")
public @ResponseBody ResponseEntity<String> getOpenBasAgentInstaller(
@PathVariable String platform, @PathVariable String token) throws IOException {
@Parameter(
description =
"Target platform for the agent installation (e.g., windows, linux, mac). Case insensitive.",
required = true)
@PathVariable
String platform,
@Parameter(
description = "Unique token associated with the agent installation.",
required = true)
@PathVariable
String token)
throws IOException {
platform = Optional.ofNullable(platform).map(String::toLowerCase).orElse("");

if (!AVAILABLE_PLATFORMS.contains(platform)) {
throw new IllegalArgumentException("Platform invalid : " + platform);
}
Optional<Token> resolvedToken = tokenRepository.findByValue(token);
if (resolvedToken.isEmpty()) {
throw new UnsupportedOperationException("Invalid token");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static io.openbas.database.specification.InjectorSpecification.byName;
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.service.EndpointService.JFROG_BASE;
import static io.openbas.utils.AgentUtils.AVAILABLE_ARCHITECTURES;
import static io.openbas.utils.AgentUtils.AVAILABLE_PLATFORMS;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
Expand Down Expand Up @@ -338,6 +340,13 @@ public InjectorRegistration registerInjector(
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody ResponseEntity<byte[]> getOpenBasImplant(
@PathVariable String platform, @PathVariable String architecture) throws IOException {
if (!AVAILABLE_PLATFORMS.contains(platform)) {
throw new IllegalArgumentException("Platform invalid : " + platform);
}
if (!AVAILABLE_ARCHITECTURES.contains(architecture)) {
throw new IllegalArgumentException("Architecture invalid : " + architecture);
}

InputStream in = null;
String filename = "";
String resourcePath = "/openbas-implant/" + platform + "/" + architecture + "/";
Expand Down
20 changes: 20 additions & 0 deletions openbas-api/src/main/java/io/openbas/utils/AgentUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openbas.utils;

import io.openbas.database.model.Endpoint;
import java.util.List;

public class AgentUtils {

private AgentUtils() {}

public static final List<String> AVAILABLE_PLATFORMS =
List.of(
Endpoint.PLATFORM_TYPE.Linux.name().toLowerCase(),
Endpoint.PLATFORM_TYPE.Windows.name().toLowerCase(),
Endpoint.PLATFORM_TYPE.MacOS.name().toLowerCase());

public static final List<String> AVAILABLE_ARCHITECTURES =
List.of(
Endpoint.PLATFORM_ARCH.x86_64.name().toLowerCase(),
Endpoint.PLATFORM_ARCH.arm64.name().toLowerCase());
}

0 comments on commit 1002ad4

Please sign in to comment.