Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could please make a sample file used by coraza wasm on istio-ingressgateway? #211

Open
ericinfra opened this issue Jun 29, 2023 · 7 comments

Comments

@ericinfra
Copy link

I see that the samples are all using coraza wasm through envoyfilter
However, when users access k8s, they will first go through the istio-ingressgateway, and then go to envoy

  1. In actual scenarios, not every pod will deploy sidecar
  2. Handling attack traffic in istio-ingressgateway is better than handling it in envoy

Could you please make a sample file used by coraza wasm on istio-ingressgateway? ThankS

Realize blocking malicious attacks on istio-ingressgateway
Avoid attack traffic to envoy

@M4tteoP

@jcchavezs
Copy link
Member

jcchavezs commented Jun 29, 2023 via email

@M4tteoP
Copy link
Member

M4tteoP commented Jun 29, 2023

Hey, just like stated by @jcchavezs currently there is not an Istio example on this repo. Mainly the point is: the istio-ingressgateway is an Envoy, therefore testing Coraza wasm through envoyfilter is a lower abstraction that should permit to deploy it both in a Istio sidecar or in any other Envoy instance (like an Istio Ingress).
This wasmplugin.yaml should be a valid starting point to deploy the module in a Istio Ingress

@ericinfra
Copy link
Author

e2e has been tested successfully, the specific configuration is as follows:

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: coraza-waf
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://docker.io/erictarrence/universal:coraza-3.0
  imagePullPolicy: IfNotPresent
  phase: AUTHN
  pluginConfig:
    rules:
      - "SecDebugLogLevel 3"
      - "SecRuleEngine On"
      - "SecAuditEngine On"
      - "SecAuditLogParts ABIJDEFHZ"
      - "SecAuditLogType Concurrent"
      - "SecDefaultAction \"phase:3,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:4,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:5,log,auditlog,deny,status:403\""
      - "SecAuditLogRelevantStatus ^(1[0-9]{2}|2[0-9]{2}|3[0-8][0-9]|39[0-9]|40[0-3]|405|5[0-9]{2})$"
      - "Include @crs-setup-demo-conf"
      - "Include crs/*.conf"

The ingressgateway log is as follows:

# kubectl  -n istio-system logs  istio-ingressgateway-6dbdfd9d46-gbpf7 -f
  
2023-07-07T09:23:16.155432Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Found User-Agent associated with security scanner [file "crs/REQUEST-913-SCANNER-DETECTION.conf"] [line "1348"] [id "913100"] [rev ""] [msg "Found User-Agent associated with security scanner"] [data "Matched Data: sqlmap found within MATCHED_VARS:REQUEST_HEADERS:user-agent: sqlmap/1.7.5.4#dev (https://sqlmap.org)"] [severity "critical"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-reputation-scanner"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/118/224/541/310"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.155538Z	warning	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1151	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Host header is a numeric IP address [file "crs/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "2243"] [id "920350"] [rev ""] [msg "Host header is a numeric IP address"] [data "192.168.122.102:31889"] [severity "warning"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156384Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8) [file "crs/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "10773"] [id "949111"] [rev ""] [msg "Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8)"] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156882Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 5). Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0,  [file "crs/RESPONSE-980-CORRELATION.conf"] [line "12628"] [id "980170"] [rev ""] [msg "Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0, "] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "reporting"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
{"start_time": "2023-07-07T09:23:16.155Z","req_method": "GET","x_envoy_original_path": "/productpage","protocol": "HTTP/1.1","response_code": "403","response_flags": "-","bytes_received": "0","bytes_send": "0","duration": "1","resp_x_envoy_upstream_service_time": "-","x_forwarded_for": "192.168.122.1","user_agent": "sqlmap/1.7.5.4#dev (https://sqlmap.org)","x_request_id": "bbc6f649-6f2b-999d-a436-5d0c3dc5d92b","authority": "192.168.122.102:31889","upstream_host": "-","upstream_cluster": "outbound|9080||productpage.default.svc.cluster.local","upstream_local_address": "-","downstream_local_address": "10.110.32.28:8080","downstream_remote_address": "192.168.122.1:60184","resp_x_foo_fault_flag": "-","response_headers": "close","REQ_headers": "-"}

@jcchavezs
Copy link
Member

Awesome @ericinfra! Do you think you can take over the e2e PR and land it into the repo? This would ease debugging of the issues for istio.

@ericinfra
Copy link
Author

Awesome @ericinfra! Do you think you can take over the e2e PR and land it into the repo? This would ease debugging of the issues for istio.

git push encountered some problems, could you modify #80 e2e/istio/wasmplugin.yaml?

@priyanka-operant
Copy link

e2e has been tested successfully, the specific configuration is as follows:

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: coraza-waf
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://docker.io/erictarrence/universal:coraza-3.0
  imagePullPolicy: IfNotPresent
  phase: AUTHN
  pluginConfig:
    rules:
      - "SecDebugLogLevel 3"
      - "SecRuleEngine On"
      - "SecAuditEngine On"
      - "SecAuditLogParts ABIJDEFHZ"
      - "SecAuditLogType Concurrent"
      - "SecDefaultAction \"phase:3,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:4,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:5,log,auditlog,deny,status:403\""
      - "SecAuditLogRelevantStatus ^(1[0-9]{2}|2[0-9]{2}|3[0-8][0-9]|39[0-9]|40[0-3]|405|5[0-9]{2})$"
      - "Include @crs-setup-demo-conf"
      - "Include crs/*.conf"

The ingressgateway log is as follows:

# kubectl  -n istio-system logs  istio-ingressgateway-6dbdfd9d46-gbpf7 -f
  
2023-07-07T09:23:16.155432Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Found User-Agent associated with security scanner [file "crs/REQUEST-913-SCANNER-DETECTION.conf"] [line "1348"] [id "913100"] [rev ""] [msg "Found User-Agent associated with security scanner"] [data "Matched Data: sqlmap found within MATCHED_VARS:REQUEST_HEADERS:user-agent: sqlmap/1.7.5.4#dev (https://sqlmap.org)"] [severity "critical"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-reputation-scanner"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/118/224/541/310"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.155538Z	warning	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1151	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Host header is a numeric IP address [file "crs/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "2243"] [id "920350"] [rev ""] [msg "Host header is a numeric IP address"] [data "192.168.122.102:31889"] [severity "warning"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156384Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8) [file "crs/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "10773"] [id "949111"] [rev ""] [msg "Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8)"] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156882Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 5). Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0,  [file "crs/RESPONSE-980-CORRELATION.conf"] [line "12628"] [id "980170"] [rev ""] [msg "Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0, "] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "reporting"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
{"start_time": "2023-07-07T09:23:16.155Z","req_method": "GET","x_envoy_original_path": "/productpage","protocol": "HTTP/1.1","response_code": "403","response_flags": "-","bytes_received": "0","bytes_send": "0","duration": "1","resp_x_envoy_upstream_service_time": "-","x_forwarded_for": "192.168.122.1","user_agent": "sqlmap/1.7.5.4#dev (https://sqlmap.org)","x_request_id": "bbc6f649-6f2b-999d-a436-5d0c3dc5d92b","authority": "192.168.122.102:31889","upstream_host": "-","upstream_cluster": "outbound|9080||productpage.default.svc.cluster.local","upstream_local_address": "-","downstream_local_address": "10.110.32.28:8080","downstream_remote_address": "192.168.122.1:60184","resp_x_foo_fault_flag": "-","response_headers": "close","REQ_headers": "-"}

Does this config apply to a sidecar as well? I was trying to apply it directly to a httpbin Envoy sidecar with the workload selector being app: httpbin in the app's namespace. But I'm not seeing any logs etc that the plugin is active.

@ericinfra
Copy link
Author

e2e has been tested successfully, the specific configuration is as follows:

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: coraza-waf
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://docker.io/erictarrence/universal:coraza-3.0
  imagePullPolicy: IfNotPresent
  phase: AUTHN
  pluginConfig:
    rules:
      - "SecDebugLogLevel 3"
      - "SecRuleEngine On"
      - "SecAuditEngine On"
      - "SecAuditLogParts ABIJDEFHZ"
      - "SecAuditLogType Concurrent"
      - "SecDefaultAction \"phase:3,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:4,log,auditlog,deny,status:403\""
      - "SecDefaultAction \"phase:5,log,auditlog,deny,status:403\""
      - "SecAuditLogRelevantStatus ^(1[0-9]{2}|2[0-9]{2}|3[0-8][0-9]|39[0-9]|40[0-3]|405|5[0-9]{2})$"
      - "Include @crs-setup-demo-conf"
      - "Include crs/*.conf"

The ingressgateway log is as follows:

# kubectl  -n istio-system logs  istio-ingressgateway-6dbdfd9d46-gbpf7 -f
  
2023-07-07T09:23:16.155432Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Found User-Agent associated with security scanner [file "crs/REQUEST-913-SCANNER-DETECTION.conf"] [line "1348"] [id "913100"] [rev ""] [msg "Found User-Agent associated with security scanner"] [data "Matched Data: sqlmap found within MATCHED_VARS:REQUEST_HEADERS:user-agent: sqlmap/1.7.5.4#dev (https://sqlmap.org)"] [severity "critical"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-reputation-scanner"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/118/224/541/310"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.155538Z	warning	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1151	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Host header is a numeric IP address [file "crs/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "2243"] [id "920350"] [rev ""] [msg "Host header is a numeric IP address"] [data "192.168.122.102:31889"] [severity "warning"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156384Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 1). Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8) [file "crs/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "10773"] [id "949111"] [rev ""] [msg "Inbound Anomaly Score Exceeded in phase 1 (Total Score: 8)"] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
2023-07-07T09:23:16.156882Z	critical	envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1157	wasm log istio-system.coraza-waf: [client "192.168.122.1"] Coraza: Access denied (phase 5). Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0,  [file "crs/RESPONSE-980-CORRELATION.conf"] [line "12628"] [id "980170"] [rev ""] [msg "Anomaly Scores: (Inbound Scores: blocking=8, detection=8, per_pl=8-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0, "] [data ""] [severity "emergency"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "reporting"] [hostname "10.110.32.28"] [uri "/productpage"] [unique_id "NvWxxzQgkoLulvepkVI"]
	thread=33
{"start_time": "2023-07-07T09:23:16.155Z","req_method": "GET","x_envoy_original_path": "/productpage","protocol": "HTTP/1.1","response_code": "403","response_flags": "-","bytes_received": "0","bytes_send": "0","duration": "1","resp_x_envoy_upstream_service_time": "-","x_forwarded_for": "192.168.122.1","user_agent": "sqlmap/1.7.5.4#dev (https://sqlmap.org)","x_request_id": "bbc6f649-6f2b-999d-a436-5d0c3dc5d92b","authority": "192.168.122.102:31889","upstream_host": "-","upstream_cluster": "outbound|9080||productpage.default.svc.cluster.local","upstream_local_address": "-","downstream_local_address": "10.110.32.28:8080","downstream_remote_address": "192.168.122.1:60184","resp_x_foo_fault_flag": "-","response_headers": "close","REQ_headers": "-"}

Does this config apply to a sidecar as well? I was trying to apply it directly to a httpbin Envoy sidecar with the workload selector being app: httpbin in the app's namespace. But I'm not seeing any logs etc that the plugin is active.

sorry,It’s been a long time, the configuration of sidecar envoyfilter is as follows:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: wasm-example
spec:
  configPatches:
  # The first patch defines a named Wasm extension and provides a URL to fetch Wasm binary from,
  # and the binary configuration. It should come before the next patch that applies it.
  # This resource is visible to all proxies in the namespace "myns". It is possible to provide
  # multiple definitions for the same name "my-wasm-extension" in multiple namespaces. We recommend that:
  # - if overriding is desired, then the root level definition can be overriden per namespace with REPLACE.
  # - if overriding is not desired, then the name should be qualified with the namespace "myns/my-wasm-extension",
  #   to avoid accidental name collisions.
  - applyTo: EXTENSION_CONFIG
    patch:
      operation: ADD # REPLACE is also supported, and would override a cluster level resource with the same name.
      value:
        name: my-wasm-extension
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
          config:
            root_id: my-wasm-root-id
            configuration:
              '@type': type.googleapis.com/google.protobuf.StringValue
              value: |
                {
                          "directives_map": {
                              "default": [
                                  "SecDebugLogLevel 3",
                                  "SecRuleEngine On",
                                  "SecAuditEngine On",
                                  "SecAuditLogParts ABIJDEFHZ",
                                  "SecAuditLogType Concurrent", 
                                  "SecDefaultAction \"phase:3,log,auditlog,deny,status:403\"",
                                  "SecDefaultAction \"phase:4,log,auditlog,deny,status:403\"",
                                  "SecDefaultAction \"phase:5,log,auditlog,deny,status:403\"",
                                  "SecAuditLogRelevantStatus ^(1[0-9]{2}|2[0-9]{2}|3[0-8][0-9]|39[0-9]|40[0-3]|405|5[0-9]{2})$",
                                  "Include @crs-setup-demo-conf",
                                  "Include @owasp_crs/*.conf"
                              ]
                          },
                          "default_directives": "default"
                        }
            vm_config:
              vm_id: my-wasm-vm-id
              runtime: envoy.wasm.runtime.v8
              code:
                remote:
                  http_uri:
                    uri: http://192.168.0.101/soft/wasm/main.wasm
  # The second patch instructs to apply the above Wasm filter to the listener/http connection manager.
  - applyTo: HTTP_FILTER
    match:
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
    patch:
      operation: INSERT_BEFORE
      value:
        name: my-wasm-extension # This must match the name above
        config_discovery:
          config_source:
            ads: {}
          type_urls: ["type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants