waf
87 TopicsFile Uploads and ASM
File Uploads through a WAF Let’s say we have a web application with a form field that permits the upload of arbitrary files. It would appear to the user similar to the below: Aside from photos, the application may permit users to upload Word documents, Excel spreadsheets, PDF’s, and so forth. This can cause many false positives when the web application is protected by ASM, because the uploaded files may: Contain attack signatures. Image files may be parsed as ASCII, and suspicious-looking strings detected; Word or Excel documents may contain XSS tags or SQL injection strings. After all, Mr. ‘Select’ – ‘Union City’ -- is one of our most valuable customers. Contain illegal metacharacters, like XSS tags <> Be so large that the maximum request size (10MB by default) is exceeded Trip other violations It is therefore necessary to inform ASM that a particular parameter on a form field is one that contains a file upload so that checking for attack signatures and metacharacters can be disabled. Why not just disable the signature? Simply, because we do not want to introduce unnecessary exposure into the security policy. Just because a particular signature causes a false positive on the file upload transaction does not mean it should do elsewhere on the web application. At the time of writing, ASM permits attack signatures to be selectively disabled on parameters, but not URLs. Identify the Upload Parameter(s) Use a HTTP inspection tool such as Fiddler, Burp or Developer Tools to determine the name of the upload parameter and URL. In this case, we are uploading a JPG file named DSCF8205.JPG; the parameter used to transfer the file is called ‘filename1’. The URL is /foo.cfm. NOTE: This can also be obtained from the ASM request log; however these do sometimes get truncated making it impossible to determine the parameter name if it occurs more than 5KB into the request. Define the Upload Parameter(s) Assuming the upload is specific to a given URL, create that URL in the ASM policy. Next, create a parameter with the name we discovered earlier, and ensure it is set to type ‘File Upload’. Alternate Configuration Options If file upload is possible in many parts of the site using the same filename, create the parameter globally without defining the URL as we did first here If many file upload parameters are present on a single page with a similar name (e.g. filename1, filename2, filename3…), create a wildcard parameter name filename* ‘Disallow file upload of executables’ is a desirable feature. It checks the magic number of the uploaded file and blocks the upload if it indicates an executable file. As with all ASM configurations, understanding the HTTP fields passed to the application is key The above procedure should work for most cases, and arbitrary file uploads (except executables) should be allowed. However, there are some cases where additional configuration is required. Didn’t Work? Attack signatures have a defined scope, as seen below: Table C.1Attack signature keywords and usage Keyword Usage content Match in the full content. SeeUsing the content rule option, for syntax information. uricontent Match in the URI, including the query string (unless using theobjonlymodifier). SeeUsing the uricontent rule option, for syntax information. headercontent Match in the HTTP headers. SeeUsing the headercontent rule option, for syntax information. valuecontent Matches an alpha-numeric user-input parameter (or an extra-normalizedparameter, if using thenormmodifier); used for parameter values and XML objects. SeeUsing the valuecontent rule option, for syntax information, andScope modifiers for the pcre rule option, for more information on scope modifiers. An XML payload is checked for attack signatures when thevaluecontentkeyword is used in the signature. Note:Thevaluecontentparameter replaces theparamcontentparameter that was used in the Application Security Manager versions earlier than 10.0. reference Provides an external link to documentation and other information for the rule. SeeUsing the reference rule option, for syntax information. This information can be found in ASM under “Attack Signatures List”. As an example, search for ‘Path Traversal’ attack types and expand signature id’s 200007006 and 200007000: A signature with a ‘Request’ scope does not pay any attention to parameter extraction – it just performs a bitwise comparison of the signature to the entire request as a big flat hex blob. So to prevent this signature from being triggered, we can (a) disable it, (b) use an iRule to disable it on these specific requests. Before we can use iRules on an ASM policy, we need to switch on the ‘Trigger ASM iRule Events’ setting on the main policy configuration page. Further information can be found at: https://techdocs.f5.com/kb/en-us/products/big-ip_asm/manuals/product/asm-implementations-11-5-0/27.html. The below is an iRule that will prevent a request meeting the following characteristics from raising an ASM violation: Is a POST URI ends with /foo.cfm Content-Type is ‘multipart/form-data’ Attack Signature violation raised with signature ID 200007000 when ASM_REQUEST_VIOLATION { if {([HTTP::method] equals "POST") and ([string tolower [HTTP::path]] ends_with "/foo.cfm") and ([string tolower [HTTP::header "Content-Type"]] contains "multipart/form-data") } { if {([lindex [ASM::violation_data] 0] contains "VIOLATION_ATTACK_SIGNATURE_DETECTED") and ([ASM::violation details] contains "sig_data.sig_id 200007000") } { ASM::unblock } } } What if you’re getting a lot of false positives and just want to disable attack signatures with Request scope? when ASM_REQUEST_VIOLATION { if {([HTTP::method] equals "POST") and ([string tolower [HTTP::path]] ends_with "/foo.cfm") and ([string tolower [HTTP::header "Content-Type"]] contains "multipart/form-data") } { if {([lindex [ASM::violation_data] 0] contains "VIOLATION_ATTACK_SIGNATURE_DETECTED") and ([ASM::violation details] contains "context request") } { ASM::unblock } } } But it’s not an attack signature… False positives might also be generated by large file uploads exceeding the system-defined maximum size. This value is 10MB by default and can be configured. See https://support.f5.com/csp/article/K7935 for more information. However, this is a system-wide variable, and it may not be desirable to change this globally, nor may it be desirable to disable the violation. Again, we can use an iRule to disable this violation on the file upload: when ASM_REQUEST_VIOLATION { if {([HTTP::method] equals "POST") and ([string tolower [HTTP::path]] ends_with "/foo.cfm") and ([string tolower [HTTP::header "Content-Type"]] contains "multipart/form-data") } { if {([lindex [ASM::violation_data] 0] contains "VIOLATION_REQUEST_TOO_LONG") } { ASM::unblock } } } ASM iRules reference https://clouddocs.f5.com/api/irules/ASM__violation_data.html https://clouddocs.f5.com/api/irules/ASM__violation.html https://clouddocs.f5.com/api/icontrol-soap/ASM__ViolationName.html13KViews3likes7CommentsUse F5 Distributed Cloud to service chain WAAP and CDN
The Content Delivery Network (CDN) market has become increasingly commoditized. Many providers have augmented their CDN capabilities with WAFs/WAAPs, DNS, load balancing, edge compute, and networking. Managing all these solutions together creates a web of operational complexity, which can be confusing. F5’s synergistic bundling of CDN with Web Application and API Protection (WAAP) benefits those looking for simplicity and ease of use. It provides a way around the complications and silos that many resource-strapped organizations face with their IT systems. This bundling also signifies how CDN has become a commodity product often not purchased independently anymore. This trend is encouraging many competitors to evolve their capabilities to include edge computing – a space where F5 has gained considerable experience in recent years. F5 is rapidly catching up to other providers’ CDNs. F5’s experience and leadership building the world’s best-of-breed Application Delivery Controller (ADC), the BIG-IP load balancer, put it in a unique position to offer the best application delivery and security services directly at the edge with many of its CDN points of presence. With robust regional edge capabilities and a global network, F5 has entered the CDN space with a complementary offering to an already compelling suite of features. This includes the ability to run microservices and Kubernetes workloads anywhere, with a complete range of services to support app infrastructure deployment, scale, and lifecycle management all within a single management console. With advancements made in the application security space at F5, WAAP capabilities are directly integrated into the Distributed Cloud Platform to protect both web apps and APIs. Features include (yet not limited to): Web Application Firewall: Signature + Behavioral WAF functionality Bot Defense: Detect client signals, determining if clients are human or automated DDoS Mitigation: Fully managed by F5 API Security: Continuous inspection and detection of shadow APIs Solution Combining the Distributed Cloud WAAP with CDN as a form of service chaining is a straightforward process. This not only gives you the best security protection for web apps and APIs, but also positions apps regionally to deliver them with low latency and minimal compute per request. In the following solution, we’ve combined Distributed Cloud WAAP and CDN to globally deliver an app protected by a WAF policy from the closest regional point of presence to the user. Follow along as I demonstrate how to configure the basic elements. Configuration Log in to the Distributed Cloud Console and navigate to the DNS Management service. Decide if you want Distributed Cloud to manage the DNS zone as a Primary DNS server or if you’d rather delegate the fully qualified domain name (FQDN) for your app to Distributed Cloud with a CNAME. While using Delegation or Managed DNS is optional, doing so makes it possible for Distributed Cloud to automatically create and manage the SSL certificates needed to securely publish your app. Next, in Distributed Cloud Console, navigate to the Web App and API Protection service, then go to App Firewall, then Add App Firewall. This is where you’ll create the security policy that we’ll later connect our HTTP LB. Let’s use the following basic WAF policy in YAML format, you can paste it directly in to the Console by changing the configuration view to JSON and then changing the format to YAML. Note: This uses the namespace “waap-cdn”, change this to match your individual tenant’s configuration. metadata: name: buytime-waf namespace: waap-cdn labels: {} annotations: {} disable: false spec: blocking: {} detection_settings: signature_selection_setting: default_attack_type_settings: {} high_medium_low_accuracy_signatures: {} enable_suppression: {} enable_threat_campaigns: {} default_violation_settings: {} bot_protection_setting: malicious_bot_action: BLOCK suspicious_bot_action: REPORT good_bot_action: REPORT allow_all_response_codes: {} default_anonymization: {} use_default_blocking_page: {} With the WAF policy saved, it’s time to configure the origin server. Navigate to Load Balancers > Origin Pools, then Add Origin Pool. The following YAML uses a FQDN DNS name reach the app server. Using an IP address for the server is possible as well. metadata: name: buytime-pool namespace: waap-cdn labels: {} annotations: {} disable: false spec: origin_servers: - public_name: dns_name: webserver.f5-cloud-demo.com labels: {} no_tls: {} port: 80 same_as_endpoint_port: {} healthcheck: [] loadbalancer_algorithm: LB_OVERRIDE endpoint_selection: LOCAL_PREFERRED With the supporting WAF and Origin Pool resources configured, it’s time to create the HTTP Load Balancer. Navigate to Load Balancers > HTTP Load Balancers, then create a new one. Use the following YAML to create the LB and use both resources created above. metadata: name: buytime-online namespace: waap-cdn labels: {} annotations: {} disable: false spec: domains: - buytime.waap.f5-cloud-demo.com https_auto_cert: http_redirect: true add_hsts: true port: 443 tls_config: default_security: {} no_mtls: {} default_header: {} enable_path_normalize: {} non_default_loadbalancer: {} header_transformation_type: default_header_transformation: {} advertise_on_public_default_vip: {} default_route_pools: - pool: tenant: your-tenant-uid namespace: waap-cdn name: buytime-pool kind: origin_pool weight: 1 priority: 1 endpoint_subsets: {} routes: [] app_firewall: tenant: your-tenant-uid namespace: waap-cdn name: buytime-waf kind: app_firewall add_location: true no_challenge: {} user_id_client_ip: {} disable_rate_limit: {} waf_exclusion_rules: [] data_guard_rules: [] blocked_clients: [] trusted_clients: [] ddos_mitigation_rules: [] service_policies_from_namespace: {} round_robin: {} disable_trust_client_ip_headers: {} disable_ddos_detection: {} disable_malicious_user_detection: {} disable_api_discovery: {} disable_bot_defense: {} disable_api_definition: {} disable_ip_reputation: {} disable_client_side_defense: {} resource_version: "517528014" With the HTTP LB successfully deployed, check that its status is ready on the status page. You can verify the LB is working by sending a basic request using the command line tool, curl. Confirm that the value of the HTTP header “Server” is “volt-adc”. da.potter@lab ~ % curl -I https://buytime.waap.f5-cloud-demo.com HTTP/2 200 date: Mon, 17 Oct 2022 23:23:55 GMT content-type: text/html; charset=UTF-8 content-length: 2200 vary: Origin access-control-allow-credentials: true accept-ranges: bytes cache-control: public, max-age=0 last-modified: Wed, 24 Feb 2021 11:06:36 GMT etag: W/"898-177d3b82260" x-envoy-upstream-service-time: 136 strict-transport-security: max-age=31536000 set-cookie: 1f945=1666049035840-557942247; Path=/; Domain=f5-cloud-demo.com; Expires=Sun, 17 Oct 2032 23:23:55 GMT set-cookie: 1f9403=viJrSNaAp766P6p6EKZK7nyhofjXCVawnskkzsrMBUZIoNQOEUqXFkyymBAGlYPNQXOUBOOYKFfs0ne+fKAT/ozN5PM4S5hmAIiHQ7JAh48P4AP47wwPqdvC22MSsSejQ0upD9oEhkQEeTG1Iro1N9sLh+w+CtFS7WiXmmJFV9FAl3E2; path=/ x-volterra-location: wes-sea server: volt-adc Now it’s time to configure the CDN Distribution and service chain it to the WAAP HTTP LB. Navigate to Content Delivery Network > Distributions, then Add Distribution. The following YAML creates a basic CDN configuration that uses the WAAP HTTP LB above. metadata: name: buytime-cdn namespace: waap-cdn labels: {} annotations: {} disable: false spec: domains: - buytime.f5-cloud-demo.com https_auto_cert: http_redirect: true add_hsts: true tls_config: tls_12_plus: {} add_location: false more_option: cache_ttl_options: cache_ttl_override: 1m origin_pool: public_name: dns_name: buytime.waap.f5-cloud-demo.com use_tls: use_host_header_as_sni: {} tls_config: default_security: {} volterra_trusted_ca: {} no_mtls: {} origin_servers: - public_name: dns_name: buytime.waap.f5-cloud-demo.com follow_origin_redirect: false resource_version: "518473853" After saving the configuration, verify that the status is “Active”. You can confirm the CDN deployment status for each individual region by going to the distribution’s action button “Show Global Status”, and scrolling down to each region to see that each region’s “site_status.status” value is “DEPLOYMENT_STATUS_DEPLOYED”. Verification With the CDN Distribution successfully deployed, it’s possible to confirm with the following basic request using curl. Take note of the two HTTP headers “Server” and “x-cache-status”. The Server value will now be “volt-cdn”, and the x-cache-status will be “MISS” for the first request. da.potter@lab ~ % curl -I https://buytime.f5-cloud-demo.com HTTP/2 200 date: Mon, 17 Oct 2022 23:24:04 GMT content-type: text/html; charset=UTF-8 content-length: 2200 vary: Origin access-control-allow-credentials: true accept-ranges: bytes cache-control: public, max-age=0 last-modified: Wed, 24 Feb 2021 11:06:36 GMT etag: W/"898-177d3b82260" x-envoy-upstream-service-time: 63 strict-transport-security: max-age=31536000 set-cookie: 1f945=1666049044863-471593352; Path=/; Domain=f5-cloud-demo.com; Expires=Sun, 17 Oct 2032 23:24:04 GMT set-cookie: 1f9403=aCNN1JINHqvWPwkVT5OH3c+OIl6+Ve9Xkjx/zfWxz5AaG24IkeYqZ+y6tQqE9CiFkNk+cnU7NP0EYtgGnxV0dLzuo3yHRi3dzVLT7PEUHpYA2YSXbHY6yTijHbj/rSafchaEEnzegqngS4dBwfe56pBZt52MMWsUU9x3P4yMzeeonxcr; path=/ x-volterra-location: dal3-dal server: volt-cdn x-cache-status: MISS strict-transport-security: max-age=31536000 To see a security violation detected by the WAF in real-time, you can simulate a simple XSS exploit with the following curl: da.potter@lab ~ % curl -Gv "https://buytime.f5-cloud-demo.com?<script>('alert:XSS')</script>" * Trying x.x.x.x:443... * Connected to buytime.f5-cloud-demo.com (x.x.x.x) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem * CApath: none * (304) (OUT), TLS handshake, Client hello (1): * (304) (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=buytime.f5-cloud-demo.com * start date: Oct 14 23:51:02 2022 GMT * expire date: Jan 12 23:51:01 2023 GMT * subjectAltName: host "buytime.f5-cloud-demo.com" matched cert's "buytime.f5-cloud-demo.com" * issuer: C=US; O=Let's Encrypt; CN=R3 * SSL certificate verify ok. * Using HTTP2, server supports multiplexing * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x14f010000) > GET /?<script>('alert:XSS')</script> HTTP/2 > Host: buytime.f5-cloud-demo.com > user-agent: curl/7.79.1 > accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! < HTTP/2 200 < date: Sat, 22 Oct 2022 01:04:39 GMT < content-type: text/html; charset=UTF-8 < content-length: 269 < cache-control: no-cache < pragma: no-cache < set-cookie: 1f945=1666400679155-452898837; Path=/; Domain=f5-cloud-demo.com; Expires=Fri, 22 Oct 2032 01:04:39 GMT < set-cookie: 1f9403=/1b+W13c7xNShbbe6zE3KKUDNPCGbxRMVhI64uZny+HFXxpkJMsCKmDWaihBD4KWm82reTlVsS8MumTYQW6ktFQqXeFvrMDFMSKdNSAbVT+IqQfSuVfVRfrtgRkvgzbDEX9TUIhp3xJV3R1jdbUuAAaj9Dhgdsven8FlCaADENYuIlBE; path=/ < x-volterra-location: dal3-dal < server: volt-cdn < x-cache-status: MISS < strict-transport-security: max-age=31536000 < <html><head><title>Request Rejected</title></head> <body>The requested URL was rejected. Please consult with your administrator.<br/><br/> Your support ID is 85281693-eb72-4891-9099-928ffe00869c<br/><br/><a href='javascript:history.back();'>[Go Back]</a></body></html> * Connection #0 to host buytime.f5-cloud-demo.com left intact Notice that the above request intentionally by-passes the CDN cache and is sent to the HTTP LB for the WAF policy to inspect. With this request rejected, you can confirm the attack by navigating to the WAAP HTTP LB Security page under the WAAP Security section within Apps & APIs. After refreshing the page, you’ll see the security violation under the “Top Attacked” panel. Demo To see all of this in action, watch my video below. This uses all of the configuration details above to make a WAAP + CDN service chain in Distributed Cloud. Additional Guides Virtually deploy this solution in our product simulator, or hands-on with step-by-step comprehensive demo guide. The demo guide includes all the steps, including those that are needed prior to deployment, so that once deployed, the solution works end-to-end without any tweaks to local DNS. The demo guide steps can also be automated with Ansible, in case you'd either like to replicate it or simply want to jump to the end and work your way back. Conclusion This shows just how simple it can be to use the Distributed Cloud CDN to frontend your web app protected by a WAF, all natively within the F5 Distributed Cloud’s regional edge POPs. The advantage of this solution should now be clear – the Distributed Cloud CDN is cloud-agnostic, flexible, agile, and you can enforce security policies anywhere, regardless of whether your web app lives on-prem, in and across clouds, or even at the edge. For more information about Distributed Cloud WAAP and Distributed Cloud CDN, visit the following resources: Product website: https://www.f5.com/cloud/products/cdn Distributed Cloud CDN & WAAP Demo Guide: https://github.com/f5devcentral/xcwaapcdnguide Video: https://youtu.be/OUD8R6j5Q8o Simulator: https://simulator.f5.com/s/waap-cdn Demo Guide: https://github.com/f5devcentral/xcwaapcdnguide7.3KViews10likes0CommentsDeploy WAF on any Edge with F5 Distributed Cloud (SaaS Console, Automation)
F5 XC WAAP/WAF presents a clear advantage over classical WAAP/WAFs in that it can be deployed on a variety of environments without loss of functionality. In this first article of a series, we present an overview of the main deployment options for XC WAAP while follow-on articles will dive deeper into the details of the deployment procedures.6KViews9likes0CommentsHow to deploy a basic OWASP Top 10 for 2021 compliant declarative WAF policy for BIG-IP (Part 2)
This article follows up the excellent article written by Valentin_Tobi on the same subject based on OWASP Top 10 2017. I will borrow heavily from the original and update this where changes have been made. This is part 2, where I will cover the OWASP compliance dashboard and the declarative code to bring our application into OWASP compliance. If you missed part 1 Click here The Declarative Advanced WAF policies are security policies defined using the declarative JSON format, which facilitates integration with source control systems and CI/CD pipelines. The documentation of the declarative WAF policy (v17.0) can be found here while its schema can be consulted here. Where relevant, I will show a snippet of code to represent what we are securing. The entire policy can be found here. One of the most basic Declarative WAF policies that can be applied is as follows: { "policy": { "name": "OWASP_2021", "description": "Rapid Deployment Policy", "template": { "name": "POLICY_TEMPLATE_RAPID_DEPLOYMENT" } } As you can see from the OWASP Compliance Dashboard screenshot, this policy is far from being OWASP-compliant, but we will use it as a starting point to build a fully compliant configuration. This article will go through each vulnerability class and show an example of declarative WAF policy configuration that would mitigate that respective vulnerability. Attack signatures are mentioned in numerous categories, I will just cover and mention them once as to not be redundant. Broken access control (A1) As K44094284: Securing against the OWASP Top 10 for 2021 | Chapter1: Broken access control (A1)states: "Broken access control occurs when an issue with the access control enforcement allows a user to perform an action outside of the user's limits. For example, an attacker may be able to exploit a flaw in an application with the intention of gaining elevated access to a protected resource to which they are not entitled. As a result of the privilege escalation, the attacker can perform unauthorized actions.” Securing against Broken access controls entails configuring attack signatures, allowed and disallowed URLs, URLs flow enforcement, Disallowed file types and Entities. }, "enforcementMode":"transparent", "protocolIndependent": true, "caseInsensitive": true, "general": { "trustXff": true }, "signature-settings":{ "signatureStaging": false, "minimumAccuracyForAutoAddedSignatures": "high" }, Cryptographic failures (A2) According to K00174750: Securing against the OWASP Top 10 for 2021 | Chapter 2: Cryptographic failures (A2): “Attackers often target sensitive data, such as passwords, credit card numbers, and personal information, when you do not properly protect them. Cryptographic failure is the root cause for sensitive data exposure. According to the Open Web Application Security Project (OWASP) 2021, securing your data against cryptographic failures has become more important than ever. A cryptographic failure flaw can occur when you do the following: Store or transit data in clear text (most common) Protect data with an old or weak encryption Improperly filter or mask data in transit.” Mitigation'sinclude Attack Signatures, Data Guard and Masked log values. BIG-IP Advanced WAF can protect sensitive data from being transmitted using Data Guard response scrubbing and from being logged with request log masking: "data-guard": { "enabled": true }, To get this score you must also enable SSL Encryption on both the client-side and server-side. Injection (A3) According to K13570030: Securing against the OWASP Top 10 for 2021 | Chapter 3: Injection (A3): “Injection attacks are one of the most dangerous attacks where an attacker simply sends malicious data to make the application process it and do something it is not supposed to do. Injection vulnerabilities are prevalent, especially in legacy code that does not validate or sanitize user-supplied input. Common application technologies that may be victims of an injection attack are the following: SQL NoSQL Lightweight Directory Access Protocol (LDAP) XPath Operating system commands XML parsers SMTP headers Attackers typically exploit injection flaws by injecting an operating system command, SQL query, or even a full script into a parameter, header, URL, other form of data that an application receives.” To protect your application, best practices recommend that you configure F5 products to inspect and validate all user-supplied input to your applications against known attack signatures, evasion techniques, and other known attributes/parameters. Insecure Design (A4) As per K39707080: Securing against the OWASP Top 10 for 2021 | Chapter 4: Insecure design (A4): “Insecure design is focused on the risks associated with flaws in design and architecture. It focuses on the need for threat modeling, secure design patterns, and principles. The flaws in insecure design are not something that can be rectified by an implementation. OWASP differentiates insecure design from security implementation and controls as follows: An insecure design cannot be fixed by a perfect implementation as by definition, needed security controls were never created to defend against specific attacks. To protect your applications against insecure design, you should use the following best practices when designing your applications: Analyze use cases together with misuse cases when defining the user stories. Define security rules, checks, and access controls in each user story. Use threat-modelling assessment process per each component and feature. Write unit and integration tests to validate that all critical flows are resistant to the threat model. Design tenant isolation in all layers. Limit resource consumption per user and service. Security misconfiguration (A5) According to K49812250: Securing against the OWASP Top 10 for 2021 | Chapter 5 Security misconfiguration (A5): “Security misconfiguration vulnerabilities occur when a web application component is susceptible to attack due to a misconfiguration or insecure configuration option. Misconfiguration vulnerabilities are configuration weaknesses that may exist in software components and subsystems or in user administration. For example, web server software may ship with default user accounts that an attacker can use to access the system, or the software may contain sample files, such as configuration files and scripts that an attacker can exploit. In addition, software may have unneeded services enabled, such as remote administration functionality. Misconfiguration vulnerabilities make your application susceptible to attacks that target any part of the application stack. For example, the following attack types may target misconfiguration vulnerabilities: Brute force/credential stuffing Code injection Buffer overflow Command injection Cross-site scripting (XSS) Forceful browsing XML external entity attacks Security misconfiguration in OWASP 2021 also includes XML external entity attacks. XXE attack is an attack against an application that parses XML input. The attack occurs when a weakly configured XML parser processes XML input containing a reference to an external entity. XXE attacks exploit document type definitions (DTDs), which are considered obsolete; however, they are still enabled in many XML parsers. Note: the policy already has a list of disallowed file types configured by default. Vulnerable and outdated components (A6) As per K17045144: Securing against the OWASP Top 10 for 2021 | Chapter 6: Vulnerable and outdated components (A6): “Component-based vulnerabilities occur when a software component is unsupported, out of date, or vulnerable to a known exploit. You may inadvertently use vulnerable software components in production environments, posing a threat to the web application.” Using components with known vulnerabilities makes your application susceptible to attacks that target any part of the application stack. For example, the following attack types are a few that may target known component vulnerabilities: Code injection Buffer overflow Command injection Cross-site scripting (XSS) F5 products provide security features, such as attack signatures, that protect your web application against component-based vulnerability attacks. In addition, F5 provides tools, such as the F5 iHealth diagnostic tool, that allows you to audit BIG-IP software components and their dependencies, making sure that the components are up-to-date and do not contain known vulnerabilities. Identification and authentication failures (A7) According to K14998322: Securing against the OWASP Top 10 for 2021 | Chapter 7 Identification and authentication failures (A7): “Identification and authentication failures can occur when functions related to a user's identity, authentication, or session management are not implemented correctly or not adequately protected by an application. Attackers may be able to exploit identification and authentication failures by compromising passwords, keys, session tokens, or exploit other implementation flaws to assume other users' identities, either temporarily or permanently. F5 products provide control mechanisms to mitigate and protect against attacks that attempt to exploit broken authentication. Attackers use a range of techniques to exploit broken authentication, including the following: Brute force/credential stuffing Session hijacking Session fixation Cross Site Request Forgery (CSRF) Execution After Redirect (EAR) One-click attack The BIG-IP Advanced WAF/ASM system provides the following controls to protect your application against identification and authentication failures, Attack signatures, Session hijacking protection, Cookie encryption, Brute force protection, Credential stuffing protection, CSRF protection and Login enforcement. }, "brute-force-attack-preventions": [ { "bruteForceProtectionForAllLoginPages": true, "leakedCredentialsCriteria": { "action": "alarm-and-blocking-page", "enabled": true } } ], "csrf-protection": { "enabled": true }, "csrf-urls": [ { "enforcementAction": "verify-csrf-token", "method": "GET", "url": "/trading/index.php" Software and data integrity (A8) As per K50295355: Securing against the OWASP Top 10 for 2021 | Chapter 8: Software and data integrity (A8): “Software and data integrity failures relate to code and infrastructure that does not protect against integrity violations. This can occur when you use software from untrusted sources and repositories or even software that has been tampered with at the source, in transit, or even the endpoint cache. Attackers can exploit this to potentially introduce unauthorized access, malicious code, or system compromise as part of the following attacks: Cache Poisoning Code injection Command execution Denial of Service You can use BIG-IP Advanced WAF/ASM to mitigate software and data integrity failures by using the following guidance: Attack Signatures, Enforced cookies and Content profiles. Security logging and monitoring failures (A9) According to K94068935: Securing against the OWASP Top 10 for 2021 | Chapter 9: Security logging and monitoring failures (A9) “Security logging and monitoring failures are frequently a factor in major security incidents. The BIG-IP system includes advanced logging and monitoring functionality and provides security features to protect against attacks that can result from insufficient system and application logging and monitoring. Failure to sufficiently log, monitor, or report security events, such as login attempts, makes suspicious behavior difficult to detect and significantly raises the likelihood that an attacker can successfully exploit your application. For example, an attacker may probe your application or software components for known vulnerabilities over a period. Allowing such probes to continue undetected increases the likelihood that the attacker ultimately finds a vulnerability and successfully exploits the flaw. Insufficient logging, monitoring, or reporting makes your application susceptible to attacks that target any part of the application stack. For example, the following attack types may result from a failure to log, monitor, or report security events: Code injection Buffer overflow Command injection Cross-site scripting (XSS) Forceful browsing This configuration is not part of the declarative WAF policy so it will not be described here - please follow the instructions in the referred article. Once logging has been configured, check the relevant items in the OWASP Compliance Dashboard. Server-side request forgery (SSRF) (A10) According to K36263043: Securing against the OWASP Top 10 for 2021 | Chapter 10: Server-side request forgery (SSRF): Server-side request forgery (SSRF) flaws occur whenever a web application is fetching a remote resource without validating the user-supplied URL. The vulnerable web application will often have privileges to read, write, or import data using a URL. To execute an SSRF attack, the attacker abuses the functionality on the server to read or update internal resources. The attacker can then force the application to send requests to access unintended resources, often bypassing security controls. Use SSRF protection (BIG-IP Advanced WAF 16.1.0 and later). Identify parameters of data type URI that are subjected to SSRF attack and explicitly define the URI parameters in your security policy or use the Auto-detect Parameter feature to automatically detect URI parameters in your application. From these parameters, identify the specific hosts to which you want disallow access, and, in your security policy under Advanced Protection, for SSRF Protection, add these specific hosts (IP addresses or host names) to the SSRF Hosts list. Conclusion This article has shown a very basic OWASP Top 10 for 2021 - compliant declarative WAF policy. It worth noting that, although this WAF policy is fully compliant to OWASP Top 10 recommendations, it contains elements that need to be customised for each individual application and should only be treated as a starting point for a production-ready WAF policy that would most likely need to be additional configuration. Many sections have items that need to be configured manually and/or policies and procedures need to be implemented to become compliant. The F5 OWASP dashboardshows the requirement, then allows you to manually indicate you are compliant for the dashboard to show complete. The full configuration of the declarative policy used in this example can be found on CodeShare: Example OWASP Top 10-compliant declarative WAF policy4.6KViews4likes0CommentsAdvanced WAF v16.0 - Declarative API
Since v15.1 (in draft), F5® BIG-IP® Advanced WAF™ canimport Declarative WAF policy in JSON format. The F5® BIG-IP® Advanced Web Application Firewall (Advanced WAF) security policies can be deployed using the declarative JSON format, facilitating easy integration into a CI/CD pipeline. The declarative policies are extracted from a source control system, for example Git, and imported into the BIG-IP. Using the provided declarative policy templates, you can modify the necessary parameters, save the JSON file, and import the updated security policy into your BIG-IP devices. The declarative policy copies the content of the template and adds the adjustments and modifications on to it. The templates therefore allow you to concentrate only on the specific settings that need to be adapted for the specific application that the policy protects. ThisDeclarative WAF JSON policyis similar toNGINX App Protect policy. You can find more information on theDeclarative Policyhere : NAP :https://docs.nginx.com/nginx-app-protect/policy/ Adv. WAF :https://techdocs.f5.com/en-us/bigip-15-1-0/big-ip-declarative-security-policy.html Audience This guide is written for IT professionals who need to automate their WAF policy and are familiar with Advanced WAF configuration. These IT professionals can fill a variety of roles: SecOps deploying and maintaining WAF policy in Advanced WAF DevOps deploying applications in modern environment and willing to integrate Advanced WAF in their CI/CD pipeline F5 partners who sell technology or create implementation documentation This article covershow to PUSH/PULL a declarative WAF policy in Advanced WAF: With Postman With AS3 Table of contents Upload Policy in BIG-IP Check the import Apply the policy OpenAPI Spec File import AS3 declaration CI/CD integration Find the Policy-ID Update an existing policy Video demonstration First of all, you need aJSON WAF policy, as below : { "policy": { "name": "policy-api-arcadia", "description": "Arcadia API", "template": { "name": "POLICY_TEMPLATE_API_SECURITY" }, "enforcementMode": "blocking", "server-technologies": [ { "serverTechnologyName": "MySQL" }, { "serverTechnologyName": "Unix/Linux" }, { "serverTechnologyName": "MongoDB" } ], "signature-settings": { "signatureStaging": false }, "policy-builder": { "learnOnlyFromNonBotTraffic": false } } } 1. Upload Policy in BIG-IP There are 2 options to upload a JSON file into the BIG-IP: 1.1 Either youPUSHthe file into the BIG-IP and you IMPORT IT OR 1.2 the BIG-IPPULLthe file froma repository (and the IMPORT is included)<- BEST option 1.1PUSH JSON file into the BIG-IP The call is below. As you can notice, it requires a 'Content-Range' header. And the value is 0-(filesize-1)/filesize. In the example below, the file size is 662 bytes. This is not easy to integrate in a CICD pipeline, so we created the PULL method instead of the PUSH (in v16.0) curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/file-transfer/uploads/policy-api.json' \ --header 'Content-Range: 0-661/662' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --header 'Content-Type: application/json' \ --data-binary '@/C:/Users/user/Desktop/policy-api.json' At this stage,the policy is still a filein the BIG-IP file system. We need toimportit into Adv. WAF. To do so, the next call is required. This call import the file "policy-api.json" uploaded previously. AnCREATEthe policy /Common/policy-api-arcadia curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Content-Type: application/javascript' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --data-raw '{ "filename":"policy-api.json", "policy": { "fullPath":"/Common/policy-api-arcadia" } }' 1.2PULL JSON file from a repository Here, theJSON file is hosted somewhere(in Gitlab or Github ...). And theBIG-IP will pull it. The call is below. As you can notice, the call refers to the remote repo and the body is a JSON payload. Just change the link value with your JSON policy URL. With one call, the policy isPULLEDandIMPORTED. curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --data-raw '{ "fileReference": { "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json" } }' Asecond versionof this call exists, and refer to the fullPath of the policy.This will allow you to update the policy, from a second version of the JSON file, easily.One call for the creation and the update. As you can notice below, we add the"policy":"fullPath" directive. The value of the "fullPath" is thepartitionand thename of the policyset in the JSON policy file. This method is VERY USEFUL for CI/CD integrations. curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --data-raw '{ "fileReference": { "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json" }, "policy": { "fullPath":"/Common/policy-api-arcadia" } }' 2. Check the IMPORT Check if the IMPORT worked. To do so, run the next call. curl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ You should see a 200 OK, with the content below (truncated in this example). Please notice the"status":"COMPLETED". { "kind": "tm:asm:tasks:import-policy:import-policy-taskcollectionstate", "selfLink": "https://localhost/mgmt/tm/asm/tasks/import-policy?ver=16.0.0", "totalItems": 11, "items": [ { "isBase64": false, "executionStartTime": "2020-07-21T15:50:22Z", "status": "COMPLETED", "lastUpdateMicros": 1.595346627e+15, "getPolicyAttributesOnly": false, ... From now, your policy is imported and created in the BIG-IP. You can assign it to a VS as usual (Imperative Call or AS3 Call).But in the next session, I will show you how to create a Service with AS3 including the WAF policy. 3. APPLY the policy As you may know, a WAF policy needs to be applied after each change. This is the call. curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/apply-policy/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --data-raw '{"policy":{"fullPath":"/Common/policy-api-arcadia"}}' 4. OpenAPI spec file IMPORT As you know,Adv. WAF supports OpenAPI spec (2.0 and 3.0). Now, with the declarative WAF, we can import the OAS file as well. The BEST solution, is toPULL the OAS filefrom a repo. And in most of the customer' projects, it will be the case. In the example below, the OAS file is hosted in SwaggerHub(Github for Swagger files). But the file could reside in a private Gitlab repo for instance. The URL of the projectis :https://app.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3 The URL of the OAS file is :https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3 This swagger file (OpenAPI 3.0 Spec file) includes all the application URL and parameters. What's more, it includes the documentation (for NGINX APIm Dev Portal). Now, it ispretty easy to create a WAF JSON Policy with API Security template, referring to the OAS file. Below, you can notice thenew section "open-api-files"with the link reference to SwaggerHub. And thenew templatePOLICY_TEMPLATE_API_SECURITY. Now, when I upload / import and apply the policy, Adv. WAF will download the OAS file from SwaggerHub and create the policy based on API_Security template. { "policy": { "name": "policy-api-arcadia", "description": "Arcadia API", "template": { "name": "POLICY_TEMPLATE_API_SECURITY" }, "enforcementMode": "blocking", "server-technologies": [ { "serverTechnologyName": "MySQL" }, { "serverTechnologyName": "Unix/Linux" }, { "serverTechnologyName": "MongoDB" } ], "signature-settings": { "signatureStaging": false }, "policy-builder": { "learnOnlyFromNonBotTraffic": false }, "open-api-files": [ { "link": "https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3" } ] } } 5. AS3 declaration Now, it is time to learn how we cando all of these steps in one call with AS3(3.18 minimum). The documentation is here :https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/declarations/application-security.html?highlight=waf_policy#virtual-service-referencing-an-external-security-policy With thisAS3 declaration, we: Import the WAF policy from a external repo Import the Swagger file (if the WAF policy refers to an OAS file) from an external repo Create the service { "class": "AS3", "action": "deploy", "persist": true, "declaration": { "class": "ADC", "schemaVersion": "3.2.0", "id": "Prod_API_AS3", "API-Prod": { "class": "Tenant", "defaultRouteDomain": 0, "API": { "class": "Application", "template": "generic", "VS_API": { "class": "Service_HTTPS", "remark": "Accepts HTTPS/TLS connections on port 443", "virtualAddresses": ["10.1.10.27"], "redirect80": false, "pool": "pool_NGINX_API_AS3", "policyWAF": { "use": "Arcadia_WAF_API_policy" }, "securityLogProfiles": [{ "bigip": "/Common/Log all requests" }], "profileTCP": { "egress": "wan", "ingress": { "use": "TCP_Profile" } }, "profileHTTP": { "use": "custom_http_profile" }, "serverTLS": { "bigip": "/Common/arcadia_client_ssl" } }, "Arcadia_WAF_API_policy": { "class": "WAF_Policy", "url": "http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json", "ignoreChanges": true }, "pool_NGINX_API_AS3": { "class": "Pool", "monitors": ["http"], "members": [{ "servicePort": 8080, "serverAddresses": ["10.1.20.9"] }] }, "custom_http_profile": { "class": "HTTP_Profile", "xForwardedFor": true }, "TCP_Profile": { "class": "TCP_Profile", "idleTimeout": 60 } } } } } 6. CI/CID integration As you can notice, it is very easy to create a service with a WAF policy pulled from an external repo. So, it is easy to integrate these calls (or the AS3 call) into a CI/CD pipeline. Below, an Ansible playbook example. This playbook run the AS3 call above. That's it :) --- - hosts: bigip connection: local gather_facts: false vars: my_admin: "admin" my_password: "admin" bigip: "10.1.1.12" tasks: - name: Deploy AS3 WebApp uri: url: "https://{{ bigip }}/mgmt/shared/appsvcs/declare" method: POST headers: "Content-Type": "application/json" "Authorization": "Basic YWRtaW46YWRtaW4=" body: "{{ lookup('file','as3.json') }}" body_format: json validate_certs: no status_code: 200 7. FIND the Policy-ID When the policy is created, a Policy-ID is assigned. By default, this ID doesn't appearanywhere. Neither in the GUI, nor in the response after the creation. You have to calculate it or ask for it. This ID is required for several actions in a CI/CD pipeline. 7.1 Calculate the Policy-ID Wecreated this python script to calculate the Policy-ID. It is an hash from the Policy name (including the partition). For the previous created policy named"/Common/policy-api-arcadia",the policy ID is"Ar5wrwmFRroUYsMA6DuxlQ" Paste this python codein a newwaf-policy-id.pyfile, and run the commandpython waf-policy-id.py "/Common/policy-api-arcadia" Outcome will beThe Policy-ID for /Common/policy-api-arcadia is: Ar5wrwmFRroUYsMA6DuxlQ #!/usr/bin/python from hashlib import md5 import base64 import sys pname = sys.argv[1] print 'The Policy-ID for', sys.argv[1], 'is:', base64.b64encode(md5(pname.encode()).digest()).replace("=", "") 7.2 Retrieve the Policy-ID and fullPath with a REST API call Make this call below, and you will see in the response, all the policy creations. Find yours and collect thePolicyReference directive.The Policy-ID is in the link value "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0" You can see as well, at the end of the definition, the "fileReference"referring to the JSON file pulled by the BIG-IP. And please notice the"fullPath", required if you want to update your policy curl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Content-Range: 0-601/601' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ { "isBase64": false, "executionStartTime": "2020-07-22T11:23:42Z", "status": "COMPLETED", "lastUpdateMicros": 1.595417027e+15, "getPolicyAttributesOnly": false, "kind": "tm:asm:tasks:import-policy:import-policy-taskstate", "selfLink": "https://localhost/mgmt/tm/asm/tasks/import-policy/B45J0ySjSJ9y9fsPZ2JNvA?ver=16.0.0", "filename": "", "policyReference": { "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0", "fullPath": "/Common/policy-api-arcadia" }, "endTime": "2020-07-22T11:23:47Z", "startTime": "2020-07-22T11:23:42Z", "id": "B45J0ySjSJ9y9fsPZ2JNvA", "retainInheritanceSettings": false, "result": { "policyReference": { "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0", "fullPath": "/Common/policy-api-arcadia" }, "message": "The operation was completed successfully. The security policy name is '/Common/policy-api-arcadia'. " }, "fileReference": { "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json" } }, 8 UPDATE an existing policy It is pretty easy to update the WAF policy from a new JSON file version. To do so, collect from the previous call7.2 Retrieve the Policy-ID and fullPath with a REST API callthe"Policy" and"fullPath"directive. This is the path of the Policy in the BIG-IP. Then run the call below, same as1.2 PULL JSON file from a repository,but add thePolicy and fullPath directives Don't forget to APPLY this new version of the policy3. APPLY the policy curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --data-raw '{ "fileReference": { "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json" }, "policy": { "fullPath":"/Common/policy-api-arcadia" } }' TIP : this call, above, can be used in place of the FIRST call when we created the policy "1.2PULL JSON file from a repository". But be careful, the fullPath is the name set in the JSON policy file. The 2 values need to match: "name": "policy-api-arcadia" in the JSON Policy file pulled by the BIG-IP "policy":"fullPath" in the POST call 9 Video demonstration In order to help you to understand how it looks with the BIG-IP, I created this video covering 4 topics explained in this article : The JSON WAF policy Pull the policy from a remote repository Update the WAF policy with a new version of the declarative JSON file Deploy a full service with AS3 and Declarative WAF policy At the end of this video, you will be able to adapt the REST Declarative API calls to your infrastructure, in order to deploy protected services with your CI/CD pipelines. Direct link to the video on DevCentral YouTube channel : https://youtu.be/EDvVwlwEFRw3.8KViews5likes2CommentsHow to deploy a basic OWASP Top 10 for 2021 compliant declarative WAF policy for BIG-IP
This article follows up the excellent article written by Valentin_Tobi on the same subject based on OWASP Top 10 2017. I will borrow heavily from the original and update this where changes have been made. Due to length of this article, I will split this into parts to more easily digest. Part 1 will cover what is OWASP Top 10 for 2021 and what are the key changes. Part 2 will cover the OWASP Compliance dashboard in BIG-IP and what code we will use to bring our device into compliance. This article describes an example of a minimal declarative WAF policy that is OWASP Top 10 compliant. Note that there are policy elements that are customized for the application being protected, in this case a demo application named Arcadia Finance, so they will need to be adapted for each application. The policy was configured following the pattern described in K45215395: Securing against the OWASP Top 10 for 2021 guide and its conformance with OWASP Top 10 is being verified by consulting the OWASP Compliance Dashboard bundled with F5's Advanced WAF. OWASP Top 10 2021 introduction and key changes from 2017 As described in K45215395: Securing against the OWASP Top 10 for 2021, the current OWASP Top 10 for 2021 vulnerabilities are: Broken access control (A1) moves up from the fifth position; 94% of applications were tested for some form of broken access control. Cryptographic failures (A2) shifts up one position to #2, previously known as Sensitive data exposure. Injection (A3) slides down to the third position. 94% of the applications were tested for some form of injection. Insecure design (A4) is a new category for 2021. Insecure design is focused on the risks associated with flaws in design and architecture. To exploit insecure design, attackers can threat model workflows in the software to reveal a broad range of vulnerabilities and weaknesses. Security misconfiguration (A5) moves up from #6 --The former category for XML External Entities (XXE) is now part of this category. Vulnerable and outdated components (A6) Component-based vulnerabilities occur when a software component is unsupported, out of date, or vulnerable to a known exploit. Identification and authentication failures (A7) was previously Broken Authentication. Identification and authentication failures can occur when functions related to a user's identity, authentication, or session management are not implemented correctly or not adequately protected by an application. Software and data integrity failures (A8) is a new category for 2021. Software and data integrity failures relate to code and infrastructure that does not protect against integrity violations. Attackers can exploit these failures to introduce unauthorized access, malicious code, or complete system compromise. Security logging and monitoring failures (A9) was previously Insufficient Logging & Monitoring. Insufficient logging, monitoring, or reporting makes your application susceptible to attacks that target any part of the application stack. Server-side request forgery (SSRF) (A10) Server-side request forgery (SSRF) flaws occur when a web application fetches a remote resource without validating the user-supplied URL. To execute an SSRF attack, the attacker abuses the functionality on the server to read or update internal resources. Most of these vulnerabilities can be mitigated with a properly configured WAF policy while, for the few of them that depend on security measures implemented in the application itself, there are recommended guidelines on application security which will prevent the exploitation of OWASP 10 vulnerabilities. In the follow-on article, I will cover the declarative WAF policies and the effect they have on the BIG-IP Advanced WAF. Here3.7KViews2likes0CommentsThe OWASP Top 10 - 2017 vs. BIG-IP ASM
With the release of the new 2017 Edition of the OWASP Top 10, we wanted to give a quick rundown of how BIG-IP ASM can mitigate these vulnerabilities. First, here's how the 2013 edition compares to 2017. And how BIG-IP ASM mitigates the vulnerabilities. Vulnerability BIG-IP ASM Controls A1 Injection Flaws Attack signatures Meta character restrictions Parameter value length restrictions A2 Broken Authentication and Session Management Brute Force protection Credentials Stuffing protection Login Enforcement Session tracking HTTP cookie tampering protection Session hijacking protection A3 Sensitive Data Exposure Data Guard Attack signatures (“Predictable Resource Location” and “Information Leakage”) A4 XML External Entities (XXE) Attack signatures (“Other Application Attacks” - XXE) XML content profile (Disallow DTD) (Subset of API protection) A5 Broken Access Control File types Allowed/disallowed URLs Login Enforcement Session tracking Attack signatures (“Directory traversal”) A6 Security Misconfiguration Attack Signatures DAST integration Allowed Methods HTML5 Cross-Domain Request Enforcement A7 Cross-site Scripting (XSS) Attack signatures (“Cross Site Scripting (XSS)”) Parameter meta characters HttpOnly cookie attribute enforcement Parameter type definitions (such as integer) A8 Insecure Deserialization Attack Signatures (“Server Side Code Injection”) A9 Using components with known vulnerabilities Attack Signatures DAST integration A10 Insufficient Logging and Monitoring Request/response logging Attack alarm/block logging On-device logging and external logging to SIEM system Event Correlation Specifically, we have attack signatures for “A4:2017-XML External Entities (XXE)”: 200018018 External entity injection attempt 200018030 XML External Entity (XXE) injection attempt (Content) Also, XXE attack could be mitigated by XML profile, by disabling DTDs (and of course enabling the “Malformed XML data” violation): For “A8:2017-Insecure Deserialization” we have many signatures, which usually include the name “serialization” or “serialized object”, like: 200004188 PHP object serialization injection attempt (Parameter) 200003425 Java Base64 serialized object - java/lang/Runtime (Parameter) 200004282 Node.js Serialized Object Remote Code Execution (Parameter) A quick run-down thanks to some of our security folks. ps Related: What’s New In The OWASP Top 10 And How TO Use It BIG-IP ASM Operations Guide3KViews0likes0CommentsProtect your web app in under 5 minutes.
Background Adding protection for your web-facing app shouldn’t require you to be an expert in security or networking. Having no deep expertise in either area made me an ideal candidate to try out F5’snew SaaS offer: F5 Essential App Protect Service. In my last article I used Amazon Lightsail to set up a full WordPress stack with a new domain. While the full app stack approach is incredibly convenient, it’s unlikely to deploy the latest patched version of that app: stacks are typically locked to major app versions, it takes time & effort to test each stack configuration, and frankly it’s up to end-users to ensure their app stays up-to-date. WordPress, just like any other popular app, has vulnerabilities: both core and from its many plug-ins. So, adding an extra level of protection in the form of Essential App Protect is really a no-brainer, as it shields against common attacks like XSS and SQL Injection. Below are the “minimal steps” to create and set up a web application firewall (WAF) with my app: Pre-requisites F5 Cloud Services subscription: I started with an active subscription; if you don’t have one already get your own here. Access to update your DNS with a CNAME value: I’m using Amazon Route 53, but we can do the same on any other registrar like GoDaddy. You may need to talk to your IT/NetOps team if you are in a company that manages this kind of stuff for you. Your app IP or Domain: I’m using the AWS-provided IP address for my app, but we could also use a domain name value instead. API Interaction: I’m using cURL on my Mac, but it’s also native on Windows 10 1803 onwards. Of course, you can use your favorite way to interact with an API, such as Postman, Fiddler, or code. Essential App Protect Setup Part A: Login and Ready We’ll use the F5 Cloud Services API to log in and retrieve a few values needed for creating our Essential App Protect subscription. 1. Log in – use the username / password to authenticate and retrieve the authorization token that we’ll need to use in the header of the subsequent API calls to the F5 portal. API Request: curl --location --request POST 'https://api.cloudservices.f5.com/v1/svc-auth/login' --data-raw '{"username": "", "password": "" }"' API Response (tokens cropped): We’ll save the token into a file ‘headers.txt’, which we can reference in the header of subsequent calls using cURL’s @filename feature (as of 7.55.0) . Our token needs to be stored in ‘headers.txt’ in a single line (no carriage returns) in this format: Authorization: Bearer <your token>. On a separate line we’ll add another header, such as: Content-Type: application/json. The resulting ‘headers.txt’ file would therefore look like this: 2. Get User Account ID – next let’s retrieve the “ID” value for our account, which is one of the two values needed to subscribe to the Essential App Protect catalog and also to create a service subscription instance for our app. API Request: curl --location --request GET 'https://api.cloudservices.f5.com/v1/svc-account/user' --header @headers.txt API Response: 3. Get Catalogs – Here we will retrieve the list of all available Catalogs and get the Catalog ID for the Essential App Protect service, which is designated with “service_type”:”waf”. API Request: curl --location --request GET 'https://api.cloudservices.f5.com/v1/svc-catalog/catalogs' --header @headers.txt API Response: 4. Subscribe to Catalog -- This step can be skipped you have already subscribed to Essential App Protect catalog (in the portal or through API). We will use the account “id” and the “catalog_id” values retrieved earlier. API Request: curl --location --request POST 'https://api.cloudservices.f5.com/v1/svc-account/accounts/<your-account-id>/catalogs' --data-raw '{"account_id": "<your-account-id>","catalog_id": "c-aa9N0jgHI4"}' --header @headers.txt API Response: At this point we are logged in and subscribed to the Catalog. Next let’s create our service instance. Part B: Create and Activate Subscription 5. Create Subscription – Here we will use the account “id” and the “catalog_id” values retrieved earlier, plus a few other values for our app hosted on AWS. In the response we will need to capture the "subscription_id. API Request: curl --location --request POST 'https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions' --data-raw '{ "account_id": "<your-account-id>", "catalog_id": "c-aa9N0jgHI4", "service_instance_name": "<descriptive name>", "service_type": "waf", "configuration": { "waf_service": { "application": { "domain": "<cool domain>", "remark": "<cool remark>", "waf_regions": { "aws": { "us-west-2": { "endpoint": { "ips": [ "<your ip here>" ], "port": 80, "use_TLS": false } } } } }, "event_logging": { "enabled": true }, "industry": "finance", "policy": { "compliance_enforcement": { "data_guard": { "cc": true, "enabled": true, "ssn": true }, "sensitive_parameters": { "enabled": true } }, "encoding": "utf-8", "high_risk_attack_mitigation": { "allowed_methods": { "enabled": true, "methods": [ { "contains_http_data": true, "name": "POST" }, { "contains_http_data": false, "name": "HEAD" }, { "contains_http_data": false, "name": "GET" } ] }, "api_compliance_enforcement": { "enabled": true }, "disallowed_file_types": { "enabled": true, "file_types": [ "exe", "com", "bat", "dll", "back", "cfg", "dat", "cmd", "bck", "eml", "bin", "config", "ini", "old", "sav", "save", "idq", "idc", "ida", "htw", "exe1", "exe_renamed", "hta", "htr" ] }, "enabled": true, "enforcement_mode": "blocking", "geolocation_enforcement": { "disallowed_country_codes": [], "enabled": true }, "http_compliance_enforcement": { "enabled": true }, "ip_enforcement": { "enabled": true, "ips": [ { "action": "block", "address": "178.18.62.195", "description": "This is anonymous proxy", "log": true }, { "action": "allow", "address": "1.2.3.5", "description": "some description", "log": false } ] }, "signature_enforcement": { "enabled": true }, "websocket_compliance_enforcement": { "enabled": true } }, "malicious_ip_enforcement": { "enabled": true, "enforcement_mode": "blocking", "ip_categories": [ { "block": true, "log": true, "name": "tor_proxies" }, { "block": false, "log": true, "name": "cloud_services" } ] }, "threat_campaigns": { "enabled": true, "enforcement_mode": "blocking" } } } } }' --header @headers.txt API Response (truncated): 6. Activate Subscription – Now we are ready to activate the instance using the “subscription_id” captured in the previous step. Note that if the returned “service_state” is “UNDEPLOYED” it just means it’s being activated, re-running the same API call should eventually return “service_state”: “DEPLOYED”. API Request: curl --location --request POST 'https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/<your-subscription-id>/activate' --data-raw '{ "subscription_id": "<your-subscription-id>", "omit_config": true }' --header @headers.txt API Response: With this our Essential App Protect service should be live, ready to accept requests, and should look like this in the portal: CNAME & Domain Update The only remaining thing is to retrieve the CNAME value of our live Essential App Protect service. This is what we can browse to test our site, and where we will need to send traffic from our domain. Let’s do it: 7. Get CNAME Value – using the same “subscription_id” from the previous step, let’s get the info for our service and retrieve “CNAMEValue”. API Request: curl --location --request GET 'https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/<your-subscription-id>' --header @headers.txt API Response: 8. Browser Check – let’s validate what it looks like in our browser (copy + paste the value of CNAMEValue). We can see our blog, and can even try to do something like adding a disallowed filetype at the end of the URL: 9. Domain records update – finally let’s update the Amazon Route 53 configuration for our site with the new CNAME. We will need to add a record type CNAME and provide CNAMEValue. This will essentially route blog.haxrip.net traffic to Essential App Protect, which in turn will route it to the IP that we specified earlier. Conclusion Adding protection to a website with F5’s Essential App Protect is pretty straightforward and requires just a few API calls. If you’re running a web-facing app and don’t have the time or resources to keep it constantly updated to protect against known vulnerabilities -- it’s a good idea to have an extra protection in place for possible (and likely) attacks.2.6KViews0likes3Comments