Cargando…
Cargando…
Trust Center · Security Posture
simiriki operates the infrastructure its customers use to detect and remediate Microsoft 365 misconfigurations. That position — between the customer tenant and the remediation engine — demands a higher security-hygiene bar than a marketing site. This document is the result of the internal audit of May 6, 2026 against the twelve vectors an adversarial reviewer (Gartner analyst, Microsoft Digital Defense Report author, Fortune 500 CISO) would check first. Each line cites the file in code that supports it.
No denials, no pending proofs: these are verifiable facts about the public repository at github.com/jjdlr-simiriki/simiriki as of the audit date.
| Class | Status | Evidence |
|---|---|---|
| SQL injection | Clean | Every pool.query() call uses parameterized placeholders ($1, $2, $3); no string interpolation in queries across apps/api/src/**. |
| Server-Side Request Forgery (SSRF) | Clean | Grep audit found no fetch(req.body.url) or equivalent pattern in any route handler. |
| Open redirects | Clean | app/api/auth/verify/route.ts validates the next= parameter against the allowlist ALLOWED_NEXT_PREFIXES = [/dashboard, /checkout, /portal, /onboarding, /intake]. Anything outside falls back to /dashboard. |
| Cross-Site Request Forgery (CSRF) | Clean | proxy.ts:199-209 rejects POST/PUT/DELETE/PATCH with an Origin header outside the allowed set. Stripe webhooks and crons (no Origin) authenticate via signature, not origin. |
| OAuth state verification | Clean | LinkedIn, Google, and Microsoft 365 callbacks all use crypto.timingSafeEqual to compare provided state against the signed cookie. See app/api/auth/{linkedin,google}/callback/route.ts and app/api/connect-m365/callback/route.ts. |
| Stripe webhook signature | Clean | app/api/stripe/webhook/route.ts uses stripe.webhooks.constructEvent() (official timing-safe API) with STRIPE_WEBHOOK_SECRET, plus idempotency backed by Supabase stripe_webhook_events table indexed on stripe_event_id. |
| HMAC on Microsoft 365 callback | Clean | app/api/connect-m365/callback/route.ts:161 uses crypto.timingSafeEqual for bypass-token comparison against the secret. |
| Resend webhook signature | Clean | app/api/webhooks/resend/route.ts:91-115 verifies Svix HMAC-SHA256 with timingSafeEqual. Production rejects if RESEND_WEBHOOK_SECRET is unset (fail-closed). |
| Token encryption at rest | Clean | lib/crypto.ts implements AES-256-GCM with IV+authTag persistence. lib/linkedin/api.ts and app/api/connect-m365/callback/route.ts encrypt access/refresh tokens before writing to Supabase. |
| /audit/report HMAC | Clean | app/audit/report/route.ts:27-42 requires REPORT_TOKEN_SALT or INTERNAL_API_SECRET; throws in production if neither is set. |
| CFDI internal-key auth | Clean | app/api/cfdi/issue/route.ts:65-76 is fail-closed: rejects if env var is unset, compares using a constant-time XOR loop. |
| Content Security Policy (CSP) | Acceptable | proxy.ts:45-61 applies a strict CSP except 'unsafe-inline' on script-src. The nonce-only policy was deliberately walked back because it forced dynamic rendering (every headers() call), which killed edge caching. Trade-off documented at proxy.ts:11-19. For the marketing site — no user-generated content — XSS risk is low and React auto-escapes all rendered output. |
This audit also identified four items requiring attention. We list them in the interest of transparency we expect from any provider operating security infrastructure:
This document was generated via:
The audit is reproducible: every cited line of evidence exists in the referenced commit, and apps/api/src/database/migrations/ maintains an immutable history of schema changes.
Responsible vulnerability reports: security@simiriki.com. Initial response within 48 business hours. We don’t run a paid bug bounty; we offer public attribution in this document if the reporter wishes.