input validation for database connection data
This commit is contained in:
parent
1981a23b51
commit
575a7d4979
@ -44,5 +44,10 @@
|
||||
"database-parsing/limit-next": "Load at most",
|
||||
"database-parsing/limit": "row(s) of data",
|
||||
"database-parsing/store-row": "Store blank rows",
|
||||
"database-parsing/store-cell": "Store blank cells as nulls"
|
||||
"database-parsing/store-cell": "Store blank cells as nulls",
|
||||
"database-source/alert-conn-name-invalid-character": "Connection Name Input Error: Illegal Character in Input. Only [a-zA-Z0-9._-] Allowed",
|
||||
"database-source/alert-db-host-invalid-character": "Database Host Error: Illegal Character in Input. Only Alphanumeric characters allowed",
|
||||
"database-source/alert-db-user-invalid-character": "Database User Error: Illegal Character in Input. Only Alphanumeric characters allowed",
|
||||
"database-source/alert-db-port-invalid-character": "Database Port Error: Illegal Character in Input. Only Numeric values allowed."
|
||||
|
||||
}
|
||||
|
@ -127,11 +127,11 @@ Refine.DatabaseSourceUI.prototype.attachUI = function(body) {
|
||||
this._elmts.saveConnectionButton.click(function(evt) {
|
||||
|
||||
if(self._validateNewConnectionForm() == true){
|
||||
var connectionNameInput = $.trim(self._elmts.connectionNameInput[0].value);
|
||||
var connectionNameInput = $.trim(self._elmts.connectionNameInput[0].value);
|
||||
if (connectionNameInput.length === 0) {
|
||||
window.alert($.i18n('database-source/alert-connection-name'));
|
||||
} else{
|
||||
self._saveConnection(self._getConnectionInfo());
|
||||
self._saveConnection(self._getConnectionInfo());
|
||||
}
|
||||
|
||||
}
|
||||
@ -431,6 +431,9 @@ Refine.DatabaseSourceUI.prototype._getConnectionInfo = function() {
|
||||
var self = this;
|
||||
var jdbcConnectionInfo = {};
|
||||
jdbcConnectionInfo.connectionName = $.trim(self._elmts.connectionNameInput[0].value);
|
||||
|
||||
// window.alert('input:' + jdbcConnectionInfo.connectionName + ' output:' + self._removeScriptTag(jdbcConnectionInfo.connectionName) );
|
||||
|
||||
jdbcConnectionInfo.databaseType = $.trim(self._elmts.databaseTypeSelect[0].value);
|
||||
jdbcConnectionInfo.databaseServer = $.trim(self._elmts.databaseHostInput[0].value);
|
||||
jdbcConnectionInfo.databasePort = $.trim(self._elmts.databasePortInput[0].value);
|
||||
@ -442,6 +445,18 @@ Refine.DatabaseSourceUI.prototype._getConnectionInfo = function() {
|
||||
|
||||
}
|
||||
|
||||
Refine.DatabaseSourceUI.prototype._removeScriptTag = function(input) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = s;
|
||||
var scripts = div.getElementsByTagName('script');
|
||||
var i = scripts.length;
|
||||
while (i--) {
|
||||
scripts[i].parentNode.removeChild(scripts[i]);
|
||||
}
|
||||
return div.innerHTML;
|
||||
};
|
||||
|
||||
|
||||
Refine.DatabaseSourceUI.prototype._validateNewConnectionForm = function() {
|
||||
|
||||
var self = this;
|
||||
@ -454,21 +469,45 @@ Refine.DatabaseSourceUI.prototype._validateNewConnectionForm = function() {
|
||||
var initialDatabaseInput = $.trim(self._elmts.initialDatabaseInput[0].value);
|
||||
var initialSchemaInput = $.trim(self._elmts.initialSchemaInput[0].value);
|
||||
|
||||
if (databaseHostInput.length === 0) {
|
||||
var alphaNumRE = /^[a-zA-Z0-9._-]*$/;
|
||||
var numRE = /^[0-9]*$/;
|
||||
|
||||
var alphaNumConnNameTestResult = alphaNumRE.test(connectionNameInput);
|
||||
var databaseHostTestResult = alphaNumRE.test(databaseHostInput);
|
||||
var databasePortTestResult = numRE.test(databasePortInput);
|
||||
var databaseUserTestResult = alphaNumRE.test(databaseUserInput);
|
||||
|
||||
if(alphaNumConnNameTestResult == false){
|
||||
window.alert($.i18n('database-source/alert-conn-name-invalid-character'));
|
||||
return false;
|
||||
}else if(connectionNameInput.contains("<script>") || connectionNameInput.contains("<img>")){
|
||||
window.alert($.i18n('database-source/alert-conn-name-invalid-character'));
|
||||
return false;
|
||||
}else if (databaseHostInput.length === 0) {
|
||||
window.alert($.i18n('database-source/alert-server'));
|
||||
return false;
|
||||
}else if(databaseHostInput.contains("<script>") || databaseHostInput.contains("<img>")){
|
||||
window.alert($.i18n('database-source/alert-db-host-invalid-character'));
|
||||
return false;
|
||||
}else if(databasePortInput.length === 0){
|
||||
window.alert($.i18n('database-source/alert-port'));
|
||||
return false;
|
||||
window.alert($.i18n('database-source/alert-port'));
|
||||
return false;
|
||||
}else if(databaseUserInput.length === 0){
|
||||
window.alert($.i18n('database-source/alert-user'));
|
||||
return false;
|
||||
window.alert($.i18n('database-source/alert-user'));
|
||||
return false;
|
||||
}else if(databaseUserInput.contains("<script>") || databaseUserInput.contains("<img>")){
|
||||
window.alert($.i18n('database-source/alert-db-user-invalid-character'));
|
||||
return false;
|
||||
}else if(initialDatabaseInput.length === 0){
|
||||
window.alert($.i18n('database-source/alert-initial-database'));
|
||||
return false;
|
||||
window.alert($.i18n('database-source/alert-initial-database'));
|
||||
return false;
|
||||
}else if(databasePortTestResult == false){
|
||||
window.alert($.i18n('database-source/alert-db-port-invalid-character'));
|
||||
return false;
|
||||
|
||||
}
|
||||
else{
|
||||
return true;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,13 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.owasp.encoder</groupId>
|
||||
<artifactId>encoder</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
|
@ -314,7 +314,7 @@ public class DatabaseUtils {
|
||||
String fileSep = System.getProperty("file.separator");
|
||||
String filename = dir.getPath() + fileSep + DATABASE_EXTENSION_DIR + fileSep + SETTINGS_FILE_NAME;
|
||||
|
||||
// logger.info("** extension file name: {} **", filename);
|
||||
logger.debug("** extension file name: {} **", filename);
|
||||
return filename;
|
||||
}
|
||||
public static String getExtensionFolder(){
|
||||
|
@ -31,12 +31,15 @@ package com.google.refine.extension.database.cmd;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.owasp.encoder.Encode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -50,6 +53,9 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("SavedConnectionCommand");
|
||||
|
||||
private static final Pattern CONN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9._-]*");
|
||||
private static final Pattern DATABASE_PORT_PATTERN = Pattern.compile("^[0-9]*");
|
||||
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
@ -126,16 +132,24 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
writer.writeArrayFieldStart(DatabaseUtils.SAVED_CONNECTION_KEY);
|
||||
|
||||
writer.writeStartObject();
|
||||
writer.writeStringField("connectionName", savedConnection.getConnectionName());
|
||||
|
||||
String sanitizedConnName = Encode.forHtml(savedConnection.getConnectionName());
|
||||
|
||||
// writer.writeStringField("connectionName", savedConnection.getConnectionName());
|
||||
writer.writeStringField("connectionName", sanitizedConnName);
|
||||
|
||||
writer.writeStringField("databaseType", savedConnection.getDatabaseType());
|
||||
|
||||
writer.writeStringField("databaseHost", savedConnection.getDatabaseHost());
|
||||
String sanitizedHost = Encode.forHtml(savedConnection.getDatabaseHost());
|
||||
// writer.writeStringField("databaseHost", savedConnection.getDatabaseHost());
|
||||
writer.writeStringField("databaseHost", sanitizedHost);
|
||||
|
||||
writer.writeNumberField("databasePort", savedConnection.getDatabasePort());
|
||||
|
||||
writer.writeStringField("databaseName", savedConnection.getDatabaseName());
|
||||
|
||||
String sanitizedDbName = Encode.forHtml(savedConnection.getDatabaseName());
|
||||
// writer.writeStringField("databaseName", savedConnection.getDatabaseName());
|
||||
writer.writeStringField("databaseName", sanitizedDbName);
|
||||
|
||||
String dbPasswd = savedConnection.getDatabasePassword();
|
||||
if(dbPasswd != null && !dbPasswd.isEmpty()) {
|
||||
dbPasswd = DatabaseUtils.decrypt(savedConnection.getDatabasePassword());
|
||||
@ -143,8 +157,11 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
writer.writeStringField("databasePassword", dbPasswd);
|
||||
|
||||
writer.writeStringField("databaseSchema", savedConnection.getDatabaseSchema());
|
||||
String sanitizedDbUser = Encode.forHtml(savedConnection.getDatabaseUser());
|
||||
// writer.writeStringField("databaseUser", savedConnection.getDatabaseUser());
|
||||
writer.writeStringField("databaseUser", sanitizedDbUser);
|
||||
|
||||
writer.writeStringField("databaseUser", savedConnection.getDatabaseUser());
|
||||
logger.info("Input DB User:{}, SanitizedDbUser:{}", savedConnection.getDatabaseUser(), sanitizedDbUser);
|
||||
|
||||
writer.writeEndObject();
|
||||
writer.writeEndArray();
|
||||
@ -228,6 +245,7 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("doPost Connection: {}", request.getParameter("connectionName"));
|
||||
}
|
||||
|
||||
|
||||
DatabaseConfiguration jdbcConfig = getJdbcConfiguration(request);
|
||||
|
||||
@ -240,6 +258,21 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
response.flushBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!validateInput(jdbcConfig.getConnectionName(), CONN_NAME_PATTERN)) {
|
||||
logger.warn("Invalid Connection Name: {}", jdbcConfig.getConnectionName());
|
||||
response.sendError(HttpStatus.SC_BAD_REQUEST, "Connection Name is Invalid. Expecting [a-zA-Z0-9._-]");
|
||||
response.flushBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!validateInput("" + jdbcConfig.getDatabasePort(), DATABASE_PORT_PATTERN)) {
|
||||
logger.warn("Invalid Database Port: {}", jdbcConfig.getDatabasePort());
|
||||
response.sendError(HttpStatus.SC_BAD_REQUEST, "Database Port Invalid. Expecting Numeric values only");
|
||||
response.flushBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DatabaseConfiguration savedConn = DatabaseUtils.getSavedConnection(jdbcConfig.getConnectionName());
|
||||
if(savedConn != null) {
|
||||
@ -266,8 +299,14 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean validateInput(String input, Pattern pattern){
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
if(matcher.matches()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPut(HttpServletRequest request, HttpServletResponse response)
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.google.refine.extension.database.cmd;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -154,8 +157,11 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
||||
SUT.doPost(request, response);
|
||||
|
||||
String result = sw.getBuffer().toString().trim();
|
||||
|
||||
assertNotNull(result);
|
||||
assertFalse(result.isEmpty(), "Valid response Message expected!");
|
||||
|
||||
ObjectNode json = ParsingUtilities.mapper.readValue(result, ObjectNode.class);
|
||||
System.out.println("json:" + json);
|
||||
|
||||
ArrayNode savedConnections = (ArrayNode) json.get("savedConnections");
|
||||
Assert.assertNotNull(savedConnections);
|
||||
@ -229,7 +235,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
||||
Assert.assertEquals(savedConnections.size(), 1);
|
||||
|
||||
ObjectNode sc = (ObjectNode)savedConnections.get(0);
|
||||
System.out.println("sc" + sc);
|
||||
//System.out.println("sc" + sc);
|
||||
String newDbHost = sc.get("databaseHost").asText();
|
||||
Assert.assertEquals(newDbHost, newHost);
|
||||
}
|
||||
@ -288,5 +294,44 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Added to check XSS invalid tokens
|
||||
* @throws IOException
|
||||
* @throws ServletException
|
||||
*/
|
||||
@Test
|
||||
public void testDoPostInvalidConnectionName() throws IOException, ServletException {
|
||||
|
||||
when(request.getParameter("connectionName")).thenReturn("<img></img>");
|
||||
when(request.getParameter("databaseType")).thenReturn(MySQLDatabaseService.DB_NAME);
|
||||
when(request.getParameter("databaseServer")).thenReturn(testDbConfig.getDatabaseHost());
|
||||
when(request.getParameter("databasePort")).thenReturn("" + testDbConfig.getDatabasePort());
|
||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
when(response.getWriter()).thenReturn(pw);
|
||||
|
||||
SUT.doPost(request, response);
|
||||
|
||||
String result = sw.getBuffer().toString().trim();
|
||||
assertNotNull(result);
|
||||
assertFalse(result.isEmpty(), "Valid response Message expected!");
|
||||
|
||||
ObjectNode json = ParsingUtilities.mapper.readValue(result, ObjectNode.class);
|
||||
System.out.println("json:" + json);
|
||||
|
||||
ArrayNode savedConnections = (ArrayNode) json.get("savedConnections");
|
||||
Assert.assertNotNull(savedConnections);
|
||||
|
||||
int len = savedConnections.size();
|
||||
|
||||
Assert.assertEquals(len, 1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user