Skip to content

Commit

Permalink
[backend] Fix MITRE ATT&CK matrix dashboard results (#1670)
Browse files Browse the repository at this point in the history
  • Loading branch information
RomuDeuxfois authored and Dimfacion committed Oct 17, 2024
1 parent 28f035a commit e80f1c6
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,18 @@ public List<RawDocument> documents() {
@PostMapping("/api/documents/search")
public Page<RawPaginationDocument> searchDocuments(@RequestBody @Valid final SearchPaginationInput searchPaginationInput) {
OpenBASPrincipal user = currentUser();
List<Document> securityPlatformLogos = securityPlatformRepository.securityPlatformLogo();
if (user.isAdmin()) {
return buildPaginationJPA(
(Specification<Document> specification, Pageable pageable) -> this.documentRepository.findAll(
specification, pageable),
searchPaginationInput,
Document.class
).map(RawPaginationDocument::new);
).map((document) -> {
var rawPaginationDocument = new RawPaginationDocument(document);
rawPaginationDocument.setDocument_can_be_deleted(!securityPlatformLogos.contains(document));
return rawPaginationDocument;
});
} else {
return buildPaginationJPA(
(Specification<Document> specification, Pageable pageable) -> this.documentRepository.findAll(
Expand All @@ -284,7 +289,11 @@ public Page<RawPaginationDocument> searchDocuments(@RequestBody @Valid final Sea
),
searchPaginationInput,
Document.class
).map(RawPaginationDocument::new);
).map((document) -> {
var rawPaginationDocument = new RawPaginationDocument(document);
rawPaginationDocument.setDocument_can_be_deleted(!securityPlatformLogos.contains(document));
return rawPaginationDocument;
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.openbas.config.SessionHelper.currentUser;
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.utils.AtomicTestingUtils.getExpectationResultByTypesFromRaw;
import static java.util.stream.Collectors.groupingBy;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -96,13 +98,13 @@ private StatisticElement computeUserStat(Instant from, StatisticRepository repos

private List<ExpectationResultsByType> computeGlobalExpectationResults(@NotNull final Instant from) {
List<RawInjectExpectation> rawInjectExpectations = fromIterable(this.exerciseRepository.allInjectExpectationsFromDate(from));
return AtomicTestingUtils.getExpectationResultByTypesFromRaw(rawInjectExpectations);
return getExpectationResultByTypesFromRaw(rawInjectExpectations);
}

private List<ExpectationResultsByType> computeUserExpectationResults(@NotNull final Instant from) {
OpenBASPrincipal user = currentUser();
List<RawInjectExpectation> rawInjectExpectations = fromIterable(this.exerciseRepository.allGrantedInjectExpectationsFromDate(from, user.getId()));
return AtomicTestingUtils.getExpectationResultByTypesFromRaw(rawInjectExpectations);
return getExpectationResultByTypesFromRaw(rawInjectExpectations);
}

private List<InjectExpectationResultsByAttackPattern> computeGlobalInjectExpectationResults(
Expand All @@ -118,43 +120,58 @@ private List<InjectExpectationResultsByAttackPattern> computeUserInjectExpectati
return injectExpectationResultsByAttackPatternFromRawGlobalInjectExpectation(rawGlobalInjectExpectations);
}

private List<InjectExpectationResultsByAttackPattern> injectExpectationResultsByAttackPatternFromRawGlobalInjectExpectation(List<RawGlobalInjectExpectation> rawGlobalInjectExpectations ) {
private List<InjectExpectationResultsByAttackPattern> injectExpectationResultsByAttackPatternFromRawGlobalInjectExpectation(
List<RawGlobalInjectExpectation> rawGlobalInjectExpectations) {
return rawGlobalInjectExpectations.stream()
.map(RawGlobalInjectExpectation::getAttack_pattern_id)
.distinct()
.map(
attackPatternId ->
{
InjectExpectationResultsByAttackPattern resultExpectation = new InjectExpectationResultsByAttackPattern();
resultExpectation.setAttackPattern(new AttackPattern());
resultExpectation.getAttackPattern().setId(attackPatternId);
resultExpectation.setResults(rawGlobalInjectExpectations.stream()
.filter((expectation) -> expectation.getAttack_pattern_id().equals(attackPatternId))
.map((expectation) -> {
InjectExpectationResultsByAttackPattern.InjectExpectationResultsByType resultInjectExpectationResultsByAttackPattern = new InjectExpectationResultsByAttackPattern.InjectExpectationResultsByType();
resultInjectExpectationResultsByAttackPattern.setInjectTitle(expectation.getInject_title());
if(expectation.getInject_expectation_type() != null) {
SimpleRawInjectExpectation rawInjectExpectation = new SimpleRawInjectExpectation();
rawInjectExpectation.setInject_expectation_score(expectation.getInject_expectation_score());
rawInjectExpectation.setInject_expectation_expected_score(expectation.getInject_expectation_expected_score());
rawInjectExpectation.setInject_expectation_type(expectation.getInject_expectation_type());
resultInjectExpectationResultsByAttackPattern
.setResults(AtomicTestingUtils.getExpectationResultByTypesFromRaw(Stream.of(rawInjectExpectation)
.collect(Collectors.toList())));
} else {
resultInjectExpectationResultsByAttackPattern
.setResults(AtomicTestingUtils.getExpectationResultByTypesFromRaw(new ArrayList<>()));
}
return resultInjectExpectationResultsByAttackPattern;
})
.collect(Collectors.toList())
);

return resultExpectation;
}
)
.collect(Collectors.toList())
;
.map(RawGlobalInjectExpectation::getAttack_pattern_id)
.distinct()
.map(
attackPatternId ->
{
InjectExpectationResultsByAttackPattern resultExpectation = new InjectExpectationResultsByAttackPattern();
resultExpectation.setAttackPattern(new AttackPattern());
resultExpectation.getAttackPattern().setId(attackPatternId);

Map<String, Map<String, List<RawGlobalInjectExpectation>>> rawGlobalInjectExpectationsGroupByAttackAndInjectId = rawGlobalInjectExpectations.stream()
.collect(groupingBy(RawGlobalInjectExpectation::getAttack_pattern_id,
groupingBy(RawGlobalInjectExpectation::getInject_id)));

List<InjectExpectationResultsByAttackPattern.InjectExpectationResultsByType> results = new ArrayList<>();

rawGlobalInjectExpectationsGroupByAttackAndInjectId.forEach((attackId, injects) -> {
if (attackId.equals(attackPatternId)) {
injects.forEach((injectId, expectations) -> {
RawGlobalInjectExpectation expectation = expectations.getFirst();
InjectExpectationResultsByAttackPattern.InjectExpectationResultsByType resultInjectExpectationResultsByAttackPattern = new InjectExpectationResultsByAttackPattern.InjectExpectationResultsByType();
resultInjectExpectationResultsByAttackPattern.setInjectTitle(expectation.getInject_title());

ArrayList<RawInjectExpectation> expectationsRefined = new ArrayList<>();

expectations.stream().forEach(e -> {
if (e.getInject_expectation_type() != null) {
SimpleRawInjectExpectation rawInjectExpectation = new SimpleRawInjectExpectation();
rawInjectExpectation.setInject_expectation_score(e.getInject_expectation_score());
rawInjectExpectation.setInject_expectation_expected_score(
e.getInject_expectation_expected_score());
rawInjectExpectation.setInject_expectation_type(e.getInject_expectation_type());
expectationsRefined.add(rawInjectExpectation);
}
});

resultInjectExpectationResultsByAttackPattern
.setResults(AtomicTestingUtils.getExpectationResultByTypesFromRaw(expectationsRefined));

results.add(resultInjectExpectationResultsByAttackPattern);
});
}
});

resultExpectation.setResults(results);

return resultExpectation;
}
)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const DocumentPopover = (props) => {
</MenuItem>
)}
{!onRemoveDocument && (
<MenuItem onClick={handleOpenDelete}>
<MenuItem onClick={handleOpenDelete} disabled={!document.document_can_be_deleted}>
{t('Delete')}
</MenuItem>
)}
Expand Down
10 changes: 5 additions & 5 deletions openbas-front/src/utils/api-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,7 @@ export interface InjectorConnection {

export interface InjectorContract {
convertedContent?: object;
injector_contract_arch?: "x86_64" | "arm64" | "Unknown";
injector_contract_atomic_testing?: boolean;
injector_contract_attack_patterns?: AttackPattern[];
injector_contract_content: string;
Expand Down Expand Up @@ -1493,6 +1494,7 @@ export interface InjectorContractInput {
}

export interface InjectorContractOutput {
injector_contract_arch?: "x86_64" | "arm64" | "Unknown";
injector_contract_attack_patterns?: string[];
injector_contract_content: string;
injector_contract_id: string;
Expand All @@ -1509,7 +1511,6 @@ export interface InjectorContractOutput {
| "Internal"
| "Unknown"
)[];
injector_contract_arch?: "x86_64" | "arm64";
}

export interface InjectorContractUpdateInput {
Expand Down Expand Up @@ -2363,7 +2364,6 @@ export interface Payload {
payload_type?: string;
/** @format date-time */
payload_updated_at: string;
executable_arch?: "x86_64" | "arm64";
}

export interface PayloadArgument {
Expand All @@ -2377,8 +2377,8 @@ export interface PayloadCreateInput {
command_content?: string;
command_executor?: string;
dns_resolution_hostname?: string;
executable_arch?: "x86_64" | "arm64" | "Unknown";
executable_file?: string;
executable_arch?: "x86_64" | "arm64";
file_drop_file?: string;
payload_arguments?: PayloadArgument[];
payload_attack_patterns?: string[];
Expand All @@ -2405,6 +2405,7 @@ export interface PayloadUpdateInput {
command_content?: string;
command_executor?: string;
dns_resolution_hostname?: string;
executable_arch?: "x86_64" | "arm64" | "Unknown";
executable_file?: string;
file_drop_file?: string;
payload_arguments?: PayloadArgument[];
Expand Down Expand Up @@ -2598,6 +2599,7 @@ export interface RawDocument {
}

export interface RawPaginationDocument {
document_can_be_deleted?: boolean;
document_description?: string;
document_exercises?: string[];
document_id?: string;
Expand Down Expand Up @@ -2631,8 +2633,6 @@ export interface RawPaginationScenario {
}

export interface RawUser {
/** @format date-time */
user_created_at?: string;
user_email?: string;
user_firstname?: string;
user_gravatar?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public interface RawGlobalInjectExpectation {

Double getInject_expectation_expected_score();

String getInject_id();

String getInject_title();

String getAttack_pattern_id();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class RawPaginationDocument {
List<String> document_scenarios;
String document_type;
List<String> document_tags;
boolean document_can_be_deleted = true;

public RawPaginationDocument(final Document document) {
this.document_id = document.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ List<RawInjectExpectation> allGrantedInjectExpectationsFromDate(@Param("from") I
* @return a list of expectations
*/
@Query(value =
"SELECT ie.inject_expectation_type, ie.inject_expectation_score, ie.inject_expectation_expected_score, injects.inject_title, icap.attack_pattern_id "
"SELECT ie.inject_expectation_type, ie.inject_expectation_score, ie.inject_expectation_expected_score, "
+ "injects.inject_id, injects.inject_title, icap.attack_pattern_id "
+
"FROM exercises " +
"INNER JOIN injects ON exercises.exercise_id = injects.inject_exercise " +
"LEFT JOIN injects_expectations ie ON injects.inject_id = ie.exercise_id " +
"JOIN injects_expectations ie ON injects.inject_id = ie.inject_id " +
"INNER JOIN injectors_contracts ic ON injects.inject_injector_contract = ic.injector_contract_id " +
"INNER JOIN injectors_contracts_attack_patterns icap ON ic.injector_contract_id = icap.injector_contract_id "
+
Expand All @@ -115,7 +116,8 @@ List<RawInjectExpectation> allGrantedInjectExpectationsFromDate(@Param("from") I
* @return the list of global expectations
*/
@Query(value =
"SELECT ie.inject_expectation_type, ie.inject_expectation_score, ie.inject_expectation_expected_score, injects.inject_title, icap.attack_pattern_id "
"SELECT ie.inject_expectation_type, ie.inject_expectation_score, ie.inject_expectation_expected_score, "
+ "injects.inject_id, injects.inject_title, icap.attack_pattern_id "
+
"FROM exercises " +
"INNER JOIN injects ON exercises.exercise_id = injects.inject_exercise " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openbas.database.repository;

import io.openbas.database.model.Document;
import io.openbas.database.model.SecurityPlatform;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -8,6 +9,7 @@
import org.springframework.stereotype.Repository;

import java.time.Instant;
import java.util.List;
import java.util.Optional;

@Repository
Expand All @@ -29,4 +31,9 @@ public interface SecurityPlatformRepository extends CrudRepository<SecurityPlatf
@Override
@Query("select count(distinct s) from SecurityPlatform s where s.createdAt < :creationDate")
long globalCount(@Param("creationDate") Instant creationDate);

@Query("select distinct s.logoDark from SecurityPlatform s " +
"union " +
"select distinct s.logoLight from SecurityPlatform s ")
List<Document> securityPlatformLogo();
}

0 comments on commit e80f1c6

Please sign in to comment.