diff --git a/sdk/storage/azure-storage-blob-cryptography/src/test/java/com/azure/storage/blob/specialized/cryptography/EncryptedFlux.java b/sdk/storage/azure-storage-blob-cryptography/src/test/java/com/azure/storage/blob/specialized/cryptography/EncryptedFlux.java
index 7f1c0f7b2769..319756981ccf 100644
--- a/sdk/storage/azure-storage-blob-cryptography/src/test/java/com/azure/storage/blob/specialized/cryptography/EncryptedFlux.java
+++ b/sdk/storage/azure-storage-blob-cryptography/src/test/java/com/azure/storage/blob/specialized/cryptography/EncryptedFlux.java
@@ -142,7 +142,7 @@ public EncryptedFlux(int testCase, AsyncKeyEncryptionKey key, APISpec spec) thro
this.plainText = spec.getRandomData(DOWNLOAD_SIZE - 2); // This will yield two bytes of padding... for fun.
EncryptedBlob encryptedBlob = new EncryptedBlobAsyncClient(
- null, null, BlobServiceVersion.getLatest(), null, null, null, null, null, key, "keyWrapAlgorithm")
+ null, "https://random.blob.core.windows.net", BlobServiceVersion.getLatest(), null, null, null, null, null, key, "keyWrapAlgorithm")
.encryptBlob(Flux.just(this.plainText)).block();
this.cipherText = APISpec.collectBytesInBuffer(encryptedBlob.getCiphertextFlux()).block();
this.encryptionData = encryptedBlob.getEncryptionData();
diff --git a/sdk/storage/azure-storage-blob/CHANGELOG.md b/sdk/storage/azure-storage-blob/CHANGELOG.md
index 548b137d4b19..bcc283e39043 100644
--- a/sdk/storage/azure-storage-blob/CHANGELOG.md
+++ b/sdk/storage/azure-storage-blob/CHANGELOG.md
@@ -2,6 +2,7 @@
## 12.7.0-beta.1 (Unreleased)
- Fixed a bug that caused auth failures when constructing a client to a secondary endpoint using token auth.
+- Modified client constructors to throw on invalid urls early to prevent SAS tokens from being logged in Exceptions.
## 12.6.1 (2020-05-06)
- Updated `azure-core` version to `1.5.0` to pickup fixes for percent encoding `UTF-8` and invalid leading bytes in a body string.
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
index 007d0650c23d..f98bd03a7c47 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
@@ -42,6 +42,7 @@
import com.azure.storage.common.implementation.StorageImplUtils;
import reactor.core.publisher.Mono;
+import java.net.URI;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
@@ -55,8 +56,8 @@
import static com.azure.core.util.FluxUtil.monoError;
import static com.azure.core.util.FluxUtil.pagedFluxError;
import static com.azure.core.util.FluxUtil.withContext;
-import static com.azure.storage.common.Utility.STORAGE_TRACING_NAMESPACE_VALUE;
import static com.azure.core.util.tracing.Tracer.AZ_TRACING_NAMESPACE_KEY;
+import static com.azure.storage.common.Utility.STORAGE_TRACING_NAMESPACE_VALUE;
/**
* Client to a container. It may only be instantiated through a {@link BlobContainerClientBuilder} or via the method
@@ -112,6 +113,13 @@ public final class BlobContainerAsyncClient {
BlobContainerAsyncClient(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion,
String accountName, String containerName, CpkInfo customerProvidedKey, EncryptionScope encryptionScope,
BlobContainerEncryptionScope blobContainerEncryptionScope) {
+ /* Check to make sure the uri is valid. We don't want the error to occur later in the generated layer
+ when the sas token has already been applied. */
+ try {
+ URI.create(url);
+ } catch (IllegalArgumentException ex) {
+ throw logger.logExceptionAsError(ex);
+ }
this.azureBlobStorage = new AzureBlobStorageBuilder()
.pipeline(pipeline)
.url(url)
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobServiceAsyncClient.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobServiceAsyncClient.java
index 163fb7b91ed9..ff24c1a12cf1 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobServiceAsyncClient.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobServiceAsyncClient.java
@@ -40,6 +40,7 @@
import com.azure.storage.common.sas.AccountSasSignatureValues;
import reactor.core.publisher.Mono;
+import java.net.URI;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.ArrayList;
@@ -103,6 +104,13 @@ public final class BlobServiceAsyncClient {
BlobServiceAsyncClient(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion, String accountName,
CpkInfo customerProvidedKey, EncryptionScope encryptionScope,
BlobContainerEncryptionScope blobContainerEncryptionScope, boolean anonymousAccess) {
+ /* Check to make sure the uri is valid. We don't want the error to occur later in the generated layer
+ when the sas token has already been applied. */
+ try {
+ URI.create(url);
+ } catch (IllegalArgumentException ex) {
+ throw logger.logExceptionAsError(ex);
+ }
this.azureBlobStorage = new AzureBlobStorageBuilder()
.pipeline(pipeline)
.url(url)
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java
index cfa417c04718..4062478e4b78 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java
@@ -59,6 +59,7 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
@@ -139,6 +140,13 @@ protected BlobAsyncClientBase(HttpPipeline pipeline, String url, BlobServiceVers
protected BlobAsyncClientBase(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion,
String accountName, String containerName, String blobName, String snapshot, CpkInfo customerProvidedKey,
EncryptionScope encryptionScope) {
+ /* Check to make sure the uri is valid. We don't want the error to occur later in the generated layer
+ when the sas token has already been applied. */
+ try {
+ URI.create(url);
+ } catch (IllegalArgumentException ex) {
+ throw logger.logExceptionAsError(ex);
+ }
this.azureBlobStorage = new AzureBlobStorageBuilder()
.pipeline(pipeline)
.url(url)
diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ServiceAPITest.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ServiceAPITest.groovy
index 9de90f238737..5b4828d39d74 100644
--- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ServiceAPITest.groovy
+++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ServiceAPITest.groovy
@@ -4,27 +4,14 @@
package com.azure.storage.blob
import com.azure.identity.DefaultAzureCredentialBuilder
-import com.azure.identity.EnvironmentCredentialBuilder
-import com.azure.storage.blob.models.BlobAnalyticsLogging
-import com.azure.storage.blob.models.BlobContainerItem
-import com.azure.storage.blob.models.BlobContainerListDetails
-import com.azure.storage.blob.models.BlobCorsRule
-import com.azure.storage.blob.models.BlobMetrics
-import com.azure.storage.blob.models.BlobRetentionPolicy
-import com.azure.storage.blob.models.BlobServiceProperties
-import com.azure.storage.blob.models.CustomerProvidedKey
-import com.azure.storage.blob.models.ListBlobContainersOptions
-import com.azure.storage.blob.models.StaticWebsite
-
-import com.azure.storage.common.StorageSharedKeyCredential
-import com.azure.storage.blob.models.BlobStorageException
-
+import com.azure.storage.blob.models.*
import com.azure.storage.common.policy.RequestRetryOptions
import com.azure.storage.common.policy.RequestRetryPolicy
import com.azure.storage.common.sas.AccountSasPermission
import com.azure.storage.common.sas.AccountSasResourceType
import com.azure.storage.common.sas.AccountSasService
import com.azure.storage.common.sas.AccountSasSignatureValues
+import spock.lang.Unroll
import java.time.Duration
import java.time.OffsetDateTime
@@ -532,4 +519,29 @@ class ServiceAPITest extends APISpec {
then:
notThrown(Exception)
}
+
+ @Unroll
+ def "sas token does not show up on invalid uri"() {
+ setup:
+ /* random sas token. this does not actually authenticate anything. */
+ def mockSas = "?sv=2019-10-10&ss=b&srt=sco&sp=r&se=2019-06-04T12:04:58Z&st=2090-05-04T04:04:58Z&spr=http&sig=doesntmatter"
+
+ when:
+ BlobServiceClient client = new BlobServiceClientBuilder()
+ .endpoint(service)
+ .sasToken(mockSas)
+ .buildClient();
+ client.getBlobContainerClient(container)
+ .getBlobClient("blobname")
+
+ then:
+ def e = thrown(IllegalArgumentException)
+ !e.getMessage().contains(mockSas)
+
+ where:
+ service | container || _
+ "https://doesntmatter. blob.core.windows.net" | "containername" || _
+ "https://doesntmatter.blob.core.windows.net" | "container name" || _
+ /* Note: the check is on the blob builder as well but I can't test it this way since we encode all blob names - so it will not be invalid. */
+ }
}
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[0].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[0].json
new file mode 100644
index 000000000000..d3803998d14b
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[0].json
@@ -0,0 +1,105 @@
+{
+ "networkCallRecords" : [ {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net/jtcsastokendoesnotshowuponinvaliduri0555729625f76b47?restype=container",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "bf9bf799-e167-411a-97e9-552ac22a5e80"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "ETag" : "0x8D7FD07BB0063F4",
+ "Last-Modified" : "Wed, 20 May 2020 21:49:54 GMT",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-id" : "15ce2a1e-601e-0096-57f0-2e4471000000",
+ "Date" : "Wed, 20 May 2020 21:49:53 GMT",
+ "x-ms-client-request-id" : "bf9bf799-e167-411a-97e9-552ac22a5e80"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "522f7e7c-4201-41eb-b455-3ed29a0b7927",
+ "Content-Type" : "application/xml; charset=utf-8"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "d043da61-101e-000a-03f0-2ee917000000",
+ "Date" : "Wed, 20 May 2020 21:49:55 GMT",
+ "x-ms-client-request-id" : "522f7e7c-4201-41eb-b455-3ed29a0b7927"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "cef8048a-c027-4788-b8b9-30e8038059b9",
+ "Content-Type" : "application/xml; charset=utf-8"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "9b5a6e75-301e-0032-64f0-2e4dd7000000",
+ "Date" : "Wed, 20 May 2020 21:49:55 GMT",
+ "x-ms-client-request-id" : "cef8048a-c027-4788-b8b9-30e8038059b9"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "GET",
+ "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcsastokendoesnotshowuponinvaliduri&comp=list",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "b793f994-bd25-4ef8-a6bf-4060bb15c690"
+ },
+ "Response" : {
+ "Transfer-Encoding" : "chunked",
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "StatusCode" : "200",
+ "x-ms-request-id" : "d1bd715e-801e-0045-54f0-2e9843000000",
+ "Body" : "jtcsastokendoesnotshowuponinvalidurijtcsastokendoesnotshowuponinvaliduri0555729625f76b47Wed, 20 May 2020 21:49:54 GMT\"0x8D7FD07BB0063F4\"unlockedavailable$account-encryption-keyfalsefalsefalse",
+ "Date" : "Wed, 20 May 2020 21:49:57 GMT",
+ "x-ms-client-request-id" : "b793f994-bd25-4ef8-a6bf-4060bb15c690",
+ "Content-Type" : "application/xml"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "DELETE",
+ "Uri" : "https://REDACTED.blob.core.windows.net/jtcsastokendoesnotshowuponinvaliduri0555729625f76b47?restype=container",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "cd14b8d7-a9ee-4c1f-8a8f-62e408c1cd47"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "0f0cec0e-c01e-0009-2cf0-2e0873000000",
+ "Date" : "Wed, 20 May 2020 21:49:57 GMT",
+ "x-ms-client-request-id" : "cd14b8d7-a9ee-4c1f-8a8f-62e408c1cd47"
+ },
+ "Exception" : null
+ } ],
+ "variables" : [ "jtcsastokendoesnotshowuponinvaliduri0555729625f76b47" ]
+}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[1].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[1].json
new file mode 100644
index 000000000000..196535628985
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ServiceAPITestsastokendoesnotshowuponinvaliduri[1].json
@@ -0,0 +1,105 @@
+{
+ "networkCallRecords" : [ {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net/jtcsastokendoesnotshowuponinvaliduri0138028e4e760e5e?restype=container",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "43908848-6eb4-4046-9a96-b1063d286e66"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "ETag" : "0x8D7FD07BDFE0B11",
+ "Last-Modified" : "Wed, 20 May 2020 21:49:59 GMT",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-id" : "782b810b-301e-001d-64f0-2e401c000000",
+ "Date" : "Wed, 20 May 2020 21:49:58 GMT",
+ "x-ms-client-request-id" : "43908848-6eb4-4046-9a96-b1063d286e66"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "e84e7786-891b-4004-9b07-2fb0822b1682",
+ "Content-Type" : "application/xml; charset=utf-8"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "ce91ccdd-901e-0059-66f0-2eca23000000",
+ "Date" : "Wed, 20 May 2020 21:50:00 GMT",
+ "x-ms-client-request-id" : "e84e7786-891b-4004-9b07-2fb0822b1682"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "837d9bc7-0312-4d76-b4b1-00a4b6612890",
+ "Content-Type" : "application/xml; charset=utf-8"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "a47ab135-e01e-006c-7ef0-2ea637000000",
+ "Date" : "Wed, 20 May 2020 21:50:01 GMT",
+ "x-ms-client-request-id" : "837d9bc7-0312-4d76-b4b1-00a4b6612890"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "GET",
+ "Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcsastokendoesnotshowuponinvaliduri&comp=list",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "815812d5-ebbb-4346-be0c-765f4f8677a8"
+ },
+ "Response" : {
+ "Transfer-Encoding" : "chunked",
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "StatusCode" : "200",
+ "x-ms-request-id" : "532b205c-701e-001c-49f0-2e1fc0000000",
+ "Body" : "jtcsastokendoesnotshowuponinvalidurijtcsastokendoesnotshowuponinvaliduri0138028e4e760e5eWed, 20 May 2020 21:49:59 GMT\"0x8D7FD07BDFE0B11\"unlockedavailable$account-encryption-keyfalsefalsefalse",
+ "Date" : "Wed, 20 May 2020 21:50:01 GMT",
+ "x-ms-client-request-id" : "815812d5-ebbb-4346-be0c-765f4f8677a8",
+ "Content-Type" : "application/xml"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "DELETE",
+ "Uri" : "https://REDACTED.blob.core.windows.net/jtcsastokendoesnotshowuponinvaliduri0138028e4e760e5e?restype=container",
+ "Headers" : {
+ "x-ms-version" : "2019-07-07",
+ "User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.7; Windows 10 10.0)",
+ "x-ms-client-request-id" : "d16b3202-4412-4062-8ff1-fa9bf6d8907e"
+ },
+ "Response" : {
+ "x-ms-version" : "2019-07-07",
+ "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "Content-Length" : "0",
+ "StatusCode" : "202",
+ "x-ms-request-id" : "80c8813c-f01e-0094-48f0-2efac9000000",
+ "Date" : "Wed, 20 May 2020 21:50:02 GMT",
+ "x-ms-client-request-id" : "d16b3202-4412-4062-8ff1-fa9bf6d8907e"
+ },
+ "Exception" : null
+ } ],
+ "variables" : [ "jtcsastokendoesnotshowuponinvaliduri0138028e4e760e5e" ]
+}
\ No newline at end of file