Skip to content

Commit 7b461fc

Browse files
committed
show a best practice where we omit limit so attackers cant abuse that surface
1 parent fc3b39b commit 7b461fc

File tree

6 files changed

+27
-63
lines changed

6 files changed

+27
-63
lines changed

examples/next/app/client/page.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export default function Page() {
2323
}
2424

2525
const LaunchesQuery = graphql(`
26-
query Launches_SSR($limit: Int, $offset: Int) {
27-
launches(limit: $limit, offset: $offset) {
26+
query Launches_SSR($offset: Int) {
27+
launches(limit: 10, offset: $offset) {
2828
nodes {
2929
id
3030
...LaunchFields
@@ -44,7 +44,7 @@ function Launches() {
4444

4545
const [result] = useQuery({
4646
query: LaunchesQuery,
47-
variables: { limit: 10, offset },
47+
variables: { offset },
4848
})
4949

5050
return (

examples/next/app/rsc/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const { getClient } = registerClient(() =>
2424
)
2525

2626
const LaunchesQuery = graphql(`
27-
query Launches_RSC($limit: Int, $offset: Int) {
28-
launches(limit: $limit, offset: $offset) {
27+
query Launches_RSC($offset: Int) {
28+
launches(limit: 10, offset: $offset) {
2929
nodes {
3030
id
3131
...LaunchFields

examples/next/fuse/gql.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
1313
* Therefore it is highly recommended to use the babel or swc plugin for production.
1414
*/
1515
const documents = {
16-
'\n query Launches_SSR($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n':
16+
'\n query Launches_SSR($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n':
1717
types.Launches_SsrDocument,
18-
'\n query Launches_RSC($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n':
18+
'\n query Launches_RSC($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n':
1919
types.Launches_RscDocument,
2020
'\n query LaunchDetails($id: ID!) {\n node(id: $id) {\n ... on Launch {\n id\n name\n details\n launchDate\n image\n site {\n ...LaunchSiteFields\n }\n rocket {\n cost\n country\n company\n description\n }\n }\n }\n }\n':
2121
types.LaunchDetailsDocument,
@@ -27,7 +27,7 @@ const documents = {
2727
types.SiteLocationFieldsFragmentDoc,
2828
'\n fragment TotalCountFields on QueryLaunchesList {\n totalCount\n }\n':
2929
types.TotalCountFieldsFragmentDoc,
30-
'\n query PageLaunches($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n':
30+
'\n query PageLaunches($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n':
3131
types.PageLaunchesDocument,
3232
}
3333

@@ -49,14 +49,14 @@ export function graphql(source: string): unknown
4949
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
5050
*/
5151
export function graphql(
52-
source: '\n query Launches_SSR($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n',
53-
): (typeof documents)['\n query Launches_SSR($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n']
52+
source: '\n query Launches_SSR($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n',
53+
): (typeof documents)['\n query Launches_SSR($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n']
5454
/**
5555
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
5656
*/
5757
export function graphql(
58-
source: '\n query Launches_RSC($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n',
59-
): (typeof documents)['\n query Launches_RSC($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n']
58+
source: '\n query Launches_RSC($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n',
59+
): (typeof documents)['\n query Launches_RSC($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n ...LaunchFields\n }\n ...TotalCountFields\n }\n }\n']
6060
/**
6161
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
6262
*/
@@ -91,8 +91,8 @@ export function graphql(
9191
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
9292
*/
9393
export function graphql(
94-
source: '\n query PageLaunches($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n',
95-
): (typeof documents)['\n query PageLaunches($limit: Int, $offset: Int) {\n launches(limit: $limit, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n']
94+
source: '\n query PageLaunches($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n',
95+
): (typeof documents)['\n query PageLaunches($offset: Int) {\n launches(limit: 10, offset: $offset) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n']
9696

9797
export function graphql(source: string) {
9898
return (documents as any)[source] ?? {}

examples/next/fuse/graphql.ts

+6-42
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ export type User = Node & {
146146
}
147147

148148
export type Launches_SsrQueryVariables = Exact<{
149-
limit?: InputMaybe<Scalars['Int']['input']>
150149
offset?: InputMaybe<Scalars['Int']['input']>
151150
}>
152151

@@ -166,7 +165,6 @@ export type Launches_SsrQuery = {
166165
}
167166

168167
export type Launches_RscQueryVariables = Exact<{
169-
limit?: InputMaybe<Scalars['Int']['input']>
170168
offset?: InputMaybe<Scalars['Int']['input']>
171169
}>
172170

@@ -255,7 +253,6 @@ export type TotalCountFieldsFragment = {
255253
} & { ' $fragmentName'?: 'TotalCountFieldsFragment' }
256254

257255
export type PageLaunchesQueryVariables = Exact<{
258-
limit?: InputMaybe<Scalars['Int']['input']>
259256
offset?: InputMaybe<Scalars['Int']['input']>
260257
}>
261258

@@ -390,22 +387,14 @@ export const TotalCountFieldsFragmentDoc = {
390387
],
391388
} as unknown as DocumentNode<TotalCountFieldsFragment, unknown>
392389
export const Launches_SsrDocument = {
393-
__meta__: { hash: 'bb6e5ac452c5d08659b1855799a08ee2543a05ca' },
390+
__meta__: { hash: '152c2558141de086b4bd6905725533e9f7949725' },
394391
kind: 'Document',
395392
definitions: [
396393
{
397394
kind: 'OperationDefinition',
398395
operation: 'query',
399396
name: { kind: 'Name', value: 'Launches_SSR' },
400397
variableDefinitions: [
401-
{
402-
kind: 'VariableDefinition',
403-
variable: {
404-
kind: 'Variable',
405-
name: { kind: 'Name', value: 'limit' },
406-
},
407-
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
408-
},
409398
{
410399
kind: 'VariableDefinition',
411400
variable: {
@@ -426,10 +415,7 @@ export const Launches_SsrDocument = {
426415
{
427416
kind: 'Argument',
428417
name: { kind: 'Name', value: 'limit' },
429-
value: {
430-
kind: 'Variable',
431-
name: { kind: 'Name', value: 'limit' },
432-
},
418+
value: { kind: 'IntValue', value: '10' },
433419
},
434420
{
435421
kind: 'Argument',
@@ -508,22 +494,14 @@ export const Launches_SsrDocument = {
508494
],
509495
} as unknown as DocumentNode<Launches_SsrQuery, Launches_SsrQueryVariables>
510496
export const Launches_RscDocument = {
511-
__meta__: { hash: '616ad65c55a2a69941aff21ec3c1d0964773771f' },
497+
__meta__: { hash: '0192e96f2b35d87a9354448458e417c76a10df21' },
512498
kind: 'Document',
513499
definitions: [
514500
{
515501
kind: 'OperationDefinition',
516502
operation: 'query',
517503
name: { kind: 'Name', value: 'Launches_RSC' },
518504
variableDefinitions: [
519-
{
520-
kind: 'VariableDefinition',
521-
variable: {
522-
kind: 'Variable',
523-
name: { kind: 'Name', value: 'limit' },
524-
},
525-
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
526-
},
527505
{
528506
kind: 'VariableDefinition',
529507
variable: {
@@ -544,10 +522,7 @@ export const Launches_RscDocument = {
544522
{
545523
kind: 'Argument',
546524
name: { kind: 'Name', value: 'limit' },
547-
value: {
548-
kind: 'Variable',
549-
name: { kind: 'Name', value: 'limit' },
550-
},
525+
value: { kind: 'IntValue', value: '10' },
551526
},
552527
{
553528
kind: 'Argument',
@@ -796,22 +771,14 @@ export const LaunchDetailsDocument = {
796771
],
797772
} as unknown as DocumentNode<LaunchDetailsQuery, LaunchDetailsQueryVariables>
798773
export const PageLaunchesDocument = {
799-
__meta__: { hash: '351e381d4b9bbd1da05483d9f533cc48dfcd2777' },
774+
__meta__: { hash: '05081df7e8571aaa7aa52b3a7abbc88857c55a6c' },
800775
kind: 'Document',
801776
definitions: [
802777
{
803778
kind: 'OperationDefinition',
804779
operation: 'query',
805780
name: { kind: 'Name', value: 'PageLaunches' },
806781
variableDefinitions: [
807-
{
808-
kind: 'VariableDefinition',
809-
variable: {
810-
kind: 'Variable',
811-
name: { kind: 'Name', value: 'limit' },
812-
},
813-
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
814-
},
815782
{
816783
kind: 'VariableDefinition',
817784
variable: {
@@ -832,10 +799,7 @@ export const PageLaunchesDocument = {
832799
{
833800
kind: 'Argument',
834801
name: { kind: 'Name', value: 'limit' },
835-
value: {
836-
kind: 'Variable',
837-
name: { kind: 'Name', value: 'limit' },
838-
},
802+
value: { kind: 'IntValue', value: '10' },
839803
},
840804
{
841805
kind: 'Argument',
+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"bb6e5ac452c5d08659b1855799a08ee2543a05ca": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_SSR($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
3-
"616ad65c55a2a69941aff21ec3c1d0964773771f": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_RSC($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
2+
"152c2558141de086b4bd6905725533e9f7949725": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_SSR($offset: Int) { __typename launches(limit: 10, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
3+
"0192e96f2b35d87a9354448458e417c76a10df21": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_RSC($offset: Int) { __typename launches(limit: 10, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
44
"06f997a01891cf62f3b0499580b0d70a0d9658ae": "fragment LaunchSiteFields on Site { __typename details id location { __typename ...SiteLocationFields } name status } fragment SiteLocationFields on Location { __typename latitude longitude name region } query LaunchDetails($id: ID!) { __typename node(id: $id) { __typename ... on Launch { __typename details id image launchDate name rocket { __typename company cost country description } site { __typename ...LaunchSiteFields } } } }",
5-
"351e381d4b9bbd1da05483d9f533cc48dfcd2777": "query PageLaunches($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id name } totalCount } }"
5+
"05081df7e8571aaa7aa52b3a7abbc88857c55a6c": "query PageLaunches($offset: Int) { __typename launches(limit: 10, offset: $offset) { __typename nodes { __typename id name } totalCount } }"
66
}

examples/next/pages/test.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ function Page() {
2626
}
2727

2828
const LaunchesQuery = graphql(`
29-
query PageLaunches($limit: Int, $offset: Int) {
30-
launches(limit: $limit, offset: $offset) {
29+
query PageLaunches($offset: Int) {
30+
launches(limit: 10, offset: $offset) {
3131
nodes {
3232
id
3333
name
@@ -44,7 +44,7 @@ function Launches() {
4444

4545
const [result] = useQuery({
4646
query: LaunchesQuery,
47-
variables: { limit: 10, offset },
47+
variables: { offset },
4848
})
4949

5050
return (
@@ -69,7 +69,7 @@ export async function getServerSideProps() {
6969
exchanges: [cacheExchange, ssrCache, persistedExchange, fetchExchange],
7070
})
7171

72-
await client.query(LaunchesQuery, { limit: 10, offset: 0 }).toPromise()
72+
await client.query(LaunchesQuery, { offset: 0 }).toPromise()
7373

7474
const graphqlState = ssrCache.extractData()
7575

0 commit comments

Comments
 (0)