Skip to content

Commit 5b1d2bd

Browse files
committed
add validation for name and description for model model group and connector resources
Signed-off-by: Dhrubo Saha <[email protected]>
1 parent c51c5e4 commit 5b1d2bd

13 files changed

+412
-6
lines changed

common/src/main/java/org/opensearch/ml/common/transport/connector/MLCreateConnectorRequest.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.connector;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -39,8 +40,25 @@ public MLCreateConnectorRequest(StreamInput in) throws IOException {
3940
@Override
4041
public ActionRequestValidationException validate() {
4142
ActionRequestValidationException exception = null;
43+
4244
if (mlCreateConnectorInput == null) {
43-
exception = addValidationError("ML Connector input can't be null", exception);
45+
return addValidationError("ML Connector input can't be null", exception);
46+
}
47+
48+
String modelName = mlCreateConnectorInput.getName();
49+
String description = mlCreateConnectorInput.getDescription();
50+
51+
if (modelName != null && !isSafeText(modelName)) {
52+
exception = addValidationError(
53+
"Model connector name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
54+
exception
55+
);
56+
}
57+
if (description != null && !isSafeText(description)) {
58+
exception = addValidationError(
59+
"Model connector description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
60+
exception
61+
);
4462
}
4563

4664
return exception;

common/src/main/java/org/opensearch/ml/common/transport/connector/MLUpdateConnectorRequest.java

+17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.connector;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -57,6 +58,22 @@ public ActionRequestValidationException validate() {
5758

5859
if (updateContent == null) {
5960
exception = addValidationError("Update connector content can't be null", exception);
61+
} else {
62+
String modelName = updateContent.getName();
63+
String description = updateContent.getDescription();
64+
65+
if (modelName != null && !isSafeText(modelName)) {
66+
exception = addValidationError(
67+
"Model connector name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.). Max length: 1000 characters.",
68+
exception
69+
);
70+
}
71+
if (description != null && !isSafeText(description)) {
72+
exception = addValidationError(
73+
"Model connector description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.). Max length: 1000 characters.",
74+
exception
75+
);
76+
}
6077
}
6178

6279
return exception;

common/src/main/java/org/opensearch/ml/common/transport/model/MLUpdateModelRequest.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.model;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -45,8 +46,25 @@ public MLUpdateModelRequest(StreamInput in) throws IOException {
4546
@Override
4647
public ActionRequestValidationException validate() {
4748
ActionRequestValidationException exception = null;
49+
4850
if (updateModelInput == null) {
49-
exception = addValidationError("Update Model Input can't be null", exception);
51+
return addValidationError("Update Model Input can't be null", exception);
52+
}
53+
54+
String modelName = updateModelInput.getName();
55+
String description = updateModelInput.getDescription();
56+
57+
if (modelName != null && !isSafeText(modelName)) {
58+
exception = addValidationError(
59+
"Model name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
60+
exception
61+
);
62+
}
63+
if (description != null && !isSafeText(description)) {
64+
exception = addValidationError(
65+
"Model description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
66+
exception
67+
);
5068
}
5169

5270
return exception;

common/src/main/java/org/opensearch/ml/common/transport/model_group/MLRegisterModelGroupRequest.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.model_group;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -45,8 +46,25 @@ public MLRegisterModelGroupRequest(StreamInput in) throws IOException {
4546
@Override
4647
public ActionRequestValidationException validate() {
4748
ActionRequestValidationException exception = null;
49+
4850
if (registerModelGroupInput == null) {
49-
exception = addValidationError("Model meta input can't be null", exception);
51+
return addValidationError("Model group input can't be null", exception);
52+
}
53+
54+
String modelName = registerModelGroupInput.getName();
55+
String description = registerModelGroupInput.getDescription();
56+
57+
if (modelName != null && !isSafeText(modelName)) {
58+
exception = addValidationError(
59+
"Model group name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
60+
exception
61+
);
62+
}
63+
if (description != null && !isSafeText(description)) {
64+
exception = addValidationError(
65+
"Model group description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
66+
exception
67+
);
5068
}
5169

5270
return exception;

common/src/main/java/org/opensearch/ml/common/transport/model_group/MLUpdateModelGroupRequest.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.model_group;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -45,8 +46,25 @@ public MLUpdateModelGroupRequest(StreamInput in) throws IOException {
4546
@Override
4647
public ActionRequestValidationException validate() {
4748
ActionRequestValidationException exception = null;
49+
4850
if (updateModelGroupInput == null) {
49-
exception = addValidationError("Update Model group input can't be null", exception);
51+
return addValidationError("Update Model group input can't be null", exception);
52+
}
53+
54+
String modelName = updateModelGroupInput.getName();
55+
String description = updateModelGroupInput.getDescription();
56+
57+
if (modelName != null && !isSafeText(modelName)) {
58+
exception = addValidationError(
59+
"Model group name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
60+
exception
61+
);
62+
}
63+
if (description != null && !isSafeText(description)) {
64+
exception = addValidationError(
65+
"Model group description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
66+
exception
67+
);
5068
}
5169

5270
return exception;

common/src/main/java/org/opensearch/ml/common/transport/register/MLRegisterModelRequest.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.ml.common.transport.register;
77

88
import static org.opensearch.action.ValidateActions.addValidationError;
9+
import static org.opensearch.ml.common.utils.StringUtils.isSafeText;
910

1011
import java.io.ByteArrayInputStream;
1112
import java.io.ByteArrayOutputStream;
@@ -45,8 +46,25 @@ public MLRegisterModelRequest(StreamInput in) throws IOException {
4546
@Override
4647
public ActionRequestValidationException validate() {
4748
ActionRequestValidationException exception = null;
49+
4850
if (registerModelInput == null) {
49-
exception = addValidationError("ML input can't be null", exception);
51+
return addValidationError("ML input can't be null", exception);
52+
}
53+
54+
String modelName = registerModelInput.getModelName();
55+
String description = registerModelInput.getDescription();
56+
57+
if (modelName != null && !isSafeText(modelName)) {
58+
exception = addValidationError(
59+
"Model name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
60+
exception
61+
);
62+
}
63+
if (description != null && !isSafeText(description)) {
64+
exception = addValidationError(
65+
"Model description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.)",
66+
exception
67+
);
5068
}
5169

5270
return exception;

common/src/main/java/org/opensearch/ml/common/utils/StringUtils.java

+19
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public class StringUtils {
6060
+ " return input;"
6161
+ "\n }\n";
6262

63+
// Regex allows letters, digits, spaces, hyphens, underscores, and dots.
64+
private static final String SAFE_INPUT_REGEX = "^[a-zA-Z0-9 _\\-\\.:]+$";
65+
6366
public static final Gson gson;
6467

6568
static {
@@ -497,4 +500,20 @@ public static String hashString(String input) {
497500
}
498501
}
499502

503+
/**
504+
* Checks if the input is safe (non-null, non-blank, matches safe character set, max 1000 chars).
505+
*
506+
* @param value The input string to validate
507+
* @return true if input is safe, false otherwise
508+
*/
509+
public static boolean isSafeText(String value) {
510+
if (value == null || value.isBlank()) {
511+
return false;
512+
}
513+
if (value.length() > 1000) {
514+
return false;
515+
}
516+
return value.matches(SAFE_INPUT_REGEX);
517+
}
518+
500519
}

common/src/test/java/org/opensearch/ml/common/transport/connector/MLCreateConnectorRequestTests.java

+49
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,53 @@ public void writeTo(StreamOutput out) throws IOException {
147147
};
148148
MLCreateConnectorRequest.fromActionRequest(actionRequest);
149149
}
150+
151+
@Test
152+
public void validateWithUnsafeModelConnectorName() {
153+
MLCreateConnectorInput unsafeInput = MLCreateConnectorInput
154+
.builder()
155+
.name("<script>bad</script>") // Unsafe name
156+
.description("safe description")
157+
.version("1")
158+
.protocol("http")
159+
.parameters(Map.of("input", "test"))
160+
.credential(Map.of("key", "value"))
161+
.actions(List.of())
162+
.access(AccessMode.PUBLIC)
163+
.backendRoles(Arrays.asList("role1"))
164+
.addAllBackendRoles(false)
165+
.build();
166+
167+
MLCreateConnectorRequest request = MLCreateConnectorRequest.builder().mlCreateConnectorInput(unsafeInput).build();
168+
ActionRequestValidationException exception = request.validate();
169+
assertEquals(
170+
"Validation Failed: 1: Model connector name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.);",
171+
exception.getMessage()
172+
);
173+
}
174+
175+
@Test
176+
public void validateWithUnsafeModelConnectorDescription() {
177+
MLCreateConnectorInput unsafeInput = MLCreateConnectorInput
178+
.builder()
179+
.name("safeName")
180+
.description("<script>bad</script>") // Unsafe description
181+
.version("1")
182+
.protocol("http")
183+
.parameters(Map.of("input", "test"))
184+
.credential(Map.of("key", "value"))
185+
.actions(List.of())
186+
.access(AccessMode.PUBLIC)
187+
.backendRoles(Arrays.asList("role1"))
188+
.addAllBackendRoles(false)
189+
.build();
190+
191+
MLCreateConnectorRequest request = MLCreateConnectorRequest.builder().mlCreateConnectorInput(unsafeInput).build();
192+
ActionRequestValidationException exception = request.validate();
193+
assertEquals(
194+
"Validation Failed: 1: Model connector description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.);",
195+
exception.getMessage()
196+
);
197+
}
198+
150199
}

common/src/test/java/org/opensearch/ml/common/transport/connector/MLUpdateConnectorRequestTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,40 @@ public void writeTo_withTenantId_Success() throws IOException {
184184
assertEquals(connectorId, parsedRequest.getConnectorId());
185185
}
186186

187+
@Test
188+
public void validate_Exception_UnsafeConnectorName() {
189+
MLCreateConnectorInput unsafeInput = MLCreateConnectorInput
190+
.builder()
191+
.name("<script>bad</script>") // Unsafe name
192+
.description("safe description")
193+
.updateConnector(true)
194+
.build();
195+
196+
MLUpdateConnectorRequest request = MLUpdateConnectorRequest.builder().connectorId("connectorId").updateContent(unsafeInput).build();
197+
198+
ActionRequestValidationException exception = request.validate();
199+
assertEquals(
200+
"Validation Failed: 1: Model connector name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.). Max length: 1000 characters.;",
201+
exception.getMessage()
202+
);
203+
}
204+
205+
@Test
206+
public void validate_Exception_UnsafeConnectorDescription() {
207+
MLCreateConnectorInput unsafeInput = MLCreateConnectorInput
208+
.builder()
209+
.name("safeName")
210+
.description("<script>bad</script>") // Unsafe description
211+
.updateConnector(true)
212+
.build();
213+
214+
MLUpdateConnectorRequest request = MLUpdateConnectorRequest.builder().connectorId("connectorId").updateContent(unsafeInput).build();
215+
216+
ActionRequestValidationException exception = request.validate();
217+
assertEquals(
218+
"Validation Failed: 1: Model connector description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.). Max length: 1000 characters.;",
219+
exception.getMessage()
220+
);
221+
}
222+
187223
}

common/src/test/java/org/opensearch/ml/common/transport/model/MLUpdateModelRequestTest.java

+52
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,56 @@ public void writeTo(StreamOutput out) throws IOException {
113113
MLUpdateModelRequest.fromActionRequest(actionRequest);
114114
}
115115

116+
@Test
117+
public void validate_Exception_InvalidName() {
118+
MLModelConfig config = TextEmbeddingModelConfig
119+
.builder()
120+
.modelType("testModelType")
121+
.allConfig("{\"field1\":\"value1\",\"field2\":\"value2\"}")
122+
.frameworkType(TextEmbeddingModelConfig.FrameworkType.SENTENCE_TRANSFORMERS)
123+
.embeddingDimension(100)
124+
.build();
125+
126+
MLUpdateModelInput input = MLUpdateModelInput
127+
.builder()
128+
.modelId("test-model_id")
129+
.name("<script>alert(1)</script>") // unsafe input
130+
.description("safe description")
131+
.modelConfig(config)
132+
.build();
133+
134+
MLUpdateModelRequest request = MLUpdateModelRequest.builder().updateModelInput(input).build();
135+
ActionRequestValidationException exception = request.validate();
136+
assertEquals(
137+
"Validation Failed: 1: Model name can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.);",
138+
exception.getMessage()
139+
);
140+
}
141+
142+
@Test
143+
public void validate_Exception_InvalidDescription() {
144+
MLModelConfig config = TextEmbeddingModelConfig
145+
.builder()
146+
.modelType("testModelType")
147+
.allConfig("{\"field1\":\"value1\",\"field2\":\"value2\"}")
148+
.frameworkType(TextEmbeddingModelConfig.FrameworkType.SENTENCE_TRANSFORMERS)
149+
.embeddingDimension(100)
150+
.build();
151+
152+
MLUpdateModelInput input = MLUpdateModelInput
153+
.builder()
154+
.modelId("test-model_id")
155+
.name("safeName")
156+
.description("<script>bad</script>") // unsafe input
157+
.modelConfig(config)
158+
.build();
159+
160+
MLUpdateModelRequest request = MLUpdateModelRequest.builder().updateModelInput(input).build();
161+
ActionRequestValidationException exception = request.validate();
162+
assertEquals(
163+
"Validation Failed: 1: Model description can only contain letters, digits, spaces, underscores (_), hyphens (-), and dots (.);",
164+
exception.getMessage()
165+
);
166+
}
167+
116168
}

0 commit comments

Comments
 (0)