elastic / detection-rules

https://www.elastic.co/guide/en/security/current/detection-engine-overview.html
Other
1.92k stars 492 forks source link

[New Rule] Suspicious Okta Cross-Origin Authentication #3769

Open terrancedejesus opened 4 months ago

terrancedejesus commented 4 months ago

Description

Okta released a publication sharing insight into recent upticks in credential stuffing against customers with Customer Identity Cloud. Specifically, the attacks targeted the use of Cross-Origin Authentication, where trusted origin URLs, typically JavaScript apps, are approved for authenticating with Okta APIs.

Required Info

To reproduce, we can leverage a local HTTP server with an index.html containing XMLHttpRequest or Fetch API code to attempt authentication with our Okta dev environment. Specifically crafted requests to the the users API should suffice. We will need to setup the trusted origins in Okta so it accepts request from our local web server.

Example of XMLHttpRequest:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Okta Cross-Origin Test</title>
</head>
<body>
  <h1>Okta Cross-Origin Authentication Test</h1>
  <script>
    var baseUrl = 'okta.domain';  
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
        xhr.onerror = function() {
          alert('Invalid URL or cross-origin request blocked. You must explicitly add this site (' + window.location.origin + ') to the list of allowed websites in the administrator UI');
        }
        xhr.onload = function() {
            if (this.status >= 200 && this.status < 300) {
                alert('Response received: ' + this.responseText);
            } else {
                alert('Request failed. Status: ' + this.status + ', Response: ' + this.responseText);
            }
        };
        xhr.open('GET', baseUrl + '/api/v1/users/me', true);
        xhr.withCredentials = true;
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.setRequestHeader('Accept', 'application/json');
        xhr.send();
    } else {
        alert("CORS is not supported for this browser!");
    }
  </script>
</body>
</html>

Target indexes

Additional requirements

Platforms

Optional Info

There are several queries that we can generate from this emulation. Below are outcome codes that we can focus some of the queries on as well as leveraging either ES|QL or threshold rules for credential stuffing attempts.

Query

TBD

Related issues or PRs

References

terrancedejesus commented 4 months ago

Request is initially failing because Access-Control-Allow-Origin header is missing from the Okta response.

Screenshot 2024-06-10 at 9 21 07 AM

Currently reviewing this blog post for more insight on the API side and nuances with this header. Ideally the expected outcome was a successful response, but it errors when targeting the /api/v1/users/me API.

localhost/:1 Access to XMLHttpRequest at 'https://xxxxx//api/v1/users/me' from origin 'https://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
terrancedejesus commented 4 months ago

Was able to successfully authenticate with local web server. For starters, I pointed to the Okta admin console instead of the actual dev URL. This was fixed. Additionally, I was curious if HTTPS vs HTTP was an issue, therefore, I used mkcert to generate a certificate and use for the following HTTPS server, then started the server and visited the URL and got a response.

const https = require('https');
const fs = require('fs');
const path = require('path');
const express = require('express');

const app = express();

const options = {
  key: fs.readFileSync(path.join(__dirname, 'localhost-key.pem')),
  cert: fs.readFileSync(path.join(__dirname, 'localhost.pem'))
};

app.use(express.static('public'));

https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on https://localhost');
});
Screenshot 2024-06-10 at 11 17 25 AM Screenshot 2024-06-09 at 11 42 48 PM

No System Logs Reporting CORS Authentication

For some reason, we are not receiving system logs in Okta for CORS authentication, or even the API request that leverages CORS for authentication. Likewise, when we were testing and failing, there were no system logs reported.

Screenshot 2024-06-10 at 11 28 08 AM

It looks like the event codes they reference point to Auth0 event logs -> https://auth0.com/docs/deploy-monitor/logs/log-event-type-codes. We do have an Auth0 integration, but my assumption was that this data would be available via Okta.

terrancedejesus commented 4 months ago

As of 06-10-2024, I have begun setting up Auth0 to leverage CORS with the Okta dev environment I have. Once setup, I will re-run tests and point authentication for the app through Okta in hopes to generate this activity.