
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Fri, 10 Apr 2026 12:30:22 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Protecting APIs from abuse using sequence learning and variable order Markov chains]]></title>
            <link>https://blog.cloudflare.com/protecting-apis-from-abuse-using-sequence-learning-and-variable-order-markov/</link>
            <pubDate>Thu, 12 Sep 2024 14:15:00 GMT</pubDate>
            <description><![CDATA[ At Cloudflare, we protect customer APIs from abuse. This is no easy task, as abusive traffic can take different forms, from giant DDoS attacks to low-and-slow credential stuffing campaigns. We now address this challenge in a new way: by looking outside typical volumetric measures and using statistical machine learning to find important API client request sequences. ]]></description>
            <content:encoded><![CDATA[ <p>Consider the case of a malicious actor attempting to inject, <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">scrape</a>, harvest, or <a href="https://www.cloudflare.com/learning/security/what-is-data-exfiltration/">exfiltrate</a> data via an API. Such malicious activities are often characterized by the particular order in which the actor initiates requests to API endpoints. Moreover, the malicious activity is often not readily detectable using volumetric techniques alone, because the actor may intentionally execute API requests slowly, in an attempt to thwart volumetric abuse protection. To reliably prevent such malicious activity, we therefore need to consider the sequential order of API requests. We use the term <b>sequential abuse</b> to refer to malicious API request behavior. Our fundamental goal thus involves distinguishing malicious from benign API request sequences.</p><p>In this blog post, you’ll learn about how we address the challenge of helping customers protect their APIs against sequential abuse. To this end, we’ll unmask the statistical machine learning (ML) techniques currently underpinning our <a href="https://developers.cloudflare.com/api-shield/security/sequence-analytics/"><u>Sequence Analytics</u></a> product. We’ll build on the high-level introduction to Sequence Analytics provided in a <a href="https://blog.cloudflare.com/api-sequence-analytics"><u>previous blog post</u></a>.</p>
    <div>
      <h3>API sessions</h3>
      <a href="#api-sessions">
        
      </a>
    </div>
    <p>Introduced in the previous blog post, let’s consider the idea of a time-ordered series of HTTP API requests initiated by a specific user. These occur as the user interacts with a service, such as while browsing a website or using a mobile app. We refer to the user’s time-ordered series of API requests as a <b>session</b>. Choosing a familiar example, the session for a customer interacting with a banking service might look like:</p><table><thead>
  <tr>
    <th>Time Order</th>
    <th>Method</th>
    <th>Path</th>
    <th>Description</th>
  </tr></thead>
<tbody>
  <tr>
    <td>1</td>
    <td>POST</td>
    <td>/api/v1/auth</td>
    <td>Authenticates a user</td>
  </tr>
  <tr>
    <td>2</td>
    <td>GET</td>
    <td>/api/v1/accounts/{account_id}</td>
    <td>Displays account balance, where account_id is an account belonging to the user</td>
  </tr>
  <tr>
    <td>3</td>
    <td>POST</td>
    <td>/api/v1/transferFunds</td>
    <td>Containing a request body detailing an account to transfer funds from, an account to transfer funds to, and an amount of money to transfer</td>
  </tr>
</tbody>
</table>
<br /><p>One of our aims is to enable our customers to <a href="https://www.cloudflare.com/learning/security/api/what-is-api-security/"><u>secure their APIs</u></a> by automatically suggesting rules applicable to our <a href="https://developers.cloudflare.com/api-shield/security/sequence-mitigation/"><u>Sequence Mitigation</u></a> product for enforcing desired sequential behavior. If we enforce the expected behavior, we can prevent unwanted sequential behavior. In our example, desired sequential behavior might entail that /api/v1/auth must always precede /api/v1/accounts/{account_id}.</p><p>One important challenge we had to address is that the <a href="https://blog.cloudflare.com/api-sequence-analytics"><u>number of possible sessions grows rapidly as the session length increases</u></a>. To see why, we can consider the alternative ways in which a user might interact with the example banking service: The user may, for example, execute multiple transfers, and/or check the balance of multiple accounts, in any order. Assuming that there are 3 possible <b>endpoints</b>, the following graph illustrates possible sessions when the user interacts with the banking service:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5YqgBdzxmu1z2Rm5xiSR6h/ca920cfb0496e476c7af24b066581d2d/image2.png" />
          </figure><p>Because of this large number of possible sessions, suggesting mitigation rules requires that we address the challenge of summarizing sequential behavior from past session data as an intermediate step. We’ll refer to a series of consecutive endpoints in a session (for example /api/v1/accounts/{account_id} → /api/v1/transferFunds) in our example as a <b>sequence</b>. Specifically, a challenge we needed to address is that the sequential behavior relevant for creating rules isn’t necessarily apparent from volume alone: Consider for example that /api/transferFunds might nearly always be preceded by /api/v1/accounts/{account_id}, but also that the sequence /api/v1/accounts/{account_id} → /api/v1/transferFunds might occur relatively rarely, compared to the sequence /api/v1/auth → /api/v1/accounts/{account_id}. It is therefore conceivable that if we were to summarize based on volume alone, we might potentially deem the sequence /api/v1/accounts/{account_id} → /api/v1/transferFunds as unimportant, when in fact we ought to surface it as a potential rule. </p>
    <div>
      <h3>Learning important sequences from API sessions</h3>
      <a href="#learning-important-sequences-from-api-sessions">
        
      </a>
    </div>
    <p>A widely-applied modeling approach applicable to sequential data is the <a href="https://en.wikipedia.org/wiki/Markov_chain"><b><u>Markov chain</u></b></a>, in which the probability of each endpoint in our session data depends only on a fixed number of preceding endpoints. First, we’ll show how standard Markov chains can be applied to our session data, while pointing out some of their limitations. Second, we’ll show how we use a less well-known, but powerful, type of Markov chain to determine important sequences.</p><p>For illustrative purposes, let’s assume that there are 3 possible endpoints in our session data. We’ll represent these endpoints using the letters <i>a</i>, <i>b</i> and <i>c</i>:</p><ul><li><p><i>a</i>: /api/v1/auth</p></li><li><p><i>b</i>: /api/v1/accounts/{account_id}</p></li><li><p><i>c</i>: /api/v1/transferFunds</p></li></ul><p>In its simplest form, a Markov chain is nothing more than a table which tells us the probability of the next letter, given knowledge of the immediately preceding letter. If we were to model past session data using the simplest kind of Markov chain, we might end up with a table like this one:</p><table>
  <tr>
    <td>Known preceding endpoint in the session</td>
    <td>Estimated probability of next endpoint in the session</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr>
<tbody>
  <tr>
    <td>a</td>
    <td>0.10 (1555)</td>
    <td>0.89 (13718)</td>
    <td>0.01 (169)</td>
  </tr>
  <tr>
    <td>b</td>
    <td>0.03 (9618)</td>
    <td>0.63 (205084)</td>
    <td>0.35 (113382)</td>
  </tr>
  <tr>
    <td>c</td>
    <td>0.02 (3340)</td>
    <td>0.67 (109896)</td>
    <td>0.31 (51553)</td>
  </tr>
</tbody>
</table>
<small>Table 1</small>
<br /><p>Table 1 lists the parameters of the Markov chain, namely the estimated probabilities of observing <i>a</i>, <i>b</i> or <i>c</i> as the next endpoint in a session, given knowledge of the immediately preceding endpoint in the session. For example, the 3rd row cell with value 0.67 means that given knowledge of immediately preceding endpoint <i>c</i>, the estimated probability of observing <i>b</i> as the next endpoint in a session is 67%, regardless of whether <i>c </i>was preceded by any endpoints. Thus, each entry in the table corresponds to a sequence of two endpoints. The values in brackets are the number of times we saw each two-endpoint sequence in past session data and are used to compute the probabilities in the table. For example, the value 0.01 is the result of evaluating the fraction 169 / (1555+13718+169). This method of estimating probabilities is known as <a href="https://en.wikipedia.org/wiki/Maximum_likelihood_estimation"><u>maximum likelihood estimation</u></a>.</p><p>To determine important sequences, we rely on <a href="https://en.wikipedia.org/wiki/Credible_interval"><b><u>credible intervals</u></b></a> for estimating probabilities instead of maximum likelihood estimation. Instead of producing a single point estimate (as described above), credible intervals represent a plausible range of probabilities. This range reflects the amount of data available, i.e. the total number of sequence occurrences in each row. More data produces narrower credible intervals (reflecting a greater degree of certainty) and conversely less data produces wider credible intervals (reflecting a lesser degree of certainty). Based on the values in brackets in the table above, we thus might obtain the following credible intervals (entries in boldface will be explained further on):</p><table><thead>
  <tr>
    <td>Known preceding endpoint in the session</td>
    <td>Estimated probability of next endpoint in the session</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr></thead>
<tbody>
  <tr>
    <td>a</td>
    <td><b>0.09-0.11 (1555)</b></td>
    <td><b>0.88-0.89 (13718)</b></td>
    <td><b>0.01-0.01 (169)</b></td>
  </tr>
  <tr>
    <td>b</td>
    <td>0.03-0.03 (9618)</td>
    <td>0.62-0.63 (205084)</td>
    <td>0.34-0.35 (113382)</td>
  </tr>
  <tr>
    <td>c</td>
    <td>0.02-0.02 (3340)</td>
    <td>0.66-0.67 (109896)</td>
    <td>0.31-0.32 (51553)</td>
  </tr>
</tbody>
</table>
<small>Table 2</small>
<br /><p>For brevity, we won’t demonstrate here how to work out the credible intervals by hand (they involve evaluating the <a href="https://en.wikipedia.org/wiki/Quantile_function"><u>quantile function</u></a> of a <a href="https://en.wikipedia.org/wiki/Beta_distribution"><u>beta distribution</u></a>). Notwithstanding, the revised table indicates how more data causes credible intervals to shrink: note the first row with a total of 15442 occurrences in comparison to the second row with a total of 328084 occurrences.</p><p>To determine important sequences, we use slightly more complex Markov chains than those described above. As an intermediate step, let’s first consider the case where each table entry corresponds to a sequence of 3 endpoints (instead of 2 as above), exemplified by the following table:</p><table><thead>
  <tr>
    <td>Known preceding endpoints in the session</td>
    <td>Estimated probability of next endpoint in the session</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr></thead>
<tbody>
  <tr>
    <td>aa</td>
    <td><b>0.09-0.13 (173)</b></td>
    <td><b>0.86-0.90 (1367)</b></td>
    <td><b>0.00-0.02 (13)</b></td>
  </tr>
  <tr>
    <td>ba</td>
    <td><b>0.09-0.11 (940)</b></td>
    <td><b>0.88-0.90 (8552)</b></td>
    <td><b>0.01-0.01 (109)</b></td>
  </tr>
  <tr>
    <td>ca</td>
    <td><b>0.09-0.12 (357)</b></td>
    <td><b>0.87-0.90 (2945)</b></td>
    <td><b>0.01-0.02 (35)</b></td>
  </tr>
  <tr>
    <td>ab</td>
    <td>0.02-0.02 (272)</td>
    <td>0.56-0.58 (7823)</td>
    <td>0.40-0.42 (5604)</td>
  </tr>
  <tr>
    <td>bb</td>
    <td>0.03-0.03 (6067)</td>
    <td>0.60-0.60 (122796)</td>
    <td>0.37-0.37 (75801)</td>
  </tr>
  <tr>
    <td>cb</td>
    <td>0.03-0.03 (3279)</td>
    <td>0.68-0.68 (74449)</td>
    <td>0.29-0.29 (31960)</td>
  </tr>
  <tr>
    <td>ac</td>
    <td>0.01-0.09 (6)</td>
    <td>0.77-0.91 (144)</td>
    <td>0.06-0.19 (19)</td>
  </tr>
  <tr>
    <td>bc</td>
    <td>0.02-0.02 (2326)</td>
    <td>0.77-0.77 (87215)</td>
    <td>0.21-0.21 (23612)</td>
  </tr>
  <tr>
    <td>cc</td>
    <td>0.02-0.02 (1008)</td>
    <td>0.43-0.44 (22527)</td>
    <td>0.54-0.55 (27919)</td>
  </tr>
</tbody></table>
<small>Table 3</small>
<br /><p>Table 3 again lists the estimated probabilities of observing <i>a</i>, <i>b</i> or <i>c</i> as the next endpoint in a session, but given knowledge of 2 immediately preceding endpoints in the session (instead of 1 immediately preceding endpoint as before). That is, the 3rd row cell with interval 0.09-0.13 means that given knowledge of immediately preceding endpoints <i>ca</i>, the probability of observing <i>a</i> as the next endpoint has a credible interval spanning 9% and 13%, regardless of whether <i>ca </i>was preceded by any endpoints. In parlance, we say that the above table represents a Markov chain of <b>order</b> 2. This is because the entries in the table represent probabilities of observing the next endpoint, given knowledge of 2 immediately preceding endpoints as <b>context</b>.</p><p>As a special case, the Markov chain of order 0 simply represents the distribution over endpoints in a session. We can tabulate the probabilities as follows, in relation to a single row corresponding to an ‘empty context’:</p><table><thead>
  <tr>
    <td>Known preceding endpoints in the session</td>
    <td>Estimated probability of next endpoint in the session</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr></thead>
<tbody>
  <tr>
    <td></td>
    <td>0.03-0.03 (15466)</td>
    <td>0.64-0.65 (328732)</td>
    <td>0.32-0.33 (165117)</td>
  </tr>
</tbody>
</table>
<small>Table 4</small>
<br /><p>Note that the probabilities in Table 4 do not solely represent the case where there were no preceding endpoints in the session. Rather, the probabilities are for the occurrence of endpoints in the session, for the general case where we have no knowledge of the preceding endpoints and regardless of how many endpoints previously occurred.    </p><p>Returning to our task of identifying important sequences, one possible approach might be to simply use a Markov chain of some fixed order <i>N</i>. For example, if we were to apply a threshold of 0.85 to the lower bounds of credible intervals in Table 3, we’d retain 3 sequences in total. On the other hand, this approach comes with two noteworthy limitations:</p><ol><li><p>We need a way to select a suitable value for the model order <i>N</i>. </p></li><li><p>Since the model order remains fixed, identified sequences all have the same length <i>N</i>+1.</p></li></ol>
    <div>
      <h3>Variable order Markov chains</h3>
      <a href="#variable-order-markov-chains">
        
      </a>
    </div>
    <p><b>Variable order Markov chains</b> (VOMCs) are a more powerful extension of the described fixed-order Markov chains which address the preceding limitations. VOMCs make use of the fact that for some chosen value of the Markov chain of fixed order <i>N</i>, the probability table might include statistically redundant information: Let’s compare Tables 3 and 2 above and consider in Table 3 the rows in boldface corresponding to contexts <i>aa</i>, <i>ba</i>, <i>ca</i> (these 3 contexts all share <code><i>a</i></code> as their suffix). </p><p>For all the 3 possible next endpoints <i>a, b, c</i>, these rows specify credible intervals which overlap with their respective estimates in Table 2 corresponding to context <i>a</i> (also indicated in boldface). We can interpret these overlapping intervals as representing no discernible difference between probability estimates, given knowledge of <i>a</i> as the preceding endpoint. With no discernible effect of what preceded <i>a </i>on the probability of the next endpoint, we can consider these 3 rows in Table 3 redundant: We may ‘collapse’ them by replacing them with the row in Table 2 corresponding to context <i>a</i>. </p><p>The result of revising Table 3 as described looks as follows (with the new row indicated in boldface):</p><table><thead>
  <tr>
    <td>Known preceding endpoints in the session</td>
    <td>Estimated probability of next endpoint in the session</td>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr></thead>
<tbody>
  <tr>
    <td> a</td>
    <td><b>0.09-0.11 (1555)</b></td>
    <td><b>0.88-0.89 (13718)</b></td>
    <td><b>0.01-0.01 (169)</b></td>
  </tr>
  <tr>
    <td>ab</td>
    <td>0.02-0.02 (272)</td>
    <td>0.56-0.58 (7823)</td>
    <td>0.40-0.42 (5604)</td>
  </tr>
  <tr>
    <td>ac</td>
    <td>0.03-0.03 (6067)</td>
    <td>0.60-0.60 (122796)</td>
    <td>0.37-0.37 (75801)</td>
  </tr>
  <tr>
    <td>bb</td>
    <td>0.03-0.03 (3279)</td>
    <td>0.68-0.68 (74449)</td>
    <td>0.29-0.29 (31960)</td>
  </tr>
  <tr>
    <td>bc</td>
    <td>0.01-0.09 (6)</td>
    <td>0.77-0.91 (144)</td>
    <td>0.06-0.19 (19)</td>
  </tr>
  <tr>
    <td>cb</td>
    <td>0.02-0.02 (2326)</td>
    <td>0.77-0.77 (87215)</td>
    <td>0.21-0.21 (23612)</td>
  </tr>
  <tr>
    <td>cc</td>
    <td>0.02-0.02 (1008)</td>
    <td>0.43-0.44 (22527)</td>
    <td>0.54-0.55 (27919)</td>
  </tr>
</tbody></table>
<small>Table 5</small>
<br /><p>Table 5 represents a VOMC, because the context length varies: In the example, we have context lengths 1 and 2. It follows that entries in the table represent sequences of length varying between 2 and 3 endpoints, depending on context length. Generalizing the described approach of collapsing contexts leads to the following algorithm sketch for learning a VOMC in an offline setting:</p><p><code>(1) Define the table </code><code><i>T</i></code><code> containing the estimated probability of the next endpoint in a session, given alternatively </code><code><i>0, 1, 2, …, N_max</i></code><code> preceding endpoints in the session. That is, form a single table by concatenating the rows corresponding to Markov chains of fixed orders </code><code><i>0, 1, 2, …, N_max</i></code><code>.</code></p><p><code>(2) is_modified := true </code></p><p><code>(3) DO WHILE is_modified</code></p><p><code>   (4) </code><code><i>D</i></code><code> := all contexts in </code><code><i>T </i></code><code>which are not suffixes of at least 1 other      context in </code><code><i>T</i></code></p><p><code>   (5) is_modified = false</code></p><p><code>   (6) FOR </code><code><i>ctx</i></code><code> IN </code><code><i>C</i></code></p><p><code>        (7) IF length(</code><code><i>ctx</i></code><code>) &gt; 0</code></p><p><code>           (8) </code><code><i>parent_ctx</i></code><code> := the context obtained by deleting the leftmost endpoint in </code><code><i>ctx</i></code></p><p><code>           (9) IF is_collapsible(</code><code><i>ctx</i></code><code>, </code><code><i>parent_ctx</i></code><code>)</code></p><p><code>              (10) Modify </code><code><i>T</i></code><code> by discarding </code><code><i>ctx</i></code></p><p><code>              (11) is_modified = true</code></p><p>In the pseudo-code, length(<i>ctx</i>) is the length of context <i>ctx</i>. On line 9, is_collapsible() involves comparing credible intervals for the contexts <i>ctx</i> and <i>parent_ctx</i> in the manner described for generating Table 5: is_collapsible() evaluates to true, if and only if we observe that all credible intervals overlap, when comparing contexts <i>ctx</i> and <i>parent_ctx</i> separately for each of the possible next endpoints. The maximum sequence length is <i>N_max</i>+1<i>, </i>where <i>N_max </i>is some constant. On line 4, we say that context <i>q </i>is a <b>suffix</b> of another context <i>p</i> if we can form <i>p</i> by prepending zero or more endpoints to <i>q</i>. (According to this definition, the ‘empty context’ mentioned above for the order 0 model is a suffix of all contexts in <i>T</i>.) The above algorithm sketch is a variant of the ideas first introduced by Rissanen [<a href="https://ieeexplore.ieee.org/abstract/document/1056741/"><u>1</u></a>], Ron et al. [<a href="https://link.springer.com/article/10.1023/A:1026490906255"><u>2</u></a>].</p><p>Finally, we take the entries in the resulting table <i>T</i> as our important sequences. Thus, the result of applying VOMCs is a set of sequences that we deem important. For Sequence Analytics however, we believe that it is additionally useful to rank sequences. We do this by computing a ‘precedence score’ between 0.0 and 1.0, which is the number of occurrences of the sequence divided by the number of occurrences of the last endpoint in the sequence. Thus, precedence scores close to 1.0 indicate that a given endpoint is nearly always preceded by the remaining endpoints in the sequence. In this way, manual inspection of the highest-scoring sequences is a semi-automated heuristic for creating precedence rules in our Sequence Mitigation product.</p>
    <div>
      <h3>Learning sequences at scale</h3>
      <a href="#learning-sequences-at-scale">
        
      </a>
    </div>
    <p>The preceding represents a very high-level overview of the statistical ML techniques that we use in Sequence Analytics. In practice, we have devised an efficient algorithm which does not require an upfront training step, but rather updates the model continuously as the data arrive and generates a frequently-updating summary of important sequences. This approach allows us to overcome additional challenges around memory cost not touched on in this blog post. Most significantly, a straightforward implementation of the algorithm sketch above would still result in the number of table rows (contexts) exploding with increasing maximum sequence length. A further challenge we had to address is how to ensure that our system is able to deal with high-volume APIs, without adversely impacting CPU load. We use a horizontally scalable adaptive sampling strategy upfront, such that more aggressive sampling is applied to high-volume APIs. Our algorithm then consumes the sampled streams of API requests. After a customer onboards, sequences are assembled and learned over time, so that the current summary of important sequences represents a sliding window with a look-back interval of approximately 24 hours. Sequence Analytics further stores sequences in <a href="https://blog.cloudflare.com/tag/clickhouse/"><u>Clickhouse</u></a> and exposes them via a <a href="https://developers.cloudflare.com/analytics/graphql-api/"><u>GraphQL API</u></a> and via the <a href="https://dash.cloudflare.com/"><u>Cloudflare dashboard</u></a>. Customers who would like to enforce sequence rules can do so using <a href="https://developers.cloudflare.com/api-shield/security/sequence-mitigation/"><u>Sequence Mitigation</u></a>. Sequence Mitigation is what is responsible for ensuring that rules are shared and matched in distributed fashion on Cloudflare’s global network — another exciting topic for a future blog post!</p>
    <div>
      <h3>What’s next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Now that you have a better understanding of how we surface important API request sequences, stay tuned for a future blog post in this series, where we’ll describe how we find the anomalous API request sequences that customers may want to stop. For now, API Gateway customers can get started in two ways: with <a href="https://developers.cloudflare.com/api-shield/security/sequence-analytics/"><u>Sequence Analytics</u></a> to explore important API request sequences and with <a href="https://developers.cloudflare.com/api-shield/security/sequence-mitigation/"><u>Sequence Mitigation</u></a> to enforce sequences of API requests. Enterprise customers that haven’t purchased API Gateway can get started by <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/api-shield"><u>enabling the API Gateway trial</u></a> inside the Cloudflare Dashboard or contacting their account manager.</p> ]]></content:encoded>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[API Shield]]></category>
            <category><![CDATA[API Gateway]]></category>
            <category><![CDATA[API Security]]></category>
            <guid isPermaLink="false">27ZTkLyAI8VPmwUK2U3jU7</guid>
            <dc:creator>Peter Foster</dc:creator>
        </item>
        <item>
            <title><![CDATA[Detecting API abuse automatically using sequence analysis]]></title>
            <link>https://blog.cloudflare.com/api-sequence-analytics/</link>
            <pubDate>Wed, 15 Mar 2023 13:00:00 GMT</pubDate>
            <description><![CDATA[ Today, we're announcing Cloudflare Sequence Analytics for APIs. Using Sequence Analytics, Customers subscribed to API Gateway can view the most important sequences of API requests to their endpoints ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ZIGEKXxAHQjkdhTmJIlI7/88561d87ef5b611280c21d6ca2cf3c5a/image1-26.png" />
            
            </figure><p>Today, we're announcing Cloudflare Sequence Analytics for APIs. Using Sequence Analytics, Customers subscribed to <a href="https://developers.cloudflare.com/api-shield/">API Gateway</a> can view the most important sequences of API requests to their endpoints. This new feature helps customers to <a href="https://www.cloudflare.com/learning/security/api/what-is-an-api-gateway/">apply protection</a> to the most important endpoints first.</p><p>What is a sequence? It is simply a time-ordered list of HTTP API requests made by a specific visitor as they browse a website, use a mobile app, or interact with a B2B partner via API. For example, a portion of a sequence made during a bank funds transfer could look like:</p>
<table>
<thead>
  <tr>
    <th><span>Order</span></th>
    <th><span>Method</span></th>
    <th><span>Path</span></th>
    <th><span>Description</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>1</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/users/{user_id}/accounts</span></td>
    <td><span>user_id is the active user</span></td>
  </tr>
  <tr>
    <td><span>2</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/accounts/{account_id}/balance</span></td>
    <td><span>account_id is one of the user’s accounts</span></td>
  </tr>
  <tr>
    <td><span>3</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/accounts/{account_id}/balance</span></td>
    <td><span>account_id is a different account belonging to the user</span></td>
  </tr>
  <tr>
    <td><span>4</span></td>
    <td><span>POST</span></td>
    <td><span>/api/v1/transferFunds</span></td>
    <td><span>Containing a request body detailing an account to transfer funds from, an account to transfer funds to, and an amount of money to transfer</span></td>
  </tr>
</tbody>
</table><p>Why is it important to pay attention to sequences for API security? If the above API received requests for POST /api/v1/transferFunds without any of the prior requests, it would seem suspicious. Think about it: how would the API client know what the relevant account IDs are without listing them for the user? How would the API client know how much money is available to transfer? While this example may be obvious, the sheer number of API requests to any given production API can make it hard for human analysts to spot suspicious usage.</p><p>In security, one approach to defending against an untold number of threats that are impossible to screen by a team of humans is to create a <i>positive security model</i>. Instead of trying to block everything that could potentially be a threat, you allow all known good or benign traffic and block everything else by default.</p><p>Customers could already create positive security models with <a href="https://www.cloudflare.com/application-services/products/api-gateway/">API Gateway</a> in two main areas: <a href="https://developers.cloudflare.com/api-shield/security/volumetric-abuse-detection/">volumetric abuse protection</a> and <a href="https://developers.cloudflare.com/api-shield/security/schema-validation/">schema validation</a>. Sequences will form the third pillar of a positive security model for API traffic. API Gateway will be able to enforce the precedence of endpoints in any given API sequence. By establishing precedence within an API sequence, API Gateway will log or block any traffic that doesn’t match expectations, reducing abusive traffic.</p>
    <div>
      <h3>Detecting abuse by sequence</h3>
      <a href="#detecting-abuse-by-sequence">
        
      </a>
    </div>
    <p>When attackers attempt to exfiltrate data in an abusive way, they rarely follow the patterns of expected API traffic. Attacks often use special software to <a href="https://owasp.org/www-community/Fuzzing">‘fuzz’</a> the API, sending several requests with different request parameters hoping to find unexpected responses from the API indicating opportunities to exfiltrate data. Attackers can also manually send requests to APIs that attempt to trick the API in performing unauthorized actions, like granting an attacker elevated privileges or access to data through a <a href="https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa1-broken-object-level-authorization.md">Broken Object Level Authentication attack</a>. Protecting APIs with rate limits is a common best practice; however, in both of the above examples attackers may deliberately execute request sequences slowly, in an attempt to thwart volumetric abuse detection.</p><p>Think of the sequence of requests above again, but this time imagine an attacker copying the legitimate funds transfer request and modifying the request payload in an attempt to trick the system:</p>
<table>
<thead>
  <tr>
    <th><span>Order</span></th>
    <th><span>Method</span></th>
    <th><span>Path</span></th>
    <th><span>Description</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>1</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/users/{user_id}/accounts</span></td>
    <td><span>user_id is the active user</span></td>
  </tr>
  <tr>
    <td><span>2</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/accounts/{account_id}/balance</span></td>
    <td><span>account_id is one of the user’s accounts</span></td>
  </tr>
  <tr>
    <td><span>3</span></td>
    <td><span>GET</span></td>
    <td><span>/api/v1/accounts/{account_id}/balance</span></td>
    <td><span>account_id is a different account belonging to the user</span></td>
  </tr>
  <tr>
    <td><span>4</span></td>
    <td><span>POST</span></td>
    <td><span>/api/v1/transferFunds</span></td>
    <td><span>Containing a request body detailing an account to transfer funds from, an account to transfer funds to, and an amount of money to transfer</span></td>
  </tr>
  <tr>
    <td><span>… attacker copies the request to a debugging tool like Postman …</span></td>
  </tr>
  <tr>
    <td><span>5</span></td>
    <td><span>POST</span></td>
    <td><span>/api/v1/transferFunds</span></td>
    <td><span>Attacker has modified the POST body to try and trick the API</span></td>
  </tr>
  <tr>
    <td><span>6</span></td>
    <td><span>POST</span></td>
    <td><span>/api/v1/transferFunds</span></td>
    <td><span>A further modified POST body to try and trick the API</span></td>
  </tr>
  <tr>
    <td><span>7</span></td>
    <td><span>POST</span></td>
    <td><span>/api/v1/transferFunds</span></td>
    <td><span>Another</span><span>, further modified POST body to try and trick the API</span></td>
  </tr>
</tbody>
</table><p>If the customer knew beforehand that the funds transfer endpoint was critical to protect and only occurred once during a sequence, they could write a rule to ensure that it was never called twice in a row and a GET /balance always preceded a POST /transferFunds. But without prior knowledge of which endpoint sequences are critical to protect, how would the customer know which rules to define? A low rate limit is too risky, since an API user might legitimately have a few funds transfer requests to perform in a short amount of time. In the present reality there are few tools to prevent this type of abuse, and most customers are left with reactive efforts to clean up abuse with their application teams and fraud departments after it’s happened.</p><p>Ultimately, we believe that providing our customers with the ability to define positive security models on API request sequences requires a three-pronged approach:</p><ol><li><p><b>Sequence Analytics</b>: Determining which sequences of API requests occurred and when, as well as summarizing the data into readily understandable form.</p></li><li><p><b>Sequence Abuse Detection</b>: Identifying which sequences of API requests are likely of benign or malicious origin.</p></li><li><p><b>Sequence Mitigation:</b> Identifying relevant rules on sequences of API requests for deciding which traffic to allow or block.</p></li></ol>
    <div>
      <h3>Challenges of sequence creation</h3>
      <a href="#challenges-of-sequence-creation">
        
      </a>
    </div>
    <p>Sequence Analytics presents some difficult technical challenges, because sessions may be long-lived and may consist of many requests. As a result, it is not sufficient to define sequences by session identifier alone. Instead, it was necessary for us to develop a solution capable of automatically identifying multiple sequences which occur within a given session. Additionally, since important sequences are not necessarily characterized by volume alone and the set of possible sequences is large, it was necessary to develop a solution capable of identifying <i>important</i> sequences, as opposed to simply surfacing <i>frequent</i> sequences.</p><p>To help illustrate these challenges for the example of api.cloudflare.com, we can group API requests by session and plot the number of distinct sequences versus sequence length:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3AJLBVYJl3ApceVT8ubl7v/995a6548852547fb31e6e9d6a5c4b917/unnamed-1.png" />
            
            </figure><p>The plot is based on a one hour snapshot comprising approximately 88,000 sessions and 260 million API requests, with 301 distinct API endpoints. We process the data by applying a fixed-length sliding window to each session, then we count the total number of different fixed-length sequences (‘n-grams’) that we observe as a result of applying the sliding window. The plot displays results for a window size (‘n-gram length’) varying between 1 and 10 requests. The number of distinct sequences ranges from 301 (for a window size of 1 request) to approximately 780,000 (for a window size of 10 requests). Based on the plot, we observe a large number of possible sequences which grows with sequence length: As we increase the sliding window size, we see an increasingly large amount of different sequences in the sample. The smooth trend can be explained by the fact that we apply a sliding window (sessions may themselves contain many sequences) in combination with many long sessions relative to the sequence length.</p><p>Given the large number of possible sequences, trying to find abusive sequences is a ‘needles in a haystack’ situation.</p>
    <div>
      <h3>Introducing Sequence Analytics</h3>
      <a href="#introducing-sequence-analytics">
        
      </a>
    </div>
    <p>Here is a screenshot from the API Gateway dashboard highlighting Sequence Analytics:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/XNYHZ4fxireN81jqHtCs5/401355249971c341845feed2f68445a0/image2-14.png" />
            
            </figure><p>Let’s break down the new functionality seen in the screenshot.</p><p>API Gateway intelligently determines sequences of requests made by your API consumers using the methods described earlier in this article. API Gateway scores sequences by a metric we call Correlation Score. Sequence Analytics displays the top 20 sequences by highest correlation score, and we refer to these as your most important sequences. High-importance sequences contain API requests which are likely to occur together in order.</p><p>You should inspect each of your sequences to understand their correlation scores. High correlation score sequences may consist of rarely used endpoints (potentially anomalous user behavior) as well as commonly used endpoints (likely benign user behavior). Since the endpoints found in these sequences commonly occur together, they represent true usage patterns of your API. You should apply all possible API Gateway protections to these endpoints (<a href="https://developers.cloudflare.com/api-shield/security/volumetric-abuse-detection/">rate limiting suggestions</a>, <a href="https://developers.cloudflare.com/api-shield/security/schema-validation/">Schema Validation</a>, <a href="https://developers.cloudflare.com/api-shield/security/jwt-validation/">JWT Validation</a>, and <a href="https://developers.cloudflare.com/api-shield/security/mtls/">mTLS</a>) and check their specific endpoint order with your development team.</p><p>We know customers want to explicitly set allowable behavior on their APIs beyond the active protections offered by API Gateway today. Coming soon, we’re releasing sequence precedence rules and enabling the ability to block requests based on those rules. The new sequence precedence rules will allow customers to specify the exact order of allowable API requests, bringing yet another way of establishing a positive security model to <a href="https://www.cloudflare.com/application-services/solutions/api-security/">protect your API against unknown threats</a>.</p>
    <div>
      <h3>How to get started</h3>
      <a href="#how-to-get-started">
        
      </a>
    </div>
    <p>All API Gateway customers now have access to Sequence Analytics. Navigate to a zone in the Cloudflare dashboard, then click the Security tab &gt; API Gateway tab &gt; Sequences tab. You’ll see the most important sequences that your API consumers request.</p><p>Enterprise customers that haven’t purchased API Gateway can get started by <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/api-shield">enabling the API Gateway trial</a> inside the Cloudflare Dashboard or contacting their account manager.</p>
    <div>
      <h3>What’s next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Sequence-based detection is a powerful and unique capability that unlocks many new opportunities to identify and stop attacks. As we fine-tune the methods of identifying these sequences and shipping them to our global network, we will release custom sequence matching and real-time mitigation features at a future date. We will also ensure you have the actionable intelligence to take back to your team on who the API users were that attempted to request sequences that don’t match your policy.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[API Shield]]></category>
            <category><![CDATA[API Gateway]]></category>
            <category><![CDATA[API Security]]></category>
            <category><![CDATA[AI]]></category>
            <guid isPermaLink="false">1BliBrtxZ4mEP2GAGJ02Qn</guid>
            <dc:creator>John Cosgrove</dc:creator>
            <dc:creator>Peter Foster</dc:creator>
        </item>
    </channel>
</rss>