Skip to content
Merged
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
13 changes: 9 additions & 4 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,25 @@ RUN wget https://github.com/zaproxy/zaproxy/releases/download/v2.16.1/ZAP_2.16.1

# Rest of the Dockerfile remains unchanged
RUN mkdir /opt/kics
RUN mkdir /opt/dtrack
#RUN mkdir /opt/dtrack
COPY --from=kics /app/bin/kics /usr/local/bin/kics
COPY --from=kics /app/bin/assets /opt/tools/kics/assets
RUN rm -rf /opt/tools/kics/assets/queries/openAPI
RUN rm -rf /opt/tools/kics/assets/queries/common/passwords_and_secrets

# Setup Dependency-Track
RUN wget https://github.com/DependencyTrack/dependency-track/releases/download/4.13.6/dependency-track-bundled.jar -P /opt/dtrack/
## Setup Dependency-Track
#RUN wget https://github.com/DependencyTrack/dependency-track/releases/download/4.13.6/dependency-track-bundled.jar -P /opt/dtrack/

# Download and install the appropriate gitleaks for the architecture
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
wget -O gitleaks.tar.gz https://github.com/gitleaks/gitleaks/releases/download/v8.12.0/gitleaks_8.12.0_linux_x64.tar.gz; \
wget -O bearer.tar.gz https://github.com/Bearer/bearer/releases/download/v1.50.2/bearer_1.50.2_linux_amd64.tar.gz; \
wget -O grype.tar.gz https://github.com/anchore/grype/releases/download/v0.104.2/grype_0.104.2_linux_amd64.tar.gz; \
elif [ "$ARCH" = "aarch64" ]; then \
wget -O gitleaks.tar.gz https://github.com/gitleaks/gitleaks/releases/download/v8.12.0/gitleaks_8.12.0_linux_arm64.tar.gz; \
wget -O bearer.tar.gz https://github.com/Bearer/bearer/releases/download/v1.50.2/bearer_1.50.2_linux_arm64.tar.gz; \
wget -O grype.tar.gz https://github.com/anchore/grype/releases/download/v0.104.2/grype_0.104.2_linux_arm64.tar.gz; \
else \
echo "Unsupported architecture: $ARCH"; \
exit 1; \
Expand All @@ -131,7 +133,10 @@ RUN ARCH=$(uname -m) && \
rm gitleaks.tar.gz && \
tar -xzf bearer.tar.gz && \
mv bearer /usr/local/bin/bearer && \
rm bearer.tar.gz
rm bearer.tar.gz && \
tar -xzf grype.tar.gz && \
mv grype /usr/local/bin/grype && \
rm grype.tar.gz

# Create directory for Bearer rules
RUN mkdir -p /opt/bearer
Expand Down
20 changes: 10 additions & 10 deletions backend/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ else
SPRING_PROFILE="prod"
fi

# Start Dependency-Track in the background with 4GB of memory and log output to a file
LOG_FILE="/var/log/dtrack.log"
echo "Starting Dependency-Track..."
if [ -n "$PROXY_HOST" ] && [ -n "$PROXY_PORT" ]; then
java -Xmx4g -Dhttp.proxyHost=$PROXY_HOST -Dhttp.proxyPort=$PROXY_PORT -Dhttps.proxyHost=$PROXY_HOST -Dhttps.proxyPort=$PROXY_PORT -Dcom.sun.net.ssl.checkRevocation=false -Djavax.net.ssl.trustAll=true -Djavax.net.ssl.trustStore=/dev/null -Djavax.net.ssl.trustAll=true -Djavax.net.ssl.verifyHostname=false -jar /opt/dtrack/dependency-track-bundled.jar >> $LOG_FILE 2>&1 &
else
java -Xmx4g -jar /opt/dtrack/dependency-track-bundled.jar >> $LOG_FILE 2>&1 &
fi

sleep 30
## Start Dependency-Track in the background with 4GB of memory and log output to a file
#LOG_FILE="/var/log/dtrack.log"
#echo "Starting Dependency-Track..."
#if [ -n "$PROXY_HOST" ] && [ -n "$PROXY_PORT" ]; then
# java -Xmx4g -Dhttp.proxyHost=$PROXY_HOST -Dhttp.proxyPort=$PROXY_PORT -Dhttps.proxyHost=$PROXY_HOST -Dhttps.proxyPort=$PROXY_PORT -Dcom.sun.net.ssl.checkRevocation=false -Djavax.net.ssl.trustAll=true -Djavax.net.ssl.trustStore=/dev/null -Djavax.net.ssl.trustAll=true -Djavax.net.ssl.verifyHostname=false -jar /opt/dtrack/dependency-track-bundled.jar >> $LOG_FILE 2>&1 &
#else
# java -Xmx4g -jar /opt/dtrack/dependency-track-bundled.jar >> $LOG_FILE 2>&1 &
#fi
#
#sleep 30

# Start ZAP daemon
ZAP_LOG_FILE="/var/log/zap.log"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public ResponseEntity<ServiceStatusDTO> status() {
profile = activeProfiles[0];
}
try {
return new ResponseEntity<>(new ServiceStatusDTO(profile, appConfigService.isSaasMode() ? "SAAS":"SANDALONE"), HttpStatus.OK);
return new ResponseEntity<>(new ServiceStatusDTO(profile, appConfigService.isSaasMode() ? "SAAS":"STANDALONE"), HttpStatus.OK);
} catch (Exception e){
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.mixeway.mixewayflowapi.db.repository.CodeRepoBranchRepository;
import io.mixeway.mixewayflowapi.db.repository.UserRepository;
import io.mixeway.mixewayflowapi.domain.coderepo.FindCodeRepoService;
import io.mixeway.mixewayflowapi.domain.coderepobranch.GetOrCreateCodeRepoBranchService;
import io.mixeway.mixewayflowapi.domain.finding.FindFindingService;
import io.mixeway.mixewayflowapi.domain.team.FindTeamService;
import io.mixeway.mixewayflowapi.scanmanager.service.ScanManagerService;
Expand All @@ -30,6 +31,7 @@ public class GitLabCICDService {
private final CodeRepoBranchRepository codeRepoBranchRepository;
private final ScanManagerService scanManagerService;
private final FindingService findingService;
GetOrCreateCodeRepoBranchService getOrCreateCodeRepoBranchService;

public Boolean isValidApiKey(String apiKey, String repoUrl) {
Optional<UserInfo> userOptional = userRepository.findByApiKey(apiKey);
Expand All @@ -54,7 +56,7 @@ public CodeRepo getCodeRepo(String repoUrl) {
}

public CodeRepoBranch getCodeRepoBranch(String branch, CodeRepo codeRepo) {
return codeRepoBranchRepository.findByNameAndCodeRepo(branch, codeRepo).get();
return getOrCreateCodeRepoBranchService.getOrCreateCodeRepoBranch(branch, codeRepo);
}

public void runCodeRepoScan(CodeRepo codeRepo, CodeRepoBranch codeRepoBranch) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class UpdateCodeRepoService {
private final FindingRepository findingRepository;
private final CreateScanInfoService createScanInfoService;
private final FindCodeRepoService findCodeRepoService;
private boolean scaScanPerformed;

/**
* Updates the SCA UUID for a given {@link CodeRepo}.
Expand Down Expand Up @@ -59,11 +60,10 @@ public void updateComponents(List<Component> components, CodeRepo codeRepo) {
*
* @param codeRepo the {@link CodeRepo} entity to update
* @param codeRepoBranch the {@link CodeRepoBranch} entity associated with the code repository
* @param scaScanPerformed a boolean indicating if an SCA scan was performed
* @param commitId the commit ID associated with the scan
*/
@Transactional
public void updateCodeRepoStatus(CodeRepo codeRepo, CodeRepoBranch codeRepoBranch, boolean scaScanPerformed, String commitId) {
public void updateCodeRepoStatus(CodeRepo codeRepo, CodeRepoBranch codeRepoBranch, String commitId) {
codeRepo = findCodeRepoService.findById(codeRepo.getId()).get();
if (codeRepoBranch == null) {
codeRepoBranch = codeRepo.getDefaultBranch();
Expand Down Expand Up @@ -117,6 +117,63 @@ public void updateCodeRepoStatus(CodeRepo codeRepo, CodeRepoBranch codeRepoBranc
countCriticalFindings(Finding.Source.DAST, codeRepo, codeRepoBranch)
);
}
// Dependency Track version
// @Transactional
// public void updateCodeRepoStatus(CodeRepo codeRepo, CodeRepoBranch codeRepoBranch, boolean scaScanPerformed, String commitId) {
// this.scaScanPerformed = scaScanPerformed;
// codeRepo = findCodeRepoService.findById(codeRepo.getId()).get();
// if (codeRepoBranch == null) {
// codeRepoBranch = codeRepo.getDefaultBranch();
// }
// // Update status for SECRETS
// int secretsHigh = updateStatusForSource(Finding.Source.SECRETS, codeRepo, codeRepoBranch, false);
//
// // Update status for SAST
// int sastHigh = updateStatusForSource(Finding.Source.SAST, codeRepo, codeRepoBranch, false);
//
// // Update status for IaC
// int iacHigh = updateStatusForSource(Finding.Source.IAC, codeRepo, codeRepoBranch, false);
//
// int gitlabHigh = updateStatusForSource(Finding.Source.GITLAB_SCANNER, codeRepo, codeRepoBranch, false);
// int dastHigh = updateStatusForSource(Finding.Source.DAST, codeRepo, codeRepoBranch, false);
//
// // Initialize SCA counts
// int scaHigh = 0;
// int scaCritical = 0;
//
// // Update status for SCA if the scan was performed
// if (!codeRepo.getComponents().isEmpty()) {
// scaHigh = updateStatusForSource(Finding.Source.SCA, codeRepo, codeRepoBranch, false);
// scaCritical = countCriticalFindings(Finding.Source.SCA, codeRepo, codeRepoBranch);
// } else {
// scaHigh = updateStatusForSource(Finding.Source.SCA, codeRepo, codeRepoBranch, true);
// scaCritical = countCriticalFindings(Finding.Source.SCA, codeRepo, codeRepoBranch);
// }
//
// // Create or update ScanInfo snapshot
// createScanInfoService.createOrUpdateScanInfo(
// codeRepo,
// codeRepoBranch,
// commitId,
// codeRepo.getScaScan(),
// codeRepo.getSastScan(),
// codeRepo.getIacScan(),
// codeRepo.getSecretsScan(),
// codeRepo.getGitlabScan(),
// scaHigh,
// scaCritical,
// sastHigh,
// countCriticalFindings(Finding.Source.SAST, codeRepo, codeRepoBranch),
// iacHigh,
// countCriticalFindings(Finding.Source.IAC, codeRepo, codeRepoBranch),
// secretsHigh,
// countCriticalFindings(Finding.Source.SECRETS, codeRepo, codeRepoBranch),
// gitlabHigh,
// countCriticalFindings(Finding.Source.GITLAB_SCANNER, codeRepo, codeRepo.getDefaultBranch()),
// dastHigh,
// countCriticalFindings(Finding.Source.DAST, codeRepo, codeRepoBranch)
// );
// }

/**
* Updates the scan status for a specific source (SAST, SCA, IaC, Secrets) based on findings.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package io.mixeway.mixewayflowapi.domain.finding;

import io.mixeway.mixewayflowapi.db.entity.*;
import io.mixeway.mixewayflowapi.db.repository.CodeRepoRepository;
import io.mixeway.mixewayflowapi.db.repository.FindingRepository;
import io.mixeway.mixewayflowapi.domain.coderepo.UpdateCodeRepoService;
import io.mixeway.mixewayflowapi.domain.component.GetOrCreateComponentService;
import io.mixeway.mixewayflowapi.domain.suppressrule.CheckSuppressRuleService;
import io.mixeway.mixewayflowapi.domain.vulnerability.GetOrCreateVulnerabilityService;
import io.mixeway.mixewayflowapi.integrations.scanner.cloud_scanner.dto.CloudIssueReport;
import io.mixeway.mixewayflowapi.integrations.scanner.cloud_scanner.dto.CloudScannerReport;
import io.mixeway.mixewayflowapi.integrations.scanner.iac.dto.KicsReport;
import io.mixeway.mixewayflowapi.integrations.scanner.sast.dto.BearerScanSecurity;
import io.mixeway.mixewayflowapi.integrations.scanner.sast.dto.Item;
import io.mixeway.mixewayflowapi.integrations.scanner.sca.dto.GrypeReport;
import io.mixeway.mixewayflowapi.integrations.scanner.secrets.dto.Secret;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.hibernate.Hibernate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -28,6 +34,9 @@ public class CreateFindingService {
private final FindingRepository findingRepository;
private final GetOrCreateVulnerabilityService getOrCreateVulnerabilityService;
private final CheckSuppressRuleService checkSuppressRuleService;
private final GetOrCreateComponentService getOrCreateComponentService;
private final UpdateCodeRepoService updateCodeRepoService;
private final CodeRepoRepository codeRepoRepository;

@Transactional
public void saveFindings(List<Finding> newFindings, CodeRepoBranch repoWhereFindingWasFound, CodeRepo repoInWhichFindingWasFound, Finding.Source source, CloudSubscription cloudSubscription) {
Expand Down Expand Up @@ -289,6 +298,88 @@ public List<Finding> mapBearerScanToFindings(BearerScanSecurity scanSecurity, Co
return findings;
}

@Transactional
public void processGrypeComponents(GrypeReport grypeReport, CodeRepo codeRepo) {
CodeRepo managedRepo = codeRepoRepository.findById(codeRepo.getId())
.orElseThrow(() -> new IllegalArgumentException("CodeRepo not found"));

List<Component> components = grypeReport.getMatches().stream()
.map(match -> getOrCreateComponentService.getOrCreate(
match.getArtifact().getName(),
match.getArtifact().getType(),
match.getArtifact().getVersion(),
"nvd"
))
.distinct()
.toList();

updateCodeRepoService.updateComponents(components, managedRepo);
}


@Transactional
public List<Finding> mapGrypeReportToFindings(GrypeReport grypeReport, CodeRepo codeRepo, CodeRepoBranch codeRepoBranch) {
List<Finding> findings = new ArrayList<>();

for (GrypeReport.Match match : grypeReport.getMatches()) {
GrypeReport.Vulnerability vuln = match.getVulnerability();
GrypeReport.Artifact artifact = match.getArtifact();

Component component = getOrCreateComponentService.getOrCreate(
artifact.getName(),
artifact.getType(),
artifact.getVersion(),
"nvd"
);

BigDecimal epssProbability = null;
BigDecimal epssPercentile = null;
if (vuln.getEpss() != null && !vuln.getEpss().isEmpty()) {
epssProbability = BigDecimal.valueOf(vuln.getEpss().get(0).getEpss());
epssPercentile = BigDecimal.valueOf(vuln.getEpss().get(0).getPercentile());
}

String recommendation = null;
if (vuln.getFix() != null && vuln.getFix().getVersions() != null && !vuln.getFix().getVersions().isEmpty()) {
recommendation = "Update package to version " + vuln.getFix().getVersions().get(0);
}

Vulnerability vulnerability = getOrCreateVulnerabilityService.getOrCreate(
vuln.getId(),
vuln.getDescription(),
vuln.getDataSource(),
recommendation,
mapSeverity(vuln.getSeverity()),
epssProbability,
epssPercentile,
null
);

Hibernate.initialize(vulnerability.getComponents());
if (!vulnerability.getComponents().contains(component)) {
vulnerability.getComponents().add(component);
}

String location = (artifact.getName() != null ? artifact.getName() : "") +
(artifact.getVersion() != null ? ":" + artifact.getVersion() : "");

Finding finding = new Finding(
vulnerability,
component,
codeRepoBranch,
codeRepo,
null,
vuln.getDescription(),
location,
mapSeverity(vuln.getSeverity()),
Finding.Source.SCA
);
findings.add(finding);
}

return findings;
}

private List<Finding> mapItemsToFindings(List<Item> items, CodeRepoBranch codeRepoBranch, CodeRepo codeRepo, Finding.Severity severity) {
return items.stream().map(item -> {
Vulnerability vulnerability = getOrCreateVulnerabilityService.getOrCreate(item.getTitle(), item.getDescription(), null, item.getDocumentationUrl(), null, null, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public CloudIssueReport runCloudIssueScanner(String projectId, String wizAuthTok
ObjectMapper objectMapper = new ObjectMapper();
String cloudIssueJSONReport = fetchCloudIssues(projectId, wizAuthToken);
CloudIssueReport cloudIssueReport = objectMapper.readValue(cloudIssueJSONReport, CloudIssueReport.class);

return cloudIssueReport;
}

Expand Down
Loading