diff --git a/extensions/database/module/langs/translation-en.json b/extensions/database/module/langs/translation-en.json
index 2feb01e3c..b4ffadf48 100644
--- a/extensions/database/module/langs/translation-en.json
+++ b/extensions/database/module/langs/translation-en.json
@@ -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."
+
}
diff --git a/extensions/database/module/scripts/index/database-source-ui.js b/extensions/database/module/scripts/index/database-source-ui.js
index 7b5932c2e..4a4e6e234 100644
--- a/extensions/database/module/scripts/index/database-source-ui.js
+++ b/extensions/database/module/scripts/index/database-source-ui.js
@@ -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());
}
}
@@ -148,19 +148,11 @@ Refine.DatabaseSourceUI.prototype.attachUI = function(body) {
jdbcQueryInfo.databasePassword = $( "#currentDatabasePasswordInput" ).val();
jdbcQueryInfo.initialDatabase = $( "#currentInitialDatabaseInput" ).val();
jdbcQueryInfo.query = $.trim($( "#queryTextArea" ).val());
-
-// if(jdbcQueryInfo.query && jdbcQueryInfo.query.length > 0 ) {
-// self._executeQuery(jdbcQueryInfo);
-// }else{
-// window.alert($.i18n('database-source/alert-query'));
-// }
-
+
if(self.validateQuery(jdbcQueryInfo.query)) {
self._executeQuery(jdbcQueryInfo);
}
-
-
-
+
});
@@ -249,15 +241,15 @@ Refine.DatabaseSourceUI.prototype._editConnection = function(connectionInfo) {
success: function(settings) {
if(settings){
$( "#menuListUl" ).empty();
+ var menuList = $('#menuListUl');
var items = [];
$.each(settings.savedConnections,function(index,savedConnection){
-// items.push(''
-// + ''
-// + ' ');
-
- items.push('
');
+
+ var li = $('').appendTo(menuList);
+ var a = $('').appendTo(li);
+ $('').text(savedConnection.connectionName)
+ .appendTo(a);
+ $(' ').appendTo(a);
})
$( "#menuListUl" ).append(items.join(''));
@@ -275,26 +267,23 @@ Refine.DatabaseSourceUI.prototype._executeQuery = function(jdbcQueryInfo) {
//remove start line
var dismiss = DialogSystem.showBusy($.i18n('database-import/checking'));
- //$("#executeQueryBtn").text('Please wait ...').attr('disabled','disabled');
-
+
$.post(
"command/database/test-query",
jdbcQueryInfo,
function(jdbcConnectionResult) {
- // $("#executeQueryBtn").text('Preview Query Result').removeAttr('disabled');
+
dismiss();
self._controller.startImportingDocument(jdbcQueryInfo);
},
"json"
).fail(function( jqXhr, textStatus, errorThrown ){
- //$("#executeQueryBtn").text('Preview Query Result').removeAttr('disabled');
+
dismiss();
alert( textStatus + ':' + errorThrown );
});
- //remove end line
-
- //self._controller.startImportingDocument(jdbcQueryInfo);
+
}
Refine.DatabaseSourceUI.prototype._saveConnection = function(jdbcConnectionInfo) {
@@ -304,16 +293,11 @@ Refine.DatabaseSourceUI.prototype._saveConnection = function(jdbcConnectionInfo)
jdbcConnectionInfo,
function(settings) {
if(settings){
-
-// self._elmts.scListGroupDiv.empty();
+
self._elmts.menuListUl.empty();
var items = [];
$.each(settings.savedConnections,function(index,savedConnection){
-
-// items.push(''
-// + ''
-// + ' ');
-
+
items.push('');
@@ -339,14 +323,10 @@ Refine.DatabaseSourceUI.prototype._loadSavedConnections = function() {
if(settings){
self._elmts.menuListUl.empty();
- //self._elmts.scListGroupDiv.empty();
+
var items = [];
$.each(settings.savedConnections,function(index,savedConnection){
-// items.push('');
-
items.push('');
@@ -354,7 +334,7 @@ Refine.DatabaseSourceUI.prototype._loadSavedConnections = function() {
})
self._elmts.menuListUl.append(items.join(''));
- // self._elmts.scListGroupDiv.append(items.join(''));
+
}
},
@@ -407,12 +387,10 @@ Refine.DatabaseSourceUI.prototype._connect = function(jdbcConnectionInfo) {
+ jdbcConnectionInfo.databasePort + "/"
+ jdbcConnectionInfo.initialDatabase;
- //alert("connectionParam::" + connectionParam);
+
$( "#connectionParameterSpan" ).text(connectionParam);
- // self._body.find('.newConnectionDiv').hide();
- // self._body.find('.sqlEditorDiv').show();
- $( "#newConnectionDiv" ).hide();
- $( "#sqlEditorDiv" ).show();
+ $( "#newConnectionDiv" ).hide();
+ $( "#sqlEditorDiv" ).show();
}else{
window.alert("Unable to establish connection to database");
@@ -428,20 +406,21 @@ Refine.DatabaseSourceUI.prototype._connect = function(jdbcConnectionInfo) {
};
Refine.DatabaseSourceUI.prototype._getConnectionInfo = function() {
- var self = this;
- var jdbcConnectionInfo = {};
- jdbcConnectionInfo.connectionName = $.trim(self._elmts.connectionNameInput[0].value);
- jdbcConnectionInfo.databaseType = $.trim(self._elmts.databaseTypeSelect[0].value);
- jdbcConnectionInfo.databaseServer = $.trim(self._elmts.databaseHostInput[0].value);
- jdbcConnectionInfo.databasePort = $.trim(self._elmts.databasePortInput[0].value);
- jdbcConnectionInfo.databaseUser = $.trim(self._elmts.databaseUserInput[0].value);
- jdbcConnectionInfo.databasePassword = $.trim(self._elmts.databasePasswordInput[0].value);
- jdbcConnectionInfo.initialDatabase = $.trim(self._elmts.initialDatabaseInput[0].value);
- jdbcConnectionInfo.initialSchema = $.trim(self._elmts.initialSchemaInput[0].value);
- return jdbcConnectionInfo;
+ var self = this;
+ var jdbcConnectionInfo = {};
+ jdbcConnectionInfo.connectionName = $.trim(self._elmts.connectionNameInput[0].value);
+ jdbcConnectionInfo.databaseType = $.trim(self._elmts.databaseTypeSelect[0].value);
+ jdbcConnectionInfo.databaseServer = $.trim(self._elmts.databaseHostInput[0].value);
+ jdbcConnectionInfo.databasePort = $.trim(self._elmts.databasePortInput[0].value);
+ jdbcConnectionInfo.databaseUser = $.trim(self._elmts.databaseUserInput[0].value);
+ jdbcConnectionInfo.databasePassword = $.trim(self._elmts.databasePasswordInput[0].value);
+ jdbcConnectionInfo.initialDatabase = $.trim(self._elmts.initialDatabaseInput[0].value);
+ jdbcConnectionInfo.initialSchema = $.trim(self._elmts.initialSchemaInput[0].value);
+ return jdbcConnectionInfo;
}
+
Refine.DatabaseSourceUI.prototype._validateNewConnectionForm = function() {
var self = this;
@@ -454,21 +433,36 @@ 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 (databaseHostInput.length === 0) {
window.alert($.i18n('database-source/alert-server'));
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(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;
}
diff --git a/extensions/database/pom.xml b/extensions/database/pom.xml
index 04ec35734..846ace10c 100644
--- a/extensions/database/pom.xml
+++ b/extensions/database/pom.xml
@@ -166,6 +166,13 @@
commons-lang3
3.6
+
+
+ org.owasp.encoder
+ encoder
+ 1.2.2
+
+
diff --git a/extensions/database/src/com/google/refine/extension/database/DatabaseUtils.java b/extensions/database/src/com/google/refine/extension/database/DatabaseUtils.java
index 0cb37354b..a5d0a06bd 100644
--- a/extensions/database/src/com/google/refine/extension/database/DatabaseUtils.java
+++ b/extensions/database/src/com/google/refine/extension/database/DatabaseUtils.java
@@ -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(){
diff --git a/extensions/database/src/com/google/refine/extension/database/cmd/SavedConnectionCommand.java b/extensions/database/src/com/google/refine/extension/database/cmd/SavedConnectionCommand.java
index 679090de1..a30e2d000 100644
--- a/extensions/database/src/com/google/refine/extension/database/cmd/SavedConnectionCommand.java
+++ b/extensions/database/src/com/google/refine/extension/database/cmd/SavedConnectionCommand.java
@@ -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,26 +132,24 @@ public class SavedConnectionCommand extends DatabaseCommand {
writer.writeArrayFieldStart(DatabaseUtils.SAVED_CONNECTION_KEY);
writer.writeStartObject();
- writer.writeStringField("connectionName", savedConnection.getConnectionName());
+
+ writer.writeStringField("connectionName", savedConnection.getConnectionName());
writer.writeStringField("databaseType", savedConnection.getDatabaseType());
-
writer.writeStringField("databaseHost", savedConnection.getDatabaseHost());
-
writer.writeNumberField("databasePort", savedConnection.getDatabasePort());
-
writer.writeStringField("databaseName", savedConnection.getDatabaseName());
-
+
+
String dbPasswd = savedConnection.getDatabasePassword();
if(dbPasswd != null && !dbPasswd.isEmpty()) {
dbPasswd = DatabaseUtils.decrypt(savedConnection.getDatabasePassword());
}
writer.writeStringField("databasePassword", dbPasswd);
-
- writer.writeStringField("databaseSchema", savedConnection.getDatabaseSchema());
-
+ writer.writeStringField("databaseSchema", savedConnection.getDatabaseSchema());
writer.writeStringField("databaseUser", savedConnection.getDatabaseUser());
+
writer.writeEndObject();
writer.writeEndArray();
@@ -228,6 +232,7 @@ public class SavedConnectionCommand extends DatabaseCommand {
if(logger.isDebugEnabled()) {
logger.debug("doPost Connection: {}", request.getParameter("connectionName"));
}
+
DatabaseConfiguration jdbcConfig = getJdbcConfiguration(request);
@@ -240,6 +245,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 +286,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)
diff --git a/extensions/database/tests/src/com/google/refine/extension/database/cmd/SavedConnectionCommandTest.java b/extensions/database/tests/src/com/google/refine/extension/database/cmd/SavedConnectionCommandTest.java
index d8a825100..32ea6fb27 100644
--- a/extensions/database/tests/src/com/google/refine/extension/database/cmd/SavedConnectionCommandTest.java
+++ b/extensions/database/tests/src/com/google/refine/extension/database/cmd/SavedConnectionCommandTest.java
@@ -1,6 +1,10 @@
package com.google.refine.extension.database.cmd;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
@@ -11,6 +15,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.http.HttpStatus;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.Assert;
@@ -154,8 +159,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 +237,6 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
Assert.assertEquals(savedConnections.size(), 1);
ObjectNode sc = (ObjectNode)savedConnections.get(0);
- System.out.println("sc" + sc);
String newDbHost = sc.get("databaseHost").asText();
Assert.assertEquals(newDbHost, newHost);
}
@@ -276,8 +283,6 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
SUT.doDelete(request, response);
- // String result = sw.getBuffer().toString().trim();
-
ObjectNode json = ParsingUtilities.mapper.createObjectNode();
Assert.assertNotNull(json);
@@ -288,5 +293,34 @@ 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("");
+ 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);
+
+ verify(response, times(1)).sendError(HttpStatus.SC_BAD_REQUEST, "Connection Name is Invalid. Expecting [a-zA-Z0-9._-]");
+ }
+
+
+
}