Skip to content

Conversation

@matheus-vb
Copy link

Problem

Changes

How did you test this code?

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Publish to changelog?

personal_api_key = config.get("POSTHOG_PERSONAL_API_KEY")
if not personal_api_key:
print(color("Error: POSTHOG_PERSONAL_API_KEY is required for setup", "red"))
print(f"Create a personal API key at: {config['POSTHOG_HOST']}/settings/user-api-keys")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

return 1

host = config["POSTHOG_HOST"]
print(f"Connecting to PostHog at {host}...")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

display_payload = payload.copy()
display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
print(color("Request:", "blue"))
print(f" POST {url}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

In general, the fix is to avoid logging data that could directly or indirectly contain secrets, such as full URLs that might embed credentials. Instead, log only non-sensitive parts (e.g., HTTP method and path, or a redacted host), or explicitly sanitize the value before printing.

For this specific code, the best minimal change is to stop printing the raw url and instead print an obviously non-sensitive representation. We can derive the path (/flags) from context, or at least log only the host in a way that cannot leak credentials. Since url is simply f"{host}/flags", we can avoid logging any potentially credential-bearing host by replacing print(f" POST {url}") with something like print(" POST /flags"). This remains informative for debugging (the endpoint and method are clear) while eliminating the tainted flow from environment-derived config to the log.

Concretely, in call_flags_endpoint in rust/feature-flags/bin/flags_test_tool.py:

  • Change the line print(f" POST {url}") to log a constant path string instead, e.g. print(" POST /flags").
  • No new imports or helper methods are needed.
    This single change breaks the taint path and addresses all variants that complain about logging sensitive data through url.
Suggested changeset 1
rust/feature-flags/bin/flags_test_tool.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/rust/feature-flags/bin/flags_test_tool.py b/rust/feature-flags/bin/flags_test_tool.py
--- a/rust/feature-flags/bin/flags_test_tool.py
+++ b/rust/feature-flags/bin/flags_test_tool.py
@@ -568,7 +568,7 @@
         display_payload = payload.copy()
         display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
         print(color("Request:", "blue"))
-        print(f"  POST {url}")
+        print("  POST /flags")
         print(f"  {json.dumps(display_payload)}")
         print(color("Response:", "blue"))
 
EOF
@@ -568,7 +568,7 @@
display_payload = payload.copy()
display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
print(color("Request:", "blue"))
print(f" POST {url}")
print(" POST /flags")
print(f" {json.dumps(display_payload)}")
print(color("Response:", "blue"))

Copilot is powered by AI and may make mistakes. Always verify output.
display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
print(color("Request:", "blue"))
print(f" POST {url}")
print(f" {json.dumps(display_payload)}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

General fix: ensure that sensitive fields (API keys, personal keys) are never logged, even in truncated form. When constructing display_payload for printing, either remove the token field altogether or replace it with a generic placeholder such as "<redacted>". Also ensure other call sites that pass api_key around do not inadvertently log it elsewhere.

Best concrete fix here: in call_flags_endpoint, we already create display_payload specifically for logging. We can modify this logging-only copy to completely hide the token instead of including a truncated value. Changing display_payload["token"] to a constant placeholder preserves existing functionality (request still uses the real payload with the true token; only the printed representation changes) and addresses all CodeQL variants pointing to the logging of tainted api_key. No other behavior of the tool changes.

Concretely:

  • In rust/feature-flags/bin/flags_test_tool.py, in call_flags_endpoint, locate the block:
    if verbose and not show_table:
        display_payload = payload.copy()
        display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
        print(color("Request:", "blue"))
        print(f"  POST {url}")
        print(f"  {json.dumps(display_payload)}")
  • Change the assignment to:
        display_payload["token"] = "<redacted>"

This ensures that json.dumps(display_payload) no longer includes any part of the sensitive key. No imports or additional functions are required.


Suggested changeset 1
rust/feature-flags/bin/flags_test_tool.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/rust/feature-flags/bin/flags_test_tool.py b/rust/feature-flags/bin/flags_test_tool.py
--- a/rust/feature-flags/bin/flags_test_tool.py
+++ b/rust/feature-flags/bin/flags_test_tool.py
@@ -566,7 +566,7 @@
 
     if verbose and not show_table:
         display_payload = payload.copy()
-        display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
+        display_payload["token"] = "<redacted>"
         print(color("Request:", "blue"))
         print(f"  POST {url}")
         print(f"  {json.dumps(display_payload)}")
EOF
@@ -566,7 +566,7 @@

if verbose and not show_table:
display_payload = payload.copy()
display_payload["token"] = api_key[:10] + "..." if len(api_key) > 10 else api_key
display_payload["token"] = "<redacted>"
print(color("Request:", "blue"))
print(f" POST {url}")
print(f" {json.dumps(display_payload)}")
Copilot is powered by AI and may make mistakes. Always verify output.

# Configuration
print(color("\nConfiguration:", "blue"))
print(f" PostHog host: {config['POSTHOG_HOST']}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

try:
http_request(f"{host}/flags", method="POST", data={"token": project_api_key, "distinct_id": "test"})
except ConnectionError:
print(color(f"\nCannot connect to {service_name} service at {host}", "red"))

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

In general, to fix clear‑text logging of sensitive information, avoid interpolating potentially secret or tainted values directly into log messages. Instead, either remove them from the message, replace them with redacted placeholders, or log only non‑sensitive derived information.

Here, the flagged sink is the error message Cannot connect to {service_name} service at {host}. We can preserve the functionality (telling the user which service type we tried to reach) without including the actual host value. The most targeted, low‑impact fix is to change this print to omit the host, e.g. Cannot connect to {service_name} service and, optionally, add a generic hint that does not echo configuration. This avoids logging any tainted data while keeping the tool useful.

Concretely:

  • In rust/feature-flags/bin/flags_test_tool.py, around line 1048 in cmd_examples, replace the call to print(color(... host ...)) with a version that does not format in host.
  • Leave the rest of the function unchanged, including how host is used to attempt the HTTP request.

No new imports or helper methods are needed; we only adjust the string literal.

Suggested changeset 1
rust/feature-flags/bin/flags_test_tool.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/rust/feature-flags/bin/flags_test_tool.py b/rust/feature-flags/bin/flags_test_tool.py
--- a/rust/feature-flags/bin/flags_test_tool.py
+++ b/rust/feature-flags/bin/flags_test_tool.py
@@ -1045,7 +1045,7 @@
     try:
         http_request(f"{host}/flags", method="POST", data={"token": project_api_key, "distinct_id": "test"})
     except ConnectionError:
-        print(color(f"\nCannot connect to {service_name} service at {host}", "red"))
+        print(color(f"\nCannot connect to {service_name} service", "red"))
         print("Make sure the service is running.")
         return 1
 
EOF
@@ -1045,7 +1045,7 @@
try:
http_request(f"{host}/flags", method="POST", data={"token": project_api_key, "distinct_id": "test"})
except ConnectionError:
print(color(f"\nCannot connect to {service_name} service at {host}", "red"))
print(color(f"\nCannot connect to {service_name} service", "red"))
print("Make sure the service is running.")
return 1

Copilot is powered by AI and may make mistakes. Always verify output.
if args.table:
print(color("═" * 70, "blue"))
print(color(f" Feature Flags Explorer - {service_name} Service (Table View)", "bold"))
print(color(f" Endpoint: {host}/flags", "dim"))

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

General approach: Avoid logging configuration values that might contain or be derived from sensitive data (API keys, passwords, tokens). Where context is useful, either omit the value entirely or log a redacted/sanitized version that cannot leak credentials.

Best fix here: Change the line that prints the endpoint so it does not include the raw host value. We can still give the user context by describing which service is used and that it’s calling /flags, but without echoing the full URL. This addresses all four alert variants because they all point to the same sink (color(f" Endpoint: {host}/flags", "dim")) even though the taint sources differ.

Concretely:

  • In cmd_examples, replace print(color(f" Endpoint: {host}/flags", "dim")) with a message that does not interpolate host. For example: print(color(" Endpoint: /flags", "dim")) or a more generic hint like print(color(" Endpoint: /flags (see your configured POSTHOG_HOST or POSTHOG_RUST_SERVICE_HOST)", "dim")).
  • No additional imports or helper functions are required; we can reuse the existing color function.
  • No other parts of the file need to change for this specific alert.
Suggested changeset 1
rust/feature-flags/bin/flags_test_tool.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/rust/feature-flags/bin/flags_test_tool.py b/rust/feature-flags/bin/flags_test_tool.py
--- a/rust/feature-flags/bin/flags_test_tool.py
+++ b/rust/feature-flags/bin/flags_test_tool.py
@@ -1053,7 +1053,7 @@
     if args.table:
         print(color("═" * 70, "blue"))
         print(color(f"  Feature Flags Explorer - {service_name} Service (Table View)", "bold"))
-        print(color(f"  Endpoint: {host}/flags", "dim"))
+        print(color("  Endpoint: /flags (see your configured POSTHOG_HOST or POSTHOG_RUST_SERVICE_HOST)", "dim"))
         print(color("═" * 70, "blue"))
 
         table_examples = [
EOF
@@ -1053,7 +1053,7 @@
if args.table:
print(color("═" * 70, "blue"))
print(color(f" Feature Flags Explorer - {service_name} Service (Table View)", "bold"))
print(color(f" Endpoint: {host}/flags", "dim"))
print(color(" Endpoint: /flags (see your configured POSTHOG_HOST or POSTHOG_RUST_SERVICE_HOST)", "dim"))
print(color("═" * 70, "blue"))

table_examples = [
Copilot is powered by AI and may make mistakes. Always verify output.
# Detail mode - show flags one by one
print(color("═" * 70, "blue"))
print(color(f" Feature Flags Explorer - {service_name} Service", "bold"))
print(color(f" Endpoint: {host}/flags", "dim"))

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

General fix: ensure that no value derived from potentially sensitive configuration (API keys, personal tokens) is logged in clear text. In this case, the problematic logging is the line that prints the full endpoint string built from host. We can fix this by only logging non-sensitive characteristics of host (e.g., which service is used) or by redacting anything beyond a safe, constant part of the URL.

Best targeted fix here: change the detail-mode header so that instead of logging the full endpoint URL ({host}/flags), we log a generic description that doesn’t reveal the actual host string. For example, show just Endpoint: /flags or Endpoint: <redacted>/flags or indicate the service name only. This keeps the rest of the tool’s behavior intact (it still uses host to make HTTP calls) but avoids printing host to stdout, addressing all variants that complain about tainted data reaching this sink.

Concretely:

  • In rust/feature-flags/bin/flags_test_tool.py, around line 1107, replace print(color(f" Endpoint: {host}/flags", "dim")) with a version that does not interpolate host. For example: print(color(" Endpoint: /flags (host configured in environment)", "dim")).
  • No new imports or helper functions are needed; we just alter the printed string.

This single change removes the tainted host from the logging sink and thus addresses all 4 alert variants that point at this line.


Suggested changeset 1
rust/feature-flags/bin/flags_test_tool.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/rust/feature-flags/bin/flags_test_tool.py b/rust/feature-flags/bin/flags_test_tool.py
--- a/rust/feature-flags/bin/flags_test_tool.py
+++ b/rust/feature-flags/bin/flags_test_tool.py
@@ -1104,7 +1104,7 @@
     # Detail mode - show flags one by one
     print(color("═" * 70, "blue"))
     print(color(f"  Feature Flags Explorer - {service_name} Service", "bold"))
-    print(color(f"  Endpoint: {host}/flags", "dim"))
+    print(color("  Endpoint: /flags (host configured via POSTHOG_HOST/POSTHOG_RUST_SERVICE_HOST)", "dim"))
     print(color("═" * 70, "blue"))
 
     # Filter to specific flag if provided
EOF
@@ -1104,7 +1104,7 @@
# Detail mode - show flags one by one
print(color("═" * 70, "blue"))
print(color(f" Feature Flags Explorer - {service_name} Service", "bold"))
print(color(f" Endpoint: {host}/flags", "dim"))
print(color(" Endpoint: /flags (host configured via POSTHOG_HOST/POSTHOG_RUST_SERVICE_HOST)", "dim"))
print(color("═" * 70, "blue"))

# Filter to specific flag if provided
Copilot is powered by AI and may make mistakes. Always verify output.
project_api_key = config.get("POSTHOG_PROJECT_API_KEY")
if not project_api_key:
print(color("Error: POSTHOG_PROJECT_API_KEY is required", "red"))
print(f"Find your project API key at: {config['POSTHOG_HOST']}/settings/project#variables")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.


standard_flags = get_standard_flag_keys()
service_name = "Python" if args.python else "Rust"
print(color(f"\nFlags from {service_name} service ({host}/flags)", "blue"))

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 2 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants