Skip to main content

Invalid user agent and Unknown user agent

These two WAAP policies work together to identify and block requests that lack a standard user-agent parameter. If the agent is missing, this can indicate that an illegitimate client is being used.

Most browsers provide user agent information across the network to validate a client's authenticity and purpose. User agent strings typically follow this syntax:

User-Agent: <product> / <product-version> <comment>

Where:

  • <product>: A product identifier — its name or development codename.
  • <product-version>: Version number of the product.
  • <comment>: Comments containing additional details — sub-product information.

Both policies are part of the Anti-automation and bot protection group and are enabled by default. To change the state of a policy, navigate to the CDB Technical Web Portal:

  1. Navigate to WAAP > Bot Management.
  2. In the domain dropdown at the top right of the page, select the domain.
  3. Open the Bot Attacks tab.
  4. Find the Invalid user agent or Unknown user agent policy and click the dropdown next to it to enable or disable it.

The Policies endpoints manage the Invalid user agent and Unknown user agent rules. Both policies are enabled by default and belong to the Anti-automation and bot protection ruleset. Response examples include only the fields used in each step.

An API token is required, along with the ID of a WAAP-protected domain and the Python or Go SDK installed for SDK examples.

export GCORE_API_KEY="{YOUR_API_KEY}"
export WAAP_DOMAIN_ID="{YOUR_DOMAIN_ID}"

View policy states

Retrieve the current state of the Invalid user agent and Unknown user agent policies for a domain.

import gcore
import os

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

TARGET_NAMES = {"Invalid user agent", "Unknown user agent"}

rule_sets = client.waap.domains.list_rule_sets(domain_id)
aa_set = next(
    rs for rs in rule_sets if rs.resource_slug == "anti-automation-bot-protection"
)

rules = client.waap.domains.policies.list(domain_id, rule_set_id=aa_set.id)
for policy in rules:
    if policy.name in TARGET_NAMES:
        status = "enabled" if policy.mode else "disabled"
        print(f"{policy.name}: &#123;status&#125; ({policy.id})")
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)

    targetNames := map[string]bool&#123;"Invalid user agent": true, "Unknown user agent": true&#125;

    ruleSets := client.Waap.Domains.ListRuleSetsAutoPaging(context.Background(), domainID, waap.DomainListRuleSetsParams{})
    for ruleSets.Next() {
        rs := ruleSets.Current()
        if rs.ResourceSlug == "anti-automation-bot-protection" {
            policies := client.Waap.Domains.Policies.ListAutoPaging(context.Background(), domainID, waap.DomainPolicyListParams{RuleSetID: gcore.Int(rs.ID)})
            for policies.Next() {
                policy := policies.Current()
                if targetNames[policy.Name] {
                    status := "disabled"
                    if policy.Mode {
                        status = "enabled"
                    }
                    fmt.Printf("%s: %s (%s)\n", policy.Name, status, policy.ID)
                }
            }
        }
    }
}
curl -X GET "https://api.cdb-staging.cdn.orange.com/waap/v1/domains/${WAAP_DOMAIN_ID}/rule-sets" \
  -H "Authorization: APIKey ${GCORE_API_KEY}" \
  | jq '[.[] | select(.resource_slug == "anti-automation-bot-protection") | .rules[] | select(.name == "Invalid user agent" or .name == "Unknown user agent") | {name, id, mode}]'

The response lists both policies with their current state. mode: true means enabled; mode: false means disabled. The id value is unique to the domain:

[
  &#123;
    "name": "Invalid user agent",
    "id": "S3008869",
    "mode": false
    // ...
  &#125;
  // ...
]

Enable or disable a policy

Sets the policy to enabled or disabled by specifying the target state. Use the policy ID returned by the View policy states request.

ParameterRequiredDescription
policy_idYesID of the policy to configure.
domain_idYesID of the WAAP-protected domain.
modeYestrue to enable the policy, false to disable it.
import gcore
import os

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

# Find the policy ID by name
rule_sets = client.waap.domains.list_rule_sets(domain_id)
aa_set = next(
    rs for rs in rule_sets if rs.resource_slug == "anti-automation-bot-protection"
)
rules = client.waap.domains.policies.list(domain_id, rule_set_id=aa_set.id)
policy = next(r for r in rules if r.name == "Invalid user agent")

result = client.waap.domains.policies.update(policy.id, domain_id=domain_id, mode=True)
print(f"Invalid user agent is now {'enabled' if result.mode else 'disabled'}")
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.ListRuleSetsAutoPaging(context.Background(), domainID, waap.DomainListRuleSetsParams{})
    var policyID string
    for ruleSets.Next() {
        rs := ruleSets.Current()
        if rs.ResourceSlug == "anti-automation-bot-protection" {
            policies := client.Waap.Domains.Policies.ListAutoPaging(context.Background(), domainID, waap.DomainPolicyListParams{RuleSetID: gcore.Int(rs.ID)})
            for policies.Next() {
                p := policies.Current()
                if p.Name == "Invalid user agent" {
                    policyID = p.ID
                }
            }
        }
    }

    result, _ := client.Waap.Domains.Policies.Update(context.Background(), policyID, waap.DomainPolicyUpdateParams{DomainID: domainID, WaapDomainPolicySettings: waap.WaapDomainPolicySettingsParam{Mode: true}})
    status := "disabled"
    if result.Mode {
        status = "enabled"
    }
    fmt.Printf("Invalid user agent is now %s\n", status)
}
# Set POLICY_ID to the id from the View policy states response
export POLICY_ID="{POLICY_ID}"

curl -X PATCH "https://api.cdb-staging.cdn.orange.com/waap/v1/domains/${WAAP_DOMAIN_ID}/policies/${POLICY_ID}" \
  -H "Authorization: APIKey ${GCORE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '&#123;"mode": true&#125;'

The API returns the updated policy state. mode: true confirms enabled; mode: false confirms disabled:

&#123;"mode": true&#125;

Policy reference

PolicyDescriptionActionDefault
Invalid user agentBlocks requests from user agents known to be associated with malicious activity.BlockEnabled
Unknown user agentApplies a transparent JavaScript-based browser check to requests from unrecognized user agents.HandshakeEnabled

Both policies belong to the Anti-automation and bot protection ruleset, which includes six additional policies for managing automated and bot traffic.