Skip to content

Commit

Permalink
remove csrf (#610)
Browse files Browse the repository at this point in the history
Co-authored-by: Kent C. Dodds <[email protected]>
  • Loading branch information
nichtsam and kentcdodds authored Jan 29, 2024
1 parent 8b7d5d9 commit c59b979
Show file tree
Hide file tree
Showing 22 changed files with 51 additions and 96 deletions.
13 changes: 3 additions & 10 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
} from '@remix-run/react'
import { withSentry } from '@sentry/remix'
import { useRef } from 'react'
import { AuthenticityTokenProvider } from 'remix-utils/csrf/react'
import { HoneypotProvider } from 'remix-utils/honeypot/react'
import { z } from 'zod'
import { GeneralErrorBoundary } from './components/error-boundary.tsx'
Expand All @@ -47,7 +46,6 @@ import { EpicToaster } from './components/ui/sonner.tsx'
import tailwindStyleSheetUrl from './styles/tailwind.css'
import { getUserId, logout } from './utils/auth.server.ts'
import { ClientHintCheck, getHints, useHints } from './utils/client-hints.tsx'
import { csrf } from './utils/csrf.server.ts'
import { prisma } from './utils/db.server.ts'
import { getEnv } from './utils/env.server.ts'
import { honeypot } from './utils/honeypot.server.ts'
Expand Down Expand Up @@ -131,7 +129,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
}
const { toast, headers: toastHeaders } = await getToast(request)
const honeyProps = honeypot.getInputProps()
const [csrfToken, csrfCookieHeader] = await csrf.commitToken()

return json(
{
Expand All @@ -147,13 +144,11 @@ export async function loader({ request }: LoaderFunctionArgs) {
ENV: getEnv(),
toast,
honeyProps,
csrfToken,
},
{
headers: combineHeaders(
{ 'Server-Timing': timings.toString() },
toastHeaders,
csrfCookieHeader ? { 'set-cookie': csrfCookieHeader } : null,
),
},
)
Expand Down Expand Up @@ -288,11 +283,9 @@ function Logo() {
function AppWithProviders() {
const data = useLoaderData<typeof loader>()
return (
<AuthenticityTokenProvider token={data.csrfToken}>
<HoneypotProvider {...data.honeyProps}>
<App />
</HoneypotProvider>
</AuthenticityTokenProvider>
<HoneypotProvider {...data.honeyProps}>
<App />
</HoneypotProvider>
)
}

Expand Down
4 changes: 0 additions & 4 deletions app/routes/_auth+/forgot-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import {
type MetaFunction,
} from '@remix-run/node'
import { Link, useFetcher } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { z } from 'zod'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
import { ErrorList, Field } from '#app/components/forms.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { sendEmail } from '#app/utils/email.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
Expand All @@ -27,7 +25,6 @@ const ForgotPasswordSchema = z.object({

export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData()
await validateCSRF(formData, request.headers)
checkHoneypot(formData)
const submission = await parse(formData, {
schema: ForgotPasswordSchema.superRefine(async (data, ctx) => {
Expand Down Expand Up @@ -142,7 +139,6 @@ export default function ForgotPasswordRoute() {
</div>
<div className="mx-auto mt-16 min-w-full max-w-sm sm:min-w-[368px]">
<forgotPassword.Form method="POST" {...form.props}>
<AuthenticityTokenInput />
<HoneypotInputs />
<div>
<Field
Expand Down
4 changes: 0 additions & 4 deletions app/routes/_auth+/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
type MetaFunction,
} from '@remix-run/node'
import { Form, Link, useActionData, useSearchParams } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { safeRedirect } from 'remix-utils/safe-redirect'
import { z } from 'zod'
Expand All @@ -28,7 +27,6 @@ import {
ProviderConnectionForm,
providerNames,
} from '#app/utils/connections.tsx'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import { combineResponseInits, useIsPending } from '#app/utils/misc.tsx'
Expand Down Expand Up @@ -197,7 +195,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
export async function action({ request }: ActionFunctionArgs) {
await requireAnonymous(request)
const formData = await request.formData()
await validateCSRF(formData, request.headers)
checkHoneypot(formData)
const submission = await parse(formData, {
schema: intent =>
Expand Down Expand Up @@ -270,7 +267,6 @@ export default function LoginPage() {
<div>
<div className="mx-auto w-full max-w-md px-8">
<Form method="POST" {...form.props}>
<AuthenticityTokenInput />
<HoneypotInputs />
<Field
labelProps={{ children: 'Username' }}
Expand Down
4 changes: 0 additions & 4 deletions app/routes/_auth+/onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ import {
useLoaderData,
useSearchParams,
} from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { safeRedirect } from 'remix-utils/safe-redirect'
import { z } from 'zod'
import { CheckboxField, ErrorList, Field } from '#app/components/forms.tsx'
import { Spacer } from '#app/components/spacer.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireAnonymous, sessionKey, signup } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
Expand Down Expand Up @@ -70,7 +68,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
export async function action({ request }: ActionFunctionArgs) {
const email = await requireOnboardingEmail(request)
const formData = await request.formData()
await validateCSRF(formData, request.headers)
checkHoneypot(formData)
const submission = await parse(formData, {
schema: intent =>
Expand Down Expand Up @@ -177,7 +174,6 @@ export default function SignupRoute() {
className="mx-auto min-w-full max-w-sm sm:min-w-[368px]"
{...form.props}
>
<AuthenticityTokenInput />
<HoneypotInputs />
<Field
labelProps={{ htmlFor: fields.username.id, children: 'Username' }}
Expand Down
4 changes: 0 additions & 4 deletions app/routes/_auth+/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
type MetaFunction,
} from '@remix-run/node'
import { Form, useActionData, useSearchParams } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { z } from 'zod'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
Expand All @@ -18,7 +17,6 @@ import {
ProviderConnectionForm,
providerNames,
} from '#app/utils/connections.tsx'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { sendEmail } from '#app/utils/email.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
Expand All @@ -33,7 +31,6 @@ const SignupSchema = z.object({
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData()

await validateCSRF(formData, request.headers)
checkHoneypot(formData)

const submission = await parse(formData, {
Expand Down Expand Up @@ -139,7 +136,6 @@ export default function SignupRoute() {
</div>
<div className="mx-auto mt-16 min-w-full max-w-sm sm:min-w-[368px]">
<Form method="POST" {...form.props}>
<AuthenticityTokenInput />
<HoneypotInputs />
<Field
labelProps={{
Expand Down
4 changes: 0 additions & 4 deletions app/routes/_auth+/verify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { conform, useForm, type Submission } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { json, type ActionFunctionArgs } from '@remix-run/node'
import { Form, useActionData, useSearchParams } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { z } from 'zod'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
Expand All @@ -13,7 +12,6 @@ import { handleVerification as handleChangeEmailVerification } from '#app/routes
import { twoFAVerificationType } from '#app/routes/settings+/profile.two-factor.tsx'
import { type twoFAVerifyVerificationType } from '#app/routes/settings+/profile.two-factor.verify.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import { ensurePrimary } from '#app/utils/litefs.server.ts'
Expand Down Expand Up @@ -45,7 +43,6 @@ const VerifySchema = z.object({
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData()
checkHoneypot(formData)
await validateCSRF(formData, request.headers)
return validateRequest(request, formData)
}

Expand Down Expand Up @@ -284,7 +281,6 @@ export default function VerifyRoute() {
</div>
<div className="flex w-full gap-2">
<Form method="POST" {...form.props} className="flex-1">
<AuthenticityTokenInput />
<HoneypotInputs />
<Field
labelProps={{
Expand Down
4 changes: 0 additions & 4 deletions app/routes/settings+/profile.change-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
type ActionFunctionArgs,
} from '@remix-run/node'
import { Form, useActionData, useLoaderData } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { z } from 'zod'
import { ErrorList, Field } from '#app/components/forms.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
Expand All @@ -21,7 +20,6 @@ import {
type VerifyFunctionArgs,
} from '#app/routes/_auth+/verify.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { sendEmail } from '#app/utils/email.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
Expand Down Expand Up @@ -106,7 +104,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
export async function action({ request }: ActionFunctionArgs) {
const userId = await requireUserId(request)
const formData = await request.formData()
await validateCSRF(formData, request.headers)
const submission = await parse(formData, {
schema: ChangeEmailSchema.superRefine(async (data, ctx) => {
const existingUser = await prisma.user.findUnique({
Expand Down Expand Up @@ -234,7 +231,6 @@ export default function ChangeEmailIndex() {
</p>
<div className="mx-auto mt-5 max-w-sm">
<Form method="POST" {...form.props}>
<AuthenticityTokenInput />
<Field
labelProps={{ children: 'New Email' }}
inputProps={{
Expand Down
6 changes: 0 additions & 6 deletions app/routes/settings+/profile.index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ import {
type ActionFunctionArgs,
} from '@remix-run/node'
import { Link, useFetcher, useLoaderData } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { z } from 'zod'
import { ErrorList, Field } from '#app/components/forms.tsx'
import { Button } from '#app/components/ui/button.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireUserId, sessionKey } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { getUserImgSrc, useDoubleCheck } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
Expand Down Expand Up @@ -85,7 +83,6 @@ const deleteDataActionIntent = 'delete-data'
export async function action({ request }: ActionFunctionArgs) {
const userId = await requireUserId(request)
const formData = await request.formData()
await validateCSRF(formData, request.headers)
const intent = formData.get('intent')
switch (intent) {
case profileUpdateActionIntent: {
Expand Down Expand Up @@ -238,7 +235,6 @@ function UpdateProfile() {

return (
<fetcher.Form method="POST" {...form.props}>
<AuthenticityTokenInput />
<div className="grid grid-cols-6 gap-x-10">
<Field
className="col-span-3"
Expand Down Expand Up @@ -306,7 +302,6 @@ function SignOutOfSessions() {
<div>
{otherSessionsCount ? (
<fetcher.Form method="POST">
<AuthenticityTokenInput />
<StatusButton
{...dc.getButtonProps({
type: 'submit',
Expand Down Expand Up @@ -350,7 +345,6 @@ function DeleteData() {
return (
<div>
<fetcher.Form method="POST">
<AuthenticityTokenInput />
<StatusButton
{...dc.getButtonProps({
type: 'submit',
Expand Down
4 changes: 0 additions & 4 deletions app/routes/settings+/profile.password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
type ActionFunctionArgs,
} from '@remix-run/node'
import { Form, Link, useActionData } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { z } from 'zod'
import { ErrorList, Field } from '#app/components/forms.tsx'
import { Button } from '#app/components/ui/button.tsx'
Expand All @@ -19,7 +18,6 @@ import {
requireUserId,
verifyUserPassword,
} from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
Expand Down Expand Up @@ -67,7 +65,6 @@ export async function action({ request }: ActionFunctionArgs) {
const userId = await requireUserId(request)
await requirePassword(userId)
const formData = await request.formData()
await validateCSRF(formData, request.headers)
const submission = await parse(formData, {
async: true,
schema: ChangePasswordForm.superRefine(
Expand Down Expand Up @@ -137,7 +134,6 @@ export default function ChangePasswordRoute() {

return (
<Form method="POST" {...form.props} className="mx-auto max-w-md">
<AuthenticityTokenInput />
<Field
labelProps={{ children: 'Current Password' }}
inputProps={{
Expand Down
4 changes: 0 additions & 4 deletions app/routes/settings+/profile.photo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ import {
useNavigation,
} from '@remix-run/react'
import { useState } from 'react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { z } from 'zod'
import { ErrorList } from '#app/components/forms.tsx'
import { Button } from '#app/components/ui/button.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import {
getUserImgSrc,
Expand Down Expand Up @@ -75,7 +73,6 @@ export async function action({ request }: ActionFunctionArgs) {
request,
unstable_createMemoryUploadHandler({ maxPartSize: MAX_SIZE }),
)
await validateCSRF(formData, request.headers)

const submission = await parse(formData, {
schema: PhotoFormSchema.transform(async data => {
Expand Down Expand Up @@ -155,7 +152,6 @@ export default function PhotoRoute() {
onReset={() => setNewImageSrc(null)}
{...form.props}
>
<AuthenticityTokenInput />
<img
src={
newImageSrc ?? (data.user ? getUserImgSrc(data.user.image?.id) : '')
Expand Down
4 changes: 0 additions & 4 deletions app/routes/settings+/profile.two-factor.disable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import {
type ActionFunctionArgs,
} from '@remix-run/node'
import { useFetcher } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { Icon } from '#app/components/ui/icon.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireRecentVerification } from '#app/routes/_auth+/verify.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { useDoubleCheck } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
Expand All @@ -29,7 +27,6 @@ export async function loader({ request }: LoaderFunctionArgs) {

export async function action({ request }: ActionFunctionArgs) {
await requireRecentVerification(request)
await validateCSRF(await request.formData(), request.headers)
const userId = await requireUserId(request)
await prisma.verification.delete({
where: { target_type: { target: userId, type: twoFAVerificationType } },
Expand All @@ -47,7 +44,6 @@ export default function TwoFactorDisableRoute() {
return (
<div className="mx-auto max-w-sm">
<disable2FAFetcher.Form method="POST">
<AuthenticityTokenInput />
<p>
Disabling two factor authentication is not recommended. However, if
you would like to do so, click here:
Expand Down
Loading

0 comments on commit c59b979

Please sign in to comment.