diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractor.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractor.java
index 5769d1169c3f..c84e6cd982e9 100644
--- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractor.java
+++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractor.java
@@ -17,6 +17,8 @@
 import io.opentelemetry.instrumentation.api.semconv.network.internal.InternalServerAttributesExtractor;
 import io.opentelemetry.semconv.HttpAttributes;
 import io.opentelemetry.semconv.UrlAttributes;
+import java.util.Arrays;
+import java.util.List;
 import java.util.function.ToIntFunction;
 import javax.annotation.Nullable;
 
@@ -32,6 +34,9 @@ public final class HttpClientAttributesExtractor<REQUEST, RESPONSE>
         REQUEST, RESPONSE, HttpClientAttributesGetter<REQUEST, RESPONSE>>
     implements SpanKeyProvider {
 
+  private static final List<String> PARAMS_TO_REDACT =
+      Arrays.asList("AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature");
+
   /**
    * Creates the HTTP client attributes extractor with default configuration.
    *
@@ -54,6 +59,7 @@ public static <REQUEST, RESPONSE> HttpClientAttributesExtractorBuilder<REQUEST,
   private final InternalNetworkAttributesExtractor<REQUEST, RESPONSE> internalNetworkExtractor;
   private final InternalServerAttributesExtractor<REQUEST> internalServerExtractor;
   private final ToIntFunction<Context> resendCountIncrementer;
+  private final boolean redactSensitiveParameters;
 
   HttpClientAttributesExtractor(HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> builder) {
     super(
@@ -65,6 +71,9 @@ public static <REQUEST, RESPONSE> HttpClientAttributesExtractorBuilder<REQUEST,
     internalNetworkExtractor = builder.buildNetworkExtractor();
     internalServerExtractor = builder.buildServerExtractor();
     resendCountIncrementer = builder.resendCountIncrementer;
+    redactSensitiveParameters =
+        Boolean.getBoolean(
+            "otel.instrumentation.http.client.experimental.redact-sensitive-parameters");
   }
 
   @Override
@@ -104,7 +113,7 @@ public SpanKey internalGetSpanKey() {
   }
 
   @Nullable
-  private static String stripSensitiveData(@Nullable String url) {
+  private String stripSensitiveData(@Nullable String url) {
     if (url == null || url.isEmpty()) {
       return url;
     }
@@ -141,8 +150,69 @@ private static String stripSensitiveData(@Nullable String url) {
     }
 
     if (atIndex == -1 || atIndex == len - 1) {
-      return url;
+      return redactSensitiveParameters ? redactUrlParameters(url) : url;
+    }
+
+    String afterUserPwdRedaction = url.substring(atIndex);
+    return url.substring(0, schemeEndIndex + 3)
+        + "REDACTED:REDACTED"
+        + (redactSensitiveParameters
+            ? redactUrlParameters(afterUserPwdRedaction)
+            : afterUserPwdRedaction);
+  }
+
+  public static String redactUrlParameters(String urlpart) {
+
+    int questionMarkIndex = urlpart.indexOf('?');
+
+    if (questionMarkIndex == -1) {
+      return urlpart;
+    }
+
+    if (!containsParamToRedact(urlpart)) {
+      return urlpart;
+    }
+
+    StringBuilder redactedParameters = new StringBuilder();
+    boolean paramToRedact = false;
+    boolean paramNameDetected = false;
+    boolean reference = false;
+
+    StringBuilder currentParamName = new StringBuilder();
+
+    for (int i = questionMarkIndex + 1; i < urlpart.length(); i++) {
+      char currentChar = urlpart.charAt(i);
+      if (currentChar == '=') {
+        paramNameDetected = true;
+        redactedParameters.append(currentParamName);
+        redactedParameters.append('=');
+        if (PARAMS_TO_REDACT.contains(currentParamName.toString())) {
+          redactedParameters.append("REDACTED");
+          paramToRedact = true;
+        }
+      } else if (currentChar == '&') {
+        redactedParameters.append('&');
+        paramNameDetected = false;
+        paramToRedact = false;
+        currentParamName.setLength(0);
+      } else if (currentChar == '#') {
+        reference = true;
+        redactedParameters.append('#');
+      } else if (!paramNameDetected) {
+        currentParamName.append(currentChar);
+      } else if (!paramToRedact || reference) {
+        redactedParameters.append(currentChar);
+      }
+    }
+    return urlpart.substring(0, questionMarkIndex) + "?" + redactedParameters;
+  }
+
+  private static boolean containsParamToRedact(String urlpart) {
+    for (String param : PARAMS_TO_REDACT) {
+      if (urlpart.contains(param)) {
+        return true;
+      }
     }
-    return url.substring(0, schemeEndIndex + 3) + "REDACTED:REDACTED" + url.substring(atIndex);
+    return false;
   }
 }
diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractorTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractorTest.java
index f4760f0201d3..701f040aa383 100644
--- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractorTest.java
+++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesExtractorTest.java
@@ -23,6 +23,7 @@
 import static java.util.Collections.emptyMap;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.entry;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
@@ -36,9 +37,13 @@
 import java.util.List;
 import java.util.Map;
 import java.util.function.ToIntFunction;
+import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
 import org.junit.jupiter.params.provider.ArgumentsSource;
 import org.junit.jupiter.params.provider.ValueSource;
 
@@ -200,6 +205,78 @@ void normal() {
             entry(NETWORK_PEER_PORT, 456L));
   }
 
+  @ParameterizedTest
+  @ArgumentsSource(StripUrlArgumentSource.class)
+  void stripBasicAuthTest(String url, String expectedResult) {
+    Map<String, String> request = new HashMap<>();
+    request.put("urlFull", url);
+
+    System.setProperty(
+        "otel.instrumentation.http.client.experimental.redact-sensitive-parameters", "true");
+    AttributesExtractor<Map<String, String>, Map<String, String>> extractor =
+        HttpClientAttributesExtractor.create(new TestHttpClientAttributesGetter());
+
+    AttributesBuilder attributes = Attributes.builder();
+    extractor.onStart(attributes, Context.root(), request);
+
+    assertThat(attributes.build()).containsOnly(entry(URL_FULL, expectedResult));
+  }
+
+  static final class StripUrlArgumentSource implements ArgumentsProvider {
+
+    @Override
+    public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
+      return Stream.of(
+          arguments("https://user1:secret@github.com", "https://REDACTED:REDACTED@github.com"),
+          arguments(
+              "https://user1:secret@github.com/path/",
+              "https://REDACTED:REDACTED@github.com/path/"),
+          arguments(
+              "https://user1:secret@github.com#test.html",
+              "https://REDACTED:REDACTED@github.com#test.html"),
+          arguments(
+              "https://user1:secret@github.com?foo=b@r",
+              "https://REDACTED:REDACTED@github.com?foo=b@r"),
+          arguments(
+              "https://user1:secret@github.com/p@th?foo=b@r",
+              "https://REDACTED:REDACTED@github.com/p@th?foo=b@r"),
+          arguments("https://github.com/p@th?foo=b@r", "https://github.com/p@th?foo=b@r"),
+          arguments("https://github.com#t@st.html", "https://github.com#t@st.html"),
+          arguments("user1:secret@github.com", "user1:secret@github.com"),
+          arguments("https://github.com@", "https://github.com@"),
+          arguments(
+              "https://service.com?paramA=valA&paramB=valB",
+              "https://service.com?paramA=valA&paramB=valB"),
+          arguments(
+              "https://service.com?AWSAccessKeyId=AKIAIOSFODNN7",
+              "https://service.com?AWSAccessKeyId=REDACTED"),
+          arguments(
+              "https://service.com?Signature=39Up9jzHkxhuIhFE9594DJxe7w6cIRCg0V6ICGS0%3A377",
+              "https://service.com?Signature=REDACTED"),
+          arguments(
+              "https://service.com?sig=39Up9jzHkxhuIhFE9594DJxe7w6cIRCg0V6ICGS0",
+              "https://service.com?sig=REDACTED"),
+          arguments(
+              "https://service.com?X-Goog-Signature=39Up9jzHkxhuIhFE9594DJxe7w6cIRCg0V6ICGS0",
+              "https://service.com?X-Goog-Signature=REDACTED"),
+          arguments(
+              "https://service.com?paramA=valA&AWSAccessKeyId=AKIAIOSFODNN7&paramB=valB",
+              "https://service.com?paramA=valA&AWSAccessKeyId=REDACTED&paramB=valB"),
+          arguments(
+              "https://service.com?AWSAccessKeyId=AKIAIOSFODNN7&paramA=valA",
+              "https://service.com?AWSAccessKeyId=REDACTED&paramA=valA"),
+          arguments(
+              "https://service.com?paramA=valA&AWSAccessKeyId=AKIAIOSFODNN7",
+              "https://service.com?paramA=valA&AWSAccessKeyId=REDACTED"),
+          arguments(
+              "https://service.com?AWSAccessKeyId=AKIAIOSFODNN7&AWSAccessKeyId=ZGIAIOSFODNN7",
+              "https://service.com?AWSAccessKeyId=REDACTED&AWSAccessKeyId=REDACTED"),
+          arguments(
+              "https://service.com?AWSAccessKeyId=AKIAIOSFODNN7#ref",
+              "https://service.com?AWSAccessKeyId=REDACTED#ref"));
+    }
+  }
+
   @ParameterizedTest
   @ArgumentsSource(ValidRequestMethodsProvider.class)
   void shouldExtractKnownMethods(String requestMethod) {