towerops/lib/towerops_web/graphql/context.ex
Graham McIntie 34fe5d7e49 Security fixes: mask credentials in logs/API, fix cookie/CSP/LIKE injection/webhooks
CRITICAL fixes:
- Mask SNMP community string in agent channel logs (CRITICAL-1)
- Remove snmpv3 passwords from REST API responses, return _set booleans (CRITICAL-2)
- Replace snmp_community with snmp_community_set in GraphQL type (CRITICAL-3)

HIGH fixes:
- Fix cookie same_site from invalid 'Towerops' to 'Lax' (HIGH-4)
- Remove unsafe-eval from CSP script-src (HIGH-6)
- Block GraphQL introspection queries in production (HIGH-7)
- Sanitize LIKE wildcards in SNMP device name search (HIGH-8)
- Reject webhooks when no secret configured instead of accepting (HIGH-9)

MEDIUM fixes:
- Hash mobile session tokens (SHA-256) before DB storage (MEDIUM-10)
- Apply security headers in all environments, not just prod (MEDIUM-14)
- Add GraphQL query complexity limit (500) in production (MEDIUM-16)
- Fix X-Frame-Options to DENY to match frame-ancestors 'none' (MEDIUM-13)
2026-02-15 09:09:04 -06:00

39 lines
955 B
Elixir

defmodule ToweropsWeb.GraphQL.Context do
@moduledoc """
Plug that builds the Absinthe context from the authenticated API connection.
Reads the organization_id and user set by the ApiAuth plug and passes them
into the Absinthe context for use by resolvers.
"""
@behaviour Plug
def init(opts), do: opts
def call(conn, _opts) do
context = build_context(conn)
opts =
if Application.get_env(:towerops, :env) == :prod do
[context: context, analyze_complexity: true, max_complexity: 500]
else
[context: context]
end
Absinthe.Plug.put_options(conn, opts)
end
defp build_context(conn) do
context = %{}
context =
case conn.assigns[:current_organization_id] do
nil -> context
org_id -> Map.put(context, :organization_id, org_id)
end
case conn.assigns[:current_user] do
nil -> context
user -> Map.put(context, :user, user)
end
end
end