{"id":75621,"date":"2025-09-08T13:39:41","date_gmt":"2025-09-08T08:09:41","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=75621"},"modified":"2025-09-11T10:08:50","modified_gmt":"2025-09-11T04:38:50","slug":"securing-aem-as-a-cloud-service-with-traffic-filter-and-waf-rules","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/securing-aem-as-a-cloud-service-with-traffic-filter-and-waf-rules\/","title":{"rendered":"Securing AEM as a Cloud Service with Traffic Filter and WAF Rules"},"content":{"rendered":"<p>In recent times, threats to web applications have become increasingly common, including Denial of Service (DoS), Distributed Denial of Service (DDoS), malicious traffic, such as bots, injection attacks, and the misuse of system resources. These threats, if successful, can lead to downtime, data breaches, and degraded user experience. And this is where AEM as a Cloud Service steps in, with built-in traffic filtering and WAF rules, to secure applications while ensuring optimal performance.<\/p>\n<p>In this blog, we will cover traffic filter rules and a subcategory of those rules known as WAF (Web Application Firewall) traffic filter rules, or simply WAF rules. We will also discuss the syntax for writing these rules and share a few examples.<\/p>\n<p>Before diving into the syntax and examples, let\u2019s first explore where we write these rules and how and where we deploy them.<\/p>\n<h2>Rule Configuration and Deployment<\/h2>\n<p>So, using Cloud Manager\u2019s config pipelines, these traffic rules are deployed to the Adobe managed CDN. They can be deployed on dev, stage and production environments. We need to create a Config pipeline that will deploy the traffic rules.<\/p>\n<ol>\n<li>In the Cloud Manager, go to the Pipelines section.\n<p><div id=\"attachment_75623\" style=\"width: 98px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75623\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-75623 size-medium\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_19-88x300.png\" alt=\"piplines\" width=\"88\" height=\"300\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_19-88x300.png 88w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_19.png 273w\" sizes=\"(max-width: 88px) 100vw, 88px\" \/><p id=\"caption-attachment-75623\" class=\"wp-caption-text\">Piplines Menu<\/p><\/div><\/li>\n<li>On the right corner, you\u2019ll see Add Pipeline.\n<p><div id=\"attachment_75626\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75626\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-75626 size-medium\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-300x150.png\" alt=\"add pipeline\" width=\"300\" height=\"150\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-300x150.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image.png 590w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-75626\" class=\"wp-caption-text\">Add Pipeline<\/p><\/div><\/li>\n<li>Select Add Non-Production Pipeline.\n<p><div id=\"attachment_75627\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75627\" decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-75627\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-1-300x133.png\" alt=\"Non-production Pipeline\" width=\"300\" height=\"133\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-1-300x133.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-1.png 568w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-75627\" class=\"wp-caption-text\">Non-production Pipeline<\/p><\/div><\/li>\n<li>Now, configure the details as mentioned in the screenshot<br \/>\n<table style=\"border-collapse: collapse; width: 100%; height: 340px;\">\n<tbody>\n<tr style=\"height: 325px;\">\n<td style=\"width: 50%; height: 325px;\">\n<p><div id=\"attachment_75629\" style=\"width: 307px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75629\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-75629\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_14-300x269.png\" alt=\"Pipeline Config Section 1\" width=\"297\" height=\"266\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_14-300x269.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_14-768x689.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_14-624x560.png 624w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_14.png 801w\" sizes=\"(max-width: 297px) 100vw, 297px\" \/><p id=\"caption-attachment-75629\" class=\"wp-caption-text\">Pipeline Config Section 1<\/p><\/div><\/td>\n<td style=\"width: 50%; height: 325px;\">\n<p><div id=\"attachment_75628\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75628\" decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-75628\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_15-300x270.png\" alt=\"config Section 2\" width=\"300\" height=\"270\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_15-300x270.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_15-768x692.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_15-624x562.png 624w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_15.png 796w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-75628\" class=\"wp-caption-text\">Pipeline Config Section 2<\/p><\/div><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<\/ol>\n<h2>Syntax<\/h2>\n<p>The syntax for traffic rules goes like this,<\/p>\n<pre>  kind: \"CDN\"\r\n  version: \"1\"\r\n  metadata:\r\n  envTypes: [\"dev\"]\r\n  Data: &lt;traffic-filter-rules&gt;<\/pre>\n<p>These Traffic Rules are usually written <strong>cdn.yaml<\/strong> file in the <strong>config<\/strong> folder in the codebase, this is at the root level. If the configuration for all environments is same, then only one file should be enough. Else, environment-specific folder or environment-specific cdn.yaml(for eg. cdn-stg.yaml) files can be created.<\/p>\n<div id=\"attachment_75682\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75682\" decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-75682\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_21-300x107.png\" alt=\"Common cdn.yaml for all environments\" width=\"300\" height=\"107\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_21-300x107.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_21.png 432w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-75682\" class=\"wp-caption-text\">Common cdn.yaml for all environments<\/p><\/div>\n<div id=\"attachment_75683\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75683\" decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-75683\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_22-300x169.png\" alt=\"Environment-specific Folders\" width=\"300\" height=\"169\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_22-300x169.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_22.png 432w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-75683\" class=\"wp-caption-text\">Environment-specific Folders<\/p><\/div>\n<p>A traffic rules YAML file is made up of four main fields,<\/p>\n<ul>\n<li><strong>kind<\/strong>: identifies the type of configuration; for traffic rules, this is always set to CDN.<\/li>\n<li><strong>version<\/strong>: specifies the configuration format version; AEM currently supports only 1.<\/li>\n<li><strong>metadata<\/strong>: provides additional context, such as the environment the rules are written for, helping keep configurations organized.<\/li>\n<li><strong>data<\/strong>: the main section where the traffic filter rules are defined, covering both standard and WAF rules.<\/li>\n<\/ul>\n<h3>Defining Rules in the <em><span style=\"color: #808080;\">data<\/span><\/em> Section<\/h3>\n<p>As mentioned above, the data field maintains all the traffic filter rules, which can be based on the URL, hostname, geolocation, IPs, request headers, etc. Following is an example of blocking a particular path in the author or publish environment. In the example below, the user tried to access faqs.html, but it returned <span style=\"color: #808080;\"><em>Error 406 Not Acceptable,<\/em><\/span> which is expected after writing the traffic rule.<br \/>\n<strong>Example for Standard Traffic Filter Rules,<\/strong><\/p>\n<pre>\u00a0 kind: \"CDN\"\r\n\u00a0 version: \"1\"\r\n\u00a0 metadata:\r\n\u00a0 \u00a0 envTypes: [\"dev\"]\r\n\u00a0 data:\r\n\u00a0 \u00a0 trafficFilters:\r\n\u00a0 \u00a0 \u00a0 rules:\r\n\u00a0 \u00a0 \u00a0 \u00a0 - name: \"block-path\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 when:\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 allOf:\r\n\u00a0 - reqProperty: tier\u00a0\r\n\u00a0 \u00a0 equals: \u201cauthor|publish\u201d\u00a0\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 - reqProperty: path\r\n\u00a0 \u00a0 equals: \u201c\/content\/wknd\/us\/en\/faqs.html\u201d\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 action:\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 type: block<\/pre>\n<div id=\"attachment_75686\" style=\"width: 969px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75686\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-75686 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_16.png\" alt=\"error page\" width=\"959\" height=\"433\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_16.png 959w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_16-300x135.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_16-768x347.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/Screenshot_16-624x282.png 624w\" sizes=\"(max-width: 959px) 100vw, 959px\" \/><p id=\"caption-attachment-75686\" class=\"wp-caption-text\">Error Message<\/p><\/div>\n<p><em>(Note: We will look at each field in the later section of this blog.)<\/em><\/p>\n<p>If you have licensed the Enhanced Security or WAF-DDoS Protection Security, you can configure a sub category of traffic filter rules named as WAF rules, which consumes one or more WAF flags.<br \/>\nExample for WAF Rules,<\/p>\n<pre>\u00a0 kind: \"CDN\"\r\n\u00a0 version: \"1\"\r\n\u00a0 metadata:\r\n\u00a0 \u00a0 envTypes: [\"dev\"]\r\n\u00a0 data:\r\n\u00a0 \u00a0 trafficFilters:\r\n\u00a0 \u00a0 \u00a0 rules:\r\n\u00a0 \u00a0 \u00a0 \u00a0 - name: \"WAF-rule-for-XSS-and-SQL-Injection\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 when: \r\n\u00a0 - reqProperty: path \r\n\u00a0 \u00a0 like: \"*\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 action:\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 type: block\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 wafFlags: [ XSS, SQLI]<\/pre>\n<h4>Breaking Down the <span style=\"color: #808080;\"><em>data<\/em> <\/span>Section<\/h4>\n<p>Inside the data field of the cdn.yaml, you\u2019ll find <strong>trafficFilters<\/strong>, which contains the <strong>rules<\/strong> section. This is where all traffic filter rules are written. Each rule is made up of a few key fields:<\/p>\n<ol>\n<li><strong>name<\/strong> \u2013 A unique identifier for the rule. It must be alphanumeric, can include hyphens, and should not exceed 64 characters.<\/li>\n<li><strong>when<\/strong> \u2013 Defines the condition(s) under which the rule is applied.\n<ul>\n<li>Use <strong>allOf<\/strong> if all conditions must be true.<\/li>\n<li>Use <strong>anyOf<\/strong> if only one condition needs to be true.<\/li>\n<li>For a single condition, you can skip both.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h4>Writing Conditions with <span style=\"color: #808080;\"><em>when<\/em><\/span><\/h4>\n<p>A condition has two parts: a getter (what to check) and a predicate (how to evaluate it).<br \/>\n<strong>Syntax for single condition:<\/strong><\/p>\n<pre>\u00a0 when:\r\n\u00a0 \u00a0 - &lt;getter&gt;: &lt;value&gt;\r\n  \u00a0 \u00a0 &lt;predicate&gt;: &lt;value&gt;<\/pre>\n<p><strong>Multiple conditions:<\/strong><\/p>\n<pre>\u00a0 when:\r\n\u00a0 \u00a0 allOf:\r\n\u00a0 \u00a0 \u00a0 - &lt;getter&gt;: &lt;value&gt;\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;predicate&gt;: &lt;value&gt;\r\n\u00a0 \u00a0 \u00a0 - &lt;getter&gt;: &lt;value&gt;\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;predicate&gt;: &lt;value&gt;<\/pre>\n<h4>Getters and Predicates<\/h4>\n<ul>\n<li>Getters tell the rule what part of the request to inspect, such as:\n<ul style=\"list-style-type: circle;\">\n<li>reqProperty =&gt; path, URL, query string, method, client IP, region, country<\/li>\n<li>reqHeader, queryParam, reqCookie, postParam =&gt; request headers, query parameters, cookies, or POST data<\/li>\n<\/ul>\n<\/li>\n<li>Predicates define how the value should be checked:\n<ul style=\"list-style-type: circle;\">\n<li>equals, doesNotEqual =&gt; direct comparison<\/li>\n<li>like, matches =&gt; pattern or regex matching<\/li>\n<li>in, notIn =&gt; list membership<\/li>\n<li>exists =&gt;\u00a0 property presence<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>The <span style=\"color: #808080;\"><em>action<\/em> <\/span>Field<\/h3>\n<p>The <strong>action<\/strong> field defines what happens when a condition is met. Options include:<\/p>\n<ul>\n<li><strong>Allow<\/strong> &#8211; Lets the request pass through if it matches the rule.<\/li>\n<li><strong>Block<\/strong> &#8211; Denies the request completely. This is commonly used when dealing with malicious traffic, suspicious patterns, or specific wafFlags.<\/li>\n<li><strong>Log<\/strong> &#8211; It records the request details for monitoring without blocking or allowing.<\/li>\n<li>Or a combination of these with wafFlags for advanced filtering.<\/li>\n<\/ul>\n<h3>Using <em><span style=\"color: #808080;\">wafFlags<\/span><\/em><\/h3>\n<p>If you have Enhanced Security or WAF-DDoS Protection enabled, you can use wafFlags to block specific threats, such as:<\/p>\n<ul>\n<li>XSS (Cross-Site Scripting)<\/li>\n<li>SQLI (SQL Injection)<\/li>\n<li>BAD-IP, BACKDOOR, CVE exploits<\/li>\n<li>MALFORMED-DATA, JSON-ERROR, XML-ERROR<\/li>\n<\/ul>\n<p>These are just a few examples; there are more in the list.<\/p>\n<p><strong>Example: WAF Rule<\/strong><\/p>\n<pre>\u00a0 kind: \"CDN\"\r\n\u00a0 version: \"1\"\r\n\u00a0 metadata:\r\n\u00a0 \u00a0 envTypes: [\"dev\"]\r\n\u00a0 data:\r\n\u00a0 \u00a0 trafficFilters:\r\n\u00a0 \u00a0 \u00a0 rules:\r\n\u00a0 \u00a0 \u00a0 \u00a0 - name: \"WAF-rule-for-XSS-and-SQL-Injection\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 when: \r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 - reqProperty: path \r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 like: \"*\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 action:\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 type: block\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 wafFlags: [XSS, SQLI]<\/pre>\n<p>With traffic filter rules and WAF rules, <a href=\"https:\/\/www.tothenew.com\/aem-development-consulting\"><strong>AEM as a Cloud Service<\/strong><\/a> empowers you to stop harmful requests before they reach your application. A well-structured cdn.yaml not only strengthens security but also ensures a smooth, uninterrupted experience for your users. Start applying these rules today to strengthen your AEM Cloud security.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In recent times, threats to web applications have become increasingly common, including Denial of Service (DoS), Distributed Denial of Service (DDoS), malicious traffic, such as bots, injection attacks, and the misuse of system resources. These threats, if successful, can lead to downtime, data breaches, and degraded user experience. And this is where AEM as a [&hellip;]<\/p>\n","protected":false},"author":1383,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":97},"categories":[5868],"tags":[4847,7759,2645,8108,8079,8080],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75621"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1383"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=75621"}],"version-history":[{"count":12,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75621\/revisions"}],"predecessor-version":[{"id":76315,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75621\/revisions\/76315"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=75621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=75621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=75621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}