Skip to content

Commit 882381a

Browse files
authored
Add caution around endpoint security (#146)
Adds an important caution that client-side `/api/` endpoints need to be protected, and updates advice in client fetch snippet.
1 parent 8844a68 commit 882381a

6 files changed

Lines changed: 36 additions & 24 deletions

File tree

docs/capabilities/http-fetch.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ console.log('External API response:', data);
7676
Client-side fetch has different restrictions:
7777

7878
- **Domain limitation**: Can only make requests to your own webview domain
79-
- **Endpoint requirement**: All requests must target endpoints that start with /api
79+
- **Endpoint requirement**: All requests must target endpoints that start with /api/
8080
- **Authentication**: Handled automatically \- no need to manage auth tokens
8181
- **No external domains**: Cannot make requests to external domains from client-side code
8282
client/index.ts
8383

8484
```
8585
8686
const handleFetchData = async () => {
87-
// Correct: fetching your own webview's API endpoint
87+
// Correct: Fetching your own webview's API endpoint
8888
const response = await fetch("/api/user-data", {
8989
method: "GET",
9090
headers: {
@@ -96,10 +96,10 @@ const handleFetchData = async () => {
9696
console.log("API response:", data);
9797
};
9898
99-
// Incorrect: cannot fetch external domains from client-side
99+
// Incorrect: Cannot fetch external domains from client-side
100100
// const response = await fetch('https://external-api.com/data');
101101
102-
// Incorrect: endpoint must start with /api
102+
// Incorrect: Endpoint must start with /api/
103103
// const response = await fetch('/user-data');
104104
```
105105

docs/capabilities/server/http-fetch.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,17 @@ Client-side fetch has different restrictions and can only make requests to your
7070
**Client-side restrictions:**
7171

7272
- **Domain limitation**: Can only make requests to your own webview domain
73-
- **Endpoint requirement**: All requests must target endpoints that end with `/api`
73+
- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/`
7474
- **Authentication**: Handled automatically - no need to manage auth tokens
7575
- **No external domains**: Cannot make requests to external domains from client-side code
7676

77+
:::caution
78+
Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review.
79+
:::
80+
7781
```tsx title="client/index.ts"
7882
const handleFetchData = async () => {
79-
// Correct: fetching your own webview's API endpoint
83+
// Correct: Fetching your own webview's API endpoint
8084
const response = await fetch("/api/user-data", {
8185
method: "GET",
8286
headers: {
@@ -88,10 +92,10 @@ const handleFetchData = async () => {
8892
console.log("API response:", data);
8993
};
9094
91-
// Incorrect: cannot fetch external domains from client-side
95+
// Incorrect: Cannot fetch external domains from client-side
9296
// const response = await fetch('https://external-api.com/data');
9397
94-
// Incorrect: endpoint must end with /api
98+
// Incorrect: Endpoint must start with /api/
9599
// const response = await fetch('/user-data');
96100
```
97101

versioned_docs/version-0.12/capabilities/http-fetch.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ console.log('External API response:', data);
7676
Client-side fetch has different restrictions:
7777

7878
- **Domain limitation**: Can only make requests to your own webview domain
79-
- **Endpoint requirement**: All requests must target endpoints that start with /api
79+
- **Endpoint requirement**: All requests must target endpoints that start with /api/
8080
- **Authentication**: Handled automatically \- no need to manage auth tokens
8181
- **No external domains**: Cannot make requests to external domains from client-side code
8282
client/index.ts
8383

8484
```
8585
8686
const handleFetchData = async () => {
87-
// Correct: fetching your own webview's API endpoint
87+
// Correct: Fetching your own webview's API endpoint
8888
const response = await fetch("/api/user-data", {
8989
method: "GET",
9090
headers: {
@@ -96,10 +96,10 @@ const handleFetchData = async () => {
9696
console.log("API response:", data);
9797
};
9898
99-
// Incorrect: cannot fetch external domains from client-side
99+
// Incorrect: Cannot fetch external domains from client-side
100100
// const response = await fetch('https://external-api.com/data');
101101
102-
// Incorrect: endpoint must start with /api
102+
// Incorrect: Endpoint must start with /api/
103103
// const response = await fetch('/user-data');
104104
```
105105

versioned_docs/version-0.12/capabilities/server/http-fetch.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,17 @@ Client-side fetch has different restrictions and can only make requests to your
7070
**Client-side restrictions:**
7171

7272
- **Domain limitation**: Can only make requests to your own webview domain
73-
- **Endpoint requirement**: All requests must target endpoints that end with `/api`
73+
- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/`
7474
- **Authentication**: Handled automatically - no need to manage auth tokens
7575
- **No external domains**: Cannot make requests to external domains from client-side code
7676

77+
:::caution
78+
Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review.
79+
:::
80+
7781
```tsx title="client/index.ts"
7882
const handleFetchData = async () => {
79-
// Correct: fetching your own webview's API endpoint
83+
// Correct: Fetching your own webview's API endpoint
8084
const response = await fetch("/api/user-data", {
8185
method: "GET",
8286
headers: {
@@ -88,10 +92,10 @@ const handleFetchData = async () => {
8892
console.log("API response:", data);
8993
};
9094
91-
// Incorrect: cannot fetch external domains from client-side
95+
// Incorrect: Cannot fetch external domains from client-side
9296
// const response = await fetch('https://external-api.com/data');
9397
94-
// Incorrect: endpoint must end with /api
98+
// Incorrect: Endpoint must start with /api/
9599
// const response = await fetch('/user-data');
96100
```
97101

versioned_docs/version-0.13/capabilities/http-fetch.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ console.log('External API response:', data);
7676
Client-side fetch has different restrictions:
7777

7878
- **Domain limitation**: Can only make requests to your own webview domain
79-
- **Endpoint requirement**: All requests must target endpoints that start with /api
79+
- **Endpoint requirement**: All requests must target endpoints that start with /api/
8080
- **Authentication**: Handled automatically \- no need to manage auth tokens
8181
- **No external domains**: Cannot make requests to external domains from client-side code
8282
client/index.ts
8383

8484
```
8585
8686
const handleFetchData = async () => {
87-
// Correct: fetching your own webview's API endpoint
87+
// Correct: Fetching your own webview's API endpoint
8888
const response = await fetch("/api/user-data", {
8989
method: "GET",
9090
headers: {
@@ -96,10 +96,10 @@ const handleFetchData = async () => {
9696
console.log("API response:", data);
9797
};
9898
99-
// Incorrect: cannot fetch external domains from client-side
99+
// Incorrect: Cannot fetch external domains from client-side
100100
// const response = await fetch('https://external-api.com/data');
101101
102-
// Incorrect: endpoint must start with /api
102+
// Incorrect: Endpoint must start with /api/
103103
// const response = await fetch('/user-data');
104104
```
105105

versioned_docs/version-0.13/capabilities/server/http-fetch.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,17 @@ Client-side fetch has different restrictions and can only make requests to your
7070
**Client-side restrictions:**
7171

7272
- **Domain limitation**: Can only make requests to your own webview domain
73-
- **Endpoint requirement**: All requests must target endpoints that end with `/api`
73+
- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/`
7474
- **Authentication**: Handled automatically - no need to manage auth tokens
7575
- **No external domains**: Cannot make requests to external domains from client-side code
7676

77+
:::caution
78+
Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review.
79+
:::
80+
7781
```tsx title="client/index.ts"
7882
const handleFetchData = async () => {
79-
// Correct: fetching your own webview's API endpoint
83+
// Correct: Fetching your own webview's API endpoint
8084
const response = await fetch("/api/user-data", {
8185
method: "GET",
8286
headers: {
@@ -88,10 +92,10 @@ const handleFetchData = async () => {
8892
console.log("API response:", data);
8993
};
9094
91-
// Incorrect: cannot fetch external domains from client-side
95+
// Incorrect: Cannot fetch external domains from client-side
9296
// const response = await fetch('https://external-api.com/data');
9397
94-
// Incorrect: endpoint must end with /api
98+
// Incorrect: Endpoint must start with /api/
9599
// const response = await fetch('/user-data');
96100
```
97101

0 commit comments

Comments
 (0)