Back to Research

CVE-2025-62721 - LinkAce Authorization Bypass Allowing Unauthorized Access to All Private Links, Lists, and Tags via RSS Feed Endpoints

November 4, 2025

Author and Researcher

Ravindu Wickramasinghe

Ravindu Wickramasinghe

@rvz

Summary

The authenticated RSS feed endpoints in the FeedController class fail to implement proper authorization checks, allowing any authenticated user to access all links, lists, and tags from all users in the system, regardless of their ownership or visibility settings

Details

The authenticated RSS feed endpoints in the FeedController class fail to implement proper authorization checks, allowing any authenticated user to access all links, lists, and tags from all users in the system, regardless of their ownership or visibility settings. The application uses Laravel's Eloquent ORM to retrieve data but does not apply the visibleForUser() or byUser() scopes that are used elsewhere in the application to enforce access controls.

  • GET /links/feed - Exposes all links from all users
  • GET /lists/feed - Exposes all lists from all users
  • GET /tags/feed - Exposes all tags from all users
  • GET /lists/{list_id}/feed - Exposes all links in any list without visibility check
  • GET /tags/{tag_id}/feed - Exposes all links with any tag without visibility check

The vulnerable code is located in app/Http/Controllers/App/FeedController.php where these five endpoints retrieve data without any filtering:

app/Http/Controllers/App/FeedController.php
// Line 16 - Links feed
public function links(Request $request): Response
{
    $links = Link::latest()->with('user')->get();
    // Returns ALL links from ALL users
}


// Line 32 - Lists feed
public function lists(Request $request): Response
{
    $lists = LinkList::latest()->with('user')->get();
    // Returns ALL lists from ALL users
}

// Line 64 - Tags feed
public function tags(Request $request): Response
{
    $tags = Tag::latest()->with('user')->get();
    // Returns ALL tags from ALL users
}

// Line 48 - List links feed
public function listLinks(Request $request, LinkList $list): Response
{
    $links = $list->links()->with('user')->latest()->get();
    // Returns ALL links in any list without visibility check
}

// Line 80 - Tag links feed
public function tagLinks(Request $request, Tag $tag): Response
{
    $links = $tag->links()->with('user')->latest()->get();
    // Returns ALL links with any tag without visibility check
}

These endpoints are protected by the auth:sanctum middleware (defined in routes/web.php lines 81-87), which only verifies that a user is authenticated but does not enforce any authorization logic to ensure users can only access their own data or data explicitly shared with them. This allows any authenticated user to bypass the application's privacy controls and access sensitive information belonging to other users, including private bookmarks, personal lists, and private tags.

Proof of Concept

Steps to Reproduce

  1. Create two user accounts in LinkAce (User A and User B)
  2. Log in as User A and create several private links with sensitive URLs.
  3. Log in as User B using a separate browser or session
  4. Navigate to the RSS feed URL: http://[your-domain]/links/feed
  5. Observe that the RSS feed contains all links from the system, including User A's private links
  6. Test the other vulnerable endpoints: /lists/feed, /tags/feed, /lists/{id}/feed, /tags/{id}/feed
  7. Verify that all endpoints expose data from all users regardless of ownership or visibility settings

Proof of Concept (Video)

Proof of Concept (Image)

PoC - LinkAce Authorization Bypass Feed Access to Private Links

Recommendations

Implement proper authorization controls by applying the visibleForUser() scope to all data retrieval operations in the FeedController class. This scope is already implemented in the application's ScopesVisibility trait and is used correctly in other controllers. Modify each method in the FeedController to filter data based on the authenticated user's permissions.