Skip to content
Permalink
Browse files

ITT-1783 REST API: Validate masked fields when regex or custom hashin…

…g algo used
  • Loading branch information...
floragunncom committed Dec 13, 2018
1 parent 4af8dde commit 0bf3c1849b2afca8f9a7950b20174b2d79f6487d
@@ -253,6 +253,12 @@
<version>${guava.version}</version>
</dependency>

<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.4.0</version>
</dependency>

<!-- Only test scoped dependencies hereafter -->

<dependency>
@@ -46,7 +46,7 @@ public MaskedField(final String value, final byte[] defaultSalt) {
algo = tokens.get(1);
} else if (tokenCount >= 3 && tokenCount%2==1) {
name = tokens.get(0);
regexReplacements = new ArrayList<>();
regexReplacements = new ArrayList<>((tokenCount-1)/2);
for(int i=1; i<tokenCount-1; i=i+2) {
regexReplacements.add(new RegexReplacement(tokens.get(i), tokens.get(i+1)));
}
@@ -55,6 +55,10 @@ public MaskedField(final String value, final byte[] defaultSalt) {
}
}

public final void isValid() throws Exception {
mask(new byte[] {1,2,3,4,5});
}

public byte[] mask(byte[] value) {
if (isDefault()) {
return blake2bHash(value);
@@ -32,6 +32,7 @@
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;

@@ -204,7 +205,7 @@ public XContentBuilder errorsAsXContent() {
builder.startObject();
switch (this.errorType) {
case NONE:
return null;
return XContentBuilder.builder(JsonXContent.jsonXContent);
case INVALID_CONFIGURATION:
builder.field("status", "error");
builder.field("reason", ErrorType.INVALID_CONFIGURATION.getMessage());
@@ -14,10 +14,15 @@

package com.floragunn.searchguard.dlic.rest.validation;

import java.util.List;

import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;

import com.floragunn.searchguard.configuration.MaskedField;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;

public class RolesValidator extends AbstractConfigurationValidator {

@@ -31,4 +36,45 @@ public RolesValidator(final RestRequest request, final BytesReference ref, final
mandatoryOrKeys.add("indices");
mandatoryOrKeys.add("cluster");
}

@Override
public boolean validateSettings() {

if (!super.validateSettings()) {
return false;
}

boolean valid=true;

if (this.content != null && this.content.length() > 0) {

final ReadContext ctx = JsonPath.parse(this.content.utf8ToString());
final List<String> maskedFields = ctx.read("$.._masked_fields_[*]");

if (maskedFields != null) {

for (String mf : maskedFields) {
if (!validateMaskedFieldSyntax(mf)) {
valid = false;
}
}
}
}

if(!valid) {
this.errorType = ErrorType.WRONG_DATATYPE;
}

return valid;
}

private boolean validateMaskedFieldSyntax(String mf) {
try {
new MaskedField(mf, new byte[] {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,6}).isValid();
} catch (Exception e) {
wrongDatatypes.put("Masked field not valid: "+mf, e.getMessage());
return false;
}
return true;
}
}
@@ -342,7 +342,15 @@ public void testRolesApi() throws Exception {
response = rh.executeGetRequest("/_searchguard/api/roles/bulknew1", new Header[0]);
Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode());

// put valid field masks
response = rh.executePutRequest("/_searchguard/api/roles/sg_field_mask_valid",
FileHelper.loadFile("restapi/roles_field_masks_valid.json"), new Header[0]);
Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode());

// put invalid field masks
response = rh.executePutRequest("/_searchguard/api/roles/sg_field_mask_invalid",
FileHelper.loadFile("restapi/roles_field_masks_invalid.json"), new Header[0]);
Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode());

}
}
@@ -0,0 +1,22 @@
{
"cluster": [
"*"
],
"indices": {
"*": {
"*": [
"indices:data/read/*"
],
"_masked_fields_": [
"abvfg",
"*ip_dest*::[0-9]{1,3::XXX",
"*ip_source*::[0-9]{1,3}$::XXX::/^[0-9]{1,3}/::***",
"customer.name::SHA-513",
"abc::"
],
"abc": [
123
]
}
}
}
@@ -0,0 +1,22 @@
{
"cluster": [
"*"
],
"indices": {
"*": {
"*": [
"indices:data/read/*"
],
"_masked_fields_": [
"abvfg",
"*ip_dest*::/[0-9]{1,3}$/::XXX",
"*ip_source*::/[0-9]{1,3}$/::XXX::/^[0-9]{1,3}/::***",
"customer.name::SHA-512",
"/[0-9]{1,3}/::SHA-512"
],
"abc": [
123
]
}
}
}

0 comments on commit 0bf3c18

Please sign in to comment.
You can’t perform that action at this time.