Skip to content

fix: default RevertGithubDNSExperiment to true when flags can't be fetched - #509

Merged
h0x0er merged 2 commits into
intfrom
jatin/dns-revert-default-int
Nov 3, 2026
Merged

h0x0er merged 2 commits into
intfrom
jatin/dns-revert-default-int

Conversation

@h0x0er

@h0x0er h0x0er commented Nov 3, 2026

Copy link
Copy Markdown
Member

Summary

  • Default RevertGithubDNSExperiment to true when global feature flags can't be fetched, so the GitHub DNS experiment revert always runs on failure.
  • Adds a defaultGlobalFeatureFlags() helper, used on every failure path in getGlobalFeatureFlags() and as the manager's initial and uninitialized defaults.
  • A successful response is still decoded into a zero-value struct, so the server can still turn the flag off.

@step-security-bot-int step-security-bot-int left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please find StepSecurity AI-CodeWise code comments below.

Code Comments

apiclient.go

  • [High]Replace fmt.Println with structured logging and error handling
    Using fmt.Println for error logging is not suited for production systems as it cannot be controlled or filtered effectively. Instead, use a structured logging package (e.g., logrus, zap) with appropriate log levels. This aligns with logging best practices outlined in "The Go Programming Language" (Alan A. A. Donovan & Brian W. Kernighan) and the Cloud Native Computing Foundation guidelines. Replace all fmt.Println calls with a structured logger that supports levels such as Error or Warning. For example, use apiclient.logger.Error("Error creating request:", err) if a logger is available, or initialize one. This will improve observability and support better monitoring and alerting.
  • [High]Ensure response body is closed to prevent resource leaks
    The HTTP response body returned by apiclient.Client.Do(req) needs to be closed after reading to avoid resource leaks. Failing to close it can lead to file descriptor exhaustion and degrade system reliability, following Go's standard library documentation best practices. Add defer resp.Body.Close() immediately after a successful response from apiclient.Client.Do(req), before reading the body. For example:

resp, err := apiclient.Client.Do(req)
if err != nil {
// handle error
}
defer resp.Body.Close()

This ensures that the response body is properly closed whether or not reading or unmarshalling succeeds.

  • [High]Check HTTP response status before reading the body
    The code currently reads and unmarshals the response body without verifying if the HTTP status code indicates success (e.g., 200 OK). This may lead to misinterpretation of error messages as valid data. According to HTTP RFC 7231 and Go HTTP client usage best practices, responses should be validated before processing the body. After receiving resp, check resp.StatusCode. If the status code is not in the 2xx range, log or handle the error appropriately and return defaultGlobalFeatureFlags(). For example:

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
// log error
return defaultGlobalFeatureFlags()
}

This prevents downstream errors due to unexpected or error responses.

  • [Medium]Return error along with default values to propagate failure up the call chain
    Returning a default GlobalFeatureFlags struct silently on error loses failure context, making debugging and error handling at higher layers difficult. Based on Go idiomatic error handling in Effective Go and Go best practices, functions performing IO or external calls should return an error so that callers can handle or log it appropriately. Change the function signature to return (GlobalFeatureFlags, error) and forward encountered errors up. For example:

func (apiclient *ApiClient) getGlobalFeatureFlags() (GlobalFeatureFlags, error) {
...
if err != nil {
return defaultGlobalFeatureFlags(), fmt.Errorf("error creating request: %w", err)
}
...
}

This change allows better observability and fault-tolerant logic in callers.

  • [Medium]Use context with timeout for HTTP requests to prevent indefinite blocking
    HTTP requests without context timeouts can hang indefinitely if the server does not respond. The Go blog and community recommend using context.Context with timeouts or deadlines to improve robustness and avoid resource exhaustion. Use context.WithTimeout to create a context with a reasonable timeout (e.g., 5 seconds) and use http.NewRequestWithContext. Example:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)

This enforces request timeout, improving reliability.

  • [Low]Use url.URL.ResolveReference instead of path.Join to build endpoint paths
    Joining paths with path.Join can unexpectedly alter URLs (e.g., removing slashes), which can cause incorrect API endpoint URLs. The Go standard library's url.URL.ResolveReference method is designed for this purpose and preserves URL semantics. Replace

u.Path = path.Join(u.Path, "global-feature-flags")

with

u = u.ResolveReference(&url.URL{Path: "global-feature-flags"})

This avoids potential URL path concatenation issues.

  • [Low]Document the function behavior and error handling strategy
    The function lacks comments explaining its purpose, returned values, and error handling approach. Following Go documentation conventions encourages maintainability and easier collaboration. Add a doc comment to the function describing what it does, its return value, and the fact that it returns default flags on errors or possibly an error if changed. Example:

// getGlobalFeatureFlags retrieves global feature flags via API.
// Returns the flags or default flags if any error occurs.
func (apiclient *ApiClient) getGlobalFeatureFlags() GlobalFeatureFlags {
...
}

  • [Low]Avoid returning empty struct literals and prefer using named default function
    The patch already improves returning defaultGlobalFeatureFlags() instead of GlobalFeatureFlags{} which is good because it centralizes defaults. Confirm this pattern is fully applied consistently. Ensure all early return statements return defaultGlobalFeatureFlags() instead of GlobalFeatureFlags{} to maintain code consistency and easier changes to defaults.

global_feature_flags.go

  • [High]Ensure defaultGlobalFeatureFlags function provides comprehensive default values for all fields
    The function defaultGlobalFeatureFlags currently only sets RevertGithubDNSExperiment to true, leaving other feature flags at their zero values. According to the Principle of Least Astonishment (Oracle Java coding conventions) and Defensive Programming guidelines (McConnell, Code Complete), default values should be explicitly defined to prevent unexpected behavior and improve code clarity. Update defaultGlobalFeatureFlags to explicitly define all fields of GlobalFeatureFlags with appropriate default values, rather than relying on implicit zero values.
  • [Medium]Add error logging when initialization or refresh of feature flags fails
    The current code mentions fetching initial flags and handling errors gracefully but does not show any logging or error reporting mechanism. According to effective error handling best practices (SEI CERT, CWE-388), logging errors aids in diagnostics and maintenance. Implement error logging in InitGlobalFeatureFlags and RefreshGlobalFeatureFlags functions when fetching or refreshing flags fails, using a structured logger to capture contextual information.
  • [Medium]Document thread-safety guarantees clearly for public functions accessing globalManager
    The functions GetGlobalFeatureFlags and IsCustomDetectionRulesEnabled acquire read locks but do not explicitly state the thread-safety expectations in their comments. Well-documented concurrency behavior reduces misuse risks (Go Best Practices for Concurrency). Add comments to public functions indicating that they are safe for concurrent use and internally guarded by mutexes.
  • [Low]Use consistent comment style and phrasing across codebase
    Comments switch between describing return values as 'default-initialized struct' and 'default flags.' Consistent documentation improves code maintainability and developer comprehension (Google Go Style Guide). Standardize comments, e.g., always use 'returns default feature flags' when referring to fallback returns.
  • [Low]Consider renaming method 'IsCustomDetectionRulesEnabled' to 'IsCustomDetectionRulesFeatureEnabled' or similar for clarity
    Clear method names adhere to Clean Code principles (Robert C. Martin) making code intent immediately obvious. Rename 'IsCustomDetectionRulesEnabled' to 'IsCustomDetectionRulesFeatureEnabled' or a similarly descriptive name.

Feedback

We appreciate your feedback in helping us improve the service! To provide feedback, please use emojis on this comment. If you find the comments helpful, give them a 👍. If they aren't useful, kindly express that with a 👎. If you have questions or detailed feedback, please create n GitHub issue in StepSecurity/AI-CodeWise.

@codecov

codecov Bot commented Nov 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.33333% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.52%. Comparing base (025b442) to head (68bd546).
⚠️ Report is 69 commits behind head on int.

Files with missing lines Patch % Lines
apiclient.go 0.00% 5 Missing ⚠️
global_feature_flags.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              int     #509      +/-   ##
==========================================
+ Coverage   60.88%   70.52%   +9.63%     
==========================================
  Files          19       21       +2     
  Lines        2081     1730     -351     
==========================================
- Hits         1267     1220      -47     
+ Misses        682      510     -172     
+ Partials      132        0     -132     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@step-security-bot-int step-security-bot-int left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please find StepSecurity AI-CodeWise code comments below.

Code Comments

apiclient.go

  • [High]Replace fmt.Println error logging with structured and leveled logging
    Using fmt.Println for error logging is not appropriate for production code as it lacks context, severity levels, timestamps, and can be hard to manage. According to the Go blog and best practices in effective logging (https://blog.golang.org/error-handling-and-go), structured logging frameworks such as logrus or zap provide better observability and debugging capability. Replace all occurrences of fmt.Println for error logs with a proper logging framework call, e.g. logrus.WithError(err).Error("Error message") or zap.Logger.Error("Error message", zap.Error(err)). Initialize and use a logger instance in ApiClient.
  • [High]Ensure response body is closed to prevent resource leaks
    The HTTP response body should be closed after reading to avoid resource leaks. This is a best practice described in the Go net/http package documentation (https://pkg.go.dev/net/http#Client.Do). Add defer resp.Body.Close() immediately after checking for error from apiclient.Client.Do(req) to ensure the response body is closed properly.
  • [Medium]Enhance error reporting by returning errors instead of suppressing them
    Suppressing errors by returning default values without propagating error information makes debugging difficult and violates effective error handling principles (Go blog: https://blog.golang.org/error-handling-and-go). Modify getGlobalFeatureFlags() to return (GlobalFeatureFlags, error) instead of just GlobalFeatureFlags, propagate errors up, and allow callers to decide how to handle failures instead of silently returning defaults.
  • [Medium]Use immutable global default constant for defaultGlobalFeatureFlags
    Returning a default value by calling a function can lead to unnecessary allocations or inconsistent results. Defining a constant or immutable global default value is a common practice (Effective Go: https://golang.org/doc/effective_go#constants). Define a package-level variable var defaultGlobalFeatureFlags = GlobalFeatureFlags{...} initialized once, and return that directly instead of a function call to improve clarity and performance.
  • [Low]Add context with timeout or cancellation to HTTP requests
    Long-running HTTP requests without a context with timeout can cause client deadlocks or hanging goroutines. Using context from the standard library is recommended (https://blog.golang.org/context). Create the HTTP request with context: req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) where ctx has timeout or cancellation propagated from caller.
  • [Low]Avoid using path.Join for URL paths as it can modify path unintentionally
    path.Join treats the path as a filesystem path and may clean or remove trailing slashes. Use url.URL.ResolveReference or manually concatenate paths as described in Go net/url recommendations (https://golang.org/pkg/net/url/#URL.ResolveReference). Replace u.Path = path.Join(u.Path, "global-feature-flags") with using url.URL.ResolveReference to append the endpoint path safely.
  • [Low]Add unit tests covering error scenarios for getGlobalFeatureFlags
    Including test coverage for error paths helps ensure stability and correctness, and is a recognized best practice (https://testing.googleblog.com/2017/05/test-faster-with-subtests-and-sub-benchmarks.html). Add unit tests that mock apiclient.Client.Do to simulate different failure modes (e.g., errors, bad JSON, etc.) to verify the behavior of getGlobalFeatureFlags.

apiclient_test.go

  • [High]Validate and sanitize API URLs before use
    The test cases include URLs that might be malformed or invalid, such as "%zz". Using such URLs directly in HTTP clients without proper validation can lead to unexpected errors or security issues as described by OWASP API Security guidelines. Add URL validation before use in HTTP clients in production code to prevent malformed URL issues. In tests, ensure that invalid URLs are handled gracefully and consider mocking instead of using invalid URLs that might cause hard-to-debug failures.
  • [High]Use context timeouts for HTTP requests to avoid indefinite hangs
    The HTTP client used in the tests does not include any context with timeouts. According to Go best practices documented by the Go team and common secure coding standards, a context with timeout should be used to avoid requests hanging indefinitely, especially when connecting to servers that may not respond as expected. Modify ApiClient methods to accept context.Context parameters and use context-aware HTTP requests with timeout. In tests, consider setting timeouts to avoid waits caused by unresponsive test servers.
  • [Medium]Recover and handle panics in tests to avoid test suite crashes
    Tests calling getGlobalFeatureFlags on potentially malformed or closed servers might cause unexpected panics. As per Go testing best practices and error resilience principles, tests should guard against panics to ensure a single failure does not abort the entire test suite. Add defer functions with recover in tests that handle error scenarios to ensure isolated test crash does not halt the suite.
  • [Medium]Improve error handling and logging in tests
    The tests use t.Fatalf on mismatches but do not provide detailed error context for why certain branches (invalid response vs request error) produce default flags. Clear error messages improve maintainability and debugging, advised by Go testing best practices. Enhance t.Fatalf error messages to include the actual error encountered and context on why certain default values are expected, potentially capturing response bodies or errors explicitly.
  • [Medium]Avoid closing test servers immediately after creation without request handling flushing
    In the test code, closedServer is started and immediately closed which might cause race conditions or flaky tests due to requests sent after closure. According to Go's httptest package documentation, servers should be gracefully closed after ensuring all requests are handled or accounted. Refactor the closedServer usage to either not start the server at all or ensure any requests to it are fully flushed or canceled before closing to prevent flakiness.
  • [Low]Ensure consistent usage of pointer or value receivers for ApiClient methods
    The tests instantiate ApiClient as a pointer. Go best practices encourage consistency and clarity in method receivers (pointer vs value). According to Effective Go, pointer receivers should be used when the method modifies the receiver or for efficiency. Review ApiClient method signatures to use pointer receivers consistently and update tests accordingly for idiomatic Go code.
  • [Low]Avoid global mutable state in tests to improve concurrency safety
    The Test_GetGlobalFeatureFlags_DefaultsWhenUninitialized test modifies the globalManager variable, restoring it afterward. This pattern inhibits safe parallel test executions. Go testing best practices recommend tests avoid shared mutable global state or use sync mechanisms. Refactor code to avoid global state mutation in tests, or protect global state changes with synchronization and run tests sequentially if unavoidable.
  • [Low]Add comments explaining purpose of each test case in complex test tables
    The table-driven tests have different scenarios but lack explicit comments describing expectations or rationale. Clear inline documentation is recommended by software engineering best practices to improve code readability and maintainability. Add comments for each test case explaining the condition it simulates and the expected result.
  • [Low]Use constants for repeated URL path strings to avoid typos and ease maintenance
    The string "/v1/global-feature-flags" is hardcoded multiple times. Using constants improves maintainability and prevents errors as recommended by clean code guidelines. Define a const variable for API path strings and use it throughout test code.
  • [Low]Use table-driven subtests with t.Parallel() where safe to improve test suite speed
    The for loop calls t.Run but does not leverage t.Parallel() to run tests concurrently. Go testing best practices encourage parallel tests for faster execution when tests are independent. Add t.Parallel() call inside each subtest if no shared mutable state is accessed concurrently in test cases.

global_feature_flags.go

  • [High]Avoid returning zero-valued structs as defaults; provide explicit default values
    Returning zero-valued structs as defaults can lead to subtle bugs if the field zero values are not the intended defaults. According to Effective Go and Go best practices, default values should be explicitly defined to ensure consistent behavior. Introduce a function defaultGlobalFeatureFlags() that returns explicitly initialized default flags, and use this function instead of returning GlobalFeatureFlags{} directly.
  • [Medium]Use thread-safe read locks when reading concurrent shared state
    Accessing shared state without proper synchronization can cause race conditions. The use of mutex.RLock() and RUnlock() follows the sync package recommendations to safely read shared mutable state. Ensure that all accesses to the globalManager.flags are protected by a read lock, as done in GetGlobalFeatureFlags(), maintaining thread-safety.
  • [Medium]Encapsulate default flag initialization to improve maintainability and reduce duplication
    Duplicated initialization logic can lead to maintenance issues. By centralizing default flag creation in one method, changes to defaults are easier and less error-prone. This aligns with the DRY principle and is endorsed in authoritative Go style guides. Refactor the code to remove repeated default flag structs and replace all instances with calls to defaultGlobalFeatureFlags().
  • [Low]Add comments clarifying the behavior and intent of default flags
    Well-documented code improves readability and maintainability. Providing rationale comments helps future developers understand why certain defaults are chosen, consistent with documentation best practices outlined in Effective Go. Add a comment above defaultGlobalFeatureFlags() describing its purpose and when these defaults are used.

Feedback

We appreciate your feedback in helping us improve the service! To provide feedback, please use emojis on this comment. If you find the comments helpful, give them a 👍. If they aren't useful, kindly express that with a 👎. If you have questions or detailed feedback, please create n GitHub issue in StepSecurity/AI-CodeWise.

@h0x0er
h0x0er merged commit a7ceb08 into int Nov 3, 2026
5 of 6 checks passed
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