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

# Protocol validation

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 protocol validation policy group verifies the HTTP and HTTPS protocols used by clients to request content from your website's origin server. If the request meets the protocol-specific requirements, the transaction is allowed, while all non-compliant transactions are blocked. </p>

    <Info>
      **Info**

      Bot Management, which includes 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 protocol validation rules

    <p>You can review and configure protocol validation rules in the [Gcore Customer Portal](https://portal.gcore.com/accounts/reports/dashboard): </p>

    <p>1. Navigate to **WAAP** > **Bot Management**. </p>

    <p>2. In the domain dropdown at the top of the page, select the needed domain.</p>

    <p>3. The **Bot Attacks** tab contains the **Service protocol validation** and **Prevent malformed request methods** policies.</p>

    <Info>
      Service protocol validation is enabled by default. Prevent malformed request methods is disabled by default. To change the policy mode, click the **Mode** dropdown and select **Protection** or **Disabled**.
    </Info>

    ### Service protocol validation

    <p>Block clients that try to interfere with the service's internal calls, such as tampering with cookies or request headers. </p>

    ### Prevent malformed request methods

    <p>Enforce HTTP RFC requirements that define how the client is supposed to interact with the server. If the requests don't meet the RFC standards, the client will be challenged with CAPTCHA or JavaScript validation. Clients that fail to pass the validation will be blocked.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>The [Policies](/api-reference/waap#policies) endpoints manage Protocol Validation rules — blocking HTTP requests that violate protocol standards. 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. Bot Management, which includes this policy group, is available on the Pro and Enterprise WAAP plans.
    </Info>

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

    <Info>
      Protocol Validation policies are stored under the `advanced-api-protection` resource group. Filter rule sets by `resource_slug` value `advanced-api-protection`, then select Service protocol validation and Prevent malformed request methods by name.
    </Info>

    ## View policy states

    <p>Retrieve the current mode of the Protocol Validation policies for a domain.</p>

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

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

        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        adv_set = next(
            rs for rs in rule_sets if rs.resource_slug == "advanced-api-protection"
        )

        protocol_names = {"Service protocol validation", "Prevent malformed request methods"}
        for policy in adv_set.rules:
            if policy.name in protocol_names:
                status = "enabled" if policy.mode else "disabled"
                print(f"{policy.name}: {status} ({policy.id})")
        ```
      </Tab>

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

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

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

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

            protocolNames := map[string]bool{"Service protocol validation": true, "Prevent malformed request methods": true}

            ruleSets, _ := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
            for _, rs := range *ruleSets {
                if rs.ResourceSlug == "advanced-api-protection" {
                    for _, policy := range rs.Rules {
                        if protocolNames[policy.Name] {
                            status := "disabled"
                            if policy.Mode {
                                status = "enabled"
                            }
                            fmt.Printf("%s: %s (%s)\n", policy.Name, status, policy.ID)
                        }
                    }
                }
            }
        }
        ```
      </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}" \
          | jq '.[] | select(.resource_slug == "advanced-api-protection") | .rules[] | select(.name == "Service protocol validation" or .name == "Prevent malformed request methods") | {name, id, mode}'
        ```
      </Tab>
    </Tabs>

    <p>The response includes each policy with its ID and current state. `mode: true` means enabled; `mode: false` means disabled.</p>

    ## Enable or disable a policy

    <p>Use the policy ID returned by the [View policy states](#view-policy-states) request.</p>

    | Parameter   | Required | Description                                         |
    | ----------- | -------- | --------------------------------------------------- |
    | `policy_id` | Yes      | ID of the policy to configure.                      |
    | `domain_id` | Yes      | ID of the WAAP-protected domain.                    |
    | `mode`      | Yes      | `true` to enable the policy, `false` to disable it. |

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

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

        # Find the policy ID by name
        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        adv_set = next(
            rs for rs in rule_sets if rs.resource_slug == "advanced-api-protection"
        )
        policy = next(r for r in adv_set.rules if r.name == "Service protocol validation")

        result = client.waap.domains.policies.toggle(policy.id, domain_id=domain_id, mode=True)
        print(f"Service protocol validation is now {'enabled' if result.mode else 'disabled'}")
        ```
      </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/waap"
        )

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

            // Find the policy ID by name
            ruleSets, _ := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
            var policyID string
            for _, rs := range *ruleSets {
                if rs.ResourceSlug == "advanced-api-protection" {
                    for _, p := range rs.Rules {
                        if p.Name == "Service protocol validation" {
                            policyID = p.ID
                        }
                    }
                }
            }

            result, _ := client.Waap.Domains.Policies.Toggle(context.Background(), policyID, waap.DomainPolicyToggleParams{DomainID: domainID, WaapDomainPolicySettings: waap.WaapDomainPolicySettingsParam{Mode: true}})
            status := "disabled"
            if result.Mode {
                status = "enabled"
            }
            fmt.Printf("Service protocol validation is now %s\n", status)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        # Set POLICY_ID to the id from the View policy states response
        export POLICY_ID="{POLICY_ID}"

        curl -X PATCH "https://api.gcore.com/waap/v1/domains/${WAAP_DOMAIN_ID}/policies/${POLICY_ID}" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"mode": true}'
        ```
      </Tab>
    </Tabs>

    <p>The API returns the updated policy object. `mode: true` confirms the policy is now enabled; `mode: false` confirms disabled.</p>

    ## Policy reference

    <Accordion title="All Protocol Validation policies">
      The table lists both policies in the Protocol Validation group with their default states.

      | Policy                            | Purpose                                                                                                             | Default state |
      | --------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------- |
      | Service protocol validation       | Blocks clients that attempt to tamper with internal service calls, such as manipulating cookies or request headers. | Enabled       |
      | Prevent malformed request methods | Blocks or challenges clients whose requests do not conform to HTTP RFC standards.                                   | Disabled      |
    </Accordion>
  </MethodSection>
</MethodSwitch>
