Skip to content

Commit c2678ac

Browse files
Logfile audit settings validation (#52537)
Add validation for the following logfile audit settings: xpack.security.audit.logfile.events.include xpack.security.audit.logfile.events.exclude xpack.security.audit.logfile.events.ignore_filters.*.users xpack.security.audit.logfile.events.ignore_filters.*.realms xpack.security.audit.logfile.events.ignore_filters.*.roles xpack.security.audit.logfile.events.ignore_filters.*.indices Closes #52357 Relates #47711 #47038 Follows the example from #47246
1 parent 430054f commit c2678ac

File tree

3 files changed

+72
-15
lines changed

3 files changed

+72
-15
lines changed

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java

+20-14
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,33 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
136136
ANONYMOUS_ACCESS_DENIED.toString(), AUTHENTICATION_FAILED.toString(), CONNECTION_DENIED.toString(), TAMPERED_REQUEST.toString(),
137137
RUN_AS_DENIED.toString(), RUN_AS_GRANTED.toString());
138138
public static final Setting<List<String>> INCLUDE_EVENT_SETTINGS = Setting.listSetting(setting("audit.logfile.events.include"),
139-
DEFAULT_EVENT_INCLUDES, Function.identity(), Property.NodeScope, Property.Dynamic);
139+
DEFAULT_EVENT_INCLUDES, Function.identity(), value -> AuditLevel.parse(value, Collections.emptyList()),
140+
Property.NodeScope, Property.Dynamic);
140141
public static final Setting<List<String>> EXCLUDE_EVENT_SETTINGS = Setting.listSetting(setting("audit.logfile.events.exclude"),
141-
Collections.emptyList(), Function.identity(), Property.NodeScope, Property.Dynamic);
142+
Collections.emptyList(), Function.identity(), value -> AuditLevel.parse(Collections.emptyList(), value),
143+
Property.NodeScope, Property.Dynamic);
142144
public static final Setting<Boolean> INCLUDE_REQUEST_BODY = Setting.boolSetting(setting("audit.logfile.events.emit_request_body"),
143145
false, Property.NodeScope, Property.Dynamic);
144146
private static final String FILTER_POLICY_PREFIX = setting("audit.logfile.events.ignore_filters.");
145147
// because of the default wildcard value (*) for the field filter, a policy with
146148
// an unspecified filter field will match events that have any value for that
147149
// particular field, as well as events with that particular field missing
148-
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_PRINCIPALS = Setting.affixKeySetting(FILTER_POLICY_PREFIX,
149-
"users",
150-
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(), Property.NodeScope, Property.Dynamic));
151-
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_REALMS = Setting.affixKeySetting(FILTER_POLICY_PREFIX,
152-
"realms",
153-
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(), Property.NodeScope, Property.Dynamic));
154-
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_ROLES = Setting.affixKeySetting(FILTER_POLICY_PREFIX,
155-
"roles",
156-
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(), Property.NodeScope, Property.Dynamic));
157-
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_INDICES = Setting.affixKeySetting(FILTER_POLICY_PREFIX,
158-
"indices",
159-
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(), Property.NodeScope, Property.Dynamic));
150+
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_PRINCIPALS =
151+
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "users",
152+
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
153+
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
154+
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_REALMS =
155+
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "realms",
156+
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
157+
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
158+
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_ROLES =
159+
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "roles",
160+
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
161+
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
162+
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_INDICES =
163+
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "indices",
164+
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
165+
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
160166

161167
private static final Marker AUDIT_MARKER = MarkerManager.getMarker("org.elasticsearch.xpack.security.audit");
162168

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/AuditTrailSettingsUpdateTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void testInvalidFilterSettings() throws Exception {
9999
settingsBuilder.put(randomFrom(allSettingsKeys), invalidLuceneRegex);
100100
final IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
101101
() -> client().admin().cluster().prepareUpdateSettings().setTransientSettings(settingsBuilder.build()).get());
102-
assertThat(e.getMessage(), containsString("illegal value can't update"));
102+
assertThat(e.getMessage(), containsString("invalid pattern [/invalid]"));
103103
}
104104

105105
public void testDynamicHostSettings() {

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java

+51
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
import java.util.regex.Pattern;
6868

6969
import static org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail.PRINCIPAL_ROLES_FIELD_NAME;
70+
import static org.hamcrest.Matchers.containsInAnyOrder;
71+
import static org.hamcrest.Matchers.containsString;
72+
import static org.hamcrest.Matchers.hasToString;
7073
import static org.hamcrest.Matchers.is;
7174
import static org.hamcrest.Matchers.not;
7275
import static org.hamcrest.Matchers.notNullValue;
@@ -207,6 +210,54 @@ public void clearLog() throws Exception {
207210
CapturingLogger.output(logger.getName(), Level.INFO).clear();
208211
}
209212

213+
public void testEventsSettingValidation() {
214+
final String prefix = "xpack.security.audit.logfile.events.";
215+
Settings settings = Settings.builder().putList(prefix + "include", Arrays.asList("access_granted", "bogus")).build();
216+
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
217+
() -> LoggingAuditTrail.INCLUDE_EVENT_SETTINGS.get(settings));
218+
assertThat(e, hasToString(containsString("invalid event name specified [bogus]")));
219+
220+
Settings settings2 = Settings.builder().putList(prefix + "exclude", Arrays.asList("access_denied", "foo")).build();
221+
e = expectThrows(IllegalArgumentException.class, () -> LoggingAuditTrail.EXCLUDE_EVENT_SETTINGS.get(settings2));
222+
assertThat(e, hasToString(containsString("invalid event name specified [foo]")));
223+
}
224+
225+
public void testAuditFilterSettingValidation() {
226+
final String prefix = "xpack.security.audit.logfile.events.";
227+
Settings settings =
228+
Settings.builder().putList(prefix + "ignore_filters.filter1.users", Arrays.asList("mickey", "/bogus")).build();
229+
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
230+
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace("filter1").get(settings));
231+
assertThat(e, hasToString(containsString("invalid pattern [/bogus]")));
232+
233+
Settings settings2 = Settings.builder()
234+
.putList(prefix + "ignore_filters.filter2.users", Arrays.asList("tom", "cruise"))
235+
.putList(prefix + "ignore_filters.filter2.realms", Arrays.asList("native", "/foo")).build();
236+
assertThat(LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace("filter2").get(settings2),
237+
containsInAnyOrder("tom", "cruise"));
238+
e = expectThrows(IllegalArgumentException.class,
239+
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_REALMS.getConcreteSettingForNamespace("filter2").get(settings2));
240+
assertThat(e, hasToString(containsString("invalid pattern [/foo]")));
241+
242+
Settings settings3 = Settings.builder()
243+
.putList(prefix + "ignore_filters.filter3.realms", Arrays.asList("native", "oidc1"))
244+
.putList(prefix + "ignore_filters.filter3.roles", Arrays.asList("kibana", "/wrong")).build();
245+
assertThat(LoggingAuditTrail.FILTER_POLICY_IGNORE_REALMS.getConcreteSettingForNamespace("filter3").get(settings3),
246+
containsInAnyOrder("native", "oidc1"));
247+
e = expectThrows(IllegalArgumentException.class,
248+
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_ROLES.getConcreteSettingForNamespace("filter3").get(settings3));
249+
assertThat(e, hasToString(containsString("invalid pattern [/wrong]")));
250+
251+
Settings settings4 = Settings.builder()
252+
.putList(prefix + "ignore_filters.filter4.roles", Arrays.asList("kibana", "elastic"))
253+
.putList(prefix + "ignore_filters.filter4.indices", Arrays.asList("index-1", "/no-inspiration")).build();
254+
assertThat(LoggingAuditTrail.FILTER_POLICY_IGNORE_ROLES.getConcreteSettingForNamespace("filter4").get(settings4),
255+
containsInAnyOrder("kibana", "elastic"));
256+
e = expectThrows(IllegalArgumentException.class,
257+
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_INDICES.getConcreteSettingForNamespace("filter4").get(settings4));
258+
assertThat(e, hasToString(containsString("invalid pattern [/no-inspiration]")));
259+
}
260+
210261
public void testAnonymousAccessDeniedTransport() throws Exception {
211262
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
212263

0 commit comments

Comments
 (0)