@lunora/advisor 1.0.0-alpha.34 → 1.0.0-alpha.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.mjs +1 -200
- package/dist/packem_shared/AE_METRIC_EVENTS-LP_0D7Uw.mjs +1 -0
- package/dist/packem_shared/actionFetchSsrf-BbWxy1Yf.mjs +1 -0
- package/dist/packem_shared/adminRouteWithoutGuard-DSo4t9j4.mjs +1 -0
- package/dist/packem_shared/aiRawRunEscapeHatch-DfhjYm43.mjs +1 -0
- package/dist/packem_shared/aiToolSideEffectPromptInjection-DnWQOoKi.mjs +1 -0
- package/dist/packem_shared/aiUnboundedGenerationPublic-D3HZrh5_.mjs +1 -0
- package/dist/packem_shared/allowUnauthenticatedShardAccessEnabled-D4aMNBb0.mjs +1 -0
- package/dist/packem_shared/argument-derived-sink-BpO3NPPM.mjs +1 -0
- package/dist/packem_shared/authApiCallWithoutHeaders-BItMMdZP.mjs +1 -0
- package/dist/packem_shared/authCsrfCheckDisabled-De9ammtV.mjs +1 -0
- package/dist/packem_shared/authEmailVerificationDisabled-BFKdJcx4.mjs +1 -0
- package/dist/packem_shared/authSecureCookiesDisabled-B4WIzvMm.mjs +1 -0
- package/dist/packem_shared/authSessionFreshageZero-Bpcaf_Pe.mjs +1 -0
- package/dist/packem_shared/authTrustedOriginsWildcard-DjU9NXEm.mjs +1 -0
- package/dist/packem_shared/browserAllowPrivateTargets-Dxyeh6lg.mjs +1 -0
- package/dist/packem_shared/browserUserUrlWithoutAllowlist-BHBS6b0N.mjs +1 -0
- package/dist/packem_shared/circularFk-BMuJKmuZ.mjs +1 -0
- package/dist/packem_shared/constraintValidator-N339mfyx.mjs +1 -0
- package/dist/packem_shared/containerInstanceKeyFromUserInput-C8S4T3ty.mjs +1 -0
- package/dist/packem_shared/containerOversizedInstance-B9wW_sU5.mjs +1 -0
- package/dist/packem_shared/containerPublicInternet-Bx2J7tha.mjs +1 -0
- package/dist/packem_shared/containerRuntimeEgressRelaxation-BQ2ZD1aV.mjs +1 -0
- package/dist/packem_shared/containerStartEnableInternetOverride-B62WUura.mjs +1 -0
- package/dist/packem_shared/dedupeCacheKeys-7JgxaQWV.mjs +1 -0
- package/dist/packem_shared/duplicateIndex-DFT7qLQD.mjs +1 -0
- package/dist/packem_shared/emptyIndex-BiXEfyfN.mjs +1 -0
- package/dist/packem_shared/exportSinkMisconfigured-DvpAaa6j.mjs +1 -0
- package/dist/packem_shared/externalSourceIncrementalNoDeletePath-DnoL64YY.mjs +1 -0
- package/dist/packem_shared/externalSourceOnGlobal-DNPLoNUg.mjs +1 -0
- package/dist/packem_shared/externalSourceUnscoped-DqBp5jYr.mjs +1 -0
- package/dist/packem_shared/filterWithoutIndex-ht2GZQWV.mjs +1 -0
- package/dist/packem_shared/finding-BAVgqnCF.mjs +1 -0
- package/dist/packem_shared/fk-index-Bmk19RvQ.mjs +1 -0
- package/dist/packem_shared/flagGatesSecurityWithUnsafeDefault-DPGFEHTt.mjs +1 -0
- package/dist/packem_shared/fromServerSchema-CJ-AQ2kw.mjs +1 -0
- package/dist/packem_shared/geoIndexFieldNotGeopoint-DAGLZtaH.mjs +1 -0
- package/dist/packem_shared/geoIndexUnused-BgDE6_AR.mjs +1 -0
- package/dist/packem_shared/hardcodedSecret-rIRc3aNk.mjs +1 -0
- package/dist/packem_shared/helpers-DwlvEUCh.mjs +1 -0
- package/dist/packem_shared/hotShard-DVs_U17R.mjs +1 -0
- package/dist/packem_shared/httpActionMissingAuthGuard-BZDdeW_D.mjs +1 -0
- package/dist/packem_shared/httpActionResponseHeaderInjection-D063rB7U.mjs +1 -0
- package/dist/packem_shared/hyperdriveOutsideAction-CRmOQz67.mjs +1 -0
- package/dist/packem_shared/identityUndeclaredClaimTrusted-BYRYGQ74.mjs +1 -0
- package/dist/packem_shared/imagesUrlSourceFromUserInput-Cy5pc_dA.mjs +1 -0
- package/dist/packem_shared/indexReferencesUnknownField-r3QHlaz6.mjs +1 -0
- package/dist/packem_shared/indexUtilization-QfbIH_w4.mjs +1 -0
- package/dist/packem_shared/insertManyUnsafeUserData-DrH7PdRs.mjs +1 -0
- package/dist/packem_shared/kvUnscopedUserKeyIdor-B4lGxRxh.mjs +1 -0
- package/dist/packem_shared/mailInboundDispatchWithoutVerify-BivYJ5F9.mjs +1 -0
- package/dist/packem_shared/mailRecipientFromRequestInput-BR_oSh65.mjs +1 -0
- package/dist/packem_shared/maskUncoveredPiiColumn-DqPfZM2O.mjs +1 -0
- package/dist/packem_shared/maskWeakHashStrategyOnPii-CEiiGgT7.mjs +1 -0
- package/dist/packem_shared/maskedRelationLeakViaWith-CxYk0MDW.mjs +1 -0
- package/dist/packem_shared/mutatorFullRowReplace-CEgecSGm.mjs +1 -0
- package/dist/packem_shared/nondeterministicQueryMutation-BaMfbAk_.mjs +1 -0
- package/dist/packem_shared/normalizeIdUsedAsAuthorization-FjISSXJm.mjs +1 -0
- package/dist/packem_shared/notifyMissingPushConfig-C_GbVw3S.mjs +1 -0
- package/dist/packem_shared/notifySendOutsideAction-B0jZuUP3.mjs +1 -0
- package/dist/packem_shared/outputProjectionMissingOnPublicRead-9Pm9766s.mjs +1 -0
- package/dist/packem_shared/ownerFieldFromArgsNotAuth-BoR9vvst.mjs +1 -0
- package/dist/packem_shared/paymentCreateWithoutAuthorize-CurtqN8K.mjs +1 -0
- package/dist/packem_shared/paymentWebhookWideTolerance-I7ingfR8.mjs +1 -0
- package/dist/packem_shared/plaintextSecretInWranglerVariables-DXjKIm8H.mjs +1 -0
- package/dist/packem_shared/policyReferencesUnknownTable-D3WelAQa.mjs +1 -0
- package/dist/packem_shared/privilegedDispatchUnvalidatedPayload-74GuGye1.mjs +1 -0
- package/dist/packem_shared/privilegedFanoutFromPublicProcedure-C2j2GSUN.mjs +1 -0
- package/dist/packem_shared/publicArgumentUsesAny-BJb4cTqL.mjs +1 -0
- package/dist/packem_shared/publicMutationWithoutRatelimit-D9phluHW.mjs +1 -0
- package/dist/packem_shared/publicTableRlsOptoutConfusion-CaWtPGAn.mjs +1 -0
- package/dist/packem_shared/queueWithoutDlq-BLY3iy9Q.mjs +1 -0
- package/dist/packem_shared/r2sqlOutsideAction-CKK_I1Ms.mjs +1 -0
- package/dist/packem_shared/ratelimitDefaultMemoryStore-mOdI3Jmb.mjs +1 -0
- package/dist/packem_shared/ratelimitKeySpoofableOrGlobal-DaGId_Fh.mjs +1 -0
- package/dist/packem_shared/ratelimitMiddlewareFailOpen-CTWVosEc.mjs +1 -0
- package/dist/packem_shared/relationReferencesUnknownField-clqyB69Y.mjs +1 -0
- package/dist/packem_shared/relationReferencesUnknownTable-CLdrhkmS.mjs +1 -0
- package/dist/packem_shared/rlsUncoveredTable-DYHgnoos.mjs +1 -0
- package/dist/packem_shared/shapeTargetsGlobalTable-Blz-aSkg.mjs +1 -0
- package/dist/packem_shared/shapeUnknownTable-DFxtyFio.mjs +1 -0
- package/dist/packem_shared/signupMutationWithoutDisposableGating-3ir808Vz.mjs +1 -0
- package/dist/packem_shared/softDeleteIncludeDeletedFromArgs-DgxpQHRA.mjs +1 -0
- package/dist/packem_shared/sqlInjectionRisk-D2NaT-5c.mjs +1 -0
- package/dist/packem_shared/storageGenerateUploadUrlNoContentTypePin-C9cjl6Jh.mjs +1 -0
- package/dist/packem_shared/storageKeyFromUserArgs-BeS5cp56.mjs +1 -0
- package/dist/packem_shared/storagePresignedUrlForPrivateContent-j7VhwIdu.mjs +1 -0
- package/dist/packem_shared/storageUploadWithoutContentTypeAllowlist-oxKLecuf.mjs +1 -0
- package/dist/packem_shared/storageUploadWithoutMaxSize-DUDxPutk.mjs +1 -0
- package/dist/packem_shared/tableWithoutInsert-D3AhaNzR.mjs +1 -0
- package/dist/packem_shared/ttlFieldNotTimestamp-BFiRkSZD.mjs +1 -0
- package/dist/packem_shared/unboundedStringArgument-AkkIcr-S.mjs +1 -0
- package/dist/packem_shared/unindexedForeignKey-DK4eWXkb.mjs +1 -0
- package/dist/packem_shared/unindexedRelationTarget-B5fFq1E8.mjs +1 -0
- package/dist/packem_shared/unrestrictedWhereBranch-YKiydie4.mjs +1 -0
- package/dist/packem_shared/userCreatingMutationWithoutCaptcha-iDjRkUFO.mjs +1 -0
- package/dist/packem_shared/vectorsNamespaceFromUserInput-Cyq5B2kF.mjs +1 -0
- package/dist/packem_shared/workflowDuplicateStepName-cXF6Rpvg.mjs +1 -0
- package/dist/packem_shared/workflowUnknownTarget-JF8rITLP.mjs +1 -0
- package/dist/packem_shared/workflowUnused-Dx_FQwGE.mjs +1 -0
- package/package.json +2 -2
- package/dist/packem_shared/AE_METRIC_EVENTS-BM14d0lm.mjs +0 -87
- package/dist/packem_shared/actionFetchSsrf-wbmYgzmz.mjs +0 -26
- package/dist/packem_shared/adminRouteWithoutGuard-UUGBkAjU.mjs +0 -33
- package/dist/packem_shared/aiRawRunEscapeHatch-C29jd32J.mjs +0 -26
- package/dist/packem_shared/aiToolSideEffectPromptInjection-BtD3alqB.mjs +0 -33
- package/dist/packem_shared/aiUnboundedGenerationPublic-CbAcSxLB.mjs +0 -26
- package/dist/packem_shared/allowUnauthenticatedShardAccessEnabled-BcASq-jP.mjs +0 -30
- package/dist/packem_shared/argument-derived-sink-C1xTTqAt.mjs +0 -30
- package/dist/packem_shared/authApiCallWithoutHeaders-BeJhCZaf.mjs +0 -38
- package/dist/packem_shared/authCsrfCheckDisabled-DCf9FSoD.mjs +0 -26
- package/dist/packem_shared/authEmailVerificationDisabled-Dk-Tc5oU.mjs +0 -26
- package/dist/packem_shared/authSecureCookiesDisabled-osJrHW9Y.mjs +0 -26
- package/dist/packem_shared/authSessionFreshageZero-CjufCc_Q.mjs +0 -26
- package/dist/packem_shared/authTrustedOriginsWildcard-ylv4PKzC.mjs +0 -26
- package/dist/packem_shared/browserAllowPrivateTargets-CBvQxLAM.mjs +0 -26
- package/dist/packem_shared/browserUserUrlWithoutAllowlist-CvhA6w59.mjs +0 -26
- package/dist/packem_shared/circularFk-CNcAVuYa.mjs +0 -127
- package/dist/packem_shared/constraintValidator-CxwtpJ6E.mjs +0 -206
- package/dist/packem_shared/containerInstanceKeyFromUserInput-BUXj2J4w.mjs +0 -19
- package/dist/packem_shared/containerOversizedInstance-5U1VKPRM.mjs +0 -36
- package/dist/packem_shared/containerPublicInternet-CuNerJE5.mjs +0 -30
- package/dist/packem_shared/containerRuntimeEgressRelaxation-B0LlfmDA.mjs +0 -26
- package/dist/packem_shared/containerStartEnableInternetOverride-DDaHZQ1L.mjs +0 -26
- package/dist/packem_shared/dedupeCacheKeys-r5B7u_yq.mjs +0 -13
- package/dist/packem_shared/duplicateIndex-BOublMSt.mjs +0 -57
- package/dist/packem_shared/emptyIndex-BX8EuEY7.mjs +0 -32
- package/dist/packem_shared/exportSinkMisconfigured-897sVMUa.mjs +0 -46
- package/dist/packem_shared/externalSourceIncrementalNoDeletePath-DvX9cRBD.mjs +0 -45
- package/dist/packem_shared/externalSourceOnGlobal-Bg-NfCX9.mjs +0 -30
- package/dist/packem_shared/externalSourceUnscoped-5vT-Bup3.mjs +0 -44
- package/dist/packem_shared/filterWithoutIndex-BYVeJaSs.mjs +0 -31
- package/dist/packem_shared/finding-Dm_zvzS1.mjs +0 -16
- package/dist/packem_shared/fk-index-IUK1ukgs.mjs +0 -7
- package/dist/packem_shared/flagGatesSecurityWithUnsafeDefault-BhIs0shr.mjs +0 -41
- package/dist/packem_shared/fromServerSchema-CVnbSf8j.mjs +0 -70
- package/dist/packem_shared/geoIndexFieldNotGeopoint-CcaInLhY.mjs +0 -40
- package/dist/packem_shared/geoIndexUnused-D7I0UyND.mjs +0 -40
- package/dist/packem_shared/hardcodedSecret-Be-pKVdn.mjs +0 -31
- package/dist/packem_shared/helpers-BySnKhVB.mjs +0 -31
- package/dist/packem_shared/hotShard-CkC7qpre.mjs +0 -60
- package/dist/packem_shared/httpActionMissingAuthGuard-CxipddNx.mjs +0 -35
- package/dist/packem_shared/httpActionResponseHeaderInjection-DOFS7pFT.mjs +0 -39
- package/dist/packem_shared/hyperdriveOutsideAction-BgZqX7Xg.mjs +0 -30
- package/dist/packem_shared/identityUndeclaredClaimTrusted-D8nXV2dd.mjs +0 -32
- package/dist/packem_shared/imagesUrlSourceFromUserInput-YcDQ0b_Y.mjs +0 -19
- package/dist/packem_shared/indexReferencesUnknownField-BSWNngxX.mjs +0 -36
- package/dist/packem_shared/indexUtilization-B5DMQ3bI.mjs +0 -45
- package/dist/packem_shared/insertManyUnsafeUserData-Dn77XpmX.mjs +0 -26
- package/dist/packem_shared/kvUnscopedUserKeyIdor-YWwmfE8X.mjs +0 -19
- package/dist/packem_shared/mailInboundDispatchWithoutVerify-CHSRA8zz.mjs +0 -28
- package/dist/packem_shared/mailRecipientFromRequestInput-Cka2qu5J.mjs +0 -26
- package/dist/packem_shared/maskUncoveredPiiColumn-DjGIPG6M.mjs +0 -61
- package/dist/packem_shared/maskWeakHashStrategyOnPii-1c4q8Opf.mjs +0 -35
- package/dist/packem_shared/maskedRelationLeakViaWith-CPI4s0sl.mjs +0 -76
- package/dist/packem_shared/mutatorFullRowReplace-BJnNDaIV.mjs +0 -26
- package/dist/packem_shared/nondeterministicQueryMutation-GXES1fLp.mjs +0 -35
- package/dist/packem_shared/normalizeIdUsedAsAuthorization-BVPtCpzT.mjs +0 -50
- package/dist/packem_shared/notifyMissingPushConfig-Ca9EzRzy.mjs +0 -27
- package/dist/packem_shared/notifySendOutsideAction-BUZSIZa4.mjs +0 -30
- package/dist/packem_shared/outputProjectionMissingOnPublicRead-Bl5IMx0k.mjs +0 -51
- package/dist/packem_shared/ownerFieldFromArgsNotAuth-mOw3hE5z.mjs +0 -26
- package/dist/packem_shared/paymentCreateWithoutAuthorize-BYm4JLxo.mjs +0 -26
- package/dist/packem_shared/paymentWebhookWideTolerance-D9QQJMJq.mjs +0 -35
- package/dist/packem_shared/plaintextSecretInWranglerVariables-NKO4YkKf.mjs +0 -35
- package/dist/packem_shared/policyReferencesUnknownTable-DtaIEovd.mjs +0 -38
- package/dist/packem_shared/privilegedDispatchUnvalidatedPayload-5Forjckt.mjs +0 -37
- package/dist/packem_shared/privilegedFanoutFromPublicProcedure-D3dL01B8.mjs +0 -26
- package/dist/packem_shared/publicArgumentUsesAny-C71b2NCf.mjs +0 -32
- package/dist/packem_shared/publicMutationWithoutRatelimit-DbIhgi7j.mjs +0 -36
- package/dist/packem_shared/publicTableRlsOptoutConfusion-Bn71yoD4.mjs +0 -38
- package/dist/packem_shared/queueWithoutDlq-CSkGNb_0.mjs +0 -41
- package/dist/packem_shared/r2sqlOutsideAction-CtqxvMuV.mjs +0 -30
- package/dist/packem_shared/ratelimitDefaultMemoryStore-BISChG5C.mjs +0 -26
- package/dist/packem_shared/ratelimitKeySpoofableOrGlobal-DqlHYQQ3.mjs +0 -26
- package/dist/packem_shared/ratelimitMiddlewareFailOpen-CJgDCaUw.mjs +0 -33
- package/dist/packem_shared/relationReferencesUnknownField-CjbLScJ1.mjs +0 -54
- package/dist/packem_shared/relationReferencesUnknownTable-DrorpKYe.mjs +0 -33
- package/dist/packem_shared/rlsUncoveredTable-CxEfZ5eZ.mjs +0 -56
- package/dist/packem_shared/shapeTargetsGlobalTable-DHrf4Koi.mjs +0 -34
- package/dist/packem_shared/shapeUnknownTable-C8aDWFoe.mjs +0 -34
- package/dist/packem_shared/signupMutationWithoutDisposableGating-Dnbol2CS.mjs +0 -39
- package/dist/packem_shared/softDeleteIncludeDeletedFromArgs-BLqDKrkM.mjs +0 -38
- package/dist/packem_shared/sqlInjectionRisk-zwytYGLt.mjs +0 -26
- package/dist/packem_shared/storageGenerateUploadUrlNoContentTypePin-Da4L9Ge8.mjs +0 -26
- package/dist/packem_shared/storageKeyFromUserArgs-B86elJgS.mjs +0 -19
- package/dist/packem_shared/storagePresignedUrlForPrivateContent-yGmb8uqz.mjs +0 -47
- package/dist/packem_shared/storageUploadWithoutContentTypeAllowlist-BV-gF1lT.mjs +0 -27
- package/dist/packem_shared/storageUploadWithoutMaxSize-DpxO59wU.mjs +0 -27
- package/dist/packem_shared/tableWithoutInsert-CbbaYIP4.mjs +0 -34
- package/dist/packem_shared/ttlFieldNotTimestamp-Dpaj63Z6.mjs +0 -36
- package/dist/packem_shared/unboundedStringArgument-DThg2-wt.mjs +0 -32
- package/dist/packem_shared/unindexedForeignKey-BgJbKyqK.mjs +0 -45
- package/dist/packem_shared/unindexedRelationTarget-D6eyj6Xx.mjs +0 -53
- package/dist/packem_shared/userCreatingMutationWithoutCaptcha-2DZtWIPb.mjs +0 -42
- package/dist/packem_shared/vectorsNamespaceFromUserInput-CQhr5bVn.mjs +0 -19
- package/dist/packem_shared/workflowDuplicateStepName-ioBxPBCy.mjs +0 -48
- package/dist/packem_shared/workflowUnknownTarget-Cdd7WhKQ.mjs +0 -34
- package/dist/packem_shared/workflowUnused-D0jHxdz9.mjs +0 -38
package/dist/index.d.mts
CHANGED
|
@@ -808,6 +808,36 @@ interface AdvisorOwnerFieldWrite {
|
|
|
808
808
|
/** The `ctx.db` write method (`insert` / `replace` / `patch` / `insertManyUnsafe`). */
|
|
809
809
|
method: string;
|
|
810
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* One branching `defineShape({ where })` / `definePolicy({ when })` predicate arm
|
|
813
|
+
* that returns an unrestricted predicate — the `unrestricted_where_branch` lint
|
|
814
|
+
* input.
|
|
815
|
+
*
|
|
816
|
+
* A row predicate returns a *filter*, not a boolean, so the denial arm has to be a
|
|
817
|
+
* predicate matching **no** rows: `deny()` / `{ OR: [] }`, a disjunction over zero
|
|
818
|
+
* branches. The plausible-looking `{}` is its exact opposite — it matches every row,
|
|
819
|
+
* so an arm meaning "this caller sees nothing" silently replicates or exposes the
|
|
820
|
+
* whole table, with no error and no log line.
|
|
821
|
+
*
|
|
822
|
+
* Only reported for a *branching* predicate: a single-exit `where: () => ({})` is an
|
|
823
|
+
* author deliberately replicating everything, which is legitimate. Produced by the
|
|
824
|
+
* codegen feeder; runtime callers don't supply it, so the lint finds nothing there.
|
|
825
|
+
* Structurally identical to `UnrestrictedWhereBranchIR`.
|
|
826
|
+
*/
|
|
827
|
+
interface AdvisorUnrestrictedWhereBranch {
|
|
828
|
+
/** The exported binding name of the shape / policy the predicate belongs to. */
|
|
829
|
+
exportName: string;
|
|
830
|
+
/** Source file relative to the lunora dir, no extension. */
|
|
831
|
+
file: string;
|
|
832
|
+
/** Which unrestricted form was returned. */
|
|
833
|
+
form: "empty-object" | "undefined";
|
|
834
|
+
/** The config key carrying the predicate (`where` for a shape, `when` for a policy). */
|
|
835
|
+
key: string;
|
|
836
|
+
/** 1-based line of the offending returned expression. */
|
|
837
|
+
line: number;
|
|
838
|
+
/** The declaring call (`defineShape` / `definePolicy`). */
|
|
839
|
+
owner: string;
|
|
840
|
+
}
|
|
811
841
|
/**
|
|
812
842
|
* One payment webhook-adapter construction (`createStripeAdapter` /
|
|
813
843
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) —
|
|
@@ -1866,6 +1896,12 @@ interface LintContext {
|
|
|
1866
1896
|
* absent for runtime callers, where the lint finds nothing.
|
|
1867
1897
|
*/
|
|
1868
1898
|
ownerFieldWrites?: ReadonlyArray<AdvisorOwnerFieldWrite>;
|
|
1899
|
+
/**
|
|
1900
|
+
* Branching shape/policy predicate arms returning an unrestricted filter (`{}` /
|
|
1901
|
+
* `undefined`) — the `unrestricted_where_branch` lint input. Supplied by the
|
|
1902
|
+
* codegen feeder only.
|
|
1903
|
+
*/
|
|
1904
|
+
unrestrictedWhereBranches?: ReadonlyArray<AdvisorUnrestrictedWhereBranch>;
|
|
1869
1905
|
/**
|
|
1870
1906
|
* Payment webhook-adapter constructions (`createStripeAdapter` /
|
|
1871
1907
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) — the payment-webhook wide-tolerance lint's input. Each row's
|
|
@@ -3789,6 +3825,30 @@ declare const unindexedForeignKey: Lint;
|
|
|
3789
3825
|
* relation (reported there) and only fires on the otherwise-unaudited column.
|
|
3790
3826
|
*/
|
|
3791
3827
|
declare const unindexedRelationTarget: Lint;
|
|
3828
|
+
/**
|
|
3829
|
+
* Flags a branching `defineShape({ where })` / `definePolicy({ when })` predicate
|
|
3830
|
+
* whose arm returns `{}` or `undefined`.
|
|
3831
|
+
*
|
|
3832
|
+
* A row predicate returns a **filter**, not a boolean. So the denial arm has to be a
|
|
3833
|
+
* predicate that matches no rows — `deny()`, i.e. `{ OR: [] }`, a disjunction over
|
|
3834
|
+
* zero branches. `{}` is its exact opposite: it matches *every* row. A guard written
|
|
3835
|
+
* as `if (ctx.auth.userId !== userId) return {}` therefore does the opposite of what
|
|
3836
|
+
* it reads like, replicating the entire table to an unauthorized subscriber — with no
|
|
3837
|
+
* error, no log line, and a shape that still appears to work.
|
|
3838
|
+
*
|
|
3839
|
+
* `undefined` is the same trap one step removed: for a policy `when` it means "opt
|
|
3840
|
+
* this policy out" (leaving the table unrestricted by *this* policy), which reads
|
|
3841
|
+
* like a denial but isn't one.
|
|
3842
|
+
*
|
|
3843
|
+
* Only *branching* predicates are flagged. A single-exit `where: () => ({})` is an
|
|
3844
|
+
* author deliberately replicating everything, which is a legitimate (if broad) shape.
|
|
3845
|
+
* The dangerous pattern is the guard whose deny arm was meant to close the door.
|
|
3846
|
+
*
|
|
3847
|
+
* Runs only when the codegen feeder supplies the evidence
|
|
3848
|
+
* (`context.unrestrictedWhereBranches`); a runtime caller flags nothing. One finding
|
|
3849
|
+
* per offending arm.
|
|
3850
|
+
*/
|
|
3851
|
+
declare const unrestrictedWhereBranch: Lint;
|
|
3792
3852
|
/**
|
|
3793
3853
|
* Flags a public `mutation`/`action` that creates a user/session or sends mail but
|
|
3794
3854
|
* installs no CAPTCHA / bot check.
|
|
@@ -3906,4 +3966,4 @@ interface RunAdvisorOptions {
|
|
|
3906
3966
|
* `static` lints at build time and defer `runtime` lints to a live shard.
|
|
3907
3967
|
*/
|
|
3908
3968
|
declare const runAdvisor: (context: LintContext, options?: RunAdvisorOptions) => Finding[];
|
|
3909
|
-
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type Category, type Facing, type Finding, type Level, type Lint, type LintContext, type LintSource, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
|
3969
|
+
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type Category, type Facing, type Finding, type Level, type Lint, type LintContext, type LintSource, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
package/dist/index.d.ts
CHANGED
|
@@ -808,6 +808,36 @@ interface AdvisorOwnerFieldWrite {
|
|
|
808
808
|
/** The `ctx.db` write method (`insert` / `replace` / `patch` / `insertManyUnsafe`). */
|
|
809
809
|
method: string;
|
|
810
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* One branching `defineShape({ where })` / `definePolicy({ when })` predicate arm
|
|
813
|
+
* that returns an unrestricted predicate — the `unrestricted_where_branch` lint
|
|
814
|
+
* input.
|
|
815
|
+
*
|
|
816
|
+
* A row predicate returns a *filter*, not a boolean, so the denial arm has to be a
|
|
817
|
+
* predicate matching **no** rows: `deny()` / `{ OR: [] }`, a disjunction over zero
|
|
818
|
+
* branches. The plausible-looking `{}` is its exact opposite — it matches every row,
|
|
819
|
+
* so an arm meaning "this caller sees nothing" silently replicates or exposes the
|
|
820
|
+
* whole table, with no error and no log line.
|
|
821
|
+
*
|
|
822
|
+
* Only reported for a *branching* predicate: a single-exit `where: () => ({})` is an
|
|
823
|
+
* author deliberately replicating everything, which is legitimate. Produced by the
|
|
824
|
+
* codegen feeder; runtime callers don't supply it, so the lint finds nothing there.
|
|
825
|
+
* Structurally identical to `UnrestrictedWhereBranchIR`.
|
|
826
|
+
*/
|
|
827
|
+
interface AdvisorUnrestrictedWhereBranch {
|
|
828
|
+
/** The exported binding name of the shape / policy the predicate belongs to. */
|
|
829
|
+
exportName: string;
|
|
830
|
+
/** Source file relative to the lunora dir, no extension. */
|
|
831
|
+
file: string;
|
|
832
|
+
/** Which unrestricted form was returned. */
|
|
833
|
+
form: "empty-object" | "undefined";
|
|
834
|
+
/** The config key carrying the predicate (`where` for a shape, `when` for a policy). */
|
|
835
|
+
key: string;
|
|
836
|
+
/** 1-based line of the offending returned expression. */
|
|
837
|
+
line: number;
|
|
838
|
+
/** The declaring call (`defineShape` / `definePolicy`). */
|
|
839
|
+
owner: string;
|
|
840
|
+
}
|
|
811
841
|
/**
|
|
812
842
|
* One payment webhook-adapter construction (`createStripeAdapter` /
|
|
813
843
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) —
|
|
@@ -1866,6 +1896,12 @@ interface LintContext {
|
|
|
1866
1896
|
* absent for runtime callers, where the lint finds nothing.
|
|
1867
1897
|
*/
|
|
1868
1898
|
ownerFieldWrites?: ReadonlyArray<AdvisorOwnerFieldWrite>;
|
|
1899
|
+
/**
|
|
1900
|
+
* Branching shape/policy predicate arms returning an unrestricted filter (`{}` /
|
|
1901
|
+
* `undefined`) — the `unrestricted_where_branch` lint input. Supplied by the
|
|
1902
|
+
* codegen feeder only.
|
|
1903
|
+
*/
|
|
1904
|
+
unrestrictedWhereBranches?: ReadonlyArray<AdvisorUnrestrictedWhereBranch>;
|
|
1869
1905
|
/**
|
|
1870
1906
|
* Payment webhook-adapter constructions (`createStripeAdapter` /
|
|
1871
1907
|
* `createPolarAdapter` / `createAutumnAdapter` / `createDodoPaymentsAdapter`) — the payment-webhook wide-tolerance lint's input. Each row's
|
|
@@ -3789,6 +3825,30 @@ declare const unindexedForeignKey: Lint;
|
|
|
3789
3825
|
* relation (reported there) and only fires on the otherwise-unaudited column.
|
|
3790
3826
|
*/
|
|
3791
3827
|
declare const unindexedRelationTarget: Lint;
|
|
3828
|
+
/**
|
|
3829
|
+
* Flags a branching `defineShape({ where })` / `definePolicy({ when })` predicate
|
|
3830
|
+
* whose arm returns `{}` or `undefined`.
|
|
3831
|
+
*
|
|
3832
|
+
* A row predicate returns a **filter**, not a boolean. So the denial arm has to be a
|
|
3833
|
+
* predicate that matches no rows — `deny()`, i.e. `{ OR: [] }`, a disjunction over
|
|
3834
|
+
* zero branches. `{}` is its exact opposite: it matches *every* row. A guard written
|
|
3835
|
+
* as `if (ctx.auth.userId !== userId) return {}` therefore does the opposite of what
|
|
3836
|
+
* it reads like, replicating the entire table to an unauthorized subscriber — with no
|
|
3837
|
+
* error, no log line, and a shape that still appears to work.
|
|
3838
|
+
*
|
|
3839
|
+
* `undefined` is the same trap one step removed: for a policy `when` it means "opt
|
|
3840
|
+
* this policy out" (leaving the table unrestricted by *this* policy), which reads
|
|
3841
|
+
* like a denial but isn't one.
|
|
3842
|
+
*
|
|
3843
|
+
* Only *branching* predicates are flagged. A single-exit `where: () => ({})` is an
|
|
3844
|
+
* author deliberately replicating everything, which is a legitimate (if broad) shape.
|
|
3845
|
+
* The dangerous pattern is the guard whose deny arm was meant to close the door.
|
|
3846
|
+
*
|
|
3847
|
+
* Runs only when the codegen feeder supplies the evidence
|
|
3848
|
+
* (`context.unrestrictedWhereBranches`); a runtime caller flags nothing. One finding
|
|
3849
|
+
* per offending arm.
|
|
3850
|
+
*/
|
|
3851
|
+
declare const unrestrictedWhereBranch: Lint;
|
|
3792
3852
|
/**
|
|
3793
3853
|
* Flags a public `mutation`/`action` that creates a user/session or sends mail but
|
|
3794
3854
|
* installs no CAPTCHA / bot check.
|
|
@@ -3906,4 +3966,4 @@ interface RunAdvisorOptions {
|
|
|
3906
3966
|
* `static` lints at build time and defer `runtime` lints to a live shard.
|
|
3907
3967
|
*/
|
|
3908
3968
|
declare const runAdvisor: (context: LintContext, options?: RunAdvisorOptions) => Finding[];
|
|
3909
|
-
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type Category, type Facing, type Finding, type Level, type Lint, type LintContext, type LintSource, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
|
3969
|
+
export { AE_METRIC_EVENTS, ALL_LINTS, type AdvisorAdminRoute, type AdvisorAiRawRun, type AdvisorAiToolSideEffect, type AdvisorArgumentDerivedFetch, type AdvisorArgumentValidator, type AdvisorAuthApiCall, type AdvisorAuthConfig, type AdvisorBrowserUrlAccess, type AdvisorConfigCall, type AdvisorContainer, type AdvisorContainerKeyAccess, type AdvisorContainerOverride, type AdvisorExportSink, type AdvisorFailOpenGuard, type AdvisorFlagSecurityDefault, type AdvisorGeoIndexUsage, type AdvisorHttpActionGuard, type AdvisorHttpHeaderWrite, type AdvisorHyperdriveCall, type AdvisorIdentityClaimRead, type AdvisorImageDeliveryUrlAccess, type AdvisorIndex, type AdvisorIndexHit, type AdvisorInsertWrite, type AdvisorKvKeyAccess, type AdvisorMailRecipientAccess, type AdvisorMaskProcedure, type AdvisorMaskStrategy, type AdvisorMutatorWrite, type AdvisorNondeterministicCall, type AdvisorNormalizeIdAuthorization, type AdvisorNotifyCall, type AdvisorNotifyConfig, type AdvisorOwnerFieldWrite, type AdvisorPaymentWebhook, type AdvisorPrivilegedDispatch, type AdvisorProcedureProtection, type AdvisorQueryRead, type AdvisorQueue, type AdvisorQueueTuning, type AdvisorR2sqlCall, type AdvisorRatelimitKeySelector, type AdvisorRawRowReturn, type AdvisorRelation, type AdvisorRelationLoad, type AdvisorRlsProcedure, type AdvisorSchema, type AdvisorSecretLiteral, type AdvisorShape, type AdvisorShardTraffic, type AdvisorSoftDeleteRead, type AdvisorSqlInterpolation, type AdvisorStorageKeyAccess, type AdvisorStorageUpload, type AdvisorTable, type AdvisorTableSample, type AdvisorTableScan, type AdvisorVectorNamespaceAccess, type AdvisorWorkflow, type AdvisorWorkflowCall, type AdvisorWranglerVariable, type AnalyticsMetricsOptions, type AnalyticsMetricsSource, type AnalyticsRuntimeMetrics, type Category, type Facing, type Finding, type Level, type Lint, type LintContext, type LintSource, RUNTIME_LINTS, RunAdvisorOptions, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, fromServerSchema, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, loadAnalyticsRuntimeMetrics, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, unrestrictedWhereBranch, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
package/dist/index.mjs
CHANGED
|
@@ -1,200 +1 @@
|
|
|
1
|
-
import { dedupeCacheKeys } from './packem_shared/dedupeCacheKeys-r5B7u_yq.mjs';
|
|
2
|
-
import constraintValidator from './packem_shared/constraintValidator-CxwtpJ6E.mjs';
|
|
3
|
-
import hotShard from './packem_shared/hotShard-CkC7qpre.mjs';
|
|
4
|
-
import indexUtilization from './packem_shared/indexUtilization-B5DMQ3bI.mjs';
|
|
5
|
-
import actionFetchSsrf from './packem_shared/actionFetchSsrf-wbmYgzmz.mjs';
|
|
6
|
-
import adminRouteWithoutGuard from './packem_shared/adminRouteWithoutGuard-UUGBkAjU.mjs';
|
|
7
|
-
import aiRawRunEscapeHatch from './packem_shared/aiRawRunEscapeHatch-C29jd32J.mjs';
|
|
8
|
-
import aiToolSideEffectPromptInjection from './packem_shared/aiToolSideEffectPromptInjection-BtD3alqB.mjs';
|
|
9
|
-
import aiUnboundedGenerationPublic from './packem_shared/aiUnboundedGenerationPublic-CbAcSxLB.mjs';
|
|
10
|
-
import allowUnauthenticatedShardAccessEnabled from './packem_shared/allowUnauthenticatedShardAccessEnabled-BcASq-jP.mjs';
|
|
11
|
-
import authApiCallWithoutHeaders from './packem_shared/authApiCallWithoutHeaders-BeJhCZaf.mjs';
|
|
12
|
-
import authCsrfCheckDisabled from './packem_shared/authCsrfCheckDisabled-DCf9FSoD.mjs';
|
|
13
|
-
import authEmailVerificationDisabled from './packem_shared/authEmailVerificationDisabled-Dk-Tc5oU.mjs';
|
|
14
|
-
import authSecureCookiesDisabled from './packem_shared/authSecureCookiesDisabled-osJrHW9Y.mjs';
|
|
15
|
-
import authSessionFreshageZero from './packem_shared/authSessionFreshageZero-CjufCc_Q.mjs';
|
|
16
|
-
import authTrustedOriginsWildcard from './packem_shared/authTrustedOriginsWildcard-ylv4PKzC.mjs';
|
|
17
|
-
import browserAllowPrivateTargets from './packem_shared/browserAllowPrivateTargets-CBvQxLAM.mjs';
|
|
18
|
-
import browserUserUrlWithoutAllowlist from './packem_shared/browserUserUrlWithoutAllowlist-CvhA6w59.mjs';
|
|
19
|
-
import circularFk from './packem_shared/circularFk-CNcAVuYa.mjs';
|
|
20
|
-
import containerInstanceKeyFromUserInput from './packem_shared/containerInstanceKeyFromUserInput-BUXj2J4w.mjs';
|
|
21
|
-
import containerOversizedInstance from './packem_shared/containerOversizedInstance-5U1VKPRM.mjs';
|
|
22
|
-
import containerPublicInternet from './packem_shared/containerPublicInternet-CuNerJE5.mjs';
|
|
23
|
-
import containerRuntimeEgressRelaxation from './packem_shared/containerRuntimeEgressRelaxation-B0LlfmDA.mjs';
|
|
24
|
-
import containerStartEnableInternetOverride from './packem_shared/containerStartEnableInternetOverride-DDaHZQ1L.mjs';
|
|
25
|
-
import duplicateIndex from './packem_shared/duplicateIndex-BOublMSt.mjs';
|
|
26
|
-
import emptyIndex from './packem_shared/emptyIndex-BX8EuEY7.mjs';
|
|
27
|
-
import exportSinkMisconfigured from './packem_shared/exportSinkMisconfigured-897sVMUa.mjs';
|
|
28
|
-
import externalSourceIncrementalNoDeletePath from './packem_shared/externalSourceIncrementalNoDeletePath-DvX9cRBD.mjs';
|
|
29
|
-
import externalSourceOnGlobal from './packem_shared/externalSourceOnGlobal-Bg-NfCX9.mjs';
|
|
30
|
-
import externalSourceUnscoped from './packem_shared/externalSourceUnscoped-5vT-Bup3.mjs';
|
|
31
|
-
import filterWithoutIndex from './packem_shared/filterWithoutIndex-BYVeJaSs.mjs';
|
|
32
|
-
import flagGatesSecurityWithUnsafeDefault from './packem_shared/flagGatesSecurityWithUnsafeDefault-BhIs0shr.mjs';
|
|
33
|
-
import geoIndexFieldNotGeopoint from './packem_shared/geoIndexFieldNotGeopoint-CcaInLhY.mjs';
|
|
34
|
-
import geoIndexUnused from './packem_shared/geoIndexUnused-D7I0UyND.mjs';
|
|
35
|
-
import hardcodedSecret from './packem_shared/hardcodedSecret-Be-pKVdn.mjs';
|
|
36
|
-
import httpActionMissingAuthGuard from './packem_shared/httpActionMissingAuthGuard-CxipddNx.mjs';
|
|
37
|
-
import httpActionResponseHeaderInjection from './packem_shared/httpActionResponseHeaderInjection-DOFS7pFT.mjs';
|
|
38
|
-
import hyperdriveOutsideAction from './packem_shared/hyperdriveOutsideAction-BgZqX7Xg.mjs';
|
|
39
|
-
import identityUndeclaredClaimTrusted from './packem_shared/identityUndeclaredClaimTrusted-D8nXV2dd.mjs';
|
|
40
|
-
import imagesUrlSourceFromUserInput from './packem_shared/imagesUrlSourceFromUserInput-YcDQ0b_Y.mjs';
|
|
41
|
-
import indexReferencesUnknownField from './packem_shared/indexReferencesUnknownField-BSWNngxX.mjs';
|
|
42
|
-
import insertManyUnsafeUserData from './packem_shared/insertManyUnsafeUserData-Dn77XpmX.mjs';
|
|
43
|
-
import kvUnscopedUserKeyIdor from './packem_shared/kvUnscopedUserKeyIdor-YWwmfE8X.mjs';
|
|
44
|
-
import mailInboundDispatchWithoutVerify from './packem_shared/mailInboundDispatchWithoutVerify-CHSRA8zz.mjs';
|
|
45
|
-
import mailRecipientFromRequestInput from './packem_shared/mailRecipientFromRequestInput-Cka2qu5J.mjs';
|
|
46
|
-
import maskUncoveredPiiColumn from './packem_shared/maskUncoveredPiiColumn-DjGIPG6M.mjs';
|
|
47
|
-
import maskWeakHashStrategyOnPii from './packem_shared/maskWeakHashStrategyOnPii-1c4q8Opf.mjs';
|
|
48
|
-
import maskedRelationLeakViaWith from './packem_shared/maskedRelationLeakViaWith-CPI4s0sl.mjs';
|
|
49
|
-
import mutatorFullRowReplace from './packem_shared/mutatorFullRowReplace-BJnNDaIV.mjs';
|
|
50
|
-
import nondeterministicQueryMutation from './packem_shared/nondeterministicQueryMutation-GXES1fLp.mjs';
|
|
51
|
-
import normalizeIdUsedAsAuthorization from './packem_shared/normalizeIdUsedAsAuthorization-BVPtCpzT.mjs';
|
|
52
|
-
import notifyMissingPushConfig from './packem_shared/notifyMissingPushConfig-Ca9EzRzy.mjs';
|
|
53
|
-
import notifySendOutsideAction from './packem_shared/notifySendOutsideAction-BUZSIZa4.mjs';
|
|
54
|
-
import outputProjectionMissingOnPublicRead from './packem_shared/outputProjectionMissingOnPublicRead-Bl5IMx0k.mjs';
|
|
55
|
-
import ownerFieldFromArgsNotAuth from './packem_shared/ownerFieldFromArgsNotAuth-mOw3hE5z.mjs';
|
|
56
|
-
import paymentCreateWithoutAuthorize from './packem_shared/paymentCreateWithoutAuthorize-BYm4JLxo.mjs';
|
|
57
|
-
import paymentWebhookWideTolerance from './packem_shared/paymentWebhookWideTolerance-D9QQJMJq.mjs';
|
|
58
|
-
import plaintextSecretInWranglerVariables from './packem_shared/plaintextSecretInWranglerVariables-NKO4YkKf.mjs';
|
|
59
|
-
import policyReferencesUnknownTable from './packem_shared/policyReferencesUnknownTable-DtaIEovd.mjs';
|
|
60
|
-
import privilegedDispatchUnvalidatedPayload from './packem_shared/privilegedDispatchUnvalidatedPayload-5Forjckt.mjs';
|
|
61
|
-
import privilegedFanoutFromPublicProcedure from './packem_shared/privilegedFanoutFromPublicProcedure-D3dL01B8.mjs';
|
|
62
|
-
import publicArgumentUsesAny from './packem_shared/publicArgumentUsesAny-C71b2NCf.mjs';
|
|
63
|
-
import publicMutationWithoutRatelimit from './packem_shared/publicMutationWithoutRatelimit-DbIhgi7j.mjs';
|
|
64
|
-
import publicTableRlsOptoutConfusion from './packem_shared/publicTableRlsOptoutConfusion-Bn71yoD4.mjs';
|
|
65
|
-
import queueWithoutDlq from './packem_shared/queueWithoutDlq-CSkGNb_0.mjs';
|
|
66
|
-
import r2sqlOutsideAction from './packem_shared/r2sqlOutsideAction-CtqxvMuV.mjs';
|
|
67
|
-
import ratelimitDefaultMemoryStore from './packem_shared/ratelimitDefaultMemoryStore-BISChG5C.mjs';
|
|
68
|
-
import ratelimitKeySpoofableOrGlobal from './packem_shared/ratelimitKeySpoofableOrGlobal-DqlHYQQ3.mjs';
|
|
69
|
-
import ratelimitMiddlewareFailOpen from './packem_shared/ratelimitMiddlewareFailOpen-CJgDCaUw.mjs';
|
|
70
|
-
import relationReferencesUnknownField from './packem_shared/relationReferencesUnknownField-CjbLScJ1.mjs';
|
|
71
|
-
import relationReferencesUnknownTable from './packem_shared/relationReferencesUnknownTable-DrorpKYe.mjs';
|
|
72
|
-
import rlsUncoveredTable from './packem_shared/rlsUncoveredTable-CxEfZ5eZ.mjs';
|
|
73
|
-
import shapeTargetsGlobalTable from './packem_shared/shapeTargetsGlobalTable-DHrf4Koi.mjs';
|
|
74
|
-
import shapeUnknownTable from './packem_shared/shapeUnknownTable-C8aDWFoe.mjs';
|
|
75
|
-
import signupMutationWithoutDisposableGating from './packem_shared/signupMutationWithoutDisposableGating-Dnbol2CS.mjs';
|
|
76
|
-
import softDeleteIncludeDeletedFromArgs from './packem_shared/softDeleteIncludeDeletedFromArgs-BLqDKrkM.mjs';
|
|
77
|
-
import sqlInjectionRisk from './packem_shared/sqlInjectionRisk-zwytYGLt.mjs';
|
|
78
|
-
import storageGenerateUploadUrlNoContentTypePin from './packem_shared/storageGenerateUploadUrlNoContentTypePin-Da4L9Ge8.mjs';
|
|
79
|
-
import storageKeyFromUserArgs from './packem_shared/storageKeyFromUserArgs-B86elJgS.mjs';
|
|
80
|
-
import storagePresignedUrlForPrivateContent from './packem_shared/storagePresignedUrlForPrivateContent-yGmb8uqz.mjs';
|
|
81
|
-
import storageUploadWithoutContentTypeAllowlist from './packem_shared/storageUploadWithoutContentTypeAllowlist-BV-gF1lT.mjs';
|
|
82
|
-
import storageUploadWithoutMaxSize from './packem_shared/storageUploadWithoutMaxSize-DpxO59wU.mjs';
|
|
83
|
-
import tableWithoutInsert from './packem_shared/tableWithoutInsert-CbbaYIP4.mjs';
|
|
84
|
-
import ttlFieldNotTimestamp from './packem_shared/ttlFieldNotTimestamp-Dpaj63Z6.mjs';
|
|
85
|
-
import unboundedStringArgument from './packem_shared/unboundedStringArgument-DThg2-wt.mjs';
|
|
86
|
-
import unindexedForeignKey from './packem_shared/unindexedForeignKey-BgJbKyqK.mjs';
|
|
87
|
-
import unindexedRelationTarget from './packem_shared/unindexedRelationTarget-D6eyj6Xx.mjs';
|
|
88
|
-
import userCreatingMutationWithoutCaptcha from './packem_shared/userCreatingMutationWithoutCaptcha-2DZtWIPb.mjs';
|
|
89
|
-
import vectorsNamespaceFromUserInput from './packem_shared/vectorsNamespaceFromUserInput-CQhr5bVn.mjs';
|
|
90
|
-
import workflowDuplicateStepName from './packem_shared/workflowDuplicateStepName-ioBxPBCy.mjs';
|
|
91
|
-
import workflowUnknownTarget from './packem_shared/workflowUnknownTarget-Cdd7WhKQ.mjs';
|
|
92
|
-
import workflowUnused from './packem_shared/workflowUnused-D0jHxdz9.mjs';
|
|
93
|
-
export { AE_METRIC_EVENTS, loadAnalyticsRuntimeMetrics } from './packem_shared/AE_METRIC_EVENTS-BM14d0lm.mjs';
|
|
94
|
-
export { fromServerSchema } from './packem_shared/fromServerSchema-CVnbSf8j.mjs';
|
|
95
|
-
|
|
96
|
-
const STATIC_LINTS = [
|
|
97
|
-
indexReferencesUnknownField,
|
|
98
|
-
relationReferencesUnknownTable,
|
|
99
|
-
relationReferencesUnknownField,
|
|
100
|
-
workflowUnknownTarget,
|
|
101
|
-
workflowDuplicateStepName,
|
|
102
|
-
shapeUnknownTable,
|
|
103
|
-
externalSourceIncrementalNoDeletePath,
|
|
104
|
-
externalSourceOnGlobal,
|
|
105
|
-
externalSourceUnscoped,
|
|
106
|
-
emptyIndex,
|
|
107
|
-
geoIndexFieldNotGeopoint,
|
|
108
|
-
geoIndexUnused,
|
|
109
|
-
exportSinkMisconfigured,
|
|
110
|
-
ttlFieldNotTimestamp,
|
|
111
|
-
circularFk,
|
|
112
|
-
unindexedForeignKey,
|
|
113
|
-
unindexedRelationTarget,
|
|
114
|
-
duplicateIndex,
|
|
115
|
-
tableWithoutInsert,
|
|
116
|
-
workflowUnused,
|
|
117
|
-
queueWithoutDlq,
|
|
118
|
-
filterWithoutIndex,
|
|
119
|
-
shapeTargetsGlobalTable,
|
|
120
|
-
mutatorFullRowReplace,
|
|
121
|
-
nondeterministicQueryMutation,
|
|
122
|
-
hyperdriveOutsideAction,
|
|
123
|
-
r2sqlOutsideAction,
|
|
124
|
-
authApiCallWithoutHeaders,
|
|
125
|
-
policyReferencesUnknownTable,
|
|
126
|
-
rlsUncoveredTable,
|
|
127
|
-
maskUncoveredPiiColumn,
|
|
128
|
-
maskWeakHashStrategyOnPii,
|
|
129
|
-
containerOversizedInstance,
|
|
130
|
-
containerPublicInternet,
|
|
131
|
-
publicMutationWithoutRatelimit,
|
|
132
|
-
userCreatingMutationWithoutCaptcha,
|
|
133
|
-
signupMutationWithoutDisposableGating,
|
|
134
|
-
publicArgumentUsesAny,
|
|
135
|
-
unboundedStringArgument,
|
|
136
|
-
hardcodedSecret,
|
|
137
|
-
sqlInjectionRisk,
|
|
138
|
-
adminRouteWithoutGuard,
|
|
139
|
-
paymentCreateWithoutAuthorize,
|
|
140
|
-
mailInboundDispatchWithoutVerify,
|
|
141
|
-
ratelimitDefaultMemoryStore,
|
|
142
|
-
browserAllowPrivateTargets,
|
|
143
|
-
privilegedFanoutFromPublicProcedure,
|
|
144
|
-
insertManyUnsafeUserData,
|
|
145
|
-
aiUnboundedGenerationPublic,
|
|
146
|
-
actionFetchSsrf,
|
|
147
|
-
ownerFieldFromArgsNotAuth,
|
|
148
|
-
storageKeyFromUserArgs,
|
|
149
|
-
kvUnscopedUserKeyIdor,
|
|
150
|
-
containerInstanceKeyFromUserInput,
|
|
151
|
-
aiRawRunEscapeHatch,
|
|
152
|
-
vectorsNamespaceFromUserInput,
|
|
153
|
-
mailRecipientFromRequestInput,
|
|
154
|
-
browserUserUrlWithoutAllowlist,
|
|
155
|
-
privilegedDispatchUnvalidatedPayload,
|
|
156
|
-
containerStartEnableInternetOverride,
|
|
157
|
-
containerRuntimeEgressRelaxation,
|
|
158
|
-
authTrustedOriginsWildcard,
|
|
159
|
-
authCsrfCheckDisabled,
|
|
160
|
-
authSecureCookiesDisabled,
|
|
161
|
-
authEmailVerificationDisabled,
|
|
162
|
-
authSessionFreshageZero,
|
|
163
|
-
imagesUrlSourceFromUserInput,
|
|
164
|
-
ratelimitKeySpoofableOrGlobal,
|
|
165
|
-
publicTableRlsOptoutConfusion,
|
|
166
|
-
allowUnauthenticatedShardAccessEnabled,
|
|
167
|
-
storageUploadWithoutContentTypeAllowlist,
|
|
168
|
-
storageUploadWithoutMaxSize,
|
|
169
|
-
storageGenerateUploadUrlNoContentTypePin,
|
|
170
|
-
storagePresignedUrlForPrivateContent,
|
|
171
|
-
httpActionMissingAuthGuard,
|
|
172
|
-
httpActionResponseHeaderInjection,
|
|
173
|
-
ratelimitMiddlewareFailOpen,
|
|
174
|
-
flagGatesSecurityWithUnsafeDefault,
|
|
175
|
-
aiToolSideEffectPromptInjection,
|
|
176
|
-
identityUndeclaredClaimTrusted,
|
|
177
|
-
paymentWebhookWideTolerance,
|
|
178
|
-
softDeleteIncludeDeletedFromArgs,
|
|
179
|
-
maskedRelationLeakViaWith,
|
|
180
|
-
outputProjectionMissingOnPublicRead,
|
|
181
|
-
normalizeIdUsedAsAuthorization,
|
|
182
|
-
notifySendOutsideAction,
|
|
183
|
-
notifyMissingPushConfig,
|
|
184
|
-
plaintextSecretInWranglerVariables
|
|
185
|
-
];
|
|
186
|
-
const RUNTIME_LINTS = [hotShard, indexUtilization, constraintValidator];
|
|
187
|
-
const ALL_LINTS = [...STATIC_LINTS, ...RUNTIME_LINTS];
|
|
188
|
-
const runAdvisor = (context, options = {}) => {
|
|
189
|
-
const lints = options.lints ?? ALL_LINTS;
|
|
190
|
-
const findings = [];
|
|
191
|
-
for (const lint of lints) {
|
|
192
|
-
if (options.source !== void 0 && lint.source !== options.source) {
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
findings.push(...lint.run(context));
|
|
196
|
-
}
|
|
197
|
-
return dedupeCacheKeys(findings);
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
export { ALL_LINTS, RUNTIME_LINTS, STATIC_LINTS, actionFetchSsrf, adminRouteWithoutGuard, aiRawRunEscapeHatch, aiToolSideEffectPromptInjection, aiUnboundedGenerationPublic, allowUnauthenticatedShardAccessEnabled, authApiCallWithoutHeaders, authCsrfCheckDisabled, authEmailVerificationDisabled, authSecureCookiesDisabled, authSessionFreshageZero, authTrustedOriginsWildcard, browserAllowPrivateTargets, browserUserUrlWithoutAllowlist, circularFk, constraintValidator, containerInstanceKeyFromUserInput, containerOversizedInstance, containerPublicInternet, containerRuntimeEgressRelaxation, containerStartEnableInternetOverride, dedupeCacheKeys, duplicateIndex, emptyIndex, exportSinkMisconfigured, externalSourceIncrementalNoDeletePath, externalSourceOnGlobal, externalSourceUnscoped, filterWithoutIndex, flagGatesSecurityWithUnsafeDefault, geoIndexFieldNotGeopoint, geoIndexUnused, hardcodedSecret, hotShard, httpActionMissingAuthGuard, httpActionResponseHeaderInjection, hyperdriveOutsideAction, identityUndeclaredClaimTrusted, imagesUrlSourceFromUserInput, indexReferencesUnknownField, indexUtilization, insertManyUnsafeUserData, kvUnscopedUserKeyIdor, mailInboundDispatchWithoutVerify, mailRecipientFromRequestInput, maskUncoveredPiiColumn, maskWeakHashStrategyOnPii, maskedRelationLeakViaWith, mutatorFullRowReplace, nondeterministicQueryMutation, normalizeIdUsedAsAuthorization, notifyMissingPushConfig, notifySendOutsideAction, outputProjectionMissingOnPublicRead, ownerFieldFromArgsNotAuth, paymentCreateWithoutAuthorize, paymentWebhookWideTolerance, plaintextSecretInWranglerVariables, policyReferencesUnknownTable, privilegedDispatchUnvalidatedPayload, privilegedFanoutFromPublicProcedure, publicArgumentUsesAny, publicMutationWithoutRatelimit, publicTableRlsOptoutConfusion, queueWithoutDlq, r2sqlOutsideAction, ratelimitDefaultMemoryStore, ratelimitKeySpoofableOrGlobal, ratelimitMiddlewareFailOpen, relationReferencesUnknownField, relationReferencesUnknownTable, rlsUncoveredTable, runAdvisor, shapeTargetsGlobalTable, shapeUnknownTable, signupMutationWithoutDisposableGating, softDeleteIncludeDeletedFromArgs, sqlInjectionRisk, storageGenerateUploadUrlNoContentTypePin, storageKeyFromUserArgs, storagePresignedUrlForPrivateContent, storageUploadWithoutContentTypeAllowlist, storageUploadWithoutMaxSize, tableWithoutInsert, ttlFieldNotTimestamp, unboundedStringArgument, unindexedForeignKey, unindexedRelationTarget, userCreatingMutationWithoutCaptcha, vectorsNamespaceFromUserInput, workflowDuplicateStepName, workflowUnknownTarget, workflowUnused };
|
|
1
|
+
import{dedupeCacheKeys as a}from"./packem_shared/dedupeCacheKeys-7JgxaQWV.mjs";import m from"./packem_shared/constraintValidator-N339mfyx.mjs";import s from"./packem_shared/hotShard-DVs_U17R.mjs";import n from"./packem_shared/indexUtilization-QfbIH_w4.mjs";import p from"./packem_shared/actionFetchSsrf-BbWxy1Yf.mjs";import f from"./packem_shared/adminRouteWithoutGuard-DSo4t9j4.mjs";import l from"./packem_shared/aiRawRunEscapeHatch-DfhjYm43.mjs";import u from"./packem_shared/aiToolSideEffectPromptInjection-DnWQOoKi.mjs";import d from"./packem_shared/aiUnboundedGenerationPublic-D3HZrh5_.mjs";import c from"./packem_shared/allowUnauthenticatedShardAccessEnabled-D4aMNBb0.mjs";import $ from"./packem_shared/authApiCallWithoutHeaders-BItMMdZP.mjs";import h from"./packem_shared/authCsrfCheckDisabled-De9ammtV.mjs";import g from"./packem_shared/authEmailVerificationDisabled-BFKdJcx4.mjs";import U from"./packem_shared/authSecureCookiesDisabled-B4WIzvMm.mjs";import b from"./packem_shared/authSessionFreshageZero-Bpcaf_Pe.mjs";import I from"./packem_shared/authTrustedOriginsWildcard-DjU9NXEm.mjs";import S from"./packem_shared/browserAllowPrivateTargets-Dxyeh6lg.mjs";import A from"./packem_shared/browserUserUrlWithoutAllowlist-BHBS6b0N.mjs";import y from"./packem_shared/circularFk-BMuJKmuZ.mjs";import T from"./packem_shared/containerInstanceKeyFromUserInput-C8S4T3ty.mjs";import w from"./packem_shared/containerOversizedInstance-B9wW_sU5.mjs";import R from"./packem_shared/containerPublicInternet-Bx2J7tha.mjs";import k from"./packem_shared/containerRuntimeEgressRelaxation-BQ2ZD1aV.mjs";import F from"./packem_shared/containerStartEnableInternetOverride-B62WUura.mjs";import W from"./packem_shared/duplicateIndex-DFT7qLQD.mjs";import x from"./packem_shared/emptyIndex-BiXEfyfN.mjs";import C from"./packem_shared/exportSinkMisconfigured-DvpAaa6j.mjs";import P from"./packem_shared/externalSourceIncrementalNoDeletePath-DnoL64YY.mjs";import v from"./packem_shared/externalSourceOnGlobal-DNPLoNUg.mjs";import M from"./packem_shared/externalSourceUnscoped-DqBp5jYr.mjs";import D from"./packem_shared/filterWithoutIndex-ht2GZQWV.mjs";import N from"./packem_shared/flagGatesSecurityWithUnsafeDefault-DPGFEHTt.mjs";import O from"./packem_shared/geoIndexFieldNotGeopoint-DAGLZtaH.mjs";import E from"./packem_shared/geoIndexUnused-BgDE6_AR.mjs";import G from"./packem_shared/hardcodedSecret-rIRc3aNk.mjs";import z from"./packem_shared/httpActionMissingAuthGuard-BZDdeW_D.mjs";import K from"./packem_shared/httpActionResponseHeaderInjection-D063rB7U.mjs";import L from"./packem_shared/hyperdriveOutsideAction-CRmOQz67.mjs";import V from"./packem_shared/identityUndeclaredClaimTrusted-BYRYGQ74.mjs";import j from"./packem_shared/imagesUrlSourceFromUserInput-Cy5pc_dA.mjs";import q from"./packem_shared/indexReferencesUnknownField-r3QHlaz6.mjs";import _ from"./packem_shared/insertManyUnsafeUserData-DrH7PdRs.mjs";import H from"./packem_shared/kvUnscopedUserKeyIdor-B4lGxRxh.mjs";import B from"./packem_shared/mailInboundDispatchWithoutVerify-BivYJ5F9.mjs";import Q from"./packem_shared/mailRecipientFromRequestInput-BR_oSh65.mjs";import Z from"./packem_shared/maskUncoveredPiiColumn-DqPfZM2O.mjs";import J from"./packem_shared/maskWeakHashStrategyOnPii-CEiiGgT7.mjs";import X from"./packem_shared/maskedRelationLeakViaWith-CxYk0MDW.mjs";import Y from"./packem_shared/mutatorFullRowReplace-CEgecSGm.mjs";import rr from"./packem_shared/nondeterministicQueryMutation-BaMfbAk_.mjs";import or from"./packem_shared/normalizeIdUsedAsAuthorization-FjISSXJm.mjs";import tr from"./packem_shared/notifyMissingPushConfig-C_GbVw3S.mjs";import ir from"./packem_shared/notifySendOutsideAction-B0jZuUP3.mjs";import er from"./packem_shared/outputProjectionMissingOnPublicRead-9Pm9766s.mjs";import ar from"./packem_shared/ownerFieldFromArgsNotAuth-BoR9vvst.mjs";import mr from"./packem_shared/paymentCreateWithoutAuthorize-CurtqN8K.mjs";import sr from"./packem_shared/paymentWebhookWideTolerance-I7ingfR8.mjs";import nr from"./packem_shared/plaintextSecretInWranglerVariables-DXjKIm8H.mjs";import pr from"./packem_shared/policyReferencesUnknownTable-D3WelAQa.mjs";import fr from"./packem_shared/privilegedDispatchUnvalidatedPayload-74GuGye1.mjs";import lr from"./packem_shared/privilegedFanoutFromPublicProcedure-C2j2GSUN.mjs";import ur from"./packem_shared/publicArgumentUsesAny-BJb4cTqL.mjs";import dr from"./packem_shared/publicMutationWithoutRatelimit-D9phluHW.mjs";import cr from"./packem_shared/publicTableRlsOptoutConfusion-CaWtPGAn.mjs";import $r from"./packem_shared/queueWithoutDlq-BLY3iy9Q.mjs";import hr from"./packem_shared/r2sqlOutsideAction-CKK_I1Ms.mjs";import gr from"./packem_shared/ratelimitDefaultMemoryStore-mOdI3Jmb.mjs";import Ur from"./packem_shared/ratelimitKeySpoofableOrGlobal-DaGId_Fh.mjs";import br from"./packem_shared/ratelimitMiddlewareFailOpen-CTWVosEc.mjs";import Ir from"./packem_shared/relationReferencesUnknownField-clqyB69Y.mjs";import Sr from"./packem_shared/relationReferencesUnknownTable-CLdrhkmS.mjs";import Ar from"./packem_shared/rlsUncoveredTable-DYHgnoos.mjs";import yr from"./packem_shared/shapeTargetsGlobalTable-Blz-aSkg.mjs";import Tr from"./packem_shared/shapeUnknownTable-DFxtyFio.mjs";import wr from"./packem_shared/signupMutationWithoutDisposableGating-3ir808Vz.mjs";import Rr from"./packem_shared/softDeleteIncludeDeletedFromArgs-DgxpQHRA.mjs";import kr from"./packem_shared/sqlInjectionRisk-D2NaT-5c.mjs";import Fr from"./packem_shared/storageGenerateUploadUrlNoContentTypePin-C9cjl6Jh.mjs";import Wr from"./packem_shared/storageKeyFromUserArgs-BeS5cp56.mjs";import xr from"./packem_shared/storagePresignedUrlForPrivateContent-j7VhwIdu.mjs";import Cr from"./packem_shared/storageUploadWithoutContentTypeAllowlist-oxKLecuf.mjs";import Pr from"./packem_shared/storageUploadWithoutMaxSize-DUDxPutk.mjs";import vr from"./packem_shared/tableWithoutInsert-D3AhaNzR.mjs";import Mr from"./packem_shared/ttlFieldNotTimestamp-BFiRkSZD.mjs";import Dr from"./packem_shared/unboundedStringArgument-AkkIcr-S.mjs";import Nr from"./packem_shared/unindexedForeignKey-DK4eWXkb.mjs";import Or from"./packem_shared/unindexedRelationTarget-B5fFq1E8.mjs";import Er from"./packem_shared/unrestrictedWhereBranch-YKiydie4.mjs";import Gr from"./packem_shared/userCreatingMutationWithoutCaptcha-iDjRkUFO.mjs";import zr from"./packem_shared/vectorsNamespaceFromUserInput-Cyq5B2kF.mjs";import Kr from"./packem_shared/workflowDuplicateStepName-cXF6Rpvg.mjs";import Lr from"./packem_shared/workflowUnknownTarget-JF8rITLP.mjs";import Vr from"./packem_shared/workflowUnused-Dx_FQwGE.mjs";import{AE_METRIC_EVENTS as Nt,loadAnalyticsRuntimeMetrics as Ot}from"./packem_shared/AE_METRIC_EVENTS-LP_0D7Uw.mjs";import{fromServerSchema as Gt}from"./packem_shared/fromServerSchema-CJ-AQ2kw.mjs";const jr=[q,Sr,Ir,Lr,Kr,Tr,P,v,M,x,O,E,C,Mr,y,Nr,Or,W,vr,Vr,$r,D,yr,Y,rr,L,hr,$,pr,Ar,Z,J,w,R,dr,Er,Gr,wr,ur,Dr,G,kr,f,mr,B,gr,S,lr,_,d,p,ar,Wr,H,T,l,zr,Q,A,fr,F,k,I,h,U,g,b,j,Ur,cr,c,Cr,Pr,Fr,xr,z,K,br,N,u,V,sr,Rr,X,er,or,ir,tr,nr],qr=[s,n,m],_r=[...jr,...qr],vt=(i,r={})=>{const e=r.lints??_r,o=[];for(const t of e)r.source!==void 0&&t.source!==r.source||o.push(...t.run(i));return a(o)};export{Nt as AE_METRIC_EVENTS,_r as ALL_LINTS,qr as RUNTIME_LINTS,jr as STATIC_LINTS,p as actionFetchSsrf,f as adminRouteWithoutGuard,l as aiRawRunEscapeHatch,u as aiToolSideEffectPromptInjection,d as aiUnboundedGenerationPublic,c as allowUnauthenticatedShardAccessEnabled,$ as authApiCallWithoutHeaders,h as authCsrfCheckDisabled,g as authEmailVerificationDisabled,U as authSecureCookiesDisabled,b as authSessionFreshageZero,I as authTrustedOriginsWildcard,S as browserAllowPrivateTargets,A as browserUserUrlWithoutAllowlist,y as circularFk,m as constraintValidator,T as containerInstanceKeyFromUserInput,w as containerOversizedInstance,R as containerPublicInternet,k as containerRuntimeEgressRelaxation,F as containerStartEnableInternetOverride,a as dedupeCacheKeys,W as duplicateIndex,x as emptyIndex,C as exportSinkMisconfigured,P as externalSourceIncrementalNoDeletePath,v as externalSourceOnGlobal,M as externalSourceUnscoped,D as filterWithoutIndex,N as flagGatesSecurityWithUnsafeDefault,Gt as fromServerSchema,O as geoIndexFieldNotGeopoint,E as geoIndexUnused,G as hardcodedSecret,s as hotShard,z as httpActionMissingAuthGuard,K as httpActionResponseHeaderInjection,L as hyperdriveOutsideAction,V as identityUndeclaredClaimTrusted,j as imagesUrlSourceFromUserInput,q as indexReferencesUnknownField,n as indexUtilization,_ as insertManyUnsafeUserData,H as kvUnscopedUserKeyIdor,Ot as loadAnalyticsRuntimeMetrics,B as mailInboundDispatchWithoutVerify,Q as mailRecipientFromRequestInput,Z as maskUncoveredPiiColumn,J as maskWeakHashStrategyOnPii,X as maskedRelationLeakViaWith,Y as mutatorFullRowReplace,rr as nondeterministicQueryMutation,or as normalizeIdUsedAsAuthorization,tr as notifyMissingPushConfig,ir as notifySendOutsideAction,er as outputProjectionMissingOnPublicRead,ar as ownerFieldFromArgsNotAuth,mr as paymentCreateWithoutAuthorize,sr as paymentWebhookWideTolerance,nr as plaintextSecretInWranglerVariables,pr as policyReferencesUnknownTable,fr as privilegedDispatchUnvalidatedPayload,lr as privilegedFanoutFromPublicProcedure,ur as publicArgumentUsesAny,dr as publicMutationWithoutRatelimit,cr as publicTableRlsOptoutConfusion,$r as queueWithoutDlq,hr as r2sqlOutsideAction,gr as ratelimitDefaultMemoryStore,Ur as ratelimitKeySpoofableOrGlobal,br as ratelimitMiddlewareFailOpen,Ir as relationReferencesUnknownField,Sr as relationReferencesUnknownTable,Ar as rlsUncoveredTable,vt as runAdvisor,yr as shapeTargetsGlobalTable,Tr as shapeUnknownTable,wr as signupMutationWithoutDisposableGating,Rr as softDeleteIncludeDeletedFromArgs,kr as sqlInjectionRisk,Fr as storageGenerateUploadUrlNoContentTypePin,Wr as storageKeyFromUserArgs,xr as storagePresignedUrlForPrivateContent,Cr as storageUploadWithoutContentTypeAllowlist,Pr as storageUploadWithoutMaxSize,vr as tableWithoutInsert,Mr as ttlFieldNotTimestamp,Dr as unboundedStringArgument,Nr as unindexedForeignKey,Or as unindexedRelationTarget,Er as unrestrictedWhereBranch,Gr as userCreatingMutationWithoutCaptcha,zr as vectorsNamespaceFromUserInput,Kr as workflowDuplicateStepName,Lr as workflowUnknownTarget,Vr as workflowUnused};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as m}from"@lunora/errors";const y=/^[\w.-]+$/u,c={indexHit:{event:"lunora.index.hit",index:"blob3",table:"blob2"},shardRequest:{event:"lunora.shard.request",group:"blob3",shardKey:"blob2"},tableScan:{event:"lunora.table.scan",table:"blob2"}},p=e=>{const a=typeof e=="number"?e:Number(e);return Number.isFinite(a)?a:0},o=e=>typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"||typeof e=="bigint"?String(e):"",$=e=>{if(!y.test(e))throw new m("INTERNAL",`@lunora/advisor: invalid Analytics Engine dataset name "${e}" — expected a bare table identifier.`)},u=e=>`'${e.replaceAll("\\","\\\\").replaceAll("'","''")}'`,h=async(e,a)=>{try{return(await e.query(a)).rows}catch{return[]}},x=async(e,a)=>{const{event:s,group:n,shardKey:r}=c.shardRequest,l=a.group===void 0?"":` AND ${n} = ${u(a.group)}`,i=`SELECT ${r} AS shardKey, ${n} AS shardGroup, sum(_sample_interval) AS requests FROM ${a.dataset} WHERE blob1 = ${u(s)}${l} GROUP BY shardKey, shardGroup`;return(await h(e,i)).map(d=>{const b=o(d.shardGroup);return{...b===""?{}:{group:b},requests:p(d.requests),shardKey:o(d.shardKey)}})},E=async(e,a)=>{const{event:s,table:n}=c.tableScan,r=`SELECT ${n} AS scanTable, sum(_sample_interval) AS scans FROM ${a.dataset} WHERE blob1 = ${u(s)} GROUP BY scanTable`;return(await h(e,r)).map(l=>({scans:p(l.scans),table:o(l.scanTable)}))},S=async(e,a)=>{const{event:s,index:n,table:r}=c.indexHit,l=`SELECT ${r} AS hitTable, ${n} AS hitIndex, sum(_sample_interval) AS reads FROM ${a.dataset} WHERE blob1 = ${u(s)} GROUP BY hitTable, hitIndex`,i=(await h(e,l)).map(t=>({index:o(t.hitIndex),reads:p(t.reads),table:o(t.hitTable)}));if(a.declaredIndexes===void 0)return i;const d=new Set(i.map(t=>`${t.table}\0${t.index}`)),b=a.declaredIndexes.filter(t=>!d.has(`${t.table}\0${t.index}`)).map(t=>({index:t.index,reads:0,table:t.table}));return[...i,...b]},R=async(e,a)=>{$(a.dataset);const[s,n,r]=await Promise.all([x(e,a),E(e,a),S(e,a)]);return{indexHits:r,shardTraffic:s,tableScans:n}};export{c as AE_METRIC_EVENTS,R as loadAnalyticsRuntimeMetrics};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a}from"./finding-BAVgqnCF.mjs";const r={categories:["SECURITY"],description:"An action's `ctx.fetch(url)` fetches a URL derived from the handler's `args`. `ctx.fetch` applies no host allowlist, so request-controlled URLs let a caller reach cloud metadata endpoints or internal services — server-side request forgery.",facing:"EXTERNAL",level:"ERROR",name:"action_fetch_ssrf",remediation:"Validate the URL against an allowlist of expected hosts before fetching, and reject private, loopback, and link-local addresses (notably `169.254.169.254`). Never pass request input straight to `ctx.fetch`.",run:t=>t.argumentDerivedFetches===void 0?[]:t.argumentDerivedFetches.map(e=>a(r,{cacheKey:`action_fetch_ssrf:${e.file}:${e.line.toString()}`,detail:`\`ctx.fetch\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) fetches a URL derived from \`args\` — a server-side request forgery vector. Validate the URL against a host allowlist and reject private/link-local targets before fetching.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"Possible SSRF from arg-derived ctx.fetch URL"};export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i}from"./finding-BAVgqnCF.mjs";const r={categories:["SECURITY"],description:"An `httpRoute` on an admin/privileged path has no visible auth/admin guard. REST routes aren't covered by RLS, so an unguarded `/admin/*` route is callable by anyone who reaches the URL.",facing:"EXTERNAL",level:"WARN",name:"admin_route_without_guard",remediation:"Assert an authenticated, authorized caller at the top of the handler — check `ctx.auth` / `getSession(...)`, or a `requireAdmin`-style guard — and reject (401/403) before doing privileged work. For machine callers, verify a secret with a timing-safe compare.",run:a=>{if(a.adminRoutes===void 0)return[];const t=[];for(const e of a.adminRoutes)e.usesGuard||t.push(i(r,{cacheKey:`admin_route_without_guard:${e.file}:${e.method}:${e.path}`,detail:`Route \`${e.method} ${e.path}\` (\`${e.exportName}\` in ${e.file}) is on an admin/privileged path but its handler shows no auth/admin guard. Assert an authorized caller before doing privileged work.`,metadata:{exportName:e.exportName,file:e.file,method:e.method,path:e.path}}));return t},source:"static",title:"Admin route without an auth guard"};export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as r}from"./finding-BAVgqnCF.mjs";const t={categories:["SECURITY"],description:"A `ctx.ai.run(model, …)` call selects its model from the handler's `args` with no server-side scoping. `ctx.ai.run` is the raw Workers AI binding passthrough, so an arg-derived model id lets any caller pick an arbitrary model — bypassing the typed `ctx.ai.model(...)` + AI-SDK layer's cap/schema.",facing:"EXTERNAL",level:"WARN",name:"ai_raw_run_escape_hatch",remediation:"Select the model from a fixed server-side allowlist — never from `args`. Prefer the typed `ctx.ai.model(...)` + `generateText`/`streamText` path with an output cap over the raw `ctx.ai.run` escape hatch.",run:a=>a.aiRawRuns===void 0?[]:a.aiRawRuns.map(e=>r(t,{cacheKey:`ai_raw_run_escape_hatch:${e.file}:${e.line.toString()}`,detail:`\`ctx.ai.run\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) selects its model from \`args\` with no server-side scoping — any caller can pick an arbitrary model, bypassing the typed AI-SDK layer's cap/schema. Select the model from a fixed server-side allowlist instead.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"Possible arbitrary model selection from arg-derived ctx.ai.run"};export{t as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as o}from"./finding-BAVgqnCF.mjs";const n={categories:["SECURITY"],description:"A `generateText` / `streamText` call whose prompt/messages carry user-supplied text and whose model-callable `tools` perform a privileged side effect (DB write, `ctx.run` dispatch, or outbound send). An injected instruction in the user text can steer the model into firing that action — the confused-deputy prompt-injection hazard.",facing:"EXTERNAL",level:"WARN",name:"ai_tool_side_effect_prompt_injection",remediation:"Don't let a model with user-derived input directly trigger a privileged action. Have the tool return a proposal the server validates and authorizes before executing, gate the side effect behind an explicit human/step confirmation, or keep side-effecting tools out of any generation whose prompt includes untrusted input.",run:t=>t.aiToolSideEffects===void 0?[]:t.aiToolSideEffects.filter(e=>e.userInputDerived).map(e=>{const i=`\`${e.exportName}\` (${e.file}:${e.line.toString()})`;return o(n,{cacheKey:`ai_tool_side_effect_prompt_injection:${e.file}:${e.line.toString()}`,detail:`\`${e.method}\` in ${i} feeds user-derived input to a model whose tools reach \`${e.sideEffect}\`. An injected instruction can steer the model into firing that side effect.`,metadata:{exportName:e.exportName,file:e.file,line:e.line,method:e.method,sideEffect:e.sideEffect}})}),source:"static",title:"AI tool side effect reachable via prompt injection"};export{n as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as n}from"./finding-BAVgqnCF.mjs";const o={categories:["SECURITY"],description:"A public procedure runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound. Generation bills per output token, so an anonymous caller can request arbitrarily long completions in a loop — a denial-of-wallet vector that also ties up worker time on long streams.",facing:"EXTERNAL",level:"WARN",name:"ai_unbounded_generation_public",remediation:"Cap the completion with `maxOutputTokens` in the generation config, and rate-limit the public entry point (`.use(rateLimit(...))`). For expensive models, prefer running generation from an internal, authenticated path rather than exposing it directly to anonymous callers.",run:t=>t.procedureProtections===void 0?[]:t.procedureProtections.filter(e=>e.unboundedAiGeneration&&e.visibility==="public").map(e=>n(o,{cacheKey:`ai_unbounded_generation_public:${e.file}:${e.exportName}`,detail:`\`${e.exportName}\` (${e.file}) is public and runs an AI generation with no \`maxOutputTokens\` bound — an anonymous caller can drive unbounded, billable completions in a loop. Add a \`maxOutputTokens\` cap and rate-limit the entry point.`,metadata:{exportName:e.exportName,file:e.file,kind:e.kind}})),source:"static",title:"Public procedure runs unbounded AI generation (no maxOutputTokens)"};export{o as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as t}from"./finding-BAVgqnCF.mjs";const n={categories:["SECURITY"],description:"`.extend(() => ({ allowUnauthenticatedShardAccess: true }))` disables the fail-closed default that denies an unauthenticated shard lookup. Combined with a schema that doesn't enforce `.rls(\"required\")` everywhere (or that leaves a table `.public()`), an unauthenticated caller can shard-hop into another tenant's rows with no row-security guard behind the door.",facing:"EXTERNAL",level:"WARN",name:"allow_unauthenticated_shard_access_enabled",remediation:"Prefer `authorizeShard` / `authorizeFanOut` (which take precedence over `allowUnauthenticatedShardAccess` and let you allow specific unauthenticated cases) over the blanket opt-out. If the app genuinely needs open shard access, enforce `.rls(\"required\")` on the schema with no `.public()` tables so a missing identity still can't read another tenant's rows.",run:a=>a.configCalls===void 0?[]:a.schema.rlsMode!=="required"||a.schema.tables.some(e=>e.isPublic)?a.configCalls.filter(e=>e.callee==="extend"&&e.trueKeys.includes("allowUnauthenticatedShardAccess")).map(e=>t(n,{cacheKey:`allow_unauthenticated_shard_access_enabled:${e.file}:${e.line.toString()}`,detail:`\`.extend(...)\` in ${e.file}:${e.line.toString()} sets \`allowUnauthenticatedShardAccess: true\`, and the schema has an RLS gap (no \`.rls("required")\`, or a \`.public()\` table) — an unauthenticated caller can shard-hop into another tenant's rows with no row-security guard behind the door.`,metadata:{callee:e.callee,file:e.file,line:e.line}})):[],source:"static",title:"Unauthenticated shard access enabled on an RLS-gapped schema"};export{n as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as r}from"./finding-BAVgqnCF.mjs";const s=e=>{const a={categories:e.categories,description:e.description,facing:e.facing,level:e.level,name:e.name,remediation:e.remediation,run:i=>{const n=e.getAccesses(i);return n===void 0||e.suppressWhen?.(i)===!0?[]:n.map(t=>r(a,{cacheKey:e.cacheKey(t),detail:e.detail(t),metadata:e.metadata(t)}))},source:"static",title:e.title};return a};export{s as m};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as h}from"./finding-BAVgqnCF.mjs";const l={categories:["SECURITY"],description:"A `ctx.authApi.<method>(...)` call omits `headers` — better-auth skips session authorization and runs the call with full server-to-server privileges, regardless of the caller's identity.",facing:"EXTERNAL",level:"WARN",name:"auth_api_call_without_headers",remediation:"Pass the inbound `headers` from the incoming request into every `ctx.authApi.*` call: `ctx.authApi.<method>({ body, headers: request.headers })`. See the `withAuthPlugins` middleware doc for details.",run:a=>{if(a.authApiCalls===void 0)return[];const s=[],r=new Map;for(const e of a.authApiCalls){if(e.hasHeaders)continue;const t=`${e.file}:${e.line.toString()}:${e.method}`,i=(r.get(t)??0)+1;r.set(t,i);const o=i>1?`:${i.toString()}`:"";s.push(h(l,{cacheKey:`auth_api_call_without_headers:${t}${o}`,detail:`\`ctx.authApi.${e.method||"<method>"}(…)\` in ${e.exportName} (${e.file}:${e.line.toString()}) is called without \`headers\` — better-auth skips session authorization, so this runs with full privileges. Pass the inbound \`headers\`.`,metadata:{exportName:e.exportName,file:e.file,line:e.line,method:e.method}}))}return s},source:"static",title:"Privileged ctx.authApi call missing headers"};export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a}from"./finding-BAVgqnCF.mjs";const i={categories:["SECURITY"],description:"A `createAuth({...})` call sets `advanced.disableCSRFCheck: true`, turning off better-auth's origin validation for state-changing auth requests — a cross-site request riding the ambient auth cookie is processed like a same-origin one.",facing:"EXTERNAL",level:"ERROR",name:"auth_csrf_check_disabled",remediation:"Remove `advanced.disableCSRFCheck: true` from `createAuth({...})` and rely on `trustedOrigins` for origin validation instead of disabling the check.",run:t=>t.authConfigs===void 0?[]:t.authConfigs.filter(e=>e.analyzable&&e.disableCsrfCheck).map(e=>a(i,{cacheKey:`auth_csrf_check_disabled:${e.file}:${e.line.toString()}`,detail:`\`createAuth\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) sets \`advanced.disableCSRFCheck: true\`, turning off origin validation for state-changing auth requests. Remove the flag and rely on \`trustedOrigins\` instead.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"createAuth CSRF check disabled"};export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a}from"./finding-BAVgqnCF.mjs";const t={categories:["SECURITY"],description:"A `createAuth({...})` call enables `emailAndPassword` with no `requireEmailVerification: true`. better-auth defaults email verification off, so an account is usable before the caller has proven ownership of the email address.",facing:"EXTERNAL",level:"WARN",name:"auth_email_verification_disabled",remediation:"Set `emailAndPassword.requireEmailVerification: true` on `createAuth({...})` so a new account can't act until its email address is verified.",run:i=>i.authConfigs===void 0?[]:i.authConfigs.filter(e=>e.analyzable&&e.emailPasswordEnabled&&!e.requireEmailVerification).map(e=>a(t,{cacheKey:`auth_email_verification_disabled:${e.file}:${e.line.toString()}`,detail:`\`createAuth\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) enables \`emailAndPassword\` with no \`requireEmailVerification: true\`, so an account is usable before its email is proven. Set \`emailAndPassword.requireEmailVerification: true\`.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"createAuth email verification disabled"};export{t as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as o}from"./finding-BAVgqnCF.mjs";const s={categories:["SECURITY"],description:"A `createAuth({...})` call sets `advanced.useSecureCookies: false`, overriding Lunora's secure-by-default posture — the session cookie ships without `Secure` even on an HTTPS deployment, so it can be sent over a plaintext connection.",facing:"EXTERNAL",level:"ERROR",name:"auth_secure_cookies_disabled",remediation:"Remove `advanced.useSecureCookies: false` from `createAuth({...})` — let Lunora's secure-by-default posture set the `Secure` cookie attribute for an HTTPS deployment.",run:t=>t.authConfigs===void 0?[]:t.authConfigs.filter(e=>e.analyzable&&e.secureCookiesDisabled).map(e=>o(s,{cacheKey:`auth_secure_cookies_disabled:${e.file}:${e.line.toString()}`,detail:`\`createAuth\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) sets \`advanced.useSecureCookies: false\`, so the session cookie ships without \`Secure\` even on an HTTPS deployment. Remove the override and let Lunora's secure-by-default posture apply.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"createAuth secure cookies disabled"};export{s as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as s}from"./finding-BAVgqnCF.mjs";const i={categories:["SECURITY"],description:"A `createAuth({...})` call sets `session.freshAge: 0`, disabling better-auth's recent-reauth check for sensitive operations — a long-lived stolen session can perform them without proving the caller still controls the credentials.",facing:"EXTERNAL",level:"WARN",name:"auth_session_freshage_zero",remediation:"Remove `session.freshAge: 0` from `createAuth({...})` (or set it to a real window) so sensitive operations require a recently re-authenticated session.",run:t=>t.authConfigs===void 0?[]:t.authConfigs.filter(e=>e.analyzable&&e.sessionFreshAgeZero).map(e=>s(i,{cacheKey:`auth_session_freshage_zero:${e.file}:${e.line.toString()}`,detail:`\`createAuth\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) sets \`session.freshAge: 0\`, disabling the recent-reauth check for sensitive operations. Remove the override or set a real window.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"createAuth session freshAge zero"};export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e}from"./finding-BAVgqnCF.mjs";const r={categories:["SECURITY"],description:"A `createAuth({...})` call's `trustedOrigins` array contains a `\"*\"` entry, disabling better-auth's CSRF/origin validation entirely — any origin is accepted for state-changing auth requests.",facing:"EXTERNAL",level:"ERROR",name:"auth_trusted_origins_wildcard",remediation:'List the specific origins your deployment serves in `trustedOrigins` instead of `"*"` — a wildcard disables origin validation for every caller.',run:t=>t.authConfigs===void 0?[]:t.authConfigs.filter(i=>i.analyzable&&i.trustedOriginsWildcard).map(i=>e(r,{cacheKey:`auth_trusted_origins_wildcard:${i.file}:${i.line.toString()}`,detail:`\`createAuth\` in \`${i.exportName}\` (${i.file}:${i.line.toString()}) sets \`trustedOrigins\` to include \`"*"\`, disabling CSRF/origin validation for every request. List the specific origins your deployment serves instead.`,metadata:{exportName:i.exportName,file:i.file,line:i.line}})),source:"static",title:"createAuth trustedOrigins wildcard"};export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as t}from"./finding-BAVgqnCF.mjs";const r={categories:["SECURITY"],description:"`createBrowser({ allowPrivateTargets: true })` disables the private/internal-IP SSRF guard, letting a navigated URL reach cloud metadata endpoints, internal services, or loopback. Combined with a request-supplied URL this is a server-side request forgery path.",facing:"EXTERNAL",level:"ERROR",name:"browser_allow_private_targets",remediation:"Remove `allowPrivateTargets: true` from `createBrowser({...})` so the private/internal-address guard stays on. If a specific internal host is genuinely required, pin it with an `allowedHosts` allowlist instead of opening all private targets.",run:a=>a.configCalls===void 0?[]:a.configCalls.filter(e=>e.callee==="createBrowser"&&e.trueKeys.includes("allowPrivateTargets")).map(e=>t(r,{cacheKey:`browser_allow_private_targets:${e.file}:${e.line.toString()}`,detail:`\`createBrowser({ allowPrivateTargets: true })\` in ${e.file}:${e.line.toString()} disables the private/internal-address SSRF guard — a navigated URL can then reach cloud metadata, internal services, or loopback. Remove the override, or pin the specific host with \`allowedHosts\` instead.`,metadata:{callee:e.callee,file:e.file,line:e.line}})),source:"static",title:"Browser with private-target SSRF guard disabled"};export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as t}from"./argument-derived-sink-BpO3NPPM.mjs";const a=t({cacheKey:e=>`browser_user_url_without_allowlist:${e.file}:${e.line.toString()}`,categories:["SECURITY"],description:"A `ctx.browser.<method>(url, …)` call navigates to a URL derived from the handler's `args` with no server-side scoping, and no `createBrowser` allowlist contains it. The default guard blocks private targets but not arbitrary public URLs, so any caller can make the headless browser an open-proxy / SSRF tool (fetch arbitrary third-party URLs, DNS-rebind to internal hosts).",detail:e=>`\`ctx.browser.${e.method}\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) navigates to a URL derived from \`args\` with no server-side scoping, and no \`createBrowser\` allowlist contains it — the default guard blocks private targets but not arbitrary public URLs, so any caller can turn the headless browser into an open-proxy / SSRF tool. Pin \`allowedHosts\` (and/or \`resolveDns\`) on \`createBrowser({...})\`, and derive the URL from server-trusted state where possible.`,facing:"EXTERNAL",getAccesses:e=>e.browserUrlAccesses,level:"WARN",metadata:e=>({exportName:e.exportName,file:e.file,line:e.line,method:e.method}),name:"browser_user_url_without_allowlist",remediation:"Pin the browser with an `allowedHosts` allowlist (and/or `resolveDns`) on `createBrowser({...})`, and derive the navigation URL from server-trusted state where possible rather than passing `args` straight to `ctx.browser`.",suppressWhen:e=>(e.configCalls??[]).some(r=>r.callee==="createBrowser"&&r.analyzable&&(r.presentKeys.includes("allowedHosts")||r.presentKeys.includes("resolveDns"))),title:"Browser navigates to arg-derived URL with no allowlist"});export{a as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as w}from"./finding-BAVgqnCF.mjs";const E=100,k={categories:["SCHEMA"],description:"A chain of foreign-key relations forms a cycle (e.g. A → B → C → A). Circular FK dependencies can cause unexpected behavior during DELETE operations — a CASCADE chain may loop indefinitely, and even a RESTRICT cycle prevents deletion of any row in the loop without temporarily disabling constraints.",facing:"INTERNAL",level:"WARN",name:"circular_fk",remediation:"Remove or break the cycle by dropping at least one FK relation from the loop. Consider replacing the circular dependency with a nullable FK and explicit application logic, or restructure the schema using a junction table.",run:h=>{const g=[],c=[...new Set(h.schema.tables.map(e=>e.name))].sort(),d=new Map(c.map((e,n)=>[e,n])),l=new Map;for(const e of h.schema.tables)for(const n of e.relations){if(n.kind!=="one"||!d.has(n.table))continue;let t=l.get(e.name);t===void 0&&(t=new Set,l.set(e.name,t)),t.add(n.table)}const r=new Set,s=new Map,f=[],u=new Set;let p=!1;const m=e=>{r.delete(e);const n=s.get(e);if(n!==void 0)for(const t of n)n.delete(t),r.has(t)&&m(t)},b=()=>{const e=[...f];if(e.length<2)return;let n=0;for(let o=1;o<e.length;o+=1)e[o]<e[n]&&(n=o);const t=[...e.slice(n),...e.slice(0,n)],i=t.join("→");if(u.has(i))return;u.add(i);const a=[...t,t[0]].join(" → ");g.push(w(k,{cacheKey:`circular_fk:${i}`,detail:`Circular foreign-key dependency detected: ${a}. This cycle can cause unexpected behavior during DELETE operations.`,metadata:{cycle:t,path:a,tables:t}})),u.size>=E&&(p=!0)},y=(e,n,t)=>{let i=!1;f.push(e),r.add(e);for(const a of l.get(e)??[]){if(p)break;d.get(a)<t||(a===n?(b(),i=!0):!r.has(a)&&y(a,n,t)&&(i=!0))}if(i)m(e);else for(const a of l.get(e)??[]){if(d.get(a)<t)continue;let o=s.get(a);o===void 0&&(o=new Set,s.set(a,o)),o.add(e)}return f.pop(),i};for(let e=0;e<c.length&&!p;e+=1)r.clear(),s.clear(),y(c[e],c[e],e);return g},source:"static",title:"Circular foreign-key dependency"};export{k as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as u}from"./finding-BAVgqnCF.mjs";const d=5,f=a=>typeof a._id=="string"?a._id:"?",m=(a,t,e)=>a?` (sample capped at ${t.toString()} rows — ${e})`:"",p=(a,t)=>{const e=a.slice(0,d),o=t-e.length,n=e.map(i=>`"${i}"`).join(", ");return o>0?`${n} (+${o.toString()} more)`:n},v=(a,t)=>{if(a==="_id")return t.existingIds;const e=new Set;for(const o of t.rows){const n=o[a];n!=null&&e.add(String(n))}return e},x=(a,t,e,o)=>{if(e.kind!=="one"||o.truncated)return;const n=e.references,i=v(n,o),s=e.field,r=[];for(const g of t.rows){const h=g[s];if(h==null)continue;const $=String(h);i.has($)||r.push(f(g))}if(r.length===0)return;const l=t.truncated,{cap:c}=t,b=n==="_id"?`"${e.table}"`:`"${e.table}"."${n}"`,w=`Table "${t.table}": ${r.length.toString()} sampled row(s) have a dangling FK value in column "${s}" — the referenced ${b} row does not exist. Row ids: ${p(r,r.length)}${m(l,c,"more rows may exist beyond the window")}.`;return u(a,{cacheKey:`constraint_validator:fk:${t.table}:${s}`,detail:w,metadata:{cap:c,column:s,count:r.length,examples:r.slice(0,d),kind:"fk",references:n,referencesTable:e.table,table:t.table,truncated:l}})},S=(a,t,e,o)=>{if(!o)return;const n=[];for(const s of t.rows)s[e]==null&&n.push(f(s));if(n.length===0)return;const i=`Table "${t.table}": ${n.length.toString()} sampled row(s) have a null/missing value in column "${e}", which is declared as non-optional. Row ids: ${p(n,n.length)}${m(t.truncated,t.cap,"more rows may exist beyond the window")}.`;return u(a,{cacheKey:`constraint_validator:null:${t.table}:${e}`,detail:i,metadata:{cap:t.cap,column:e,count:n.length,examples:n.slice(0,d),kind:"null",table:t.table,truncated:t.truncated}})},y=(a,t)=>{const e=[];for(const o of t){const n=a[o];if(n==null)return;e.push(JSON.stringify(n))}return e.join("|")},k=(a,t,e)=>{e.includes(t)||e.push(t),e.push(a)},_=(a,t,e)=>{if(e.kind!=="index"||e.unique!==!0)return;const o=new Map,n=[];for(const s of t.rows){const r=f(s),l=y(s,e.fields);if(l===void 0)continue;const c=o.get(l);c===void 0?o.set(l,r):k(r,c,n)}if(n.length===0)return;const i=`Table "${t.table}": ${n.length.toString()} sampled row(s) share duplicate values on unique index "${e.name}" (${e.fields.join(", ")}). Row ids: ${p(n,n.length)}${m(t.truncated,t.cap,"duplicates beyond the window may exist")}.`;return u(a,{cacheKey:`constraint_validator:unique:${t.table}:${e.name}`,detail:i,metadata:{cap:t.cap,count:n.length,examples:n.slice(0,d),fields:e.fields,index:e.name,kind:"unique",table:t.table,truncated:t.truncated}})},R=(a,t,e,o)=>{const n=o.get(t.table);if(!n)return[];const i=[];for(const s of n.relations){const r=e.get(s.table);if(!r)continue;const l=x(a,t,s,r);l&&i.push(l)}for(const s of n.fields){const r=!n.optionalFields?.has(s),l=S(a,t,s,r);l&&i.push(l)}for(const s of n.indexes){const r=_(a,t,s);r&&i.push(r)}return i},T={categories:["SCHEMA"],description:"Sampled rows violate one or more declared constraints: a foreign-key column references a non-existent row, a non-optional column contains null, or a unique-indexed column has duplicate values. These violations indicate data inserted before a constraint was enforced (e.g. a schema migration, a raw import, or a bug in a past data-migration transform).",facing:"INTERNAL",level:"WARN",name:"constraint_validator",remediation:"Inspect the listed rows and correct or remove the violating values. Run a data migration to backfill nulls, dedup unique violations, or re-link dangling FK references. For FK violations, confirm the target table rows exist before fixing the referencing rows.",run:a=>{if(!a.tableSamples||a.tableSamples.length===0)return[];const t=new Map;for(const o of a.tableSamples)t.set(o.table,o);const e=new Map(a.schema.tables.map(o=>[o.name,o]));return a.tableSamples.flatMap(o=>R(T,o,t,e))},source:"runtime",title:"Constraint violation"};export{T as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as t}from"./argument-derived-sink-BpO3NPPM.mjs";const r=t({cacheKey:e=>`container_instance_key_from_user_input:${e.file}:${e.line.toString()}`,categories:["SECURITY"],description:"A `ctx.containers.<name>.get` call routes to a container instance using a key derived from the handler's `args` with no server-side scoping. Any caller can supply another tenant's key and reach that tenant's container instance — a cross-tenant insecure direct object reference (IDOR).",detail:e=>`\`ctx.containers.*.${e.method}\` in \`${e.exportName}\` (${e.file}:${e.line.toString()}) routes to a container instance using a key derived from \`args\` with no server-side scoping — any caller can reach another tenant's container (IDOR). Derive the key from a server-trusted identity (e.g. \`\${ctx.auth.userId}\`).`,facing:"EXTERNAL",getAccesses:e=>e.containerKeyAccesses,level:"WARN",metadata:e=>({exportName:e.exportName,file:e.file,line:e.line,method:e.method}),name:"container_instance_key_from_user_input",remediation:"Derive the container instance key from a server-trusted identity (e.g. `${ctx.auth.userId}`) or a record the caller owns — never pass request input straight to `ctx.containers.<name>.get`.",title:"Possible cross-tenant IDOR from arg-derived unscoped container key"});export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as s}from"./finding-BAVgqnCF.mjs";const r=new Set(["standard-3","standard-4"]),o=2,c=4096,d=e=>typeof e=="string"?r.has(e):(e.vcpu??0)>o||(e.memoryMib??0)>c,l={categories:["PERFORMANCE"],description:"A container is declared on a large instance type, whose provisioned memory and disk are billed for the lifetime of every running instance.",facing:"INTERNAL",level:"INFO",name:"container_oversized_instance",remediation:"Confirm the workload needs this size; a smaller instanceType (lite/basic/standard-1) costs less while idle-but-running.",run:e=>{const t=[];for(const i of e.containers??[]){const{instanceType:n}=i;if(n===void 0||!d(n))continue;const a=typeof n=="string"?n:JSON.stringify(n);t.push(s(l,{cacheKey:`container_oversized_instance:${i.exportName}`,detail:`Container "${i.exportName}" uses a large instance type (${a}); its memory + disk are billed while any instance runs.`,metadata:{container:i.exportName,instanceType:n}}))}return t},source:"static",title:"Oversized container instance"};export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a}from"./finding-BAVgqnCF.mjs";const r={categories:["SECURITY"],description:"A container leaves outbound internet access at the default (enabled), which is billed per GB of egress and widens the attack surface.",facing:"INTERNAL",level:"INFO",name:"container_public_internet",remediation:"Set `enableInternet: false` on the container if it doesn't call external services, or `true` to opt in deliberately.",run:n=>{const t=[];for(const e of n.containers??[])e.enableInternet===void 0&&t.push(a(r,{cacheKey:`container_public_internet:${e.exportName}`,detail:`Container "${e.exportName}" doesn't set enableInternet, so outbound internet is on by default (egress is billed).`,metadata:{container:e.exportName}}));return t},source:"static",title:"Container egress enabled by default"};export{r as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as t}from"./finding-BAVgqnCF.mjs";const i={categories:["SECURITY"],description:"A runtime `.egress.allow(...)` / `.egress.deny(...)` / `.egress.setAllowed(...)` call mutates the container's egress firewall at runtime, re-opening a network surface the static analysis assumes is locked to the `defineContainer` declaration.",facing:"EXTERNAL",level:"WARN",name:"container_runtime_egress_relaxation",remediation:"Prefer declaring the egress policy statically in `lunora/containers.ts` where it is auditable. When a runtime mutation is unavoidable, scope it behind a server-trusted check and keep the change narrow (a specific host, not a broad allow) rather than an unconditional relaxation.",run:a=>a.containerOverrides===void 0?[]:a.containerOverrides.filter(e=>e.kind==="egress_relaxation").map(e=>t(i,{cacheKey:`container_runtime_egress_relaxation:${e.file}:${e.line.toString()}`,detail:`\`${e.exportName}\` calls \`.egress.${e.detail}(...)\` at runtime, mutating the container's egress firewall.`,metadata:{exportName:e.exportName,file:e.file,line:e.line,method:e.detail}})),source:"static",title:"Runtime egress mutation relaxes the container firewall"};export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as n}from"./finding-BAVgqnCF.mjs";const i={categories:["SECURITY"],description:"A runtime `.start({ enableInternet: true, … })` call overrides the static `defineContainer` declaration and re-opens public internet egress for that container instance, defeating the `container_public_internet` lint's assumption that the declaration is authoritative.",facing:"EXTERNAL",level:"WARN",name:"container_start_enable_internet_override",remediation:"Avoid overriding `enableInternet` at `.start()` time. Set it once on the `defineContainer` declaration in `lunora/containers.ts` so the static advisors can reason about it, and gate any runtime opt-in behind a server-trusted check rather than an unconditional literal.",run:t=>t.containerOverrides===void 0?[]:t.containerOverrides.filter(e=>e.kind==="enable_internet").map(e=>n(i,{cacheKey:`container_start_enable_internet_override:${e.file}:${e.line.toString()}`,detail:`\`${e.exportName}\` calls \`.start({ enableInternet: true })\`, overriding the container's static egress posture.`,metadata:{exportName:e.exportName,file:e.file,line:e.line}})),source:"static",title:"Runtime .start() override re-enables container internet access"};export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n=a=>{const t=new Map;return a.map(e=>{const c=(t.get(e.cacheKey)??0)+1;return t.set(e.cacheKey,c),c===1?e:{...e,cacheKey:`${e.cacheKey}:${c.toString()}`}})};export{n as dedupeCacheKeys};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as o}from"./finding-BAVgqnCF.mjs";const r=(a,i)=>a.length>i.length?!1:a.every((n,d)=>n===i[d]),l={categories:["PERFORMANCE"],description:"A secondary index is redundant because another index already covers every lookup it serves (its columns are a leading prefix of the other's). The redundant index costs storage and is maintained on every write for no read benefit.",facing:"INTERNAL",level:"INFO",name:"duplicate_index",remediation:"Drop the redundant index; the covering index already serves its lookups.",run:a=>{const i=[];for(const n of a.schema.tables){const d=n.indexes.filter(e=>e.kind==="index");for(const e of d){if(e.unique===!0)continue;const t=d.find(s=>s===e||!r(e.fields,s.fields)?!1:e.fields.length===s.fields.length?e.name>s.name:!0);t&&i.push(o(l,{cacheKey:`duplicate_index:${n.name}:${e.name}`,detail:`Index "${e.name}" on table "${n.name}" (${e.fields.join(", ")}) is redundant — index "${t.name}" (${t.fields.join(", ")}) already covers its lookups.`,metadata:{coveredBy:{fields:t.fields,name:t.name},fields:e.fields,index:e.name,table:n.name}}))}}return i},source:"static",title:"Duplicate / redundant index"};export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i}from"./finding-BAVgqnCF.mjs";const o={categories:["SCHEMA"],description:"An index declares no columns, so it indexes nothing and can never narrow a read.",facing:"INTERNAL",level:"WARN",name:"empty_index",remediation:"Give the index its columns, or remove it.",run:a=>{const t=[];for(const n of a.schema.tables)for(const e of n.indexes)e.kind!=="index"||e.fields.length>0||t.push(i(o,{cacheKey:`empty_index:${n.name}:${e.name}`,detail:`Index "${e.name}" on table "${n.name}" declares no columns.`,metadata:{index:e.name,table:n.name}}));return t},source:"static",title:"Empty index"};export{o as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a}from"./finding-BAVgqnCF.mjs";const c={defineExportSink:["name","deliver"],r2Sink:["bucket","name"],webhookExportSink:["name","url"]},f={categories:["SCHEMA"],description:"A CDC export sink (`defineExportSink` / `webhookExportSink` / `r2Sink`) is missing a required config field (a webhook with no `url`, an R2 sink with no `bucket`, or a sink with no `name`/`deliver`). The sink can never deliver a change batch, so the export tap silently drains nothing.",facing:"INTERNAL",level:"ERROR",name:"export_sink_misconfigured",remediation:"Supply the missing field: a non-empty `url` for `webhookExportSink`, a `bucket` R2 binding for `r2Sink`, or `name` + `deliver` for `defineExportSink`.",run:n=>{if(n.exportSinks===void 0)return[];const t=[];for(const e of n.exportSinks){if(!e.analyzable)continue;const r=new Set(e.presentKeys),o=new Set(e.emptyKeys);for(const i of c[e.factory]??[]){if(r.has(i)&&!o.has(i))continue;const s=o.has(i)?"is set to an empty string":"is missing";t.push(a(f,{cacheKey:`export_sink_misconfigured:${e.file}:${e.line.toString()}:${i}`,detail:`\`${e.factory}({ … })\` in ${e.file}:${e.line.toString()} ${s} its required \`${i}\` field — the sink can never deliver a change batch, so the export tap drains nothing.`,metadata:{factory:e.factory,field:i,file:e.file,line:e.line}}))}}return t},source:"static",title:"Export sink is misconfigured"};export{f as default};
|