CSRF required even with API key
Current Behavior
In a frontend (browser) application, POST https://pterodactyl.file.properties/api/client/servers/1a7ce997/schedules/2 to activate/deactivate a schedule. Include a valid API key in the headers.
returns a 419 status with "CSRF token mismatch."
Expected Behavior
The API call should be successfull.
A CSRF threat exists when the authentication validation is based on a cookie; a 3rd party website can POST to the API with the browser automatically sending the (authentication) cookie details. If authentication validation is based on a header (API key), this is not automatically injected by the browser and cannot be used by a 3rd party website to piggyback onto.
Steps to Reproduce
In a frontend (browser) application, POST https://pterodactyl.file.properties/api/client/servers/1a7ce997/schedules/2 to activate/deactivate a schedule. Include a valid API key in the headers.
Doing this through CURL or Postman is not a valid test as it doesn't inject the Origin header which a browser should always send.
Panel Version
1.11.3
Wings Version
1.11.0
Games and/or Eggs Affected
Not relevant
Docker Image
Not relevant
Error Logs
Request:
POST /api/client/servers/8a16850b/schedules/284 HTTP/1.1
Accept: Application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl;q=0.8
Authorization: Bearer <removed>
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 108
Content-Type: application/json
Host: <removed>
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Body:
{
"name": "Restart",
"minute": "30",
"hour": "05,11,17,23",
"day_of_month": "*",
"day_of_week": "*",
"is_active": false
}
Response:
{
"errors": [
{
"code": "HttpException",
"status": "419",
"detail": "CSRF token mismatch."
}
]
}
Is there an existing issue for this?
- [X] I have searched the existing issues before opening this issue.
- [X] I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server.
- [X] I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system.
I'm here for the same issue. I'm testing the API using the JaSON extension for Chrome and have the same result with the /api/client/servers/XXXXX/command endpoint. This is on a new install with the built-in Source Engine nest.
Just encountered the same Issue accessing the endpoint /api/application/servers. Received error 419 Page Expired, even with an Application API Key. A current workaround I use is clearing the Cookies. Edit: Forgot the Panel Version. (1.11.3)
yes i have the same issues, i use postman { "errors": [ { "code": "HttpException", "status": "419", "detail": "CSRF token mismatch.",
i have a fix but this is dangerous i think, just a simple fix to change the verifycsrftoken.php middleware to just continue working even the csrf token mixmatching
CSRF tokens are an important security feature. However, if you're using an auth token in the API call the CSRF token should not be required. CSRF happens on an embedded form in a webpage; if they have your auth token you're already lost anyway.
Yeah, same error here, I was thinking about this middleware but its seens so insecure.
Someone have suggestion to fix that?
We Appreciate! <3
Fixed in:
#4837
Is there any way to use the API without building this fork??
I face the same issue when trying requests to the client's endpoint. Changing the "VerifyCsrfToken.php" has worked around the problem, but I can't keep it that way, as it would pose a security vulnerability. Is there any way to work around this issue without compromising the application's security?
I've tried running it via Postman and using cURL, and it always returns the "Page expired" error.