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

Adds user validation for threat intel transport layer classes and stashes the thread context for all system index interactions #1207

Merged
merged 1 commit into from
Jul 31, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,57 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.OpenSearchStatusException;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.HandledTransportAction;
import org.opensearch.common.inject.Inject;
import org.opensearch.common.settings.Settings;
import org.opensearch.commons.authuser.User;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.securityanalytics.settings.SecurityAnalyticsSettings;
import org.opensearch.securityanalytics.threatIntel.action.SADeleteTIFSourceConfigAction;
import org.opensearch.securityanalytics.threatIntel.action.SADeleteTIFSourceConfigRequest;
import org.opensearch.securityanalytics.threatIntel.action.SADeleteTIFSourceConfigResponse;
import org.opensearch.securityanalytics.threatIntel.service.SATIFSourceConfigManagementService;
import org.opensearch.securityanalytics.transport.SecureTransportAction;
import org.opensearch.securityanalytics.util.SecurityAnalyticsException;
import org.opensearch.tasks.Task;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;

public class TransportDeleteTIFSourceConfigAction extends HandledTransportAction<SADeleteTIFSourceConfigRequest, SADeleteTIFSourceConfigResponse> implements SecureTransportAction {

private static final Logger log = LogManager.getLogger(TransportDeleteTIFSourceConfigAction.class);

private final Settings settings;
private final ThreadPool threadPool;
private volatile Boolean filterByEnabled;
private final SATIFSourceConfigManagementService saTifConfigService;

@Inject
public TransportDeleteTIFSourceConfigAction(TransportService transportService,
ActionFilters actionFilters,
Settings settings,
final ThreadPool threadPool,
final SATIFSourceConfigManagementService saTifConfigService) {
super(SADeleteTIFSourceConfigAction.NAME, transportService, actionFilters, SADeleteTIFSourceConfigRequest::new);
this.settings = settings;
this.threadPool = threadPool;
this.filterByEnabled = SecurityAnalyticsSettings.FILTER_BY_BACKEND_ROLES.get(this.settings);
this.saTifConfigService = saTifConfigService;
}

@Override
protected void doExecute(Task task, SADeleteTIFSourceConfigRequest request, ActionListener<SADeleteTIFSourceConfigResponse> actionListener) {
User user = readUserFromThreadContext(this.threadPool);
String validateBackendRoleMessage = validateUserBackendRoles(user, this.filterByEnabled);
if (!"".equals(validateBackendRoleMessage)) {
actionListener.onFailure(SecurityAnalyticsException.wrap(new OpenSearchStatusException(validateBackendRoleMessage, RestStatus.FORBIDDEN)));
return;
}
this.threadPool.getThreadContext().stashContext();

saTifConfigService.deleteTIFSourceConfig(request.getId(), ActionListener.wrap(
response -> actionListener.onResponse(
new SADeleteTIFSourceConfigResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ protected void doExecute(Task task, GetIocFindingsRequest request, ActionListene
actionListener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

Table tableProp = request.getTable();
FieldSortBuilder sortBuilder = SortBuilders
.fieldSort(tableProp.getSortString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ protected void doExecute(Task task, SAGetTIFSourceConfigRequest request, ActionL
actionListener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}

this.threadPool.getThreadContext().stashContext();

saTifConfigService.getTIFSourceConfig(request.getId(), ActionListener.wrap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ protected void doExecute(final Task task, final SAIndexTIFSourceConfigRequest re
listener.onFailure(SecurityAnalyticsException.wrap(new OpenSearchStatusException(validateBackendRoleMessage, RestStatus.FORBIDDEN)));
return;
}
this.threadPool.getThreadContext().stashContext();

retrieveLockAndCreateTIFConfig(request, listener, user);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
import org.opensearch.action.support.HandledTransportAction;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.common.inject.Inject;
import org.opensearch.common.settings.Settings;
import org.opensearch.commons.authuser.User;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.index.engine.VersionConflictEngineException;
import org.opensearch.jobscheduler.spi.LockModel;
import org.opensearch.securityanalytics.settings.SecurityAnalyticsSettings;
import org.opensearch.securityanalytics.threatIntel.action.PutTIFJobAction;
import org.opensearch.securityanalytics.threatIntel.action.PutTIFJobRequest;
import org.opensearch.securityanalytics.threatIntel.action.ThreatIntelIndicesResponse;
Expand All @@ -27,6 +30,7 @@
import org.opensearch.securityanalytics.threatIntel.model.TIFJobParameter;
import org.opensearch.securityanalytics.threatIntel.service.TIFJobParameterService;
import org.opensearch.securityanalytics.threatIntel.service.TIFJobUpdateService;
import org.opensearch.securityanalytics.transport.SecureTransportAction;
import org.opensearch.tasks.Task;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
Expand All @@ -40,13 +44,16 @@
/**
* Transport action to create job to fetch threat intel feed data and save IoCs
*/
public class TransportPutTIFJobAction extends HandledTransportAction<PutTIFJobRequest, AcknowledgedResponse> {
public class TransportPutTIFJobAction extends HandledTransportAction<PutTIFJobRequest, AcknowledgedResponse> implements SecureTransportAction {
// TODO refactor this into a service class that creates feed updation job. This is not necessary to be a transport action
private static final Logger log = LogManager.getLogger(TransportPutTIFJobAction.class);

private final TIFJobParameterService tifJobParameterService;
private final TIFJobUpdateService tifJobUpdateService;
private final TIFLockService lockService;
private final Settings settings;
private final ThreadPool threadPool;
private volatile Boolean filterByEnabled;

/**
* Default constructor
Expand All @@ -64,16 +71,29 @@ public TransportPutTIFJobAction(
final ThreadPool threadPool,
final TIFJobParameterService tifJobParameterService,
final TIFJobUpdateService tifJobUpdateService,
final TIFLockService lockService
final TIFLockService lockService,
Settings settings
) {
super(PutTIFJobAction.NAME, transportService, actionFilters, PutTIFJobRequest::new);
this.tifJobParameterService = tifJobParameterService;
this.tifJobUpdateService = tifJobUpdateService;
this.lockService = lockService;
this.threadPool = threadPool;
this.settings = settings;
this.filterByEnabled = SecurityAnalyticsSettings.FILTER_BY_BACKEND_ROLES.get(this.settings);
}

@Override
protected void doExecute(final Task task, final PutTIFJobRequest request, final ActionListener<AcknowledgedResponse> listener) {
User user = readUserFromThreadContext(this.threadPool);

String validateBackendRoleMessage = validateUserBackendRoles(user, this.filterByEnabled);
if (!"".equals(validateBackendRoleMessage)) {
listener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

try {
lockService.acquireLock(request.getName(), LOCK_DURATION_IN_SECONDS, ActionListener.wrap(lock -> {
if (lock == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ protected void doExecute(Task task, SARefreshTIFSourceConfigRequest request, Act
actionListener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

saTifSourceConfigManagementService.refreshTIFSourceConfig(request.getId(), user, ActionListener.wrap(
r -> actionListener.onResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ protected void doExecute(Task task, SASearchTIFSourceConfigsRequest request, Act
actionListener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}

this.threadPool.getThreadContext().stashContext(); // stash context to make calls as admin client

StepListener<Void> defaultTifConfigsLoadedListener;
try {
defaultTifConfigsLoadedListener = new StepListener<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ protected void doExecute(Task task, DeleteThreatIntelMonitorRequest request, Act
listener.onFailure(SecurityAnalyticsException.wrap(new OpenSearchStatusException(validateBackendRoleMessage, RestStatus.FORBIDDEN)));
return;
}
this.threadPool.getThreadContext().stashContext();

AlertingPluginInterface.INSTANCE.deleteMonitor((NodeClient) client,
new DeleteMonitorRequest(request.getMonitorId(), WriteRequest.RefreshPolicy.IMMEDIATE),
listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ protected void doExecute(Task task, GetThreatIntelAlertsRequest request, ActionL
listener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

//fetch monitors and search
SearchRequest threatIntelMonitorsSearchRequest = new SearchRequest();
threatIntelMonitorsSearchRequest.indices(".opendistro-alerting-config");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ protected void doExecute(Task task, IndexThreatIntelMonitorRequest request, Acti
listener.onFailure(SecurityAnalyticsException.wrap(new OpenSearchStatusException(validateBackendRoleMessage, RestStatus.FORBIDDEN)));
return;
}
this.threadPool.getThreadContext().stashContext();

if(request.getMethod().equals(RestRequest.Method.PUT)) {
indexMonitor(request, listener, user);
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.opensearch.securityanalytics.threatIntel.transport.monitor;

import org.opensearch.OpenSearchStatusException;
import org.opensearch.action.search.SearchResponse;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.HandledTransportAction;
Expand All @@ -17,6 +18,7 @@
import org.opensearch.commons.authuser.User;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.bytes.BytesReference;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
Expand Down Expand Up @@ -70,7 +72,11 @@ protected void doExecute(Task task, SearchThreatIntelMonitorRequest request, Act
// log.info("Filtering result by: {}", user.getBackendRoles());
// addFilter(user, request.searchRequest().source(), "detector.user.backend_roles.keyword");
// } // TODO

String validateBackendRoleMessage = validateUserBackendRoles(user, this.filterByEnabled);
if (!"".equals(validateBackendRoleMessage)) {
listener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

//TODO change search request to fetch threat intel monitors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ protected void doExecute(Task task, UpdateThreatIntelAlertStatusRequest request,
listener.onFailure(new OpenSearchStatusException("Do not have permissions to resource", RestStatus.FORBIDDEN));
return;
}
this.threadPool.getThreadContext().stashContext();

//fetch monitors and search
SearchRequest threatIntelMonitorsSearchRequest = new SearchRequest();
threatIntelMonitorsSearchRequest.indices(".opendistro-alerting-config");
Expand Down
Loading