> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Behavioral WAF

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>The Web Application and API Protection (WAAP) includes a Behavioral WAF policy group that helps prevent malicious attacks on your websites. The policy group contains a set of sophisticated user behavior and reputation analysis policies that inspect traffic and defend your website against threats such as spamming or brute force attacks.</p>

    <Info>
      **Info**

      This policy group is available in the *Pro* and *Enterprise* plans. More details on the [Security pricing page](https://gcore.com/pricing/security#waap).
    </Info>

    ## Configure Behavioral WAF rules

    <p>You can review the Behavioral WAF rules and enable or disable them in the [Gcore Customer Portal](https://portal.gcore.com/accounts/reports/dashboard):</p>

    1. Navigate to **WAAP** > **Default Rules**.

    2. In the domain dropdown at the top of the page, select the needed domain.

    3. Click the **Behavioral WAF** tab to view and adjust the rules.

    <Info>
      **Info**

      Most Behavioral WAF policies are enabled by default, except for **Repeated violations**. To change a policy mode, click the dropdown near that policy.
    </Info>

    ### Probing and forced browsing

    <p>Use CAPTCHA and JavaScript validation to challenge brute-forced requests on random URLs, which might aim to discover your web application's structure and hidden directories. Requests that fail to pass the validation will be blocked.</p>

    ### Obfuscated attacks and zero-day mitigation

    <p>Block clients that perform multiple injection attacks.</p>

    ### Repeated violations

    <p>Present with CAPTCHA or block those clients that failed to answer a previously displayed challenge. Requests that fail to pass the validation will be blocked.</p>

    ### Brute-force protection

    <p>Present users with CAPTCHA when there's an attempt to guess usernames and passwords on web login forms. If the client fails to pass the validation after a few attempts, the request will be blocked.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>The [Policies](/api-reference/waap#policies) endpoints manage the Behavioral WAF policy group ? retrieve the current state of each rule and toggle individual policies on or off. Response examples include only the fields used in each step.</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required, along with the ID of a [WAAP-protected domain](/waap/getting-started/configure-waap-for-a-domain) and the [Python](/developer-tools/sdks/python) or [Go](/developer-tools/sdks/go) SDK installed for SDK examples. This policy group is available on the Pro and Enterprise WAAP plans.
    </Info>

    <p>Set these environment variables before running the examples:</p>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export WAAP_DOMAIN_ID="{YOUR_DOMAIN_ID}"
    ```

    ## View policy states

    <p>Returns the current enabled or disabled state of every Behavioral WAF rule for the domain.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import gcore
        import os

        client = gcore.Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["WAAP_DOMAIN_ID"])

        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        behavioral_set = next(
            rs for rs in rule_sets if rs.resource_slug == "behavioral-waf"
        )
        for rule in behavioral_set.rules:
            status = "enabled" if rule.mode else "disabled"
            print(f"{rule.id}: {rule.name} - {status}")
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
        	"context"
        	"fmt"
        	"os"
        	"strconv"

        	gcore "github.com/G-Core/gcore-go"
        	"github.com/G-Core/gcore-go/option"
        )

        func main() {
        	client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))
        	domainID, _ := strconv.ParseInt(os.Getenv("WAAP_DOMAIN_ID"), 10, 64)

        	ruleSets, err := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
        	if err != nil {
        		fmt.Println(err)
        		return
        	}
        	for _, rs := range *ruleSets {
        		if rs.ResourceSlug == "behavioral-waf" {
        			for _, rule := range rs.Rules {
        				status := "disabled"
        				if rule.Mode {
        					status = "enabled"
        				}
        				fmt.Printf("%s: %s - %s\n", rule.ID, rule.Name, status)
        			}
        		}
        	}
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X GET "https://api.gcore.com/waap/v1/domains/$WAAP_DOMAIN_ID/rule-sets" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        [
          {
            "id": 5,
            "name": "Behavioral WAF",
            "resource_slug": "behavioral-waf",
            "rules": [
              {
                "id": "S3008901",
                "name": "Probing and forced browsing",
                "action": "Block",
                "mode": true
              }
              // ...
            ]
          }
          // ...
        ]
        ```
      </Tab>
    </Tabs>

    <p>The response contains all rule sets for the domain. Filter by `resource_slug` value `behavioral-waf` to find the Behavioral WAF group. Each rule has a `mode` field ? `true` means enabled, `false` means disabled.</p>

    ## Toggle a policy

    <p>Flips the state of one policy ? enabled becomes disabled, disabled becomes enabled. No request body is required.</p>

    | Parameter   | Required | Description                                                                                       |
    | ----------- | -------- | ------------------------------------------------------------------------------------------------- |
    | `policy_id` | Yes      | ID of the policy to toggle, obtained from the [View policy states](#view-policy-states) response. |
    | `domain_id` | Yes      | ID of the WAAP-protected domain.                                                                  |

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import gcore
        import os

        client = gcore.Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["WAAP_DOMAIN_ID"])

        # Find the policy ID by name
        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        behavioral_set = next(
            rs for rs in rule_sets if rs.resource_slug == "behavioral-waf"
        )
        policy = next(r for r in behavioral_set.rules if r.name == "Repeated violations")

        result = client.waap.domains.policies.toggle(policy.id, domain_id=domain_id)
        status = "enabled" if result.mode else "disabled"
        print(f"Policy is now {status}")
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
        	"context"
        	"fmt"
        	"os"
        	"strconv"

        	gcore "github.com/G-Core/gcore-go"
        	"github.com/G-Core/gcore-go/option"
        	"github.com/G-Core/gcore-go/waap"
        )

        func main() {
        	client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))
        	domainID, _ := strconv.ParseInt(os.Getenv("WAAP_DOMAIN_ID"), 10, 64)

        	// Find the policy ID by name
        	ruleSets, err := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
        	if err != nil {
        		fmt.Println(err)
        		return
        	}
        	var policyID string
        	for _, rs := range *ruleSets {
        		if rs.ResourceSlug == "behavioral-waf" {
        			for _, rule := range rs.Rules {
        				if rule.Name == "Repeated violations" {
        					policyID = rule.ID
        				}
        			}
        		}
        	}

        	result, err := client.Waap.Domains.Policies.Toggle(
        		context.Background(),
        		policyID,
        		waap.DomainPolicyToggleParams{DomainID: domainID},
        	)
        	if err != nil {
        		fmt.Println(err)
        		return
        	}
        	status := "disabled"
        	if result.Mode {
        		status = "enabled"
        	}
        	fmt.Printf("Policy is now %s\n", status)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        # Set POLICY_ID to the ID from the View policy states response or the policy reference below
        curl -X PATCH "https://api.gcore.com/waap/v1/domains/$WAAP_DOMAIN_ID/policies/$POLICY_ID/toggle" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {"mode": true}
        ```
      </Tab>
    </Tabs>

    <p>The API returns the updated policy state. Call the endpoint again to flip the policy back.</p>

    ## Policy reference

    <Accordion title="All Behavioral WAF policies">
      The table lists all four policies in the Behavioral WAF group with their default states.

      | Policy                                     | Purpose                                                                                                                        | Default state |
      | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------- |
      | Probing and forced browsing                | Challenges brute-forced requests on random URLs with CAPTCHA and JavaScript validation to block directory enumeration attempts | Enabled       |
      | Obfuscated attacks and zero-day mitigation | Blocks clients that perform multiple injection attacks, including obfuscated and zero-day variants                             | Enabled       |
      | Repeated violations                        | Presents CAPTCHA or blocks clients that previously failed to pass a validation challenge                                       | Disabled      |
      | Brute-force protection                     | Presents CAPTCHA on login credential guessing attempts and blocks the client after repeated failures                           | Enabled       |
    </Accordion>
  </MethodSection>
</MethodSwitch>
