Commit graph

7 commits

Author SHA1 Message Date
Snider
d90a5be936 refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.

Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:00 +01:00
Snider
e27006de30 fix(pr#2): address CodeRabbit round 3 review findings
- cache: fix LRU race — check expiry before MoveToFront within same lock
  critical section; previously a stale entry could be promoted before
  expiry was verified
- cache: drop stale ETag/Content-Md5/Digest headers when body is
  rewritten by refreshCachedResponseMeta to avoid misrepresenting the
  new body to clients
- ratelimit: cap buckets map at 100k entries with stale-eviction fallback
  and shared overflow bucket to prevent unbounded memory growth under
  high-cardinality traffic
- ratelimit: fix clientRateLimitKey comment — credentials are tried
  second (before IP), not as a "last resort"

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-07 09:29:03 +01:00
Snider
372326297e fix(pr#2): address CodeRabbit round 2 review findings
Go:
- cache: fix TOCTOU race in get() — re-verify entry pointer under lock before
  evicting to prevent corrupting s.currentBytes and removing a newly-set entry
- bridge: fix writeErrorResponse recorder out of sync — buffer into w.body/
  w.headers and call commit() so Status(), Header(), Size() reflect error response
- bridge: fix ValidateResponse number precision — use json.Decoder+UseNumber for
  initial envelope decode to preserve large integers (matches Validate path)
- ratelimit: fix unreachable credential branches — move X-API-Key and
  Authorization hashing before IP fallback so NAT'd clients are bucketed by key
- openapi: gate cacheSuccessHeaders on sb.CacheEnabled flag, not just method==get
- openapi: use isNilRouteGroup in prepareRouteGroups to catch typed-nil RouteGroup

PHP:
- RateLimitExceededException: remove ad-hoc CORS handling — let framework CORS
  middleware apply correct headers for all responses including errors
- SeoReportService.extractCharset: parse charset token from Content-Type value
  instead of returning the full "text/html; charset=utf-8" string
- SeoReportService: validate IP literals directly with filter_var before DNS
  lookup so ::ffff:127.0.0.1-style hosts don't bypass private-IP checks
- SeoReportService.isPrivateIp: extract isPrivateIpv4 helper; handle
  IPv4-mapped IPv6 (::ffff::/96) by checking embedded IPv4 against private
  ranges; add 0.0.0.0/8 to private range list

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-07 09:11:05 +01:00
Snider
e54dd2e370 fix(pr#2): address CodeRabbit major/critical review findings
Go:
- codegen: pass trimmed specPath to buildArgs instead of raw g.SpecPath
- cmd/sdk: use local resolvedSpecFile to avoid mutating flag variable per-invocation
- export: write to temp file + atomic rename to prevent destination truncation on failure
- openapi: gate effectiveGraphQLPath/SwaggerPath/WSPath/SSEPath on enable flags; use effectiveSwaggerPath in effectiveAuthentikPublicPaths
- cache: reject oversized replacement before mutating LRU state for existing keys
- ratelimit: move setRateLimitHeaders before c.Next() so headers are sent; hash credential headers with SHA-256 to avoid storing raw secrets; prefer validated principal from context
- response_meta: track size separately from body buffer so Size() is accurate after body rewrites and in passthrough mode
- bridge: limit request body reads with http.MaxBytesReader (10 MiB); allow missing data key in ValidateResponse for nil/zero success responses; update recorder status in writeErrorResponse
- pkg/provider/proxy: validate target scheme and host after url.Parse to catch hostless inputs
- cmd_test: snapshot/restore global spec registry in TestAPISpecCmd_Good_RegisteredSpecGroups

PHP:
- HasApiResponses.php, config.php: add declare(strict_types=1)
- RateLimitExceededException: validate Origin against cors.allowed_origins before reflecting in CORS header
- ApiUsageService: import and use Core\Api\Models\ApiKey instead of fully-qualified Mod\ path
- SeoReportService: add SSRF protection (scheme check, private-IP rejection); add .throw() for HTTP error handling; disable automatic redirects

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-07 08:38:41 +01:00
Virgil
2f8f8f805e fix(api): scope rate limiting by key
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-01 18:22:17 +00:00
Virgil
e713fb9f56 feat(api): emit rate limit headers on success and reject
Adds X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset to successful responses and 429 rejections, and documents the headers in OpenAPI.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-01 16:01:09 +00:00
Virgil
6fdd769212 feat(api): add per-IP rate limiting middleware
Adds a token-bucket WithRateLimit option that rejects excess requests with 429 Too Many Requests and a standard error envelope.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-01 06:54:58 +00:00