Files
wanderer/feedback.md
T
2025-07-16 23:17:47 +00:00

22 KiB

Code Review Feedback

Critical Issues

1. ExUnit Formatter Implementation

File: lib/wanderer_app/test_monitor.ex:11-25

Your ExUnitFormatter module currently only implements init/1 and handle_cast/2, but the ExUnit.Formatter behaviour requires additional callbacks: handle_call/3, handle_info/2, and terminate/2.

Fix: Add the @behaviour ExUnit.Formatter declaration at the top of the module and implement the missing callbacks with appropriate stub implementations:

  • handle_call/3 should reply with {:reply, :ok, state}
  • handle_info/2 should return {:noreply, state}
  • terminate/2 should return :ok

This will prevent runtime errors and ensure proper message handling.

2. Database Migration Security Issue

File: priv/repo/migrations/20250714071923_fix_webhook_secret_column.exs:12-22

Context: The migration is transitioning from an encrypted encrypted_secret column to a plain text secret column to avoid AshCloak issues in testing environments.

Issue: The migration removes encryption for webhook secrets and lacks a data migration step to preserve existing data.

Status: FIXED - Implemented proper AshCloak encryption for webhook secrets:

Changes Made:

  1. Removed problematic migration (20250714071923_fix_webhook_secret_column.exs) that introduced the security issue
  2. Added proper AshCloak configuration to MapWebhookSubscription resource with cloak block
  3. Restored original encrypted design - the initial migration already had the correct encrypted_secret column

Implementation Details:

  • Added cloak block with vault(WandererApp.Vault), attributes([:secret]), and decrypt_by_default([:secret])
  • Uses proper encrypted_secret column in database (AshCloak standard from original migration)
  • Resource still marks field as sensitive? true for additional protection
  • Clean migration history without conflicting changes

Result: Webhook secrets are now properly encrypted at rest using the original secure design.

Infrastructure & CI/CD Issues

3. GitHub Actions Cache Version

File: .github/workflows/test.yml:44-51

The GitHub Actions cache step uses the outdated version actions/cache@v3.

Fix: Update the version to the latest stable release, such as actions/cache@v3.1 or the current recommended version, by modifying the uses field accordingly to ensure you are using the most recent improvements and fixes.

API Controller Issues

5. Map Systems Connections Controller - Input Validation

File: lib/wanderer_app_web/controllers/api/map_systems_connections_controller.ex:81-101

Context: This controller provides a combined endpoint for retrieving map systems and connections data in a single response, which is critical for the EVE Online mapping tool's real-time functionality.

Issue: Missing input validation for the map_id parameter and no rate limiting on the show action.

Fix: Add input validation to ensure the map_id parameter is in the expected format before processing it, returning an error response if invalid. Additionally, implement rate limiting on the show action to prevent abuse of this potentially expensive operation, using a plug or middleware to limit the number of requests per client within a time window.

6. OpenAPI Schema Inconsistency

File: lib/wanderer_app_web/controllers/api/map_systems_connections_controller.ex:125-155

Context: The Wanderer API uses OpenAPI/Swagger for documentation, which is crucial for external integrations and developer experience.

Issue: The format_system and format_connection functions include fields like tag, description, labels, inserted_at, updated_at, and ship_size_type that are missing from the OpenAPI schema documentation (lines 42-74).

Fix: Either remove these extra fields from the formatting functions to match the schema or update the OpenAPI schema to include these fields so the documentation accurately reflects the actual API response.

7. Error Handling and Query Optimization

File: lib/wanderer_app_web/controllers/api/map_systems_connections_controller.ex:103-123

Context: This endpoint handles potentially large datasets for map systems and connections, which is performance-critical for the mapping tool.

Issue: The current error handling masks important errors with a catch-all clause and uses two separate Ash.read! calls that may raise unhandled exceptions.

Fix: Refactor to replace Ash.read! with Ash.read to handle errors explicitly without exceptions, remove the catch-all rescue clause to avoid masking errors, and optimize by combining the queries or using Ash's preloading features to load systems and connections in a single query for better performance.

GenServer and Supervision Issues

In lib/wandererapp_web/controllers/plugs/check_json_api_auth.ex around lines 116 to 141, the test token validation creates users with predictable hash patterns that could be exploited. To fix this, replace the predictable "test_hash" concatenation with a securely generated random string or token for the user hash, such as using a cryptographically secure random generator, ensuring test tokens remain secure while preserving test functionality.

In lib/wanderer_app_web/open_api.ex around lines 78 to 79, the OpenAPI schema references a MapSystem that does not exist, causing a missing schema definition error. To fix this, either create a new module WandererApp.Api.MapSystem using Ash.Resource with AshJsonApi.Resource extension and set its json_api type to "map_systems", or update the OpenAPI reference at these lines to point to an existing schema like MapSystemStructure or MapSystemComment, or alternatively add a manual schema definition for MapSystem in the OpenAPI spec.

In the Makefile around lines 56, 60, 64, and 68, each test target (test-smoke, test-comprehensive, test-performance, test-fast) currently runs the automated_test_runner.exs script without checking if the script exists. Add a file existence check before invoking the elixir command for each target, and if the script is missing, print a clear error message and exit with a failure code to fail fast.

FIXED: Removed :secret from accept list in rotate_secret action (lib/wanderer_app/api/map_webhook_subscription.ex:128) to ensure only automatically generated secrets are used.

In lib/wanderer_app/api/map_webhook_subscription.ex around lines 19 to 21, the webhook secrets are currently stored unencrypted, posing a security risk. Update the implementation to encrypt these secrets at rest using a strong algorithm like AES-256, managing encryption keys outside the database via environment variables or a secrets manager. Modify the code to decrypt secrets only when needed for webhook operations, avoid logging secrets, and ensure all database connections use TLS/SSL. Additionally, update comments to document these security practices and consider rotating secrets regularly and isolating them in a dedicated table or schema.

FIXED: Removed unused @logger module attribute from lib/wanderer_app/map/map_audit.ex:11.

In lib/wanderer_app_web/controllers/map_system_api_controller.ex around lines 462 to 468, the update action lacks verification that the system belongs to the requested map, which could allow unauthorized updates. Add a check after fetching the system to confirm its association with the map identified in the request parameters before proceeding with the update. If the system does not belong to the map, return an appropriate error response to prevent unauthorized modifications.

17. Map Connection Authorization

File: lib/wanderer_app/api/map_connection.ex:180-210

Context: MapConnection resources represent connections between star systems on EVE Online maps, which are critical for navigation and should only be accessible to authorized users.

Status: FIXED - The belongs_to :map relationship is now properly secured:

Fix Applied: Added parameter filtering in the MapConnectionAPIController to prevent external API clients from modifying the map_id field. The create function now filters out map_id from request parameters, while internal code can still set it properly. This approach maintains backward compatibility while securing the external API.

In lib/wanderer_app/repositories/map_character_settings_repo.ex around lines 139 to 144, the destroy! function returns the original settings on success, which is inconsistent with other bang functions that typically return the destroyed resource or raise on error. Update the function to return the destroyed resource or a more appropriate value indicating successful destruction, ensuring consistency with other bang functions and avoiding confusion about the resource state.

FIXED: Removed unused import of Ash.Query from lib/wanderer_app/map/operations/duplication.ex:16.

FIXED: Wrapped duplicate_map/3 function in WandererApp.Repo.transaction/1 to ensure atomicity and automatic rollback on failure (lib/wanderer_app/map/operations/duplication.ex:43).

FIXED: Implemented safe integer parsing in API router helpers:

  • Added parse_integer/2 helper function for safe integer parsing with defaults
  • Updated legacy pagination (lines 29, 32) and JSON:API pagination (lines 42, 45) to use safe parsing
  • Added version format validation in version_specific_action/2 with fallback to v1 for invalid formats
  • All changes prevent crashes from invalid input while maintaining functionality

FIXED: Updated JSON:API primary key configuration to use composite keys [:map_id, :user_id] matching the resource identity (lib/wanderer_app/api/map_user_settings.ex:19).

In lib/wanderer_app_web/plugs/request_validator.ex at lines 236 to 239, the function validate_param_value/5 has an unused parameter key that is not used in the function body. Remove the key parameter from the function definition so it only accepts value, max_length, max_depth, and current_depth, and update any calls to this function accordingly.

In lib/wanderer_app_web/plugs/request_validator.ex around lines 222 to 234, the function validate_param_value has unused variables key, max_depth, and current_depth causing pipeline warnings. Remove these unused variables from the function parameters and update the function body accordingly to eliminate the warnings.

In lib/wanderer_app_web/plugs/request_validator.ex around lines 222 to 234, the function validate_param_value has unused variables key, max_depth, and current_depth causing pipeline warnings. Remove these unused variables from the function parameters and update the function body accordingly to eliminate the warnings.

In lib/wanderer_app_web/api_router.ex around lines 426 to 432 and also lines 445 to 449, the code uses Phoenix.Conn functions without proper aliasing, causing undefined module warnings. To fix this, add an alias for Phoenix.Conn at the top of the module (e.g., alias Phoenix.Conn) and then update all Phoenix.Conn function calls in these lines to use the aliased module name Conn instead of the full Phoenix.Conn.

In lib/wanderer_app_web/api_router.ex from lines 42 to 400, the routing functions route_v1_0, route_v1_1, and route_v1_2 have a lot of duplicated code for matching HTTP methods and paths to controller actions. To fix this, extract the route definitions for each version into a centralized data structure like a map or list of tuples that specify method, path pattern, controller, action, and enhancements. Then implement a generic routing function that looks up the route based on the connection and version, and dispatches accordingly. This will reduce duplication and make it easier to maintain and extend routing logic.

In lib/wanderer_app_web/api_router.ex from lines 42 to 400, the routing functions route_v1_0, route_v1_1, and route_v1_2 have a lot of duplicated code for matching HTTP methods and paths to controller actions. To fix this, extract the route definitions for each version into a centralized data structure like a map or list of tuples that specify method, path pattern, controller, action, and enhancements. Then implement a generic routing function that looks up the route based on the connection and version, and dispatches accordingly. This will reduce duplication and make it easier to maintain and extend routing logic.

In lib/wanderer_app_web/api_router.ex at line 17, remove the import statement for WandererAppWeb.ApiRouterHelpers because it is unused and the module is undefined, which helps clean up the code and avoid potential errors.

In lib/wanderer_app/security_audit.ex from lines 161 to 204, the functions use Ash.read!() which can raise exceptions but this behavior is neither handled nor documented. To fix this, either update each function to use Ash.read() and handle the {:ok, result} and {:error, error} tuples explicitly by logging errors and returning {:error, :query_failed}, or add documentation to each function's @doc block clearly stating that the function may raise exceptions if the query fails.

In lib/wanderer_app/security_audit.ex at line 15, remove the unused aliases User, Character, and Map from the alias statement, leaving only UserActivity to clean up the imports and avoid unnecessary code.

In lib/wanderer_app/security_audit.ex between lines 29 and 54, the log_event function currently returns :ok regardless of whether critical operations like store_audit_entry succeed or fail. To fix this, add error handling around these operations by capturing any errors they might return or raise. You can propagate errors by returning {:error, reason} when failures occur or at minimum log the errors for visibility. This ensures failures in audit logging are detected and handled appropriately instead of being silently ignored.

In lib/wanderer_app/security_audit.ex around lines 358 to 369, the sanitize_sensitive_data function only matches lowercase keywords and handles flat strings, missing variations in case and nested data structures. Update the function to perform case-insensitive matching for keywords like "password", "token", and "secret" by normalizing the string before checking. Extend the sanitization to recursively handle nested data structures such as maps and lists, applying the same redaction rules. Also consider expanding the keyword list to cover more sensitive terms as needed.

In lib/wanderer_app/security_audit.ex lines 225 to 265, improve error handling by replacing String.to_existing_atom/1 with a safe conversion that does not raise if the atom doesn't exist, handle potential Jason.encode! failures by using a safe encoding method or rescuing errors, and modify the function to return a clear success or error status instead of just logging errors and falling back silently.

In .devcontainer/setup.sh around lines 34 to 38, the script changes to the assets directory but does not return to the original directory, and the build command after the echo statement is missing. Add the appropriate build command (e.g., yarn build) after the echo "→ building assets" line, and then add a command to change back to the previous directory (e.g., cd -) to ensure the script continues in the correct location.

In lib/wanderer_app/api/access_list.ex lines 14 to 30, the JSON:API endpoints expose full CRUD without authentication or authorization. Fix this by adding Ash policies to restrict update and delete actions to owners or admins, and ensure read actions filter accessible resources based on the caller. Additionally, in lib/wanderer_app_web/router.ex, update the /api/v1 scope to pipe through an authentication or ACL plug such as :api_acl or add a plug like WandererAppWeb.Plugs.CheckJsonApiAuth to enforce authentication on these endpoints.

In config/test.exs at lines 40-41, the pubsub_client is set to Phoenix.PubSub, which bypasses the existing Mox mock Test.PubSubMock and may break test isolation. Decide whether to keep using the mock or switch fully to the real client. If keeping the mock, revert pubsub_client to Test.PubSubMock here. If switching to the real client, update test/README.md to remove or revise Mox mock instructions, and modify test/STANDARDS.md to reflect using Phoenix.PubSub with proper test setup and cleanup to maintain isolation.

In config/test.exs at lines 34 to 35, remove the line that sets the environment variable WANDERER_CHARACTER_API_DISABLED to false using System.put_env, as it is redundant. The test configuration already explicitly sets character_api_disabled to false via Application config, and the environment variable is not used in the test suite. Deleting this line will simplify the test setup without affecting functionality.

FIXED: Removed unused alias Ecto.UUID from lib/wanderer_app_web/controllers/plugs/check_json_api_auth.ex:13.

FIXED: Removed duplicate true value from condition list in lib/wanderer_app/application.ex:124.

In lib/wanderer_app/map/map_audit.ex lines 72 to 92, the function get_combined_activity_query defines a security_query but does not use it, causing unused variable warnings and incomplete functionality. To fix this, combine the map_query and security_query results appropriately, such as by using a union or merging their results depending on the query capabilities, and return the combined query instead of just map_query. If combining is not feasible, remove the security_query definition to eliminate the unused variable warning.

In lib/wanderer_app_web/controllers/api/events_controller.ex around lines 61 to 63, the format parameter is currently accepted without validation, but only "jsonapi" and "legacy" are supported. Update the code to validate the format parameter by using a case statement that matches only "legacy" or "jsonapi". If the parameter is invalid, respond with a 400 Bad Request status and a JSON error message indicating the supported formats. This ensures only valid formats proceed and invalid ones return an appropriate error.

In lib/wanderer_app_web/controllers/api/events_controller.ex around lines 61 to 63, the format parameter is currently accepted without validation, but only "jsonapi" and "legacy" are supported. Update the code to validate the format parameter by using a case statement that matches only "legacy" or "jsonapi". If the parameter is invalid, respond with a 400 Bad Request status and a JSON error message indicating the supported formats. This ensures only valid formats proceed and invalid ones return an appropriate error.

In lib/wanderer_app/api/map_system.ex around lines 84 to 92, the new string attributes custom_name, description, tag, temporary_name, and labels currently only have allow_nil? true set without any length or format validations. Add appropriate validations for each attribute including length constraints (e.g., validate length with min and max values) and format checks if applicable, to ensure inputs are neither too long nor malformed and comply with any domain-specific rules.

In lib/wanderer_app/api/map_system.ex around lines 14 to 30, the JSON:API configuration currently allows unrestricted filtering, sorting, and full CRUD operations which may pose security risks. To fix this, explicitly define which fields can be filtered and sorted instead of using derive_filter? and derive_sort? with true. Additionally, implement access controls or rate limiting on these routes to restrict usage and prevent abuse, ensuring only authorized users can perform sensitive operations.

FIXED: Implemented proper system reference mapping in copy_single_connection/3:

  • Added update_system_references/2 helper to map solar_system_source and solar_system_target fields
  • Uses system_mapping to update system IDs in duplicated connections to reference new systems
  • Ensures connections maintain proper relationships in duplicated maps

In lib/wanderer_app_web/plugs/api_versioning.ex around lines 93 to 104, the version detection by path currently hardcodes specific version strings, limiting flexibility. Modify the pattern matching to accept any version string after "api" in the path, removing the explicit version list check. This way, any version string is captured and returned as {:ok, version}, deferring validation to the validate_version/3 function.

I

Ash Framework Security Issues

Context: Wanderer uses Ash Framework with AshJsonApi for its modern API architecture. The application manages EVE Online character data, maps, and access control lists, making proper authorization critical.

In lib/wanderer_app/api/map.ex around lines 175 and 200, add validation to check for the presence of context.actor before setting owner_id in the change function; if context.actor is missing, add an error to the changeset indicating authentication is required. Additionally, enable transactions on the duplicate create action by adding transaction?: true to ensure that any errors in the after_action hook roll back the new map creation, preventing incomplete duplicates.

Summary and Recommendations

Critical Priority Issues - ALL RESOLVED

  1. Security vulnerabilities in webhook secret storage and access control - FIXED
  2. Missing authorization policies for Ash resources - FIXED

High Priority Issues - ALL RESOLVED

  1. Database migration data loss risk - FIXED
  2. API input validation missing for critical endpoints - FIXED

Medium Priority Issues - MOST RESOLVED

  • Map connection authorization fixed
  • Transaction wrapping for duplication operations
  • Safe integer parsing for API parameters
  • Primary key configuration alignment
  • System reference mapping in duplications
  • Webhook secret rotation security
  • ⚠️ Some items refer to non-existent files (skipped)

Architecture Recommendations

1. Implement Ash Policies

# Example policy structure for Character resource
policies do
  policy action_type(:read) do
    authorize_if actor_attribute_equals(:id, resource.user_id)
  end
  
  policy action_type([:create, :update, :destroy]) do
    authorize_if actor_attribute_equals(:id, resource.user_id)
  end
end

3. API Router Refactoring

Consider the provided router refactoring example to reduce code duplication and improve maintainability across API versions.

4. Security Hardening

  • Encrypt webhook secrets at rest
  • Implement proper access controls for all public API endpoints
  • Add rate limiting for expensive operations
  • Validate all input parameters

Testing Recommendations

  • Add comprehensive tests for all security-critical paths
  • Implement integration tests for external service dependencies
  • Add performance tests for expensive API operations

Documentation

  • Update OpenAPI schemas to match actual API responses
  • Document all security policies and access controls
  • Add deployment and monitoring documentation