Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Commit 73c0bce

Browse files
committed
chore: add url encoding to appendProperties to prevent injection vulnerabilites
1 parent fe67f1d commit 73c0bce

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcUrlUtility.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
import com.google.api.client.util.escape.CharEscapers;
2020
import com.google.cloud.bigquery.BigQueryOptions;
2121
import com.google.cloud.bigquery.exception.BigQueryJdbcRuntimeException;
22+
import java.io.UnsupportedEncodingException;
23+
import java.net.URLDecoder;
24+
import java.net.URLEncoder;
25+
import java.nio.charset.StandardCharsets;
2226
import java.util.Arrays;
2327
import java.util.Collections;
2428
import java.util.HashMap;
@@ -614,7 +618,8 @@ final class BigQueryJdbcUrlUtility {
614618
}
615619
map.put(PARTNER_TOKEN_PROPERTY_NAME.toUpperCase(), PARTNER_TOKEN_PROPERTY_NAME);
616620
map.put(ENDPOINT_OVERRIDES_PROPERTY_NAME.toUpperCase(), ENDPOINT_OVERRIDES_PROPERTY_NAME);
617-
map.put(PRIVATE_SERVICE_CONNECT_PROPERTY_NAME.toUpperCase(), PRIVATE_SERVICE_CONNECT_PROPERTY_NAME);
621+
map.put(
622+
PRIVATE_SERVICE_CONNECT_PROPERTY_NAME.toUpperCase(), PRIVATE_SERVICE_CONNECT_PROPERTY_NAME);
618623
PROPERTY_NAME_MAP = Collections.unmodifiableMap(map);
619624
}
620625

@@ -701,7 +706,14 @@ static String appendPropertiesToURL(String url, String callerClassName, Properti
701706
for (Entry<Object, Object> entry : properties.entrySet()) {
702707
if (entry.getValue() != null && !"".equals(entry.getValue())) {
703708
LOG.finest("Appending %s with value %s to URL", entry.getKey(), entry.getValue());
704-
urlBuilder.append(";").append(entry.getKey()).append("=").append(entry.getValue());
709+
try {
710+
String encodedValue =
711+
URLEncoder.encode((String) entry.getValue(), StandardCharsets.UTF_8.name())
712+
.replace("+", "%20");
713+
urlBuilder.append(";").append(entry.getKey()).append("=").append(encodedValue);
714+
} catch (UnsupportedEncodingException e) {
715+
throw new BigQueryJdbcRuntimeException(e);
716+
}
705717
}
706718
}
707719
return urlBuilder.toString();
@@ -872,7 +884,12 @@ static Map<String, String> parseOverrideProperties(String url, String callerClas
872884
Matcher matcher = pattern.matcher(url);
873885
String overridePropertiesString;
874886
if (matcher.find() && matcher.groupCount() >= 1) {
875-
overridePropertiesString = matcher.group(2);
887+
try {
888+
overridePropertiesString =
889+
URLDecoder.decode(matcher.group(2), StandardCharsets.UTF_8.name());
890+
} catch (UnsupportedEncodingException e) {
891+
throw new BigQueryJdbcRuntimeException(e);
892+
}
876893
} else {
877894
return overrideProps;
878895
}

google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcUrlUtilityTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,4 +891,38 @@ public void testParseRequestReason() {
891891
"testParseRequestReason");
892892
assertEquals("testingRequestReason", requestReason);
893893
}
894+
895+
@Test
896+
public void testAppendPropertiesToURL_propertyWithSemicolon_isEscaped() throws Exception {
897+
String url = "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;";
898+
Properties properties = new Properties();
899+
String complexValue = "value;ExtraProperty=injection";
900+
properties.setProperty("ProjectId", complexValue);
901+
902+
String updatedUrl = BigQueryJdbcUrlUtility.appendPropertiesToURL(url, null, properties);
903+
904+
Map<String, String> parsedProperties = BigQueryJdbcUrlUtility.parseUrl(updatedUrl);
905+
906+
assertThat(parsedProperties.get("ProjectId")).isEqualTo(complexValue);
907+
assertFalse(parsedProperties.containsKey("ExtraProperty"));
908+
}
909+
910+
@Test
911+
public void testEndpointOverrides_viaProperties() throws Exception {
912+
String url = "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443";
913+
Properties props = new Properties();
914+
915+
String overrides = "OAUTH2=http://localhost:1234,BIGQUERY=http://localhost:9090";
916+
props.setProperty("EndpointOverrides", overrides);
917+
918+
String updatedUrl = BigQueryJdbcUrlUtility.appendPropertiesToURL(url, null, props);
919+
920+
Map<String, String> parsedOverrides =
921+
BigQueryJdbcUrlUtility.parseOverrideProperties(updatedUrl, null);
922+
923+
assertThat(parsedOverrides).containsKey("OAUTH2");
924+
assertThat(parsedOverrides.get("OAUTH2")).isEqualTo("http://localhost:1234");
925+
assertThat(parsedOverrides).containsKey("BIGQUERY");
926+
assertThat(parsedOverrides.get("BIGQUERY")).isEqualTo("http://localhost:9090");
927+
}
894928
}

0 commit comments

Comments
 (0)