Skip to content

Commit 6a63b38

Browse files
committed
API: Prevented non-GET requests when using cookie-based auth
Added test to cover.
1 parent ff59bbd commit 6a63b38

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

app/Http/Middleware/ApiAuthenticate.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ApiAuthenticate
1717
public function handle(Request $request, Closure $next)
1818
{
1919
// Validate the token and it's users API access
20-
$this->ensureAuthorizedBySessionOrToken();
20+
$this->ensureAuthorizedBySessionOrToken($request);
2121

2222
return $next($request);
2323
}
@@ -28,15 +28,21 @@ public function handle(Request $request, Closure $next)
2828
*
2929
* @throws ApiAuthException
3030
*/
31-
protected function ensureAuthorizedBySessionOrToken(): void
31+
protected function ensureAuthorizedBySessionOrToken(Request $request): void
3232
{
3333
// Return if the user is already found to be signed in via session-based auth.
34-
// This is to make it easy to browser the API via browser after just logging into the system.
34+
// This is to make it easy to browse the API via browser when exploring endpoints via the UI.
3535
if (!user()->isGuest() || session()->isStarted()) {
36+
// Ensure the user has API access permission
3637
if (!$this->sessionUserHasApiAccess()) {
3738
throw new ApiAuthException(trans('errors.api_user_no_api_permission'), 403);
3839
}
3940

41+
// Only allow GET requests for cookie-based API usage
42+
if ($request->method() !== 'GET') {
43+
throw new ApiAuthException(trans('errors.api_cookie_auth_only_get'), 403);
44+
}
45+
4046
return;
4147
}
4248

lang/en/errors.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
'api_incorrect_token_secret' => 'The secret provided for the given used API token is incorrect',
126126
'api_user_no_api_permission' => 'The owner of the used API token does not have permission to make API calls',
127127
'api_user_token_expired' => 'The authorization token used has expired',
128+
'api_cookie_auth_only_get' => 'Only GET requests are allowed when using the API with cookie-based authentication',
128129

129130
// Settings & Maintenance
130131
'maintenance_test_email_failure' => 'Error thrown when sending a test email:',

tests/Api/ApiAuthTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,27 @@ public function test_access_prevented_for_guest_users_with_api_permission_while_
112112
$resp->assertStatus(200);
113113
}
114114

115+
public function test_only_get_requests_are_supported_with_session_auth()
116+
{
117+
$user = $this->users->admin();
118+
$this->actingAs($user, 'standard');
119+
120+
$uriByMethods = [
121+
'POST' => '/books',
122+
'PUT' => '/books/1',
123+
'DELETE' => '/books/1',
124+
'HEAD' => '/books',
125+
];
126+
127+
foreach ($uriByMethods as $method => $uri) {
128+
$resp = $this->withCredentials()->json($method, "/api{$uri}");
129+
$resp->assertStatus(403);
130+
if ($method !== 'HEAD') {
131+
$resp->assertJson($this->errorResponse('Only GET requests are allowed when using the API with cookie-based authentication', 403));
132+
}
133+
}
134+
}
135+
115136
public function test_token_expiry_checked()
116137
{
117138
$editor = $this->users->editor();

0 commit comments

Comments
 (0)