Skip to content

Commit 12dd906

Browse files
committed
nits
1 parent c61bfc0 commit 12dd906

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

src/pages/learn/file-uploads.mdx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,49 @@ environments, these solutions often introduce complexity, fragility, and securit
1818

1919
### Memory exhaustion from repeated variables
2020

21-
GraphQL operations allow the same variable to be referenced multiple times. If a file upload variable is used more than
22-
once, its stream may be consumed multiple times—or worse, not at all. This can lead to unpredictable behavior or denial of service (DoS).
21+
GraphQL operations allow the same variable to be referenced multiple times. If a file upload variable is reused, the underlying
22+
stream may be read multiple times or prematurely drained. This can result in incorrect behavior or memory exhaustion.
23+
24+
A safe practice is to use trusted documents or a validation rule to ensure each upload variable is referenced exactly once.
2325

2426
### Stream leaks on failed operations
2527

26-
GraphQL executes in phases: validation, then execution. If an error occurs during validation or authorization, your
27-
server might never reach the resolver that consumes a file stream. If file streams are left unconsumed, memory usage can
28-
spike, potentially exhausting server resources.
28+
GraphQL executes in phases: validation, then execution. If validation fails or an authorization check blocks execution, uploaded
29+
file streams may never be consumed. If your server buffers or retains these streams, it can cause memory leaks.
30+
31+
To avoid this, consider writing incoming files to temporary storage immediately, and passing references (like filenames) into
32+
resolvers. Ensure this storage is cleaned up after request completion, regardless of success or failure.
2933

3034
### Cross-Site Request Forgery (CSRF)
3135

32-
`multipart/form-data` is classified as a “simple” request by CORS and does not trigger preflight checks. Without strict CSRF
33-
protections, malicious sites may be able to upload files on behalf of unsuspecting users.
36+
`multipart/form-data` is classified as a “simple” request in the CORS spec and does not trigger a preflight check. Without
37+
explicit CSRF protection, your GraphQL server may unknowingly accept uploads from malicious origins.
3438

3539
### Oversized or excess payloads
3640

37-
Attackers can upload arbitrarily large files or extra files not referenced in the GraphQL operation. If your server accepts and
38-
buffers these files in memory, you may face reliability issues or be vulnerable to resource exhaustion.
41+
Attackers may submit very large uploads or include extraneous files under unused variable names. Servers that accept and
42+
buffer these can be overwhelmed.
43+
44+
Enforce request size caps and reject any files not explicitly referenced in the map field of the multipart payload.
3945

4046
### Untrusted file metadata
4147

42-
Uploaded file names, MIME types, and even contents are arbitrary and should be treated as untrusted input. Failing to sanitize
43-
file names can lead to path traversal vulnerabilities. Assuming a file’s MIME type is safe can lead to parsing exploits.
48+
Information such as file names, MIME types, and contents should never be trusted. To mitigate risk:
49+
50+
- Sanitize filenames to prevent path traversal or injection issues.
51+
- Sniff file types independently of declared MIME types, and reject mismatches.
52+
- Validate file contents. Be aware of format-specific exploits like zip bombs or maliciously crafted PDFs.
4453

4554
## Recommendation: Use signed URLs
4655

47-
The most secure and scalable approach is to **avoid uploading files through GraphQL entirely**. Instead:
56+
The most secure and scalable approach is to avoid uploading files through GraphQL entirely. Instead:
4857

4958
1. Use a GraphQL mutation to request a signed upload URL from your storage provider (e.g., Amazon S3).
5059
2. Upload the file directly from the client using that URL.
5160
3. Submit a second mutation to associate the uploaded file with your application’s data.
5261

53-
This approach isolates the file upload concern to infrastructure purpose-built for it, while keeping GraphQL focused on structured data.
62+
This separates responsibilities cleanly, protects your server from binary data handling, and aligns with best practices for
63+
modern web architecture.
5464

5565
## If you still choose to support uploads
5666

0 commit comments

Comments
 (0)