├── .gemrc ├── .github └── workflows │ ├── verify-docker.yml │ └── verify-ec2.yml ├── .gitignore ├── Gemfile ├── License.md ├── README.md ├── SRG-INFO ├── chefignore ├── controls ├── V-40791.rb ├── V-40792.rb ├── V-40799.rb ├── V-40800.rb ├── V-40819.rb ├── V-41600.rb ├── V-41609.rb ├── V-41611.rb ├── V-41612.rb ├── V-41613.rb ├── V-41614.rb ├── V-41615.rb ├── V-41616.rb ├── V-41617.rb ├── V-41620.rb ├── V-41668.rb ├── V-41670.rb ├── V-41671.rb ├── V-41672.rb ├── V-41674.rb ├── V-41684.rb ├── V-41693.rb ├── V-41694.rb ├── V-41695.rb ├── V-41696.rb ├── V-41698.rb ├── V-41699.rb ├── V-41700.rb ├── V-41701.rb ├── V-41702.rb ├── V-41703.rb ├── V-41704.rb ├── V-41706.rb ├── V-41730.rb ├── V-41731.rb ├── V-41738.rb ├── V-41745.rb ├── V-41746.rb ├── V-41807.rb ├── V-41811.rb ├── V-41812.rb ├── V-41821.rb ├── V-41833.rb ├── V-41852.rb ├── V-41854.rb ├── V-41855.rb ├── V-55945.rb ├── V-55947.rb ├── V-55949.rb ├── V-55951.rb ├── V-55953.rb ├── V-55955.rb ├── V-55957.rb ├── V-55959.rb ├── V-55961.rb ├── V-55969.rb ├── V-55971.rb ├── V-55973.rb ├── V-55975.rb ├── V-55977.rb ├── V-55979.rb ├── V-55981.rb ├── V-55983.rb ├── V-55985.rb ├── V-55987.rb ├── V-55989.rb ├── V-55991.rb ├── V-55993.rb ├── V-55995.rb ├── V-55997.rb ├── V-55999.rb ├── V-56001.rb ├── V-56003.rb ├── V-56005.rb ├── V-56007.rb ├── V-56009.rb ├── V-56011.rb ├── V-56013.rb ├── V-56015.rb ├── V-56017.rb ├── V-56019.rb ├── V-56021.rb ├── V-56025.rb ├── V-56027.rb ├── V-56029.rb ├── V-56031.rb ├── V-56033.rb ├── V-56035.rb └── V-61353.rb ├── example.inputs.yml ├── hardened.threshold.yml ├── inspec.yml ├── kitchen.docker.yml ├── kitchen.ec2.yml ├── kitchen.vagrant.yml ├── spec └── ansible │ └── nginx-hardening │ ├── ansible.cfg │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── hardening-playbook.yml │ ├── meta │ └── main.yml │ ├── requirements.yml │ ├── tasks │ └── main.yml │ ├── templates │ └── hardening.conf.j2 │ ├── tests │ ├── official-nginx-role-debian.yml │ ├── official-nginx-role-redhat.yml │ └── test.yml │ ├── vanilla-playbook.yml │ └── vars │ ├── docker.vars.yml │ ├── ec2.vars.yml │ ├── main.yml │ └── vagrant.vars.yml └── vanilla.threshold.yml /.gemrc: -------------------------------------------------------------------------------- 1 | gem: --no-rdoc --no-ri 2 | -------------------------------------------------------------------------------- /.github/workflows/verify-docker.yml: -------------------------------------------------------------------------------- 1 | name: Verify the Baseline using Docker 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | release: 9 | types: 10 | - published 11 | 12 | jobs: 13 | my-job: 14 | defaults: 15 | run: 16 | shell: bash -l {0} 17 | name: Validate my profile 18 | runs-on: ubuntu-latest 19 | env: 20 | CHEF_LICENSE: accept-silent 21 | CHEF_LICENSE_KEY: ${{ secrets.SAF_CHEF_LICENSE_KEY }} 22 | KITCHEN_YAML: kitchen.docker.yml 23 | strategy: 24 | matrix: 25 | suite: ["vanilla", "hardened"] 26 | fail-fast: false 27 | steps: 28 | - name: Check out code 29 | uses: actions/checkout@v4 30 | - name: Setup Ruby 31 | uses: ruby/setup-ruby@v1 32 | with: 33 | ruby-version: "3.1" 34 | - name: Setup caching 35 | uses: actions/cache@v4 36 | with: 37 | path: vendor/bundle 38 | key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} 39 | restore-keys: | 40 | ${{ runner.os }}-gems- 41 | - name: Bundle install 42 | run: | 43 | gem install bundler 44 | bundle config path vendor/bundle 45 | bundle install 46 | - name: Regenerate current `profile.json` 47 | run: | 48 | bundle exec inspec json . | jq . > profile.json 49 | - name: Lint the Inspec profile 50 | run: bundle exec inspec check . 51 | - name: Test-Kitchen 52 | run: | 53 | mkdir results 54 | bundle exec kitchen test --destroy=always ${{ matrix.suite }}-ubuntu-1804 || true 55 | - name: Display our ${{ matrix.suite }} results summary 56 | uses: mitre/saf_action@v1 57 | with: 58 | command_string: "view:summary -i spec/results/${{ matrix.suite }}-test-result.json" 59 | - name: Ensure the scan meets our ${{ matrix.suite }} results threshold 60 | uses: mitre/saf_action@v1 61 | with: 62 | command_string: "validate:threshold -i spec/results/${{ matrix.suite }}-test-result.json -T ${{ matrix.suite }}.threshold.yml" 63 | - name: Save Test Result JSON 64 | uses: actions/upload-artifact@v4 65 | with: 66 | name: ${{ matrix.suite }}-results 67 | path: spec/results 68 | -------------------------------------------------------------------------------- /.github/workflows/verify-ec2.yml: -------------------------------------------------------------------------------- 1 | name: Verify the Baseline on EC2 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | release: 9 | types: 10 | - published 11 | jobs: 12 | my-job: 13 | name: Validate my profile 14 | runs-on: ubuntu-latest 15 | env: 16 | CHEF_LICENSE: accept-silent 17 | CHEF_LICENSE_KEY: ${{ secrets.SAF_CHEF_LICENSE_KEY }} 18 | KITCHEN_YAML: kitchen.ec2.yml 19 | strategy: 20 | matrix: 21 | suite: ['vanilla', 'hardened'] 22 | fail-fast: false 23 | steps: 24 | - name: add needed packages 25 | run: sudo apt-get install -y jq 26 | - name: Configure AWS credentials 27 | env: 28 | AWS_SUBNET_ID: ${{ secrets.SAF_AWS_SUBNET_ID }} 29 | AWS_SSH_KEY_ID: ${{ secrets.SAF_AWS_SSH_KEY_ID }} 30 | uses: aws-actions/configure-aws-credentials@v1 31 | with: 32 | aws-access-key-id: ${{ secrets.SAF_AWS_ACCESS_KEY_ID }} 33 | aws-secret-access-key: ${{ secrets.SAF_AWS_SECRET_ACCESS_KEY }} 34 | aws-region: ${{ secrets.SAF_AWS_REGION }} 35 | - name: Check out repository 36 | uses: actions/checkout@v4 37 | - name: Clone full repository so we can push 38 | run: git fetch --prune --unshallow 39 | - name: Setup Ruby 40 | uses: ruby/setup-ruby@v1 41 | with: 42 | ruby-version: '3.1' 43 | # - name: Setup caching 44 | # uses: actions/cache@v4 45 | # with: 46 | # path: vendor/bundle 47 | # key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} 48 | # restore-keys: | 49 | # ${{ runner.os }}-gems- 50 | - name: Bundle install 51 | run: | 52 | gem install bundler 53 | bundle config path vendor/bundle 54 | bundle install 55 | - name: Regenerate current `profile.json` 56 | run: | 57 | bundle exec inspec json . | jq . > profile.json 58 | - name: Update profile.json in the repository 59 | uses: stefanzweifel/git-auto-commit-action@v4.1.0 60 | with: 61 | commit_message: 'Updating profile.json in the repository' 62 | branch: ${{ github.branch }} 63 | - name: Run Kitchen Create 64 | run: bundle exec kitchen create ${{ matrix.suite }}-ubuntu-1804 || true 65 | - name: Run Kitchen Converge 66 | run: bundle exec kitchen converge ${{ matrix.suite }}-ubuntu-1804 || true 67 | - name: Run Kitchen Verify 68 | run: bundle exec kitchen verify ${{ matrix.suite }}-ubuntu-1804 || true 69 | - name: Run Kitchen Destroy 70 | run: bundle exec kitchen destroy ${{ matrix.suite }}-ubuntu-1804 || true 71 | - name: Display our ${{ matrix.suite }} results summary 72 | uses: mitre/saf_action@v1 73 | with: 74 | command_string: 'view:summary -i spec/results/${{ matrix.suite }}-test-result.json' 75 | - name: Ensure the scan meets our ${{ matrix.suite }} results threshold 76 | uses: mitre/saf_action@v1 77 | with: 78 | command_string: 'validate:threshold -i spec/results/${{ matrix.suite }}-test-result.json -T ${{ matrix.suite }}.threshold.yml' 79 | - name: Save Test Result JSON 80 | uses: actions/upload-artifact@v4 81 | with: 82 | name: ${{ matrix.suite }}-results 83 | path: spec/results 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # -*- mode: gitignore; -*- 2 | *~ 3 | \#*\# 4 | /.emacs.desktop 5 | /.emacs.desktop.lock 6 | *.elc 7 | auto-save-list 8 | tramp 9 | .\#* 10 | 11 | # Org-mode 12 | .org-id-locations 13 | *_archive 14 | 15 | # flymake-mode 16 | *_flymake.* 17 | 18 | # eshell files 19 | /eshell/history 20 | /eshell/lastdir 21 | 22 | # elpa packages 23 | /elpa/ 24 | 25 | # reftex files 26 | *.rel 27 | 28 | # AUCTeX auto folder 29 | /auto/ 30 | 31 | # cask packages 32 | .cask/ 33 | dist/ 34 | 35 | # Flycheck 36 | flycheck_*.el 37 | 38 | # server auth directory 39 | /server/ 40 | 41 | # projectiles files 42 | .projectile 43 | 44 | # directory configuration 45 | .dir-locals.el 46 | 47 | # network security 48 | /network-security.data 49 | 50 | *.lock 51 | *.gem 52 | *.rbc 53 | 54 | !Gemfile.lock 55 | .attribute.yml 56 | 57 | /.config 58 | /coverage/ 59 | /InstalledFiles 60 | /pkg/ 61 | /spec/reports/ 62 | /spec/examples.txt 63 | inspec-azure.plan 64 | inspec-aws-*.plan 65 | 66 | 67 | *.tfstate 68 | *.tfstate.* 69 | .terraform/ 70 | terraform.tfvars 71 | 72 | .kitchen/ 73 | .kitchen.local.yml 74 | kitchen.local.yml 75 | 76 | .vagrant 77 | 78 | inspec-deprecations-in-cfg.txt 79 | inspec-deprecations-in-lib.txt 80 | 81 | # Docker 82 | *.retry 83 | .backup 84 | 85 | 86 | # OSX 87 | # General 88 | .DS_Store 89 | .AppleDouble 90 | .LSOverride 91 | 92 | # Icon must end with two \r 93 | Icon 94 | 95 | # Thumbnails 96 | ._* 97 | 98 | # Files that might appear in the root of a volume 99 | .DocumentRevisions-V100 100 | .fseventsd 101 | .Spotlight-V100 102 | .TemporaryItems 103 | .Trashes 104 | .VolumeIcon.icns 105 | .com.apple.timemachine.donotpresent 106 | 107 | # Directories potentially created on remote AFP share 108 | .AppleDB 109 | .AppleDesktop 110 | Network Trash Folder 111 | Temporary Items 112 | .apdisk 113 | 114 | # Logs 115 | *.log 116 | 117 | 118 | ## Documentation cache and generated files: 119 | /.yardoc/ 120 | /_yardoc/ 121 | /doc/ 122 | /rdoc/ 123 | 124 | # Ignore bundler config 125 | /.bundle/ 126 | /vendor/ 127 | /vendor/bundle 128 | vendor/cookbooks 129 | 130 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 131 | .rvmrc 132 | .packer 133 | 134 | # for a library or gem, you might want to ignore these files since the code is 135 | # intended to run in multiple environments; otherwise, check them in: 136 | .ruby-version 137 | .ruby-gemset 138 | 139 | 140 | ## JetBrain 141 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 142 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 143 | .idea/ 144 | 145 | ## Specific to RubyMotion: 146 | .dat* 147 | .repl_history 148 | *.bridgesupport 149 | 150 | # File-based project format 151 | *.iws 152 | 153 | # IntelliJ 154 | out/ 155 | 156 | # mpeltonen/sbt-idea plugin 157 | .idea_modules/ 158 | 159 | # Crashlytics plugin (for Android Studio and IntelliJ) 160 | com_crashlytics_export_strings.xml 161 | crashlytics.properties 162 | crashlytics-build.properties 163 | fabric.properties 164 | 165 | # JIRA plugin 166 | atlassian-ide-plugin.xml 167 | 168 | 169 | # Build Folder 170 | /build/ 171 | /build-iPhoneOS/ 172 | /build-iPhoneSimulator/ 173 | 174 | 175 | # Ignore rendered files from docs/ 176 | source/docs/reference/ 177 | examples/meta-profile/vendor/ 178 | habitat/VERSION 179 | habitat/results 180 | /lib/bundler/man/ 181 | 182 | 183 | # USER 184 | /.gitignoredir/ 185 | /tmp/ 186 | /test/tmp/ 187 | /test/version_tmp/ 188 | /.emacs.desktop 189 | .gitter 190 | *.elc 191 | nbproject 192 | auto-save-list 193 | tramp 194 | /.direnv 195 | /.envrc 196 | results/ 197 | contrib/* 198 | 199 | # Test Results (.json) 200 | *.json 201 | 202 | # Kitchen logs 203 | .kitchen 204 | 205 | # Gem 206 | Gemfile.lock -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'test-kitchen' 4 | gem 'kitchen-ansible' 5 | gem 'kitchen-inspec' 6 | gem 'inspec-bin' 7 | gem 'kitchen-vagrant' 8 | gem 'kitchen-docker' 9 | gem 'kitchen-ec2' -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | 2 | Licensed under the apache-2.0 license, except as noted below. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright/ digital rights 8 | legend, this list of conditions and the following Notice. 9 | 10 | * Redistributions in binary form must reproduce the above copyright copyright/digital 11 | rights legend, this list of conditions and the following Notice in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of The MITRE Corporation nor the names of its contributors may be 15 | used to endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | MITRE’s licensed products incorporate third-party materials that are subject to open source or free software licenses (“Open Source Materials”). The Open Source Materials are as follows: 19 | 20 | DISA SRGs. Please visit https://public.cyber.mil/stigs/ for full terms of use. 21 | 22 | The Open Source Materials are licensed under the terms of the applicable third-party licenses that accompany the Open Source Materials. MITRE’s license does not limit a licensee’s rights under the terms of the Open Source Materials license. MITRE’s license also does not grant licensee rights to the Open Source Materials that supersede the terms and conditions of the Open Source Materials license. -------------------------------------------------------------------------------- /SRG-INFO: -------------------------------------------------------------------------------- 1 | # Source SRG Info 2 | 3 | This profile was developed using the follow SRG from DISA 4 | 5 | benchmark.title: Web Server Security Requirements Guide 6 | benchmark.id: Web_Server_SRG 7 | benchmark.description: 'The Web Server SRG is published as a tool to improve the security 8 | of Department of Defense (DoD) information systems. The requirements are derived 9 | from the NIST 800-53 and related documents. Comments or proposed revisions to this 10 | document should be sent via e-mail to the following address: disa.letterkenny.FSO.mbx.stig-customer-support-mailbox@mail.mil.' 11 | benchmark.version: '2' 12 | benchmark.status: accepted 13 | benchmark.status.date: '2015-08-28' 14 | benchmark.notice.id: terms-of-use 15 | benchmark.plaintext: 'Release: 2 Benchmark Date: 23 Oct 2015' 16 | benchmark.plaintext.id: release-info 17 | reference.href: http://iase.disa.mil 18 | reference.dc.publisher: DISA 19 | reference.dc.source: STIG.DOD.MIL 20 | reference.dc.title: DPMS Target SRG-APP-WSR 21 | reference.dc.subject: SRG-APP-WSR 22 | reference.dc.type: DPMS Target 23 | reference.dc.identifier: '2557' 24 | content_ref.name: M 25 | content_ref.href: DPMS_XCCDF_Benchmark_Web_Server_SRG.xml -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | .kitchen 2 | kitchen*.yml -------------------------------------------------------------------------------- /controls/V-40792.rb: -------------------------------------------------------------------------------- 1 | control 'V-40792' do 2 | title 'The NGINX web server must perform server-side session management.' 3 | desc "Session management is the practice of protecting the bulk of the user 4 | authorization and identity information. Storing of this data can occur on the 5 | client system or on the server. 6 | 7 | When the session information is stored on the client, the session ID, along 8 | with the user authorization and identity information, is sent along with each 9 | client request and is stored in either a cookie, embedded in the uniform 10 | resource locator (URL), or placed in a hidden field on the displayed form. Each 11 | of these offers advantages and disadvantages. The biggest disadvantage to all 12 | three is the hijacking of a session along with all of the user's credentials. 13 | 14 | When the user authorization and identity information is stored on the 15 | server in a protected and encrypted database, the communication between the 16 | client and web server will only send the session identifier, and the server can 17 | then retrieve user credentials for the session when needed. If, during 18 | transmission, the session were to be hijacked, the user's credentials would not 19 | be compromised. 20 | " 21 | desc 'check', "Review the NGINX web server documentation and configuration to determine if 22 | server-side session management is configured. 23 | 24 | If it is determined that the web server is not required to perform session management, 25 | this check is Not Applicable. 26 | 27 | If it is not configured, this is a finding. 28 | " 29 | desc 'fix', "Configure the NGINX web server to perform server-side session 30 | management." 31 | impact 0.5 32 | tag "severity": 'medium' 33 | tag "gtitle": 'SRG-APP-000001-WSR-000002' 34 | tag "gid": 'V-40792' 35 | tag "rid": 'SV-53023r3_rule' 36 | tag "stig_id": 'SRG-APP-000001-WSR-000002' 37 | tag "fix_id": 'F-45949r2_fix' 38 | tag "cci": ['CCI-000054'] 39 | tag "nist": %w(AC-10) 40 | 41 | if input('performs_session_management') == false 42 | impact 0.0 43 | describe 'This check is NA because session management is not required.' do 44 | skip 'This check is NA because session management is not required.' 45 | end 46 | else 47 | describe "This test requires a Manual Review: Determine if server-side session management 48 | is required. If it is required, verify that it is configured." do 49 | skip "This test requires a Manual Review: Determine if server-side session management 50 | is required. If it is required, verify that it is configured." 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /controls/V-40819.rb: -------------------------------------------------------------------------------- 1 | control 'V-40819' do 2 | title "The NGINX web server must use cryptography to protect the integrity of 3 | remote sessions." 4 | desc "Data exchanged between the user and the web server can range from 5 | static display data to credentials used to log into the hosted application. 6 | Even when data appears to be static, the non-displayed logic in a web page may 7 | expose business logic or trusted system relationships. The integrity of all the 8 | data being exchanged between the user and web server must always be trusted. To 9 | protect the integrity and trust, encryption methods should be used to protect 10 | the complete communication session." 11 | desc 'check', "Review the NGINX web server documentation and configuration to 12 | make certain that the NGINX web server is configured to use cryptography to protect 13 | the integrity of remote access sessions. 14 | 15 | If there are no websites configured or if NGINX is not configured to serve files, 16 | this check is Not Applicable. 17 | 18 | Check for the following: 19 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf 20 | and any separated include configuration file. 21 | 22 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 23 | this check is Not Applicable. 24 | 25 | If the 'ssl_protocols' directive is not set to the approved TLS version, this is a finding. 26 | " 27 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration file(s) 28 | and configure it to use the approved TLS protocols to utilize encryption during 29 | remote access sessions. 30 | 31 | Example: 32 | server { 33 | ssl_protocols TLSv1.2; 34 | } 35 | " 36 | impact 0.5 37 | tag "severity": 'medium' 38 | tag "gtitle": 'SRG-APP-000015-WSR-000014' 39 | tag "gid": 'V-40819' 40 | tag "rid": 'SV-53068r3_rule' 41 | tag "stig_id": 'SRG-APP-000015-WSR-000014' 42 | tag "fix_id": 'F-45994r2_fix' 43 | tag "cci": ['CCI-001453'] 44 | tag "nist": ['AC-17 (2)', ''] 45 | 46 | if nginx_conf.servers.nil? 47 | impact 0.0 48 | describe 'This check is NA because NGINX has not been configured to serve files.' do 49 | skip 'This check is NA because NGINX has not been configured to serve files.' 50 | end 51 | else 52 | nginx_conf.servers.each do |server| 53 | if server.params['ssl_protocols'].nil? 54 | impact 0.0 55 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 56 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 57 | end 58 | else 59 | server.params['ssl_protocols'].each do |protocol| 60 | describe 'Each protocol' do 61 | it 'should be included in the list of protocols approved to encrypt data' do 62 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 63 | end 64 | end 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /controls/V-41600.rb: -------------------------------------------------------------------------------- 1 | control 'V-41600' do 2 | title "The NGINX web server must generate, at a minimum, log records for system 3 | startup and shutdown, system access, and system authentication events." 4 | desc "Log records can be generated from various components within the web 5 | server (e.g., httpd, plug-ins to external backends, etc.). From a web server 6 | perspective, certain specific web server functionalities may be logged as well. 7 | The web server must allow the definition of what events are to be logged. As 8 | conditions change, the number and types of events to be logged may change, and 9 | the web server must be able to facilitate these changes. 10 | 11 | The minimum list of logged events should be those pertaining to system 12 | startup and shutdown, system access, and system authentication events. If these 13 | events are not logged at a minimum, any type of forensic investigation would be 14 | missing pertinent information needed to replay what occurred. 15 | " 16 | desc 'check', " 17 | Review the NGINX web server documentation and the deployed system configuration to determine 18 | if, at a minimum, system startup and shutdown, system access, and system authentication events are logged. 19 | 20 | If there are no websites configured for NGINX, this check is Not Applicable. 21 | 22 | Check for the following: 23 | # grep the 'log_format' directive in the http context of the nginx.conf. 24 | 25 | The logs will not include the minimum logable events if the 'log_format' directive does not exist. 26 | 27 | If the the 'log_format' directive does not exist, this is a finding. 28 | 29 | Example configuration: 30 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 31 | '$status $body_bytes_sent "'$http_referer'"' 32 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 33 | 34 | " 35 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf file to look like the following: 36 | 37 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 38 | '$status $body_bytes_sent "'$http_referer'"' 39 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 40 | 41 | NOTE: Your log format may be using different variables based on your environment, 42 | however it should be verified to be producing the same end result of logged elements." 43 | 44 | impact 0.5 45 | tag "severity": 'medium' 46 | tag "gtitle": 'SRG-APP-000089-WSR-000047' 47 | tag "gid": 'V-41600' 48 | tag "rid": 'SV-54177r3_rule' 49 | tag "stig_id": 'SRG-APP-000089-WSR-000047' 50 | tag "fix_id": 'F-47059r3_fix' 51 | tag "cci": ['CCI-000169'] 52 | tag "nist": ['AU-12 a', ''] 53 | 54 | # Verify that the log_format directive exists 55 | if nginx_conf.params['http'].nil? 56 | impact 0.0 57 | describe 'This check is NA because no websites have been configured.' do 58 | skip 'This check is NA because no websites have been configured.' 59 | end 60 | else 61 | nginx_conf.params['http'].each do |http| 62 | describe 'Each http context' do 63 | it 'should include a log_format directive for logging minimum logable events.' do 64 | expect(http).to(include 'log_format') 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /controls/V-41609.rb: -------------------------------------------------------------------------------- 1 | control 'V-41609' do 2 | title "The NGINX web server must capture, record, and log all content related to a 3 | user session." 4 | desc "A user session to a web server is in the context of a user accessing a 5 | hosted application that extends to any plug-ins/modules and services that may 6 | execute on behalf of the user. 7 | 8 | The web server must be capable of enabling a setting for troubleshooting, 9 | debugging, or forensic gathering purposes which will log all user session 10 | information related to the hosted application session. Without the capability 11 | to capture, record, and log all content related to a user session, 12 | investigations into suspicious user activity would be hampered. 13 | " 14 | desc 'check', " 15 | Review the NGINX web server documentation and deployed configuration to determine 16 | if the NGINX web server captures and logs all content related to a user session. 17 | 18 | If there are no websites configured for NGINX, this check is Not Applicable. 19 | 20 | Check for the following: 21 | #grep the 'log_format' directive in the http context of the nginx.conf. 22 | 23 | If the the 'log_format' does not include the '$remote_user' variable, this is a finding. 24 | " 25 | desc 'fix', "Configure the 'log_format' directive in the http context of the nginx.conf to include the '$remote_user' 26 | variable to capture and log all content related to a user session." 27 | impact 0.5 28 | tag "severity": 'medium' 29 | tag "gtitle": 'SRG-APP-000093-WSR-000053' 30 | tag "gid": 'V-41609' 31 | tag "rid": 'SV-54186r3_rule' 32 | tag "stig_id": 'SRG-APP-000093-WSR-000053' 33 | tag "fix_id": 'F-47068r2_fix' 34 | tag "cci": ['CCI-001462'] 35 | tag "nist": ['AU-14 (2)', ''] 36 | 37 | # log_format - Context: http 38 | if nginx_conf.params['http'].nil? 39 | impact 0.0 40 | describe 'This check is NA because no websites have been configured.' do 41 | skip 'This check is NA because no websites have been configured.' 42 | end 43 | else 44 | nginx_conf.params['http'].each do |http| 45 | http['log_format'].each do |log_format| 46 | describe 'remote_user' do 47 | it 'should be part of every log format in the http context.' do 48 | expect(log_format.to_s).to(match(/.*?\$remote_user.*?/)) 49 | end 50 | end 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /controls/V-41611.rb: -------------------------------------------------------------------------------- 1 | control 'V-41611' do 2 | title 'The NGINX web server must initiate session logging upon start up.' 3 | desc "An attacker can compromise a web server during the startup process. If 4 | logging is not initiated until all the web server processes are started, key 5 | information may be missed and not available during a forensic investigation. To 6 | assure all logable events are captured, the web server must begin logging once 7 | the first web server process is initiated." 8 | 9 | desc 'check', "Review the NGINX web server documentation and deployed configuration to determine 10 | if the NGINX web server captures log data as soon as the NGINX web server is started. 11 | 12 | If there are no websites configured or if NGINX is not configured to serve files, 13 | this check is Not Applicable. 14 | 15 | Check for the following: 16 | # grep for 'access_log' and 'error_log' directives in the nginx.conf and any separated 17 | include configuration file. 18 | 19 | Execute the following commands: 20 | # file /access.log 21 | # file /error.log 22 | 23 | If the 'access_log' and 'error_log' directives cannot be found in NGINX configuration files, 24 | this check is Not Applicable. 25 | 26 | If the access.log and error.log files do not exist, this is a finding. 27 | " 28 | desc 'fix', "Enable loggin on the NGINX web server by configuring the 'access_log' and 'error_log' directives in the NGINX configuration 29 | file(s) to generate log records for system startup." 30 | impact 0.5 31 | tag "severity": 'medium' 32 | tag "gtitle": 'SRG-APP-000092-WSR-000055' 33 | tag "gid": 'V-41611' 34 | tag "rid": 'SV-54188r3_rule' 35 | tag "stig_id": 'SRG-APP-000092-WSR-000055' 36 | tag "fix_id": 'F-47070r2_fix' 37 | tag "cci": ['CCI-001464'] 38 | tag "nist": ['AU-14 (1)', ''] 39 | 40 | # Verify that access_log and error_log is enabled 41 | if nginx_conf.params['http'].nil? 42 | impact 0.0 43 | describe 'This check is NA because no websites have been configured.' do 44 | skip 'This check is NA because no websites have been configured.' 45 | end 46 | else 47 | nginx_conf.params['http'].each do |http| 48 | if http['access_log'].nil? 49 | impact 0.0 50 | describe 'This test is NA because the access_log directive has not been configured.' do 51 | skip 'This test is NA because access_log directive has not been configured.' 52 | end 53 | else 54 | http['access_log'].each do |access_log| 55 | access_log.each do |access_value| 56 | next unless access_value.include? 'access.log' 57 | 58 | describe file(access_value) do 59 | it 'The access log should exist.' do 60 | expect(subject).to(exist) 61 | end 62 | end 63 | end 64 | end 65 | end 66 | end 67 | if nginx_conf.params['error_log'].nil? 68 | impact 0.0 69 | describe 'This test is NA because the error_log directive has not been configured.' do 70 | skip 'This test is NA because error_log directive has not been configured.' 71 | end 72 | else 73 | nginx_conf.params['error_log'].each do |error_log| 74 | error_log.each do |error_value| 75 | next unless error_value.include? 'error.log' 76 | 77 | describe file(error_value) do 78 | it 'The error log should exist.' do 79 | expect(subject).to(exist) 80 | end 81 | end 82 | end 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /controls/V-41612.rb: -------------------------------------------------------------------------------- 1 | control 'V-41612' do 2 | title "The NGINX web server must produce log records containing sufficient 3 | information to establish what type of events occurred." 4 | desc "Web server logging capability is critical for accurate forensic 5 | analysis. Without sufficient and accurate information, a correct replay of the 6 | events cannot be determined. 7 | 8 | Ascertaining the correct type of event that occurred is important during 9 | forensic analysis. The correct determination of the event and when it occurred 10 | is important in relation to other events that happened at that same time. 11 | 12 | Without sufficient information establishing what type of log event 13 | occurred, investigation into the cause of event is severely hindered. Log 14 | record content that may be necessary to satisfy the requirement of this control 15 | includes, but is not limited to, time stamps, source and destination IP 16 | addresses, user/process identifiers, event descriptions, application-specific 17 | events, success/fail indications, file names involved, access control, or flow 18 | control rules invoked. 19 | " 20 | 21 | desc 'check', " 22 | Review the NGINX web server documentation and deployed configuration to determine 23 | if the NGINX web server contains sufficient information to establish what type of 24 | event occurred. 25 | 26 | If there are no websites configured for NGINX, this check is Not Applicable. 27 | 28 | Check for the following: 29 | # grep the 'log_format' directive in the http context of the nginx.conf. 30 | 31 | The logs will not include sufficient information if the 'log_format' directive does not exist. 32 | 33 | If the the 'log_format' directive does not exist, this is a finding. 34 | 35 | Example configuration: 36 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 37 | '$status $body_bytes_sent "'$http_referer'"' 38 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 39 | " 40 | desc 'fix', " 41 | Configure the 'log_format' directive in the nginx.conf file to look like the following: 42 | 43 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 44 | '$status $body_bytes_sent "'$http_referer'"' 45 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 46 | 47 | NOTE: Your log format may be using different variables based on the determination of 48 | what information is sufficient in order to establish what type of events occured." 49 | 50 | impact 0.5 51 | tag "severity": 'medium' 52 | tag "gtitle": 'SRG-APP-000095-WSR-000056' 53 | tag "gid": 'V-41612' 54 | tag "rid": 'SV-54189r3_rule' 55 | tag "stig_id": 'SRG-APP-000095-WSR-000056' 56 | tag "fix_id": 'F-47071r2_fix' 57 | tag "cci": ['CCI-000130'] 58 | tag "nist": %w(AU-3) 59 | 60 | # Verify that the log_format directive exists 61 | if nginx_conf.params['http'].nil? 62 | impact 0.0 63 | describe 'This check is NA because no websites have been configured.' do 64 | skip 'This check is NA because no websites have been configured.' 65 | end 66 | else 67 | nginx_conf.params['http'].each do |http| 68 | describe 'Each http context' do 69 | it 'should include a log_format directive for logging sufficient information.' do 70 | expect(http).to(include 'log_format') 71 | end 72 | end 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /controls/V-41613.rb: -------------------------------------------------------------------------------- 1 | control 'V-41613' do 2 | title "The NGINX web server must produce log records containing sufficient 3 | information to establish when (date and time) events occurred." 4 | desc "Web server logging capability is critical for accurate forensic 5 | analysis. Without sufficient and accurate information, a correct replay of the 6 | events cannot be determined. 7 | 8 | Ascertaining the correct order of the events that occurred is important 9 | during forensic analysis. Events that appear harmless by themselves might be 10 | flagged as a potential threat when properly viewed in sequence. By also 11 | establishing the event date and time, an event can be properly viewed with an 12 | enterprise tool to fully see a possible threat in its entirety. 13 | 14 | Without sufficient information establishing when the log event occurred, 15 | investigation into the cause of event is severely hindered. Log record content 16 | that may be necessary to satisfy the requirement of this control includes, but 17 | is not limited to, time stamps, source and destination IP addresses, 18 | user/process identifiers, event descriptions, application-specific events, 19 | success/fail indications, file names involved, access control, or flow control 20 | rules invoked. 21 | " 22 | desc 'check', "Review the NGINX web server documentation and deployment configuration 23 | to determine if the NGINX web server is configured to generate a date and time for each 24 | logged event. 25 | 26 | If there are no websites configured for NGINX, this check is Not Applicable. 27 | 28 | Check for the following: 29 | # grep for a 'log_format' directive in the http context of the nginx.conf. 30 | 31 | If the 'log_format' directive is not configured to contain the '$time_local' variable, 32 | this is a finding. 33 | " 34 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf to use the '$time_local' 35 | variable to log date and time with the event." 36 | 37 | impact 0.5 38 | tag "severity": 'medium' 39 | tag "gtitle": 'SRG-APP-000096-WSR-000057' 40 | tag "gid": 'V-41613' 41 | tag "rid": 'SV-54190r3_rule' 42 | tag "stig_id": 'SRG-APP-000096-WSR-000057' 43 | tag "fix_id": 'F-47072r2_fix' 44 | tag "cci": ['CCI-000131'] 45 | tag "nist": %w(AU-3) 46 | 47 | if nginx_conf.params['http'].nil? 48 | impact 0.0 49 | describe 'This check is NA because no websites have been configured.' do 50 | skip 'This check is NA because no websites have been configured.' 51 | end 52 | else 53 | nginx_conf.params['http'].each do |http| 54 | http['log_format'].each do |log_format| 55 | describe 'time_local' do 56 | it 'should be part of every log format in the http context.' do 57 | expect(log_format.to_s).to(match(/.*?\$time_local.*?/)) 58 | end 59 | end 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /controls/V-41614.rb: -------------------------------------------------------------------------------- 1 | control 'V-41614' do 2 | title "The NGINX web server must produce log records containing sufficient 3 | information to establish where within the web server the events occurred." 4 | desc "Web server logging capability is critical for accurate forensic 5 | analysis. Without sufficient and accurate information, a correct replay of the 6 | events cannot be determined. 7 | 8 | Ascertaining the correct location or process within the web server where 9 | the events occurred is important during forensic analysis. Correctly 10 | determining the web service, plug-in, or module will add information to the 11 | overall reconstruction of the logged event. For example, an event that occurred 12 | during communication to a cgi module might be handled differently than an event 13 | that occurred during a communication session to a user. 14 | 15 | Without sufficient information establishing where the log event occurred 16 | within the web server, investigation into the cause of event is severely 17 | hindered. Log record content that may be necessary to satisfy the requirement 18 | of this control includes, but is not limited to, time stamps, source and 19 | destination IP addresses, user/process identifiers, event descriptions, 20 | application-specific events, success/fail indications, file names involved, 21 | access control, or flow control rules invoked. 22 | " 23 | desc 'check', "Review the NGINX web server documentation and deployment configuration 24 | to determine if the web server is configured to generate sufficient information to resolve 25 | in which process within the web server the log event occurred. 26 | 27 | If there are no websites configured for NGINX, this check is Not Applicable. 28 | 29 | Check for the following: 30 | # grep the 'log_format' directive in the http context of the nginx.conf. 31 | 32 | The logs will not include sufficient information if the 'log_format' directive does not exist. 33 | 34 | If the the 'log_format' directive does not exist, this is a finding. 35 | 36 | Example configuration: 37 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 38 | '$status $body_bytes_sent "'$http_referer'"' 39 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 40 | " 41 | desc 'fix', " 42 | Configure the 'log_format' directive in the nginx.conf file to look like the following: 43 | 44 | log_format main '$remote_addr - $remote_user [$time_local] "'$request'"' 45 | '$status $body_bytes_sent "'$http_referer'"' 46 | '"'$http_user_agent'' ''$http_x_forwarded_for'"'; 47 | 48 | NOTE: Your log format may be using different variables based on the determination of what 49 | information is sufficient in order to establish where the event occured." 50 | 51 | impact 0.5 52 | tag "severity": 'medium' 53 | tag "gtitle": 'SRG-APP-000097-WSR-000058' 54 | tag "gid": 'V-41614' 55 | tag "rid": 'SV-54191r3_rule' 56 | tag "stig_id": 'SRG-APP-000097-WSR-000058' 57 | tag "fix_id": 'F-47073r2_fix' 58 | tag "cci": ['CCI-000132'] 59 | tag "nist": %w(AU-3) 60 | 61 | # Verify that the log_format directive exists 62 | if nginx_conf.params['http'].nil? 63 | impact 0.0 64 | describe 'This check is NA because no websites have been configured.' do 65 | skip 'This check is NA because no websites have been configured.' 66 | end 67 | else 68 | nginx_conf.params['http'].each do |http| 69 | describe 'Each http context' do 70 | it 'should include a log_format directive for logging sufficient information.' do 71 | expect(http).to(include 'log_format') 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /controls/V-41615.rb: -------------------------------------------------------------------------------- 1 | control 'V-41615' do 2 | title "The web server must produce log records containing sufficient 3 | information to establish the source of events." 4 | desc "Web server logging capability is critical for accurate forensic 5 | analysis. Without sufficient and accurate information, a correct replay of the 6 | events cannot be determined. 7 | 8 | Ascertaining the correct source, e.g. source IP, of the events is important 9 | during forensic analysis. Correctly determining the source will add information 10 | to the overall reconstruction of the logable event. By determining the source 11 | of the event correctly, analysis of the enterprise can be undertaken to 12 | determine if the event compromised other assets within the enterprise. 13 | 14 | Without sufficient information establishing the source of the logged event, 15 | investigation into the cause of event is severely hindered. Log record content 16 | that may be necessary to satisfy the requirement of this control includes, but 17 | is not limited to, time stamps, source and destination IP addresses, 18 | user/process identifiers, event descriptions, application-specific events, 19 | success/fail indications, file names involved, access control, or flow control 20 | rules invoked. 21 | " 22 | 23 | desc 'check', "Review the NGINX web server documentation and deployment 24 | configuration to determine if the NGINX web server is configured to generate 25 | sufficient information to resolve the source, e.g. source IP, of the log event. 26 | 27 | If there are no websites configured for NGINX, this check is Not Applicable. 28 | 29 | Check for the following: 30 | # grep for a 'log_format' directive in the http context of the nginx.conf. 31 | 32 | If the 'log_format' directive is not configured to contain the '$remote_addr', 33 | '$remote_user', and '$http_user_agent' variables, this is a finding. 34 | " 35 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf to use the 36 | '$remote_user', '$remote_addr', and '$http_user_agent' variables to generate 37 | the source of each logable event." 38 | 39 | impact 0.5 40 | tag "severity": 'medium' 41 | tag "gtitle": 'SRG-APP-000098-WSR-000059' 42 | tag "gid": 'V-41615' 43 | tag "rid": 'SV-54192r3_rule' 44 | tag "stig_id": 'SRG-APP-000098-WSR-000059' 45 | tag "fix_id": 'F-47074r2_fix' 46 | tag "cci": ['CCI-000133'] 47 | tag "nist": %w(AU-3) 48 | 49 | # log_format - Context: http 50 | if nginx_conf.params['http'].nil? 51 | impact 0.0 52 | describe 'This check is NA because no websites have been configured.' do 53 | skip 'This check is NA because no websites have been configured.' 54 | end 55 | else 56 | nginx_conf.params['http'].each do |http| 57 | http['log_format'].each do |log_format| 58 | describe 'remote_addr' do 59 | it 'should be part of every log format in http.' do 60 | expect(log_format.to_s).to(match(/.*?\$remote_addr.*?/)) 61 | end 62 | end 63 | describe 'remote_user' do 64 | it 'should be part of every log format in http.' do 65 | expect(log_format.to_s).to(match(/.*?\$remote_user.*?/)) 66 | end 67 | end 68 | describe 'http_user_agent' do 69 | it 'should be part of every log format in http.' do 70 | expect(log_format.to_s).to(match(/.*?\$http_user_agent.*?/)) 71 | end 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /controls/V-41616.rb: -------------------------------------------------------------------------------- 1 | control 'V-41616' do 2 | title "A NGINX web server, behind a load balancer or proxy server, must produce log 3 | records containing the client IP information as the source and destination and 4 | not the load balancer or proxy IP information with each event." 5 | desc "Web server logging capability is critical for accurate forensic 6 | analysis. Without sufficient and accurate information, a correct replay of the 7 | events cannot be determined. 8 | 9 | Ascertaining the correct source, e.g. source IP, of the events is important 10 | during forensic analysis. Correctly determining the source of events will add 11 | information to the overall reconstruction of the logable event. By determining 12 | the source of the event correctly, analysis of the enterprise can be undertaken 13 | to determine if events tied to the source occurred in other areas within the 14 | enterprise. 15 | 16 | A web server behind a load balancer or proxy server, when not configured 17 | correctly, will record the load balancer or proxy server as the source of every 18 | logable event. When looking at the information forensically, this information 19 | is not helpful in the investigation of events. The web server must record with 20 | each event the client source of the event. 21 | " 22 | desc 'check', "Review the deployment configuration to determine if the NGINX web 23 | server is sitting behind a proxy server. 24 | 25 | If the web server is not sitting behind a proxy server, this finding is Not Applicable. 26 | 27 | If the NGINX web server is behind a proxy server, review the documentation and deployment 28 | configuration to determine if the web server is configured to generate sufficient 29 | information to resolve the source, e.g. source IP, of the logged event and not the 30 | proxy server. 31 | 32 | If there are no websites configured for NGINX, this check is Not Applicable. 33 | 34 | Check for the following: 35 | # grep for a 'log_format' directive in the http context of the nginx.conf. 36 | 37 | If the 'log_format' directive is not configured to contain the '$realip_remote_addr' 38 | variable, this is a finding. 39 | " 40 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf to use the '$realip_remote_addr' 41 | variable to generate the client source, not the load balancer or proxy server, of each logable event." 42 | 43 | impact 0.5 44 | tag "severity": 'medium' 45 | tag "gtitle": 'SRG-APP-000098-WSR-000060' 46 | tag "gid": 'V-41616' 47 | tag "rid": 'SV-54193r3_rule' 48 | tag "stig_id": 'SRG-APP-000098-WSR-000060' 49 | tag "fix_id": 'F-47075r2_fix' 50 | tag "cci": ['CCI-000133'] 51 | tag "nist": %w(AU-3) 52 | 53 | if input('behind_proxy_server') == false 54 | impact 0.0 55 | describe 'This check is NA because the web server is not sitting behind a proxy server.' do 56 | skip 'This check is NA because the web server is not sitting behind a proxy server.' 57 | end 58 | elsif nginx_conf.params['http'].nil? 59 | impact 0.0 60 | describe 'This check is NA because no websites have been configured.' do 61 | skip 'This check is NA because no websites have been configured.' 62 | end 63 | else 64 | nginx_conf.params['http'].each do |http| 65 | http['log_format'].each do |log_format| 66 | describe 'realip_remote_addr' do 67 | it 'should be part of every log format in http.' do 68 | expect(log_format.to_s).to(match(/.*?\$realip_remote_addr.*?/)) 69 | end 70 | end 71 | end 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /controls/V-41617.rb: -------------------------------------------------------------------------------- 1 | control 'V-41617' do 2 | title "The NGINX web server must produce log records that contain sufficient 3 | information to establish the outcome (success or failure) of events." 4 | desc "Web server logging capability is critical for accurate forensic 5 | analysis. Without sufficient and accurate information, a correct replay of the 6 | events cannot be determined. 7 | 8 | Ascertaining the success or failure of an event is important during 9 | forensic analysis. Correctly determining the outcome will add information to 10 | the overall reconstruction of the logable event. By determining the success or 11 | failure of the event correctly, analysis of the enterprise can be undertaken to 12 | determine if events tied to the event occurred in other areas within the 13 | enterprise. 14 | 15 | Without sufficient information establishing the success or failure of the 16 | logged event, investigation into the cause of event is severely hindered. The 17 | success or failure also provides a means to measure the impact of an event and 18 | help authorized personnel to determine the appropriate response. Log record 19 | content that may be necessary to satisfy the requirement of this control 20 | includes, but is not limited to, time stamps, source and destination IP 21 | addresses, user/process identifiers, event descriptions, application-specific 22 | events, success/fail indications, file names involved, access control, or flow 23 | control rules invoked. 24 | " 25 | desc 'check', "Review the NGINX web server documentation and deployment 26 | configuration to determine if the web server is configured to generate the 27 | outcome (success or failure) of the event. 28 | 29 | If there are no websites configured for NGINX, this check is Not Applicable. 30 | 31 | Check for the following: 32 | # grep for a 'log_format' directive in the http context of the nginx.conf. 33 | 34 | If the 'log_format' directive is not configured to contain the '$status' variable, 35 | this is a finding. 36 | " 37 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf to use the 38 | '$status' variable to generate the outcome, success or failure, as part of each 39 | logable event." 40 | 41 | impact 0.5 42 | tag "severity": 'medium' 43 | tag "gtitle": 'SRG-APP-000099-WSR-000061' 44 | tag "gid": 'V-41617' 45 | tag "rid": 'SV-54194r3_rule' 46 | tag "stig_id": 'SRG-APP-000099-WSR-000061' 47 | tag "fix_id": 'F-47076r2_fix' 48 | tag "cci": ['CCI-000134'] 49 | tag "nist": %w(AU-3) 50 | 51 | if nginx_conf.params['http'].nil? 52 | impact 0.0 53 | describe 'This check is NA because no websites have been configured.' do 54 | skip 'This check is NA because no websites have been configured.' 55 | end 56 | else 57 | nginx_conf.params['http'].each do |http| 58 | http['log_format'].each do |log_format| 59 | describe 'status' do 60 | it 'should be part of every log format in http.' do 61 | expect(log_format.to_s).to(match(/.*?\$status.*?/)) 62 | end 63 | end 64 | end 65 | end 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /controls/V-41620.rb: -------------------------------------------------------------------------------- 1 | control 'V-41620' do 2 | title "The web server must produce log records containing sufficient 3 | information to establish the identity of any user/subject or process associated 4 | with an event." 5 | desc "Web server logging capability is critical for accurate forensic 6 | analysis. Without sufficient and accurate information, a correct replay of the 7 | events cannot be determined. 8 | 9 | Determining user accounts, processes running on behalf of the user, and 10 | running process identifiers also enable a better understanding of the overall 11 | event. User tool identification is also helpful to determine if events are 12 | related to overall user access or specific client tools. 13 | 14 | Log record content that may be necessary to satisfy the requirement of this 15 | control includes: time stamps, source and destination addresses, user/process 16 | identifiers, event descriptions, success/fail indications, file names involved, 17 | and access control or flow control rules invoked. 18 | " 19 | desc 'check', "Review the NGINX web server documentation and deployment 20 | configuration to determine if the web server can generate log data containing 21 | the user/subject identity. 22 | 23 | If there are no websites configured for NGINX, this check is Not Applicable. 24 | 25 | Check for the following: 26 | # grep for a 'log_format' directive in the http context of the nginx.conf. 27 | 28 | If the 'log_format' directive is not configured to contain the '$remote_user' 29 | variable, this is a finding. 30 | " 31 | desc 'fix', " 32 | Configure the 'log_format' directive in the nginx.conf to use the '$remote_user' 33 | variable to to include the user/subject identity or process as part of each log record." 34 | 35 | impact 0.5 36 | tag "severity": 'medium' 37 | tag "gtitle": 'SRG-APP-000100-WSR-000064' 38 | tag "gid": 'V-41620' 39 | tag "rid": 'SV-54197r3_rule' 40 | tag "stig_id": 'SRG-APP-000100-WSR-000064' 41 | tag "fix_id": 'F-47079r2_fix' 42 | tag "cci": ['CCI-001487'] 43 | tag "nist": %w(AU-3) 44 | 45 | if nginx_conf.params['http'].nil? 46 | impact 0.0 47 | describe 'This check is NA because no websites have been configured.' do 48 | skip 'This check is NA because no websites have been configured.' 49 | end 50 | else 51 | nginx_conf.params['http'].each do |http| 52 | http['log_format'].each do |log_format| 53 | describe 'remote_user' do 54 | it 'should be part of every log format in http.' do 55 | expect(log_format.to_s).to(match(/.*?\$remote_user.*?/)) 56 | end 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /controls/V-41668.rb: -------------------------------------------------------------------------------- 1 | control 'V-41668' do 2 | title "The NGINX web server must use the internal system clock to generate time 3 | stamps for log records." 4 | desc "Without an internal clock used as the reference for the time stored on 5 | each event to provide a trusted common reference for the time, forensic 6 | analysis would be impeded. Determining the correct time a particular event 7 | occurred on the web server is critical when conducting forensic analysis and 8 | investigating system events. 9 | 10 | If the internal clock is not used, the web server may not be able to 11 | provide time stamps for log messages. The web server can use the capability of 12 | an operating system or purpose-built module for this purpose. 13 | 14 | Time stamps generated by the web server shall include both date and time. 15 | The time may be expressed in Coordinated Universal Time (UTC), a modern 16 | continuation of Greenwich Mean Time (GMT), or local time with an offset from 17 | UTC. 18 | " 19 | desc 'check', "Review the NGINX web server documentation and deployment 20 | configuration to determine if the internal system clock is used for date and 21 | time stamps. If this is not feasible, an alternative workaround is to take an 22 | action that generates an entry in the log and then immediately query the operating system 23 | for the current time. A reasonable match between the two times will suffice as 24 | evidence that the system is using the internal clock for date and time stamps. 25 | 26 | If there are no websites configured for NGINX, this check is Not Applicable. 27 | 28 | Check for the following: 29 | # grep for a 'log_format' directive in the http context of the nginx.conf. 30 | 31 | If the 'log_format' directive is not configured to contain the '$time_local' 32 | variable, this is a finding. 33 | " 34 | desc 'fix', " 35 | Configure the 'log_format' directive in the nginx.conf to use the '$time_local' 36 | variable to use internal system clocks to generate date and time stamps for 37 | log records." 38 | 39 | impact 0.5 40 | tag "severity": 'medium' 41 | tag "gtitle": 'SRG-APP-000116-WSR-000066' 42 | tag "gid": 'V-41668' 43 | tag "rid": 'SV-54245r3_rule' 44 | tag "stig_id": 'SRG-APP-000116-WSR-000066' 45 | tag "fix_id": 'F-47127r2_fix' 46 | tag "cci": ['CCI-000159'] 47 | tag "nist": ['AU-8 a', ''] 48 | 49 | if nginx_conf.params['http'].nil? 50 | impact 0.0 51 | describe 'This check is NA because no websites have been configured.' do 52 | skip 'This check is NA because no websites have been configured.' 53 | end 54 | else 55 | nginx_conf.params['http'].each do |http| 56 | http['log_format'].each do |log_format| 57 | describe 'time_local' do 58 | it 'should be part of every log format in http.' do 59 | expect(log_format.to_s).to(match(/.*?\$time_local.*?/)) 60 | end 61 | end 62 | end 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /controls/V-41674.rb: -------------------------------------------------------------------------------- 1 | control 'V-41674' do 2 | title "The log data and records from the NGINX web server must be backed up onto a 3 | different system or media." 4 | desc "Protection of log data includes assuring log data is not accidentally 5 | lost or deleted. Backing up log records to an unrelated system or onto separate 6 | media than the system the web server is actually running on helps to assure 7 | that, in the event of a catastrophic system failure, the log records will be 8 | retained." 9 | 10 | desc 'check', " 11 | Review the NGINX web server documentation and deployed configuration to determine 12 | if the web server log records are backed up onto an unrelated system or media 13 | than the system being logged. 14 | 15 | Interview the Information System Security Officer, System Administrator, Web Manager, 16 | Webmaster, or developers as necessary to determine whether a tested and verifiable 17 | backup strategy has been implemented for web server software and all web server 18 | data files. 19 | 20 | Proposed questions: 21 | - Who maintains the backup and recovery procedures? 22 | - Do you have a copy of the backup and recovery procedures? 23 | - Where is the off-site backup location? 24 | - Is the contingency plan documented? 25 | - When was the last time the contingency plan was tested? 26 | - Are the test dates and results documented? 27 | 28 | If there is not a backup and recovery process for the web server, this is a finding. 29 | " 30 | desc 'fix', 'Document the NGINX web server backup procedures.' 31 | impact 0.5 32 | tag "severity": 'medium' 33 | tag "gtitle": 'SRG-APP-000125-WSR-000071' 34 | tag "gid": 'V-41674' 35 | tag "rid": 'SV-54251r3_rule' 36 | tag "stig_id": 'SRG-APP-000125-WSR-000071' 37 | tag "fix_id": 'F-47133r3_fix' 38 | tag "cci": ['CCI-001348'] 39 | tag "nist": ['AU-9 (2)', ''] 40 | 41 | describe "This test requires a Manual Review: Interview the ISSO, SA, WM, Webmaster, or developers to 42 | determine whether a tested and verifiable backup strategy has been implemented for web server software 43 | and all web server data files." do 44 | skip "This test requires a Manual Review: Interview the ISSO,SA, WM, Webmaster, or developers to 45 | determine whether a tested and verifiable backup strategy has been implemented for web server software 46 | and all web server data files." 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /controls/V-41684.rb: -------------------------------------------------------------------------------- 1 | control 'V-41684' do 2 | title "Expansion modules must be fully reviewed, tested, and signed before 3 | they can exist on a production NGINX web server." 4 | desc "In the case of a production web server, areas for content development 5 | and testing will not exist, as this type of content is only permissible on a 6 | development website. The process of developing on a functional production 7 | website entails a degree of trial and error and repeated testing. This process 8 | is often accomplished in an environment where debugging, sequencing, and 9 | formatting of content are the main goals. The opportunity for a malicious user 10 | to obtain files that reveal business logic and login schemes is high in this 11 | situation. The existence of such immature content on a web server represents a 12 | significant security risk that is totally avoidable. 13 | 14 | The web server must enforce, internally or through an external utility, the 15 | signing of modules before they are implemented into a production environment. 16 | By signing modules, the author guarantees that the module has been reviewed and 17 | tested before production implementation. 18 | " 19 | 20 | desc 'check', "Review the NGINX web server documentation and configuration 21 | to determine if web server modules are fully tested before implementation in 22 | the production environment. 23 | 24 | Review the web server for modules identified as test, debug, or backup and 25 | that cannot be reached through the hosted application. 26 | 27 | Review the web server to see if the web server or an external utility is in 28 | use to enforce the signing of modules before they are put into a production 29 | environment. 30 | 31 | Enter the following command to get a list of the modules installed: 32 | # nginx -V 33 | 34 | If there are any modules not required for operation or unsigned modules, this is a finding. 35 | " 36 | desc 'fix', "Use the configure script (available in the nginx download package) to exclude 37 | modules unsigned modules using the --without {module_name} option." 38 | 39 | impact 0.5 40 | tag "severity": 'medium' 41 | tag "gtitle": 'SRG-APP-000131-WSR-000073' 42 | tag "gid": 'V-41684' 43 | tag "rid": 'SV-54261r3_rule' 44 | tag "stig_id": 'SRG-APP-000131-WSR-000073' 45 | tag "fix_id": 'F-47143r2_fix' 46 | tag "cci": ['CCI-001749'] 47 | tag "nist": ['CM-5 (3)', ''] 48 | 49 | # Only allow a small subset of authorized modules in an attempt to minimize the number of modules active 50 | 51 | describe nginx do 52 | its('modules') { should be_in input('nginx_authorized_modules') } 53 | end 54 | describe nginx do 55 | its('modules') { should_not be_in input('nginx_unauthorized_modules') } 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /controls/V-41693.rb: -------------------------------------------------------------------------------- 1 | control 'V-41693' do 2 | title "The NGINX web server must only contain services and functions necessary for 3 | operation." 4 | desc "A web server can provide many features, services, and processes. Some 5 | of these may be deemed unnecessary or too unsecure to run on a production DoD 6 | system. 7 | 8 | The web server must provide the capability to disable, uninstall, or 9 | deactivate functionality and services that are deemed to be non-essential to 10 | the web server mission or can adversely impact server performance. 11 | " 12 | 13 | desc 'check', "Review the NGINX web server documentation and deployed configuration 14 | to determine if web server features, services, and processes are installed that are not 15 | needed for hosted application deployment. 16 | 17 | If the site requires the use of a particular piece of software, the ISSO will need 18 | to maintain documentation identifying this software as necessary for operations. The 19 | software must be operated at the vendor’s current patch level and must be a supported 20 | vendor release. 21 | 22 | If programs or utilities that meet the above criteria are installed on the Web Server, 23 | and appropriate documentation and signatures are in evidence, this is not a finding. 24 | 25 | Determine whether the web server is configured with unnecessary software. 26 | 27 | Determine whether processes other than those that support the web server are loaded 28 | and/or run on the web server. 29 | 30 | Examples of software that should not be on the web server are all web development 31 | tools, office suites (unless the web server is a private web development server), 32 | compilers, and other utilities that are not part of the web server suite or the basic 33 | operating system. 34 | 35 | Check the directory structure of the server and ensure that additional, unintended, or 36 | unneeded applications are not loaded on the system. 37 | 38 | If, after review of the application on the system, there is no justification for the 39 | identified software, this is a finding. 40 | " 41 | desc 'fix', "Uninstall or deactivate features, services, and processes not 42 | needed by the NGINX web server for operation." 43 | impact 0.5 44 | tag "severity": 'medium' 45 | tag "gtitle": 'SRG-APP-000141-WSR-000075' 46 | tag "gid": 'V-41693' 47 | tag "rid": 'SV-54270r3_rule' 48 | tag "stig_id": 'SRG-APP-000141-WSR-000075' 49 | tag "fix_id": 'F-47152r2_fix' 50 | tag "cci": ['CCI-000381'] 51 | tag "nist": ['CM-7 a', ''] 52 | 53 | describe "This test requires a Manual Review: Check the directory structure of the server and 54 | ensure that additional, unintended, or unneeded applications are not loaded on the system." do 55 | skip "This test requires a Manual Review: Check the directory structure of the server and 56 | ensure that additional, unintended, or unneeded applications are not loaded on the system." 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /controls/V-41694.rb: -------------------------------------------------------------------------------- 1 | control 'V-41694' do 2 | title 'The NGINX web server must not be a proxy server.' 3 | desc "A web server should be primarily a web server or a proxy server but 4 | not both, for the same reasons that other multi-use servers are not 5 | recommended. Scanning for web servers that will also proxy requests into an 6 | otherwise protected network is a very common attack making the attack 7 | anonymous." 8 | 9 | desc 'check', "Review the NGINX web server documentation and deployed 10 | configuration to determine if the web server is also a proxy server. 11 | 12 | If the NGINX server is a proxy server and not a web server, this check is Not Applicable. 13 | 14 | If NGINX is not configured to serve files, this check is Not Applicable. 15 | 16 | Execute the following command: 17 | 18 | # nginx -V 19 | 20 | Verify the ‘nginx_http_proxy_module’ module is not installed. 21 | 22 | # grep the 'proxy_pass' directive in the location context of the nginx.conf and any 23 | separated include configuration file. 24 | 25 | If the 'nginx_http_proxy_module' module is installed and the 'proxy_pass' directive exists, 26 | this is a finding. 27 | " 28 | desc 'fix', " 29 | Use the configure script (available in the nginx download package) to exclude the 30 | 'nginx_http_proxy_module' module by using the --without {module_name} option. 31 | 32 | Ensure the 'proxy_pass' directive is not enabled in the NGINX configuration file(s). 33 | " 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000141-WSR-000076' 37 | tag "gid": 'V-41694' 38 | tag "rid": 'SV-54271r3_rule' 39 | tag "stig_id": 'SRG-APP-000141-WSR-000076' 40 | tag "fix_id": 'F-47153r3_fix' 41 | tag "cci": ['CCI-000381'] 42 | tag "nist": ['CM-7 a', ''] 43 | 44 | if input('proxy_server') == 'true' 45 | impact 0.0 46 | describe 'This check is NA because NGINX server is a proxy server and not a web server' do 47 | skip 'This check is NA because NGINX server is a proxy server and not a web server' 48 | end 49 | elsif nginx_conf.locations.nil? 50 | impact 0.0 51 | describe 'This check is NA because NGINX has not been configured to serve files.' do 52 | skip 'This check is NA because NGINX has not been configured to serve files.' 53 | end 54 | else 55 | describe nginx do 56 | its('modules') { should_not include 'http_proxy' } 57 | end 58 | nginx_conf.locations.each do |location| 59 | describe 'proxy_pass' do 60 | it 'should not exist in the location context.' do 61 | expect(location.params).to_not(include 'proxy_pass') 62 | end 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /controls/V-41695.rb: -------------------------------------------------------------------------------- 1 | control 'V-41695' do 2 | title "The NGINX web server must provide install options to exclude the 3 | installation of documentation, sample code, example applications, and 4 | tutorials." 5 | desc "Web server documentation, sample code, example applications, and 6 | tutorials may be an exploitable threat to a web server because this type of 7 | code has not been evaluated and approved. A production web server must only 8 | contain components that are operationally necessary (e.g., compiled code, 9 | scripts, web-content, etc.). 10 | 11 | Any documentation, sample code, example applications, and tutorials must be 12 | removed from a production web server. To make certain that the documentation 13 | and code are not installed or uninstalled completely; the web server must offer 14 | an option as part of the installation process to exclude these packages or to 15 | uninstall the packages if necessary. 16 | " 17 | 18 | desc 'check', " 19 | Review the NGINX web server documentation and deployment configuration to 20 | determine if the web server contains documentation, sample code, example 21 | applications, or tutorials. 22 | 23 | If the site requires the use of a particular piece of software, verify that 24 | the Information System Security Officer (ISSO) maintains documentation 25 | identifying this software as necessary for operations. The software must 26 | be operated at the vendor’s current patch level and must be a supported 27 | vendor release. 28 | 29 | If programs or utilities that meet the above criteria are installed on the 30 | web server and appropriate documentation and signatures are in evidence, 31 | this is not a finding. 32 | 33 | Determine whether the web server is configured with unnecessary software. 34 | This may change with the software versions, but the following are some 35 | examples of what to look for (This should not be the definitive list of 36 | sample files, but only an example of the common samples that are provided 37 | with the associated web server. This list will be updated as additional 38 | information is discovered.): 39 | 40 | # ls -Ll /usr/share/man/man8/nginx.8.gz 41 | 42 | Determine whether processes other than those that support the web server 43 | are loaded and/or run on the web server. 44 | 45 | Examples of software that should not be on the web server are all web 46 | development tools, office suites (unless the web server is a private 47 | web development server), compilers, and other utilities that are not 48 | part of the web server suite or the basic operating system. 49 | 50 | Check the directory structure of the server and verify that additional, 51 | unintended, or unneeded applications are not loaded on the system. 52 | 53 | " 54 | desc 'fix', 'Remove any unnecessary applications per ISSO documentation.' 55 | impact 0.5 56 | tag "severity": 'medium' 57 | tag "gtitle": 'SRG-APP-000141-WSR-000077' 58 | tag "gid": 'V-41695' 59 | tag "rid": 'SV-54272r3_rule' 60 | tag "stig_id": 'SRG-APP-000141-WSR-000077' 61 | tag "fix_id": 'F-47154r2_fix' 62 | tag "cci": ['CCI-000381'] 63 | tag "nist": ['CM-7 a', ''] 64 | 65 | if input('nginx_disallowed_file_list').empty? 66 | describe 'This check is skipped because the disallowed files list should not be empty.' do 67 | skip 'This check is skipped because the disallowed files list should not be empty.' 68 | end 69 | else 70 | input('nginx_disallowed_file_list').each do |file| 71 | describe file(file) do 72 | it { should_not exist } 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /controls/V-41696.rb: -------------------------------------------------------------------------------- 1 | control 'V-41696' do 2 | title "Web server accounts not utilized by installed features (i.e., tools, 3 | utilities, specific services, etc.) must not be created and must be deleted 4 | when the NGINX web server feature is uninstalled." 5 | desc "When accounts used for web server features such as documentation, 6 | sample code, example applications, tutorials, utilities, and services are 7 | created even though the feature is not installed, they become an exploitable 8 | threat to a web server. 9 | 10 | These accounts become inactive, are not monitored through regular use, and 11 | passwords for the accounts are not created or updated. An attacker, through 12 | very little effort, can use these accounts to gain access to the web server and 13 | begin investigating ways to elevate the account privileges. 14 | 15 | The accounts used for web server features not installed must not be created 16 | and must be deleted when these features are uninstalled. 17 | " 18 | 19 | desc 'check', "Review the NGINX web server documentation to determine the user 20 | accounts created when particular features are installed. 21 | 22 | Verify that user specified is an authorized user: 23 | #grep the 'user' directive in the main context of the nginx.conf file 24 | 25 | If the 'user' directive cannot be found in NGINX configuration files, 26 | this check is Not Applicable. 27 | 28 | Verify the accounts specified in the 'user' directive has an entry in /etc/passwd: 29 | # grep -w '' /etc/passwd' 30 | 31 | If any accounts exist that are not used by the installed features, this is a finding. 32 | " 33 | desc 'fix', "Ensure at least one 'user' directive exists in the nginx.conf file 34 | and remove user accounts not used by the installed NGINX web server features." 35 | 36 | impact 0.5 37 | tag "severity": 'medium' 38 | tag "gtitle": 'SRG-APP-000141-WSR-000078' 39 | tag "gid": 'V-41696' 40 | tag "rid": 'SV-54273r3_rule' 41 | tag "stig_id": 'SRG-APP-000141-WSR-000078' 42 | tag "fix_id": 'F-47155r2_fix' 43 | tag "cci": ['CCI-000381'] 44 | tag "nist": ['CM-7 a', ''] 45 | 46 | if nginx_conf.params['user'].nil? 47 | impact 0.0 48 | describe 'This check is NA because the user directive is not configured properly.' do 49 | skip 'This check is NA because the user directive is not configured properly.' 50 | end 51 | else 52 | nginx_conf.params['user'].each do |user| 53 | user.each do |value| 54 | describe 'The value of user' do 55 | it 'should be the default nginx user or other authorized user.' do 56 | expect(value).to (eq input('nginx_owner')).or(be_in(input('authorized_user_list'))) 57 | end 58 | end 59 | describe 'The password file' do 60 | it 'should include the nginx account.' do 61 | expect(command("grep -w #{value} /etc/passwd").stdout).to(match(/.*?#{value}.*?/)) 62 | end 63 | end 64 | end 65 | end 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /controls/V-41698.rb: -------------------------------------------------------------------------------- 1 | control 'V-41698' do 2 | title "The NGINX web server must provide install options to exclude installation of 3 | utility programs, services, plug-ins, and modules not necessary for operation." 4 | desc "Just as running unneeded services and protocols is a danger to the web 5 | server at the lower levels of the OSI model, running unneeded utilities and 6 | programs is also a danger at the application layer of the OSI model. Office 7 | suites, development tools, and graphical editors are examples of such programs 8 | that are troublesome. 9 | 10 | Individual productivity tools have no legitimate place or use on an 11 | enterprise, production web server and they are also prone to their own security 12 | risks. The web server installation process must provide options allowing the 13 | installer to choose which utility programs, services, and modules are to be 14 | installed or removed. By having a process for installation and removal, the web 15 | server is guaranteed to be in a more stable and secure state than if these 16 | services and programs were installed and removed manually. 17 | " 18 | 19 | desc 'check', "Review the NGINX web server documentation and deployment 20 | configuration to determine which web server utilities, services, and modules 21 | are installed. Verify these options are essential to the operation of the 22 | web server. Also, confirm the web server install process offers an option to 23 | exclude these utilities, services, and modules from installation that are not 24 | needed for operation and that there is an uninstall option for their removal. 25 | 26 | Enter the following command to get a list of the modules installed: 27 | # nginx -V 28 | 29 | If there are more modules installed than are needed for the operation of 30 | the NGINX web server, this is a finding. 31 | " 32 | desc 'fix', "Use the configure script (available in the nginx download package) 33 | to exclude modules not needed by NGINX using the --without {module_name} option." 34 | 35 | impact 0.5 36 | tag "severity": 'medium' 37 | tag "gtitle": 'SRG-APP-000141-WSR-000080' 38 | tag "gid": 'V-41698' 39 | tag "rid": 'SV-54275r3_rule' 40 | tag "stig_id": 'SRG-APP-000141-WSR-000080' 41 | tag "fix_id": 'F-47157r2_fix' 42 | tag "cci": ['CCI-000381'] 43 | tag "nist": ['CM-7 a', ''] 44 | 45 | # Only allow a small subset of authorized modules in an attempt to minimize the number of modules active 46 | describe nginx do 47 | its('modules') { should be_in input('nginx_authorized_modules') } 48 | end 49 | describe nginx do 50 | its('modules') { should_not be_in input('nginx_unauthorized_modules') } 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /controls/V-41699.rb: -------------------------------------------------------------------------------- 1 | control 'V-41699' do 2 | title "The NGINX web server must have Multipurpose Internet Mail Extensions (MIME) 3 | that invoke OS shell programs disabled." 4 | desc "Controlling what a user of a hosted application can access is part of 5 | the security posture of the web server. Any time a user can access more 6 | functionality than is needed for the operation of the hosted application poses 7 | a security issue. A user with too much access can view information that is not 8 | needed for the user's job role, or the user could use the function in an 9 | unintentional manner. 10 | 11 | A MIME tells the web server what type of program various file types and 12 | extensions are and what external utilities or programs are needed to execute 13 | the file type. 14 | 15 | A shell is a program that serves as the basic interface between the user 16 | and the operating system, so hosted application users must not have access to 17 | these programs. Shell programs may execute shell escapes and can then perform 18 | unauthorized activities that could damage the security posture of the web 19 | server. 20 | " 21 | 22 | desc 'check', "Review the web server documentation and deployment configuration to 23 | determine if the OS shell is accessible by any MIME types that are enabled. 24 | 25 | Enter the following command to find the mime.types file: 26 | # find / mime.types 27 | 28 | Review the 'mime.types' file. 29 | 30 | If there are any MIME types enabled for .exe, .dll, .com, .bat, and .csh 31 | programs, this is a finding. 32 | " 33 | desc 'fix', "Edit the 'mime.types' file and disable all MIME types for .exe, 34 | .dll, .com, .bat, and .csh programs. 35 | " 36 | 37 | impact 0.5 38 | tag "severity": 'medium' 39 | tag "gtitle": 'SRG-APP-000141-WSR-000081' 40 | tag "gid": 'V-41699' 41 | tag "rid": 'SV-54276r3_rule' 42 | tag "stig_id": 'SRG-APP-000141-WSR-000081' 43 | tag "fix_id": 'F-47158r2_fix' 44 | tag "cci": ['CCI-000381'] 45 | tag "nist": ['CM-7 a', ''] 46 | 47 | # Checks for enabled mime types against the disallowed list 48 | if input('nginx_disallowed_mime_type').empty? 49 | describe 'This check is skipped because the disallowed mime list should not be empty.' do 50 | skip 'This check is skipped because the disallowed mime list should not be empty.' 51 | end 52 | else 53 | input('nginx_disallowed_mime_type').each do |mime_type| 54 | describe "The MIME type: #{mime_type}" do 55 | it 'should not be enabled in the configuration' do 56 | expect(command("grep -w #{mime_type} " + input('mime_type_path')).stdout).to(eq '') 57 | end 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /controls/V-41700.rb: -------------------------------------------------------------------------------- 1 | control 'V-41700' do 2 | title "The web server must allow the mappings to unused and vulnerable 3 | scripts to be removed." 4 | desc "Scripts allow server side processing on behalf of the hosted 5 | application user or as processes needed in the implementation of hosted 6 | applications. Removing scripts not needed for application operation or deemed 7 | vulnerable helps to secure the web server. 8 | 9 | To assure scripts are not added to the web server and run maliciously, 10 | those script mappings that are not needed or used by the web server for hosted 11 | application operation must be removed. 12 | " 13 | 14 | desc 'check', " 15 | Review the web server documentation and deployment configuration to 16 | determine what script mappings are available. 17 | 18 | Review the scripts used by the web server and the hosted applications. 19 | 20 | If NGINX is not configured to serve files, this check is Not Applicable. 21 | 22 | Check the following: 23 | # grep 'fastcgi_param' directive in the location context of the nginx.conf 24 | and any separated include configuration file. 25 | 26 | If the 'fastcgi_param' directive cannot be found in NGINX configuration files, 27 | this check is Not Applicable. 28 | 29 | Review the 'fastcgi_param' directive and go into each directory to locate 30 | cgi-bin scripts with the following command: 31 | # ls 32 | 33 | If the 'fastcgi_params' directive exists and if there are any scripts are 34 | present that are unused or vulnerable, this is a finding. 35 | 36 | If this is not documented and approved by the Information System Security 37 | Officer (ISSO), this is a finding. 38 | " 39 | desc 'fix', "Review script mappings that are configured in the 'fastcgi_param' 40 | directive, if it exists, and remove scripts that are not needed for the NGINX web 41 | server and hosted application operation." 42 | 43 | impact 0.5 44 | tag "severity": 'medium' 45 | tag "gtitle": 'SRG-APP-000141-WSR-000082' 46 | tag "gid": 'V-41700' 47 | tag "rid": 'SV-54277r3_rule' 48 | tag "stig_id": 'SRG-APP-000141-WSR-000082' 49 | tag "fix_id": 'F-47159r2_fix' 50 | tag "cci": ['CCI-000381'] 51 | tag "nist": ['CM-7 a', ''] 52 | 53 | if nginx_conf.locations.nil? 54 | impact 0.0 55 | describe 'This check is NA because NGINX has not been configured to serve files.' do 56 | skip 'This check is NA because NGINX has not been configured to serve files.' 57 | end 58 | else 59 | nginx_conf.locations.each do |location| 60 | if location.params['fastcgi_param'].nil? 61 | impact 0.0 62 | describe 'This check is NA because the fastcgi_param directive has not been configured.' do 63 | skip 'This check is NA because the fastcgi_param directive has not been configured.' 64 | end 65 | else 66 | location.params['fastcgi_param'].each do |value| 67 | next unless value[0] == 'SCRIPT_FILENAME' 68 | 69 | cgi_script_path = command("echo #{value[1]} | cut -d '$' -f 1").stdout 70 | cgi_scripts = command("ls #{cgi_script_path}").stdout.split("\n") 71 | cgi_scripts.uniq! 72 | 73 | cgi_scripts.each do |script| 74 | describe(script) do 75 | it { should be_in input('nginx_allowed_script_list') } 76 | end 77 | end 78 | end 79 | end 80 | end 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /controls/V-41701.rb: -------------------------------------------------------------------------------- 1 | control 'V-41701' do 2 | title "The NGINX web server must have resource mappings set to disable the serving 3 | of certain file types." 4 | desc "Resource mapping is the process of tying a particular file type to a 5 | process in the web server that can serve that type of file to a requesting 6 | client and to identify which file types are not to be delivered to a client. 7 | 8 | By not specifying which files can and which files cannot be served to a 9 | user, the web server could deliver to a user web server configuration files, 10 | log files, password files, etc. 11 | 12 | The web server must only allow hosted application file types to be served 13 | to a user and all other types must be disabled. 14 | " 15 | 16 | desc 'check', "Review the web server documentation and deployment configuration to 17 | determine what types of files are being used for the hosted applications. 18 | 19 | Enter the following command to find the mime.types file: 20 | # find / mime.types 21 | 22 | Review the 'mime.types' file. 23 | 24 | If there are any MIME types enabled for .exe, .dll, .com, .bat, and 25 | .csh programs, this is a finding. 26 | 27 | " 28 | desc 'fix', "Configure the web server to disable all MIME types that invoke 29 | OS shell programs. Edit the 'mime.types' file and disable MIME types for .exe, 30 | .dll, .com, .bat, and .csh programs." 31 | impact 0.5 32 | tag "severity": 'medium' 33 | tag "gtitle": 'SRG-APP-000141-WSR-000083' 34 | tag "gid": 'V-41701' 35 | tag "rid": 'SV-54278r3_rule' 36 | tag "stig_id": 'SRG-APP-000141-WSR-000083' 37 | tag "fix_id": 'F-47160r2_fix' 38 | tag "cci": ['CCI-000381'] 39 | tag "nist": ['CM-7 a', ''] 40 | 41 | # Checks for enabled mime types against the disallowed list 42 | if input('nginx_disallowed_mime_type').empty? 43 | describe 'This check is skipped because the disallowed mime list should not be empty.' do 44 | skip 'This check is skipped because the disallowed mime list should not be empty.' 45 | end 46 | else 47 | input('nginx_disallowed_mime_type').each do |mime_type| 48 | describe "The MIME type: #{mime_type}" do 49 | it 'should not be enabled in the configuration' do 50 | expect(command("grep -w #{mime_type} " + input('mime_type_path')).stdout).to(eq '') 51 | end 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /controls/V-41702.rb: -------------------------------------------------------------------------------- 1 | control 'V-41702' do 2 | title 'The web server must have Web Distributed Authoring (WebDAV) disabled.' 3 | desc "A web server can be installed with functionality that, just by its 4 | nature, is not secure. Web Distributed Authoring (WebDAV) is an extension to 5 | the HTTP protocol that, when developed, was meant to allow users to create, 6 | change, and move documents on a server, typically a web server or web share. 7 | Allowing this functionality, development, and deployment is much easier for web 8 | authors. 9 | 10 | WebDAV is not widely used and has serious security concerns because it may 11 | allow clients to modify unauthorized files on the web server. 12 | " 13 | 14 | desc 'check', "Review the web server documentation and deployment configuration to 15 | determine if Web Distributed Authoring (WebDAV) is enabled. 16 | 17 | Execute the following command: 18 | 19 | # nginx -V 20 | 21 | Verify the ‘ngx_http_dav_module’ module is not installed. 22 | " 23 | desc 'fix', "Use the configure script (available in the nginx download package) to 24 | exclude the 'ngx_http_dav_module' module by using the --without {module_name} option." 25 | 26 | impact 0.5 27 | tag "severity": 'medium' 28 | tag "gtitle": 'SRG-APP-000141-WSR-000085' 29 | tag "gid": 'V-41702' 30 | tag "rid": 'SV-54279r3_rule' 31 | tag "stig_id": 'SRG-APP-000141-WSR-000085' 32 | tag "fix_id": 'F-47161r2_fix' 33 | tag "cci": ['CCI-000381'] 34 | tag "nist": ['CM-7 a', ''] 35 | 36 | describe nginx do 37 | its('modules') { should_not include 'ngx_http_dav' } 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /controls/V-41704.rb: -------------------------------------------------------------------------------- 1 | control 'V-41704' do 2 | title "Users and scripts running on behalf of users must be contained to the 3 | document root or home directory tree of the NGINX web server." 4 | desc "A web server is designed to deliver content and execute scripts or 5 | applications on the request of a client or user. Containing user requests to 6 | files in the directory tree of the hosted web application and limiting the 7 | execution of scripts and applications guarantees that the user is not accessing 8 | information protected outside the application's realm. 9 | 10 | The web server must also prohibit users from jumping outside the hosted 11 | application directory tree through access to the user's home directory, 12 | symbolic links or shortcuts, or through search paths for missing files. 13 | " 14 | 15 | desc 'check', "Review the NGINX web server documentation and configuration 16 | to determine where the document root or home directory for each application 17 | hosted by the web server is located. 18 | 19 | If NGINX is not configured to serve files, this check is Not Applicable. 20 | 21 | Check for the following: 22 | # grep for a 'deny' directive in the root directoy location context of the 23 | nginx.conf and any separated include configuration file. 24 | 25 | Verify that there is a 'deny all' set in each root directory location context 26 | to deny access by default. If a 'deny all' is not set in each location, 27 | this is a finding." 28 | 29 | desc 'fix', "Add a 'deny all' in each location context in the NGINX configuration 30 | file(s) to contain users and scripts to each hosted application's domain. 31 | 32 | Example configuration: 33 | 34 | 'location / { 35 | deny all; 36 | }'" 37 | impact 0.5 38 | tag "severity": 'medium' 39 | tag "gtitle": 'SRG-APP-000141-WSR-000087' 40 | tag "gid": 'V-41704' 41 | tag "rid": 'SV-54281r3_rule' 42 | tag "stig_id": 'SRG-APP-000141-WSR-000087' 43 | tag "fix_id": 'F-47163r2_fix' 44 | tag "cci": ['CCI-000381'] 45 | tag "nist": ['CM-7 a', ''] 46 | 47 | if nginx_conf.locations.empty? 48 | impact 0.0 49 | describe 'This check is NA because NGINX has not been configured to serve files.' do 50 | skip 'This check is NA because NGINX has not been configured to serve files.' 51 | end 52 | else 53 | nginx_conf.locations.each do |location| 54 | deny_values = [] 55 | deny_values.push(location.params['deny']) unless location.params['deny'].nil? 56 | describe 'Each location context' do 57 | it 'should include an deny all directive.' do 58 | expect(deny_values.to_s).to(include 'all') 59 | end 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /controls/V-41706.rb: -------------------------------------------------------------------------------- 1 | control 'V-41706' do 2 | title "The NGINX web server must be configured to use a specified IP address and 3 | port." 4 | desc "The web server must be configured to listen on a specified IP address 5 | and port. Without specifying an IP address and port for the web server to 6 | utilize, the web server will listen on all IP addresses available to the 7 | hosting server. If the web server has multiple IP addresses, i.e., a 8 | management IP address, the web server will also accept connections on the 9 | management IP address. 10 | 11 | Accessing the hosted application through an IP address normally used for 12 | non-application functions opens the possibility of user access to resources, 13 | utilities, files, ports, and protocols that are protected on the desired 14 | application IP address. 15 | " 16 | 17 | desc 'check', "Review the NGINX web server documentation and deployment 18 | configuration to determine whether the web server is configured to listen 19 | on a specified IP address and port. 20 | 21 | If NGINX is not configured to serve files, this check is Not Applicable. 22 | 23 | Check for the following: 24 | # grep the 'listen' directive in the server context of the nginx.conf and any 25 | separated include configuration file. 26 | 27 | If the 'listen' directive cannot be found in NGINX configuration files, 28 | this check is Not Applicable. 29 | 30 | Verify that any enabled 'listen' directives specify both an IP address and 31 | port number. 32 | 33 | If the 'listen' directive is found with only an IP address or only a port number 34 | specified, this is finding. 35 | 36 | If the IP address is all zeros (i.e., 0.0.0.0:80 or [::ffff:0.0.0.0]:80), 37 | this is a finding. 38 | " 39 | desc 'fix', "Configure the 'listen' directive in the server context of the NGINX 40 | configuration file(s) to listen on a specific IP address and port." 41 | 42 | impact 0.5 43 | tag "severity": 'medium' 44 | tag "gtitle": 'SRG-APP-000142-WSR-000089' 45 | tag "gid": 'V-41706' 46 | tag "rid": 'SV-54283r3_rule' 47 | tag "stig_id": 'SRG-APP-000142-WSR-000089' 48 | tag "fix_id": 'F-47165r2_fix' 49 | tag "cci": ['CCI-000382'] 50 | tag "nist": ['CM-7 b', ''] 51 | 52 | if nginx_conf.servers.nil? 53 | impact 0.0 54 | describe 'This check is NA because NGINX has not been configured to serve files.' do 55 | skip 'This check is NA because NGINX has not been configured to serve files.' 56 | end 57 | else 58 | nginx_conf.servers.each do |server| 59 | describe 'The listen directive' do 60 | if server.params['listen'].nil? 61 | impact 0.0 62 | describe 'This test is NA because the listen directive has not been configured.' do 63 | skip 'This test is NA because the listen directive has not been configured.' 64 | end 65 | else 66 | server.params['listen'].each do |listen| 67 | it 'should include both the IP and port number.' do 68 | expect(listen.join).to(match(/[0-9]+(?:\.[0-9]+){3}|[a-zA-Z]:[0-9]+/)) 69 | end 70 | it 'should not be 0.0.0.0:80 or [::ffff:0.0.0.0]:80.' do 71 | expect(listen.join.split(':').first).not_to(cmp('0.0.0.0')) 72 | expect(listen.join.split(':').first).not_to(cmp('[::ffff:0.0.0.0]')) 73 | end 74 | end 75 | end 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /controls/V-41731.rb: -------------------------------------------------------------------------------- 1 | control 'V-41731' do 2 | title "Only authenticated system administrators or the designated PKI Sponsor 3 | for the NGINX web server must have access to the web servers private key." 4 | desc "The web server's private key is used to prove the identity of the 5 | server to clients and securely exchange the shared secret key used to encrypt 6 | communications between the web server and clients. 7 | 8 | By gaining access to the private key, an attacker can pretend to be an 9 | authorized server and decrypt the SSL traffic between a client and the web 10 | server. 11 | " 12 | 13 | desc 'check', "If the NGINX web server does not have a private key, this 14 | check is Not Applicable. 15 | 16 | Review the web server documentation and deployed configuration to determine 17 | whether only authenticated system administrators and the designated PKI Sponsor 18 | for the web server can access the web server private key. 19 | 20 | If NGINX is not configured to serve files, this check is Not Applicable. 21 | 22 | Check for the following: 23 | # grep the 'ssl_certificate' and 'ssl_certificate_key' directives in the server 24 | context of the nginx.conf and any separated include configuration file. 25 | 26 | # ls -l on these files to determine ownership of the file 27 | 28 | -The SA or Designated PKI Sponsor should be the owner of the web server private key 29 | - Permissions on these files should be 400 30 | 31 | If the private key is accessible by unauthenticated or unauthorized users, this is a finding. 32 | " 33 | desc 'fix', "Configure the NGINX web server to ensure only authenticated and authorized 34 | users can access the web server's private key. 35 | 36 | Run the following commands: 37 | 38 | # cd <'private key path'>/ 39 | # chown <'authorized user'>:<'authorized group'> <'private key file'> 40 | # chmod 400 <'private key file'> 41 | " 42 | impact 0.5 43 | tag "severity": 'medium' 44 | tag "gtitle": 'SRG-APP-000176-WSR-000096' 45 | tag "gid": 'V-41731' 46 | tag "rid": 'SV-54308r3_rule' 47 | tag "stig_id": 'SRG-APP-000176-WSR-000096' 48 | tag "fix_id": 'F-47190r2_fix' 49 | tag "cci": ['CCI-000186'] 50 | tag "nist": ['IA-5 (2) (b)', ''] 51 | 52 | if nginx_conf.servers.nil? 53 | impact 0.0 54 | describe 'This check is NA because NGINX has not been configured to serve files.' do 55 | skip 'This check is NA because NGINX has not been configured to serve files.' 56 | end 57 | else 58 | nginx_conf.servers.each do |server| 59 | if server.params['ssl_certificate'].nil? 60 | impact 0.0 61 | describe 'This test is NA because the ssl_certificate directive has not been configured.' do 62 | skip 'This test is NA because the ssl_certificate directive has not been configured.' 63 | end 64 | else 65 | server.params['ssl_certificate'].each do |certificate| 66 | certificate_string = certificate.to_s 67 | describe file(certificate.join) do 68 | its('owner') { should be_in input('sys_admin') } 69 | its('group') { should be_in input('sys_admin_group') } 70 | its('mode') { should cmp '0400' } 71 | end 72 | end 73 | end 74 | if server.params['ssl_certificate_key'].nil? 75 | impact 0.0 76 | describe 'This test is NA because the ssl_certificate_key directive has not been configured.' do 77 | skip 'This test is NA because the ssl_certificate_key directive has not been configured.' 78 | end 79 | else 80 | server.params['ssl_certificate_key'].each do |certificate_key| 81 | describe file(certificate_key.join) do 82 | its('owner') { should be_in input('sys_admin') } 83 | its('group') { should be_in input('sys_admin_group') } 84 | its('mode') { should cmp '0400' } 85 | end 86 | end 87 | end 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /controls/V-41738.rb: -------------------------------------------------------------------------------- 1 | control 'V-41738' do 2 | title 'The NGINX web server must encrypt passwords during transmission.' 3 | desc "Data used to authenticate, especially passwords, needs to be protected 4 | at all times, and encryption is the standard method for protecting 5 | authentication data during transmission. Data used to authenticate can be 6 | passed to and from the web server for many reasons. 7 | 8 | Examples include data passed from a user to the web server through an HTTPS 9 | connection for authentication, the web server authenticating to a backend 10 | database for data retrieval and posting, and the web server authenticating to a 11 | clustered web server manager for an update. 12 | " 13 | 14 | desc 'check', "Review the NGINX web server documentation and deployed 15 | configuration to determine whether passwords are being passed to or from the 16 | web server. 17 | 18 | If NGINX is not configured to serve files, this check is Not Applicable. 19 | 20 | Check for the following: 21 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf 22 | and any separated include configuration file. 23 | 24 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 25 | this check is Not Applicable. 26 | 27 | If TLS is not enabled, then passwords are not encrypted. If the 'ssl_protocols' 28 | directive is not set to the approved TLS versions, this is a finding. 29 | " 30 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration file(s) 31 | and configure it to use the approved TLS protocols to encrypt the transmission passwords. 32 | 33 | Example: 34 | server { 35 | ssl_protocols TLSv1.2; 36 | } 37 | " 38 | impact 0.5 39 | tag "severity": 'medium' 40 | tag "gtitle": 'SRG-APP-000172-WSR-000104' 41 | tag "gid": 'V-41738' 42 | tag "rid": 'SV-54315r3_rule' 43 | tag "stig_id": 'SRG-APP-000172-WSR-000104' 44 | tag "fix_id": 'F-47197r2_fix' 45 | tag "cci": ['CCI-000197'] 46 | tag "nist": ['IA-5 (1) (c)', ''] 47 | 48 | if nginx_conf.servers.nil? 49 | impact 0.0 50 | describe 'This check is NA because NGINX has not been configured to serve files.' do 51 | skip 'This check is NA because NGINX has not been configured to serve files.' 52 | end 53 | else 54 | nginx_conf.servers.each do |server| 55 | if server.params['ssl_protocols'].nil? 56 | impact 0.0 57 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 58 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 59 | end 60 | else 61 | server.params['ssl_protocols'].each do |protocol| 62 | describe 'Each protocol' do 63 | it 'should be included in the list of protocols approved to encrypt data' do 64 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /controls/V-41745.rb: -------------------------------------------------------------------------------- 1 | control 'V-41745' do 2 | title "The NGINX web server must use cryptographic modules that meet the 3 | requirements of applicable federal laws, Executive Orders, directives, 4 | policies, regulations, standards, and guidance when encrypting stored data." 5 | desc "Encryption is only as good as the encryption modules utilized. 6 | Unapproved cryptographic module algorithms cannot be verified, and cannot be 7 | relied upon to provide confidentiality or integrity, and DoD data may be 8 | compromised due to weak algorithms. 9 | 10 | FIPS 140-2 is the current standard for validating cryptographic modules and 11 | NSA Type-X (where X=1, 2, 3, 4) products are NSA-certified, hardware-based 12 | encryption modules. 13 | 14 | The web server must provide FIPS-compliant encryption modules when storing 15 | encrypted data and configuration settings. 16 | " 17 | 18 | desc 'check', "Review NGINX web server documentation and deployed configuration 19 | to determine whether the encryption modules utilized for storage of data are FIPS 140-2 20 | compliant. 21 | 22 | Verify the Operating System and OpenSSL are in FIPS Mode - 23 | Execute the following command to check the OS: 24 | 25 | # sudo sysctl –a | grep fips 26 | 27 | If crypto.fips_enabled is set to 0, this is a finding. 28 | 29 | Execute the following command to check OpenSSL: 30 | # nginx -V 31 | 32 | The version of OpenSSL specified should include a '-fips'. If NGINX is not build with 33 | a version of OpenSSL that is FIPS compliant, this is a finding. 34 | " 35 | desc 'fix', "Configure the web server to utilize FIPS 140-2 approved 36 | encryption modules when the web server is storing data." 37 | 38 | impact 0.5 39 | tag "severity": 'medium' 40 | tag "gtitle": 'SRG-APP-000179-WSR-000110' 41 | tag "gid": 'V-41745' 42 | tag "rid": 'SV-54322r3_rule' 43 | tag "stig_id": 'SRG-APP-000179-WSR-000110' 44 | tag "fix_id": 'F-47204r2_fix' 45 | tag "cci": ['CCI-000803'] 46 | tag "nist": %w(IA-7) 47 | 48 | if virtualization.system.eql?('docker') 49 | impact 0.0 50 | describe "Control not applicable - Kernel config for FIPS capability must be done on the host" do 51 | skip "Control not applicable - Kernel config for FIPS capability must be done on the host" 52 | end 53 | else 54 | describe command('sysctl –a | grep fips') do 55 | its('stdout') { should eq "crypto.fips_enabled = 1\n" } 56 | its('exit_status') { should eq 0 } 57 | end 58 | 59 | describe command('nginx -V 2>&1').stdout do 60 | it { should match(/-fips/) } 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /controls/V-41746.rb: -------------------------------------------------------------------------------- 1 | control 'V-41746' do 2 | title "The NGINX web server must use cryptographic modules that meet the 3 | requirements of applicable federal laws, Executive Orders, directives, 4 | policies, regulations, standards, and guidance for such authentication." 5 | desc "Encryption is only as good as the encryption modules utilized. 6 | Unapproved cryptographic module algorithms cannot be verified and cannot be 7 | relied upon to provide confidentiality or integrity, and DoD data may be 8 | compromised due to weak algorithms. 9 | 10 | FIPS 140-2 is the current standard for validating cryptographic modules and 11 | NSA Type-X (where X=1, 2, 3, 4) products are NSA-certified, hardware-based 12 | encryption modules. 13 | 14 | The web server must provide FIPS-compliant encryption modules when 15 | authenticating users and processes. 16 | " 17 | 18 | desc 'check', " 19 | Review NGINX web server documentation and deployed configuration to determine 20 | whether the encryption modules utilized for authentication are FIPS 140-2 21 | compliant. Reference the following NIST site to identify validated encryption 22 | modules: http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140val-all.htm 23 | 24 | If NGINX is not configured to serve files, this check is Not Applicable. 25 | 26 | Check for the following: 27 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf 28 | and any separated include configuration file. 29 | 30 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 31 | this check is Not Applicable. 32 | 33 | If the 'ssl_protocols' directive is not set to the FIPS comliant TLS versions, 34 | this is a finding. 35 | " 36 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration file(s) 37 | and configure it to use the FIPS compliant TLS protocols. 38 | Example: 39 | server { 40 | ssl_protocols TLSv1.2; 41 | } 42 | " 43 | 44 | impact 0.5 45 | tag "severity": 'medium' 46 | tag "gtitle": 'SRG-APP-000179-WSR-000111' 47 | tag "gid": 'V-41746' 48 | tag "rid": 'SV-54323r3_rule' 49 | tag "stig_id": 'SRG-APP-000179-WSR-000111' 50 | tag "fix_id": 'F-47205r2_fix' 51 | tag "cci": ['CCI-000803'] 52 | tag "nist": %w(IA-7) 53 | 54 | if nginx_conf.servers.nil? 55 | impact 0.0 56 | describe 'This check is NA because NGINX has not been configured to serve files.' do 57 | skip 'This check is NA because NGINX has not been configured to serve files.' 58 | end 59 | else 60 | nginx_conf.servers.each do |server| 61 | if server.params['ssl_protocols'].nil? 62 | impact 0.0 63 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 64 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 65 | end 66 | else 67 | server.params['ssl_protocols'].each do |protocol| 68 | describe 'Each protocol' do 69 | it 'should be included in the list of protocols approved to encrypt data' do 70 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 71 | end 72 | end 73 | end 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /controls/V-41807.rb: -------------------------------------------------------------------------------- 1 | control 'V-41807' do 2 | title "The NGINX web server must generate unique session identifiers that cannot be 3 | reliably reproduced." 4 | desc "Communication between a client and the web server is done using the 5 | HTTP protocol, but HTTP is a stateless protocol. In order to maintain a 6 | connection or session, a web server will generate a session identifier (ID) for 7 | each client session when the session is initiated. The session ID allows the 8 | web server to track a user session and, in many cases, the user, if the user 9 | previously logged into a hosted application. 10 | 11 | By being able to guess session IDs, an attacker can easily perform a 12 | man-in-the-middle attack. To truly generate random session identifiers that 13 | cannot be reproduced, the web server session ID generator, when used twice with 14 | the same input criteria, must generate an unrelated random ID. 15 | 16 | The session ID generator also needs to be a FIPS 140-2 approved generator. 17 | " 18 | 19 | desc 'check', "Review the NGINX web server documentation and deployed configuration 20 | to verify that random and unique session identifiers are generated. 21 | 22 | If it is determined that the web server is not required to perform session management, 23 | this check is Not Applicable. 24 | 25 | NGINX web server versions after 1.11.0 have the $request_id embedded variable by default. 26 | This variable is a unique request identifier generated from 16 random bytes, in hexadecimal. 27 | 28 | Execute the following command to get the current version of NGINX running: 29 | # nginx -v 30 | 31 | If the current version of NGINX running is 1.11.0 or earlier, this is a finding. 32 | " 33 | desc 'fix', "Upgrade to the lastest stable version of NGINX web server to use the '$request_id' 34 | embedded variable for generating an unique identifier that cannot be reliably reproduced." 35 | 36 | impact 0.5 37 | tag "severity": 'medium' 38 | tag "gtitle": 'SRG-APP-000224-WSR-000136' 39 | tag "satisfies": %w(SRG-APP-000224-WSR-000137 SRG-APP-000224-WSR-000138 SRG-APP-000224-WSR-000139 40 | SRG-APP-000223-WSR-000145 SRG-APP-000224-WSR-000135) 41 | tag "gid": 'V-41807' 42 | tag "rid": 'SV-54384r3_rule' 43 | tag "stig_id": 'SRG-APP-000224-WSR-000136' 44 | tag "fix_id": 'F-47266r2_fix' 45 | tag "cci": %w(CCI-001188 CCI-001664) 46 | tag "nist": ['SC-23 (3)', ''] 47 | 48 | if input('performs_session_management') == false 49 | impact 0.0 50 | describe 'This check is NA because session management is not required.' do 51 | skip 'This check is NA because session management is not required.' 52 | end 53 | else 54 | describe nginx do 55 | its('version') { should cmp > '1.11.0' } 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /controls/V-41811.rb: -------------------------------------------------------------------------------- 1 | control 'V-41811' do 2 | title "The NGINX web server must be built to fail to a known safe state if system 3 | initialization fails, shutdown fails, or aborts fail." 4 | desc "Determining a safe state for failure and weighing that against a 5 | potential DoS for users depends on what type of application the web server is 6 | hosting. For an application presenting publicly available information that is 7 | not critical, a safe state for failure might be to shut down for any type of 8 | failure; but for an application that presents critical and timely information, 9 | a shutdown might not be the best state for all failures. 10 | 11 | Performing a proper risk analysis of the hosted applications and 12 | configuring the web server according to what actions to take for each failure 13 | condition will provide a known fail safe state for the web server. 14 | " 15 | 16 | desc 'check', "Review the NGINX web server documentation, deployed configuration, 17 | and risk analysis documentation to determine whether the web server will fail to known 18 | states for system initialization, shutdown, or abort failures. 19 | 20 | Interview the System Administrator for the NGINX web server. 21 | 22 | Ask for documentation on the disaster recovery methods tested and planned for 23 | the NGINX web server in the event of the necessity for rollback. 24 | 25 | If documentation for a disaster recovery has not been established, this is a finding. 26 | " 27 | desc 'fix', "Prepare documentation for disaster recovery methods for the NGINX 28 | web server in the event of the necessity for rollback. 29 | 30 | Document and test the disaster recovery methods designed." 31 | 32 | impact 0.5 33 | tag "severity": 'medium' 34 | tag "gtitle": 'SRG-APP-000225-WSR-000140' 35 | tag "gid": 'V-41811' 36 | tag "rid": 'SV-54388r3_rule' 37 | tag "stig_id": 'SRG-APP-000225-WSR-000140' 38 | tag "fix_id": 'F-47270r3_fix' 39 | tag "cci": ['CCI-001190'] 40 | tag "nist": %w(SC-24) 41 | 42 | describe "This test requires a Manual Review: Interview the SA and ask for documentation on the 43 | disaster recovery for the NGINX web server in the event of the necessity for rollback." do 44 | skip "This test requires a Manual Review: Interview the SA and ask for documentation on the 45 | disaster recovery for the NGINX web server in the event of the necessity for rollback." 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /controls/V-41812.rb: -------------------------------------------------------------------------------- 1 | control 'V-41812' do 2 | title 'The NGINX web server must provide a clustering capability.' 3 | desc "The web server may host applications that display information that 4 | cannot be disrupted, such as information that is time-critical or 5 | life-threatening. In these cases, a web server that shuts down or ceases to be 6 | accessible when there is a failure is not acceptable. In these types of cases, 7 | clustering of web servers is used. 8 | 9 | Clustering of multiple web servers is a common approach to providing 10 | fail-safe application availability. To assure application availability, the web 11 | server must provide clustering or some form of failover functionality. 12 | " 13 | 14 | desc 'check', "Review the NGINX web server documentation, deployed configuration, 15 | and risk analysis documentation to verify that the web server is configured to provide 16 | clustering functionality, if the web server is a high-availability web server. 17 | 18 | If the NGINX web server is not a high-availability web server, this finding is 19 | Not Applicable. 20 | 21 | If the web server is not configured to provide clustering or some form of failover 22 | functionality and the web server is a high-availability server, this is a finding. 23 | " 24 | desc 'fix', "Configure the web server to provide application failover, or participate 25 | in a web cluster that provides failover for high-availability web servers. 26 | " 27 | impact 0.5 28 | tag "severity": 'medium' 29 | tag "gtitle": 'SRG-APP-000225-WSR-000141' 30 | tag "gid": 'V-41812' 31 | tag "rid": 'SV-54389r3_rule' 32 | tag "stig_id": 'SRG-APP-000225-WSR-000141' 33 | tag "fix_id": 'F-47271r2_fix' 34 | tag "cci": ['CCI-001190'] 35 | tag "nist": %w(SC-24) 36 | 37 | if input('high_availability') == false 38 | impact 0.0 39 | describe 'This check is NA because NGINX is not a high-availability web server.' do 40 | skip 'This check is NA because NGINX is not a high-availability web server.' 41 | end 42 | elsif input('is_cluster_master') == false 43 | describe nginx do 44 | its('modules') { should_not include 'ngx_stream_zone_sync_module' } 45 | end 46 | else 47 | describe nginx do 48 | its('modules') { should include 'ngx_stream_zone_sync_module' } 49 | end 50 | describe package('nginx-sync') do 51 | it { should be_installed } 52 | end 53 | describe parse_config_file('/etc/nginx-sync.conf') do 54 | its('NODES') { should_not be nil } 55 | its('CONFPATHS') { should_not be nil } 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /controls/V-41821.rb: -------------------------------------------------------------------------------- 1 | control 'V-41821' do 2 | title "The NGINX web server document directory must be in a separate partition from 3 | the web servers system files." 4 | desc "A web server is used to deliver content on the request of a client. 5 | The content delivered to a client must be controlled, allowing only hosted 6 | application files to be accessed and delivered. To allow a client access to 7 | system files of any type is a major security risk that is entirely avoidable. 8 | Obtaining such access is the goal of directory traversal and URL manipulation 9 | vulnerabilities. To facilitate such access by misconfiguring the web document 10 | (home) directory is a serious error. In addition, having the path on the same 11 | drive as the system folder compounds potential attacks such as drive space 12 | exhaustion." 13 | 14 | desc 'check', "Review the NGINX web server documentation and deployed configuration 15 | to determine where the document directory is located for each hosted application. 16 | 17 | If there are no websites configured or if NGINX is not configured to serve files, 18 | this check is Not Applicable. 19 | 20 | Check for the following: 21 | 22 | #grep the 'root' directive in the http, server, and location context of the 23 | nginx.conf and any separated include configuration file. 24 | 25 | If the 'root' directive cannot be found in NGINX configuration files, this check is Not Applicable. 26 | 27 | If the path for any of the directives is on the same partition as the web server 28 | operating system files, this is a finding. 29 | " 30 | desc 'fix', "Create and mount a new partition. 31 | Once partition is created, the directory needs to be copied over using the following command: 32 | # sudo rsync -av . 33 | 34 | Update the 'root' directives in the NGINX configuration file(s) with the new location." 35 | impact 0.5 36 | tag "severity": 'medium' 37 | tag "gtitle": 'SRG-APP-000233-WSR-000146' 38 | tag "gid": 'V-41821' 39 | tag "rid": 'SV-54398r3_rule' 40 | tag "stig_id": 'SRG-APP-000233-WSR-000146' 41 | tag "fix_id": 'F-47280r2_fix' 42 | tag "cci": ['CCI-001084'] 43 | tag "nist": %w(SC-3) 44 | 45 | webserver_roots = [] 46 | 47 | if nginx_conf.params['http'].nil? 48 | impact 0.0 49 | describe 'This check is NA because no websites have been configured.' do 50 | skip 'This check is NA because no websites have been configured.' 51 | end 52 | else 53 | nginx_conf.http.entries.each do |http| 54 | webserver_roots.push(http.params['root']) unless http.params['root'].nil? 55 | end 56 | end 57 | 58 | if nginx_conf.servers.nil? 59 | impact 0.0 60 | describe 'This check is NA because NGINX has not been configured to serve files.' do 61 | skip 'This check is NA because NGINX has not been configured to serve files.' 62 | end 63 | else 64 | nginx_conf.servers.entries.each do |server| 65 | webserver_roots.push(server.params['root']) unless server.params['root'].nil? 66 | end 67 | end 68 | 69 | if nginx_conf.locations.nil? 70 | impact 0.0 71 | describe 'This check is NA because NGINX has not been configured to serve files.' do 72 | skip 'This check is NA because NGINX has not been configured to serve files.' 73 | end 74 | else 75 | nginx_conf.locations.entries.each do |location| 76 | webserver_roots.push(location.params['root']) unless location.params['root'].nil? 77 | end 78 | end 79 | 80 | if webserver_roots.empty? 81 | impact 0.0 82 | describe 'This check is NA because no root directories have been set.' do 83 | skip 'This test is NA because no root directories have been set.' 84 | end 85 | else 86 | webserver_roots.flatten!.uniq! 87 | webserver_roots.each do |root| 88 | describe "The root directory #{root}" do 89 | it { should_not cmp '/' } 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /controls/V-41852.rb: -------------------------------------------------------------------------------- 1 | control 'V-41852' do 2 | title 'The NGINX web server must limit the character set used for data entry.' 3 | desc "Invalid user input occurs when a user inserts data or characters into 4 | a hosted application's data entry field and the hosted application is 5 | unprepared to process that data. This results in unanticipated application 6 | behavior, potentially leading to an application compromise. Invalid user input 7 | is one of the primary methods employed when attempting to compromise an 8 | application. 9 | 10 | An attacker can also enter Unicode into hosted applications in an effort to 11 | break out of the document home or root home directory or to bypass security 12 | checks. 13 | 14 | The web server, by defining the character set available for data entry, can 15 | trap efforts to bypass security checks or to compromise an application. 16 | " 17 | 18 | desc 'check', "Review the NGINX web server documentation and deployed configuration 19 | to determine what the data set is for data entry. 20 | 21 | If there are no websites configured or if NGINX is not configured to serve files, 22 | this check is Not Applicable. 23 | 24 | Check for the following: 25 | # grep the 'charset' directive in the http, server, and location context of 26 | the nginx.conf and any separated include configuration file. 27 | 28 | If the 'charset' directive does not exist or is not configured to use the charsets expected by the 29 | host application, this is a finding. 30 | " 31 | desc 'fix', "Configure the NGINX web server to include the 'charset' directive 32 | and use the character sets the application expects." 33 | 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000251-WSR-000157' 37 | tag "gid": 'V-41852' 38 | tag "rid": 'SV-54429r3_rule' 39 | tag "stig_id": 'SRG-APP-000251-WSR-000157' 40 | tag "fix_id": 'F-47311r2_fix' 41 | tag "cci": ['CCI-001310'] 42 | tag "nist": %w(SI-10) 43 | 44 | if nginx_conf.params['http'].nil? 45 | impact 0.0 46 | describe 'This check is NA because no websites have been configured.' do 47 | skip 'This check is NA because no websites have been configured.' 48 | end 49 | else 50 | nginx_conf.params['http'].each do |http| 51 | describe 'Charset directive' do 52 | it 'should exist and be configured to the expected value in the http context.' do 53 | expect(http).to(include 'charset') 54 | expect(http['charset'].join).to(cmp(input('charset_required'))) 55 | end 56 | end 57 | end 58 | end 59 | 60 | if nginx_conf.servers.nil? 61 | impact 0.0 62 | describe 'This check is NA because NGINX has not been configured to serve files.' do 63 | skip 'This check is NA because NGINX has not been configured to serve files.' 64 | end 65 | else 66 | nginx_conf.servers.each do |server| 67 | describe 'Charset' do 68 | it 'should be configured to the expected value if found in the server context.' do 69 | expect(server.params['charset'].join).to(cmp(input('charset_required'))) unless server.params['charset'].nil? 70 | end 71 | end 72 | end 73 | end 74 | 75 | if nginx_conf.locations.nil? 76 | impact 0.0 77 | describe 'This check is NA because NGINX has not been configured to serve files.' do 78 | skip 'This check is NA because NGINX has not been configured to serve files.' 79 | end 80 | else 81 | nginx_conf.locations.each do |location| 82 | describe 'Charset' do 83 | it 'should be configured to the expected value if found in the location context.' do 84 | unless location.params['charset'].nil? 85 | expect(location.params['charset'].join).to(cmp(input('charset_required'))) 86 | end 87 | end 88 | end 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /controls/V-41855.rb: -------------------------------------------------------------------------------- 1 | control 'V-41855' do 2 | title "Debugging and trace information used to diagnose the NGINX web server must 3 | be disabled." 4 | desc "Information needed by an attacker to begin looking for possible 5 | vulnerabilities in a web server includes any information about the web server 6 | and plug-ins or modules being used. When debugging or trace information is 7 | enabled in a production web server, information about the web server, such as 8 | web server type, version, patches installed, plug-ins and modules installed, 9 | type of code being used by the hosted application, and any backends being used 10 | for data storage may be displayed. Since this information may be placed in logs 11 | and general messages during normal operation of the web server, an attacker 12 | does not need to cause an error condition to gain this information." 13 | 14 | desc 'check', " 15 | Review the NGINX web server documentation and deployed configuration to determine 16 | if debugging and trace information are enabled. 17 | 18 | Check for the following: 19 | # grep the 'error_log' directive the nginx.conf 20 | 21 | If the 'error_log' directive cannot be found in NGINX configuration files, 22 | this check is Not Applicable. 23 | 24 | If the 'error_log' directive is set to error log level 'debug', this is a finding. 25 | " 26 | desc 'fix', "The 'error_log' directive should not have the error log level set to 27 | 'debug' to minimize the information given to clients on error conditions." 28 | 29 | impact 0.5 30 | tag "severity": 'medium' 31 | tag "gtitle": 'SRG-APP-000266-WSR-000160' 32 | tag "gid": 'V-41855' 33 | tag "rid": 'SV-54432r3_rule' 34 | tag "stig_id": 'SRG-APP-000266-WSR-000160' 35 | tag "fix_id": 'F-47314r2_fix' 36 | tag "cci": ['CCI-001312'] 37 | tag "nist": ['SI-11 a', ''] 38 | 39 | if nginx_conf.params['error_log'].nil? 40 | impact 0.0 41 | describe 'This check is NA because the error_log directive is not configured.' do 42 | skip 'This check is NA because the error_log directive is not configured.' 43 | end 44 | else 45 | nginx_conf.params['error_log'].each do |error_log| 46 | error_log.each do |error_value| 47 | describe 'The error log level' do 48 | it 'should not be set to debug.' do 49 | expect(error_value).not_to(eq 'debug') 50 | end 51 | end 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /controls/V-55945.rb: -------------------------------------------------------------------------------- 1 | control 'V-55945' do 2 | title "The NGINX web server must enforce approved authorizations for logical access 3 | to hosted applications and resources in accordance with applicable access 4 | control policies." 5 | desc "To control access to sensitive information and hosted applications by 6 | entities that have been issued certificates by DoD-approved PKIs, the web 7 | server must be properly configured to incorporate a means of authorization that 8 | does not simply rely on the possession of a valid certificate for access. 9 | Access decisions must include a verification that the authenticated entity is 10 | permitted to access the information or application. Authorization decisions 11 | must leverage a variety of methods, such as mapping the validated PKI 12 | certificate to an account with an associated set of permissions on the system. 13 | If the web server relied only on the possession of the certificate and did not 14 | map to system roles and privileges, each user would have the same abilities and 15 | roles to make changes to the production system." 16 | 17 | desc 'check', " 18 | The NGINX web server must be configured to perform an authorization check to 19 | verify that the authenticated entity should be granted access to the requested 20 | content. 21 | 22 | If NGINX is not configured to serve files, this check is Not Applicable. 23 | 24 | Check for the following: 25 | #grep the 'auth_request' directive in the location context of the nginx.conf 26 | and any separated include configuration file. 27 | 28 | If the 'auth_request' directive does not exist inside the location context, 29 | this is a finding. 30 | " 31 | desc 'fix', "Configure server to use the 'auth_request' directive in the 32 | NGINX configuration file(s) to implement client authorization." 33 | 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000033-WSR-000169' 37 | tag "gid": 'V-55945' 38 | tag "rid": 'SV-70199r2_rule' 39 | tag "stig_id": 'SRG-APP-000033-WSR-000169' 40 | tag "fix_id": 'F-60823r1_fix' 41 | tag "cci": ['CCI-000213'] 42 | tag "nist": %w(AC-3) 43 | 44 | # List of all auth_request uris in the configuration files 45 | auth_uris = [] 46 | 47 | if nginx_conf.locations.nil? 48 | impact 0.0 49 | describe 'This check is NA because NGINX has not been configured to serve files.' do 50 | skip 'This check is NA because NGINX has not been configured to serve files.' 51 | end 52 | else 53 | nginx_conf.locations.entries.each do |location| 54 | auth_uris.push(location.params['auth_request']) unless location.params['auth_request'].nil? 55 | end 56 | describe 'The uris collected from the auth_request directives' do 57 | it 'should not be an empty list.' do 58 | expect(auth_uris).to_not(be_empty) 59 | end 60 | end 61 | if auth_uris.empty? 62 | describe 'This test is skipped because the auth_request directive has not been configured for locations.' do 63 | skip 'This test is skipped because the auth_request directive has not been configured for locations.' 64 | end 65 | else 66 | auth_uris.flatten!.uniq! 67 | nginx_conf.locations.each do |location| 68 | auth_uris.each do |uri| 69 | next if location.params['_'].flatten.include?(uri) 70 | 71 | describe 'Each location context' do 72 | it 'should include an auth_request directive.' do 73 | expect(location.params).to(include 'auth_request') 74 | end 75 | end 76 | end 77 | end 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /controls/V-55953.rb: -------------------------------------------------------------------------------- 1 | control 'V-55953' do 2 | title "Remote access to the NGINX web server must follow access policy or work in 3 | conjunction with enterprise tools designed to enforce policy requirements." 4 | desc "Remote access to the web server is any access that communicates 5 | through an external, non-organization-controlled network. Remote access can be 6 | used to access hosted applications or to perform management functions. 7 | 8 | A web server can be accessed remotely and must be able to enforce remote 9 | access policy requirements or work in conjunction with enterprise tools 10 | designed to enforce policy requirements. 11 | 12 | Examples of the web server enforcing a remote access policy are 13 | implementing IP filtering rules, using https instead of http for communication, 14 | implementing secure tokens, and validating users. 15 | " 16 | 17 | desc 'check', "Review the NGINX web server product documentation and deployed 18 | configuration to determine if the server or an enterprise tool is enforcing the 19 | organization's requirements for remote connections. 20 | 21 | If NGINX is not configured to serve files, this check is Not Applicable. 22 | 23 | If the an enterprise tools is enforcing the organization's requirements for remote 24 | connections, this control must be reviewed manually. 25 | 26 | If NGINX is enforcing the requirements for remote connections, check for the following: 27 | # grep for a 'deny' directive in the location context of the nginx.conf and any 28 | separated include configuration file. 29 | 30 | Verify that there is a 'deny all' set in each location context to deny all IP addresses 31 | by default and allow only approved IP addresses. 32 | 33 | If a 'deny all' is not set in each location, this is a finding. 34 | " 35 | desc 'fix', "Add a 'deny all' in each location context in the NGINX configuration 36 | file(s) to enforce the remote access policy. 37 | 38 | Then add 'allow' directive(s) in each location context in the NGINX configuration file(s) 39 | and configure it to only allow approved IP addresses." 40 | 41 | impact 0.5 42 | tag "severity": 'medium' 43 | tag "gtitle": 'SRG-APP-000315-WSR-000003' 44 | tag "gid": 'V-55953' 45 | tag "rid": 'SV-70207r2_rule' 46 | tag "stig_id": 'SRG-APP-000315-WSR-000003' 47 | tag "fix_id": 'F-60831r2_fix' 48 | tag "cci": ['CCI-002314'] 49 | tag "nist": ['AC-17 (1)', ''] 50 | 51 | if input('uses_enterprise_tool') == 'true' 52 | describe "This test requires a Manual Review: Determine if the enterprise tool is enforcing 53 | the organization's requirements for remote connections." do 54 | skip "This test requires a Manual Review: Determine if the enterprise tool is enforcing 55 | the organization's requirements for remote connections." 56 | end 57 | elsif nginx_conf.locations.empty? 58 | impact 0.0 59 | describe 'This check is NA because NGINX has not been configured to serve files.' do 60 | skip 'This check is NA because NGINX has not been configured to serve files.' 61 | end 62 | else 63 | nginx_conf.locations.each do |location| 64 | deny_values = [] 65 | deny_values.push(location.params['deny']) unless location.params['deny'].nil? 66 | describe 'Each location context' do 67 | it 'should include an deny all directive.' do 68 | expect(deny_values.to_s).to(include 'all') 69 | end 70 | end 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /controls/V-55955.rb: -------------------------------------------------------------------------------- 1 | control 'V-55955' do 2 | title "The NGINX web server must provide the capability to immediately disconnect 3 | or disable remote access to the hosted applications." 4 | desc "During an attack on the web server or any of the hosted applications, 5 | the system administrator may need to disconnect or disable access by users to 6 | stop the attack. 7 | 8 | The web server must provide a capability to disconnect users to a hosted 9 | application without compromising other hosted applications unless deemed 10 | necessary to stop the attack. Methods to disconnect or disable connections are 11 | to stop the application service for a specified hosted application, stop the 12 | web server, or block all connections through web server access list. 13 | 14 | The web server capabilities used to disconnect or disable users from 15 | connecting to hosted applications and the web server must be documented to make 16 | certain that, during an attack, the proper action is taken to conserve 17 | connectivity to any other hosted application if possible and to make certain 18 | log data is conserved for later forensic analysis. 19 | " 20 | 21 | desc 'check', "Review the NGINX web server documentation and configuration 22 | to make certain that the web server is configured to allow for the immediate 23 | disconnection or disabling of remote access to hosted applications when necessary. 24 | 25 | Interview the SA and Web Manager. 26 | 27 | Ask for documentation for the NGINX administration. 28 | 29 | Verify there are documented procedures for shutting down an NGINX website in the 30 | event of an attack. The procedure should, at a minimum, provide the following steps: 31 | 32 | Determine the respective website for the application at risk of an attack. 33 | 34 | In a command line, enter the following command: 35 | 36 | # kill -TERM `cat <'INSTALLED PATH'>/nginx.pid` 37 | 38 | If NGINX is not capable of or cannot be configured to disconnect or disable remote 39 | access to the hosted applications when necessary, this is a finding. 40 | " 41 | desc 'fix', "Prepare documented procedures for shutting down an NGINX website in the 42 | event of an attack. 43 | 44 | The procedure should, at a minimum, provide the following steps: 45 | 46 | In a command line, enter the following command: 47 | 48 | # kill -TERM `cat <'INSTALLED PATH'>/nginx.pid`" 49 | impact 0.5 50 | tag "severity": 'medium' 51 | tag "gtitle": 'SRG-APP-000316-WSR-000170' 52 | tag "gid": 'V-55955' 53 | tag "rid": 'SV-70209r2_rule' 54 | tag "stig_id": 'SRG-APP-000316-WSR-000170' 55 | tag "fix_id": 'F-60833r1_fix' 56 | tag "cci": ['CCI-002322'] 57 | tag "nist": ['AC-17 (9)', ''] 58 | 59 | describe "This test requires a Manual Review: Interview the SA and Web Manager and ask 60 | for documentation.Verify there are documented procedures for shutting down an NGINX website 61 | in the event of an attack." do 62 | skip "This test requires a Manual Review: Interview the SA and Web Manager and ask 63 | for documentation.Verify there are documented procedures for shutting down an NGINX website 64 | in the event of an attack." 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /controls/V-55957.rb: -------------------------------------------------------------------------------- 1 | control 'V-55957' do 2 | title "An NGINX web server that is part of a web server cluster must route all 3 | remote management through a centrally managed access control point." 4 | desc "A web server cluster is a group of independent web servers that are 5 | managed as a single system for higher availability, easier manageability, and 6 | greater scalability. Without having centralized control of the web server 7 | cluster, management of the cluster becomes difficult. It is critical that 8 | remote management of the cluster be done through a designated management system 9 | acting as a single access point." 10 | 11 | desc 'check', "Review the web server documentation and configuration to 12 | determine if the web server is part of a cluster. 13 | 14 | If the web server is not part of a cluster, then this check is Not Applicable. 15 | 16 | If the web server is part of a cluster and is not centrally managed, then 17 | this is a finding. 18 | " 19 | desc 'fix', 'Configure the web server to be centrally managed.' 20 | impact 0.5 21 | tag "severity": 'medium' 22 | tag "gtitle": 'SRG-APP-000356-WSR-000007' 23 | tag "gid": 'V-55957' 24 | tag "rid": 'SV-70211r2_rule' 25 | tag "stig_id": 'SRG-APP-000356-WSR-000007' 26 | tag "fix_id": 'F-60835r1_fix' 27 | tag "cci": ['CCI-001844'] 28 | tag "nist": ['AU-3 (2)', ''] 29 | 30 | if input('is_cluster') == false 31 | impact 0.0 32 | describe 'This check is NA because NGINX is not part of a cluster.' do 33 | skip 'This check is NA because NGINX is not part of a cluster.' 34 | end 35 | elsif input('is_cluster_master') == false 36 | describe nginx do 37 | its('modules') { should include 'ngx_stream_zone_sync_module' } 38 | end 39 | else 40 | describe nginx do 41 | its('modules') { should include 'ngx_stream_zone_sync_module' } 42 | end 43 | describe package('nginx-sync') do 44 | it { should be_installed } 45 | end 46 | describe parse_config_file('/etc/nginx-sync.conf') do 47 | its('NODES') { should_not be nil } 48 | its('CONFPATHS') { should_not be nil } 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /controls/V-55961.rb: -------------------------------------------------------------------------------- 1 | control 'V-55961' do 2 | title 'The NGINX web server must restrict inbound connections from nonsecure zones.' 3 | desc "Remote access to the web server is any access that communicates 4 | through an external, non-organization-controlled network. Remote access can be 5 | used to access hosted applications or to perform management functions. 6 | 7 | A web server can be accessed remotely and must be capable of restricting 8 | access from what the DoD defines as nonsecure zones. Nonsecure zones are 9 | defined as any IP, subnet, or region that is defined as a threat to the 10 | organization. The nonsecure zones must be defined for public web servers 11 | logically located in a DMZ, as well as private web servers with perimeter 12 | protection devices. By restricting access from nonsecure zones, through 13 | internal web server access list, the web server can stop or slow denial of 14 | service (DoS) attacks on the web server. 15 | " 16 | 17 | desc 'check', " 18 | Review the NGINX web server configuration to verify that the web server is 19 | restricting access from nonsecure zones. 20 | 21 | If the an enterprise tools is enforcing the organization's requirements for remote 22 | connections, this control must be reviewed manually. 23 | 24 | Check for the following: 25 | # grep for a 'deny' directive in the location context of the nginx.conf 26 | and any separated include configuration file. 27 | 28 | Verify that there is a 'deny all' set in each location context to deny all IP 29 | addresses by default and only allow addresses in secure zones. If a 'deny all' 30 | is not set in each location, this is a finding. 31 | " 32 | desc 'fix', "Add a 'deny all' in each location context in the NGINX configuration 33 | file(s) to deny access to all IP addresses by default, including addresses in 34 | nonsecure zones. 35 | 36 | Then add 'allow' directive(s) in each location context in the NGINX configuration file(s) 37 | and configure it to only allow addresses in secure zones." 38 | 39 | impact 0.5 40 | tag "severity": 'medium' 41 | tag "gtitle": 'SRG-APP-000315-WSR-000004' 42 | tag "gid": 'V-55961' 43 | tag "rid": 'SV-70215r2_rule' 44 | tag "stig_id": 'SRG-APP-000315-WSR-000004' 45 | tag "fix_id": 'F-60839r1_fix' 46 | tag "cci": ['CCI-002314'] 47 | tag "nist": ['AC-17 (1)', ''] 48 | 49 | if input('uses_enterprise_tool') == 'true' 50 | describe "This test requires a Manual Review: Determine if the enterprise tool is enforcing 51 | the organization's requirements for remote connections." do 52 | skip "This test requires a Manual Review: Determine if the enterprise tool is enforcing 53 | the organization's requirements for remote connections." 54 | end 55 | elsif nginx_conf.locations.empty? 56 | impact 0.0 57 | describe 'This check is NA because NGINX has not been configured to serve files.' do 58 | skip 'This check is NA because NGINX has not been configured to serve files.' 59 | end 60 | else 61 | nginx_conf.locations.each do |location| 62 | deny_values = [] 63 | deny_values.push(location.params['deny']) unless location.params['deny'].nil? 64 | describe 'Each location context' do 65 | it 'should include an deny all directive.' do 66 | expect(deny_values.to_s).to(include 'all') 67 | end 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /controls/V-55973.rb: -------------------------------------------------------------------------------- 1 | control 'V-55973' do 2 | title "The NGINX web server must use a logging mechanism that is configured to 3 | alert the ISSO and SA in the event of a processing failure." 4 | desc "Reviewing log data allows an investigator to recreate the path of an 5 | attacker and to capture forensic data for later use. Log data is also essential 6 | to system administrators in their daily administrative duties on the hosted 7 | system or within the hosted applications. 8 | 9 | If the logging system begins to fail, events will not be recorded. 10 | Organizations shall define logging failure events, at which time the 11 | application or the logging mechanism the application utilizes will provide a 12 | warning to the ISSO and SA at a minimum. 13 | " 14 | 15 | desc 'check', "Review the NGINX web server documentation and deployment 16 | configuration settings to determine if the web server logging system provides an 17 | alert to the ISSO and the SA at a minimum when a processing failure occurs. 18 | 19 | Work with the SIEM administrator to determine if an alert is configured when audit 20 | data is no longer received as expected. 21 | 22 | If there is no alert configured, this is a finding. 23 | " 24 | desc 'fix', "Work with the SIEM administrator to configure an alert when no audit 25 | data is received from NGINX based on the defined schedule of connections 26 | " 27 | impact 0.5 28 | tag "severity": 'medium' 29 | tag "gtitle": 'SRG-APP-000108-WSR-000166' 30 | tag "gid": 'V-55973' 31 | tag "rid": 'SV-70227r2_rule' 32 | tag "stig_id": 'SRG-APP-000108-WSR-000166' 33 | tag "fix_id": 'F-60851r2_fix' 34 | tag "cci": ['CCI-000139'] 35 | tag "nist": ['AU-5 a', ''] 36 | 37 | describe "This test requires a Manual Review: Work with the SIEM administrator to determine 38 | if an alert is configured when audit data is no longer received as expected." do 39 | skip "This test requires a Manual Review: Work with the SIEM administrator to determine 40 | if an alert is configured when audit data is no longer received as expected." 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /controls/V-55975.rb: -------------------------------------------------------------------------------- 1 | control 'V-55975' do 2 | title "The NGINX web server must use a logging mechanism that is configured to 3 | provide a warning to the ISSO and SA when allocated record storage volume 4 | reaches 75% of maximum log record storage capacity." 5 | desc "It is critical for the appropriate personnel to be aware if a system 6 | is at risk of failing to process logs as required. Log processing failures 7 | include: software/hardware errors, failures in the log capturing mechanisms, 8 | and log storage capacity being reached or exceeded. 9 | 10 | If log capacity were to be exceeded, then events subsequently occurring 11 | would not be recorded. Organizations shall define a maximum allowable 12 | percentage of storage capacity serving as an alarming threshold (e.g., web 13 | server has exceeded 75% of log storage capacity allocated), at which time the 14 | web server or the logging mechanism the web server utilizes will provide a 15 | warning to the ISSO and SA at a minimum. 16 | 17 | This requirement can be met by configuring the web server to utilize a 18 | dedicated log tool that meets this requirement. 19 | " 20 | 21 | desc 'check', "Review the NGINX web server documentation and deployment 22 | configuration settings to determine if the web server log system provides a 23 | warning to the ISSO and SA when allocated record storage volume reaches 75% of 24 | maximum record storage capacity. 25 | 26 | Work with the SIEM administrator to determine if an alert is configured when 27 | allocated record storage volume reaches 75% of maximum log record storage capacity. 28 | 29 | If there is no alert configured, this is a finding. 30 | " 31 | desc 'fix', "Work with the SIEM administrator to configure an alert when allocated 32 | record storage volume reaches 75% of maximum log record storage capacity." 33 | impact 0.5 34 | tag "severity": 'medium' 35 | tag "gtitle": 'SRG-APP-000359-WSR-000065' 36 | tag "gid": 'V-55975' 37 | tag "rid": 'SV-70229r2_rule' 38 | tag "stig_id": 'SRG-APP-000359-WSR-000065' 39 | tag "fix_id": 'F-60853r1_fix' 40 | tag "cci": ['CCI-001855'] 41 | tag "nist": ['AU-5 (1)', ''] 42 | 43 | describe "This test requires a Manual Review: Work with the SIEM admin to determine 44 | if an alert is configured when allocated record storage volume reaches 75% of 45 | maximum log record storage capacity." do 46 | skip "This test requires a Manual Review: Work with the SIEM admin to determine 47 | if an alert is configured when allocated record storage volume reaches 75% of 48 | maximum log record storage capacity." 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /controls/V-55977.rb: -------------------------------------------------------------------------------- 1 | control 'V-55977' do 2 | title "The NGINX web server must record time stamps for log records to a minimum 3 | granularity of one second." 4 | desc "Without sufficient granularity of time stamps, it is not possible to 5 | adequately determine the chronological order of records. 6 | 7 | Time stamps generated by the web server include date and time and must be 8 | to a granularity of one second. 9 | " 10 | 11 | desc 'check', "Review the NGINX web server documentation and configuration to 12 | determine if log records are time stamped to a minimum granularity of one second. 13 | 14 | If there are no websites configured for NGINX, this check is Not Applicable. 15 | 16 | Check for the following: 17 | # grep for a 'log_format' directive in the http context of the nginx.conf. 18 | 19 | If the 'log_format' directive is not configured to contain the '$time_local' 20 | variable, this is a finding. 21 | " 22 | desc 'fix', "Configure the 'log_format' directive in the nginx.conf to use the 23 | '$time_local' variable to record log events with a time stamp to a granularity 24 | of one second." 25 | 26 | impact 0.5 27 | tag "severity": 'medium' 28 | tag "gtitle": 'SRG-APP-000375-WSR-000171' 29 | tag "gid": 'V-55977' 30 | tag "rid": 'SV-70231r2_rule' 31 | tag "stig_id": 'SRG-APP-000375-WSR-000171' 32 | tag "fix_id": 'F-60855r1_fix' 33 | tag "cci": ['CCI-001889'] 34 | tag "nist": ['AU-8 b', ''] 35 | 36 | if nginx_conf.params['http'].nil? 37 | impact 0.0 38 | describe 'This check is NA because no websites have been configured.' do 39 | skip 'This check is NA because no websites have been configured.' 40 | end 41 | else 42 | nginx_conf.params['http'].each do |http| 43 | http['log_format'].each do |log_format| 44 | describe 'time_local' do 45 | it 'should be part of every log format in the http context.' do 46 | expect(log_format.to_s).to(match(/.*?\$time_local.*?/)) 47 | end 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /controls/V-55979.rb: -------------------------------------------------------------------------------- 1 | control 'V-55979' do 2 | title "The NGINX web server must generate log records that can be mapped to 3 | Coordinated Universal Time (UTC) or Greenwich Mean Time (GMT)." 4 | desc "If time stamps are not consistently applied and there is no common 5 | time reference, it is difficult to perform forensic analysis across multiple 6 | devices and log records. 7 | 8 | Time stamps generated by the web server include date and time. Time is 9 | commonly expressed in Coordinated Universal Time (UTC), a modern continuation 10 | of Greenwich Mean Time (GMT), or local time with an offset from UTC. 11 | " 12 | 13 | desc 'check', " 14 | Review the NGINX web server documentation and configuration to determine the time 15 | stamp format for log data. 16 | 17 | Check for the following: 18 | # grep for all 'env' directives in the main context of the nginx.conf. 19 | 20 | If the 'env' directive cannot be found in NGINX configuration files, this check is 21 | Not Applicable. 22 | 23 | If neither 'env TZ=UTC' or 'env TZ=GMT' exists, this is a finding. 24 | " 25 | desc 'fix', "Configure the 'TZ' environment variable in the nginx.conf to store 26 | log data time stamps in a format that is mappted to UTC or GMT time. 27 | 28 | Example configuration: 29 | 'env TZ=UTC;' 30 | or 31 | 'env TZ=GMT;'" 32 | 33 | impact 0.5 34 | tag "severity": 'medium' 35 | tag "gtitle": 'SRG-APP-000374-WSR-000172' 36 | tag "gid": 'V-55979' 37 | tag "rid": 'SV-70233r2_rule' 38 | tag "stig_id": 'SRG-APP-000374-WSR-000172' 39 | tag "fix_id": 'F-60857r1_fix' 40 | tag "cci": ['CCI-001890'] 41 | tag "nist": ['AU-8 b', ''] 42 | 43 | if nginx_conf.params['env'].nil? 44 | impact 0.0 45 | describe 'This check is NA because the env directive has not been configured.' do 46 | skip 'This check is NA because the env directive has not been configured.' 47 | end 48 | else 49 | describe.one do 50 | describe nginx_conf.params['env'].join do 51 | it { should cmp 'TZ=UTC' } 52 | end 53 | describe nginx_conf.params['env'].join do 54 | it { should cmp 'TZ=GMT' } 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /controls/V-55983.rb: -------------------------------------------------------------------------------- 1 | control 'V-55983' do 2 | title "All NGINX web server files must be verified for their integrity (e.g., 3 | checksums and hashes) before becoming part of the production web server." 4 | desc "Being able to verify that a patch, upgrade, certificate, etc., being 5 | added to the web server is unchanged from the producer of the file is essential 6 | for file validation and non-repudiation of the information. 7 | 8 | The web server or hosting system must have a mechanism to verify that 9 | files, before installation, are valid. 10 | 11 | Examples of validation methods are sha1 and md5 hashes and checksums. 12 | " 13 | 14 | desc 'check', "Review the NGINX web server documentation and deployment 15 | configuration to determine if the web server validates files before the 16 | files are implemented into the running configuration. 17 | 18 | If the NGINX web server does not meet this requirement and an external facility 19 | is not available for use, this is a finding. 20 | " 21 | desc 'fix', "Configure the web server to verify object integrity before 22 | becoming part of the production web server or utilize an external tool designed 23 | to meet this requirement." 24 | impact 0.5 25 | tag "severity": 'medium' 26 | tag "gtitle": 'SRG-APP-000131-WSR-000051' 27 | tag "gid": 'V-55983' 28 | tag "rid": 'SV-70237r2_rule' 29 | tag "stig_id": 'SRG-APP-000131-WSR-000051' 30 | tag "fix_id": 'F-60861r1_fix' 31 | tag "cci": ['CCI-001749'] 32 | tag "nist": ['CM-5 (3)', ''] 33 | 34 | describe "This test requires a Manual Review: Determine if the web server or external 35 | facility validates files before the files are implemented into the running configuration." do 36 | skip "This test requires a Manual Review: Determine if the web server or external 37 | facility validates files before the files are implemented into the running configuration." 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /controls/V-55985.rb: -------------------------------------------------------------------------------- 1 | control 'V-55985' do 2 | title "The NGINX web server must be configured in accordance with the security 3 | configuration settings based on DoD security configuration or implementation 4 | guidance, including STIGs, NSA configuration guides, CTOs, and DTMs." 5 | desc "Configuring the web server to implement organization-wide security 6 | implementation guides and security checklists guarantees compliance with 7 | federal standards and establishes a common security baseline across the DoD 8 | that reflects the most restrictive security posture consistent with operational 9 | requirements. 10 | 11 | Configuration settings are the set of parameters that can be changed that 12 | affect the security posture and/or functionality of the system. 13 | Security-related parameters are those parameters impacting the security state 14 | of the web server, including the parameters required to satisfy other security 15 | control requirements. 16 | " 17 | 18 | desc 'check', "Review the NGINX web server documentation and deployed 19 | configuration to determine if web server is configured in accordance with 20 | the security configuration settings based on DoD security configuration or 21 | implementation guidance. 22 | 23 | Review the website to determine if 'HTTP' and 'HTTPS' are used in accordance 24 | with well-known ports (e.g., 80 and 443) or those ports and services as registered 25 | and approved for use by the DoD Ports, Protocols, and Services Management (PPSM). 26 | 27 | Verify that any variation in PPS is documented, registered, and approved by the PPSM. 28 | 29 | If NGINX is not configured to serve files, this check is Not Applicable. 30 | 31 | Check for the following: 32 | # grep for all 'listen' directives in the server context of the nginx.conf and 33 | any separated include configuration file. 34 | 35 | If the 'listen' directive cannot be found in NGINX configuration files, 36 | this check is Not Applicable. 37 | 38 | If the 'listen' directive is not configured to use port 80 (for HTTP) or port 39 | 443 (for HTTPS) and port configured is not approved for used by PPSM, this is 40 | a finding. 41 | " 42 | desc 'fix', "Configure the 'listen' directives in the NGINX configuration file(s) 43 | to use IANA well-known ports for 'HTTP' and 'HTTPS'." 44 | 45 | impact 0.5 46 | tag "severity": 'medium' 47 | tag "gtitle": 'SRG-APP-000516-WSR-000174' 48 | tag "gid": 'V-55985' 49 | tag "rid": 'SV-70239r2_rule' 50 | tag "stig_id": 'SRG-APP-000516-WSR-000174' 51 | tag "fix_id": 'F-60863r1_fix' 52 | tag "cci": ['CCI-000366'] 53 | tag "nist": ['CM-6 b', ''] 54 | 55 | if nginx_conf.servers.nil? 56 | impact 0.0 57 | describe 'This check is NA because NGINX has not been configured to serve files.' do 58 | skip 'This check is NA because NGINX has not been configured to serve files.' 59 | end 60 | else 61 | nginx_conf.servers.entries.each do |server| 62 | if server.params['listen'].nil? 63 | impact 0.0 64 | describe 'This test is NA because the listen directive has not been configured.' do 65 | skip 'This test is NA because the listen directive has not been configured.' 66 | end 67 | else 68 | server.params['listen'].each do |listen| 69 | describe 'The listen directive' do 70 | listen_address = listen.join 71 | it 'should include the specific IP address and port' do 72 | expect(listen_address).to(match(/[0-9]+(?:\.[0-9]+){3}|[a-zA-Z]:[0-9]+/)) 73 | end 74 | end 75 | describe 'The listening port' do 76 | listen_port = listen.join.split(':')[1] 77 | listen_port = listen_port.tr('ssl', '') unless listen_port.nil? 78 | it 'should be an approved port.' do 79 | expect(listen_port).to(be_in(input('authorized_ports'))) 80 | end 81 | end 82 | end 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /controls/V-55987.rb: -------------------------------------------------------------------------------- 1 | control 'V-55987' do 2 | title "The account used to run the NGINX web server must not have a valid 3 | login shell and password defined." 4 | desc "During installation of the web server software, accounts are created 5 | for the web server to operate properly. The accounts installed can have either 6 | no password installed or a default password, which will be known and documented 7 | by the vendor and the user community. 8 | 9 | The first things an attacker will try when presented with a login screen 10 | are the default user identifiers with default passwords. Installed applications 11 | may also install accounts with no password, making the login even easier. Once 12 | the web server is installed, the passwords for any created accounts should be 13 | changed and documented. The new passwords must meet the requirements for all 14 | passwords, i.e., upper/lower characters, numbers, special characters, time 15 | until change, reuse policy, etc. 16 | 17 | Service accounts or system accounts that have no login capability do not 18 | need to have passwords set or changed. 19 | " 20 | 21 | desc 'check', "Review the NGINX web server documentation and deployment 22 | configuration to determine what non-service/system accounts were installed 23 | by the web server installation process. 24 | 25 | Identify the account that is running the 'nginx' process: 26 | # ps -ef | grep -i nginx | grep -v grep 27 | 28 | root 675 1 0 Jun01 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf 29 | nginx 677 675 0 Jun01 ? 00:00:00 nginx: worker process 30 | 31 | If no service accounts are found, this check is Not Applicable. 32 | 33 | Check to see if the accounts have a valid login shell: 34 | 35 | # cut -d: -f1,7 /etc/passwd | grep -i nginx:/sbin/nologin 36 | # cut -d: -f1,7 /etc/passwd | grep -i root:/sbin/nologin 37 | 38 | If the service account has a valid login shell, verify that no password is 39 | configured for the account: 40 | 41 | # cut -d: -f1,2 /etc/shadow | grep -i root:! 42 | # cut -d: -f1,2 /etc/shadow | grep -i nginx:! 43 | 44 | If the account has a valid login shell and a password defined, 45 | this is a finding. 46 | " 47 | desc 'fix', " 48 | Update the /etc/passwd file to assign the accounts used to run the 'nginx' 49 | process an invalid login shell such as '/sbin/nologin'. 50 | 51 | Lock the accounts used to run the 'nginx' process: 52 | 53 | # passwd -l 54 | Locking password for user 55 | passwd: Success 56 | " 57 | impact 0.5 58 | tag "severity": 'medium' 59 | tag "gtitle": 'SRG-APP-000516-WSR-000079' 60 | tag "gid": 'V-55987' 61 | tag "rid": 'SV-70241r2_rule' 62 | tag "stig_id": 'SRG-APP-000516-WSR-000079' 63 | tag "fix_id": 'F-60865r1_fix' 64 | tag "cci": ['CCI-000366'] 65 | tag "nist": ['CM-6 b', ''] 66 | 67 | service_accounts = [] 68 | 69 | login_shells = file('/etc/shells').content.lines.collect(&:strip) 70 | 71 | if command('ps').exist? 72 | ps_output = command('ps -ef | grep -i nginx | grep -v grep').stdout.split("\n") 73 | 74 | ps_output.each do |output| 75 | account = command("echo '#{output}' | awk '{print $1}'").stdout.split 76 | service_accounts.push(account) 77 | end 78 | else 79 | service_accounts << input('nginx_owner') 80 | end 81 | 82 | if service_accounts.empty? || service_accounts.nil? 83 | impact 0.0 84 | describe 'This test is NA because the no service accounts were found.' do 85 | skip 'This test is NA because the service accounts were found.' 86 | end 87 | else 88 | service_accounts.flatten.uniq 89 | service_accounts.each do |account| 90 | describe.one do 91 | describe user(account.to_s) do 92 | its('shell') { should_not be_in login_shells } 93 | end 94 | describe passwd do 95 | its('users') { should_not include account.to_s } 96 | end 97 | end 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /controls/V-55991.rb: -------------------------------------------------------------------------------- 1 | control 'V-55991' do 2 | title "The NGINX web server must prohibit or restrict the use of nonsecure or 3 | unnecessary ports, protocols, modules, and/or services." 4 | desc "Web servers provide numerous processes, features, and functionalities 5 | that utilize TCP/IP ports. Some of these processes may be deemed unnecessary or 6 | too unsecure to run on a production system. 7 | 8 | The web server must provide the capability to disable or deactivate 9 | network-related services that are deemed to be non-essential to the server 10 | mission, are too unsecure, or are prohibited by the PPSM CAL and vulnerability 11 | assessments. 12 | " 13 | 14 | desc 'check', " 15 | Review the NGINX web server documentation and deployment configuration to 16 | determine which ports and protocols are enabled. 17 | 18 | Verify that the ports and protocols being used are permitted, necessary for 19 | the operation of the web server and the hosted applications and are secure for 20 | a production system. 21 | 22 | If NGINX is not configured to serve files, this check is Not Applicable. 23 | 24 | Check for the following: 25 | # grep for all 'listen' directives in the server context of the nginx.conf and 26 | any separated include configuration file. 27 | 28 | If the 'listen' directive cannot be found in NGINX configuration files, 29 | this check is Not Applicable. 30 | 31 | If the 'listen' directive is not configured to use port 80 (for HTTP) or port 32 | 443 (for HTTPS) and port configured is not approved for used by PPSM, this is 33 | a finding. 34 | " 35 | desc 'fix', "Configure the 'listen' directives in the NGINX configuration file(s) 36 | to use IANA well-known ports for 'HTTP' and 'HTTPS'." 37 | 38 | impact 0.5 39 | tag "severity": 'medium' 40 | tag "gtitle": 'SRG-APP-000383-WSR-000175' 41 | tag "gid": 'V-55991' 42 | tag "rid": 'SV-70245r2_rule' 43 | tag "stig_id": 'SRG-APP-000383-WSR-000175' 44 | tag "fix_id": 'F-60869r1_fix' 45 | tag "cci": ['CCI-001762'] 46 | tag "nist": ['CM-7 (1) (b)', ''] 47 | 48 | if nginx_conf.servers.nil? 49 | impact 0.0 50 | describe 'This check is NA because NGINX has not been configured to serve files.' do 51 | skip 'This check is NA because NGINX has not been configured to serve files.' 52 | end 53 | else 54 | nginx_conf.servers.entries.each do |server| 55 | if server.params['listen'].nil? 56 | impact 0.0 57 | describe 'This test is NA because the listen directive has not been configured.' do 58 | skip 'This test is NA because the listen directive has not been configured.' 59 | end 60 | else 61 | server.params['listen'].each do |listen| 62 | describe 'The listen directive' do 63 | listen_address = listen.join 64 | it 'should include the specific IP address and port' do 65 | expect(listen_address).to(match(/[0-9]+(?:\.[0-9]+){3}|[a-zA-Z]:[0-9]+/)) 66 | end 67 | end 68 | describe 'The listening port' do 69 | listen_port = listen.join.split(':')[1] 70 | listen_port = listen_port.tr('ssl', '') unless listen_port.nil? 71 | it 'should be an approved port.' do 72 | expect(listen_port).to(be_in(input('authorized_ports'))) 73 | end 74 | end 75 | end 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /controls/V-55993.rb: -------------------------------------------------------------------------------- 1 | control 'V-55993' do 2 | title "Anonymous user access to the NGINX web server application directories must 3 | be prohibited." 4 | desc "In order to properly monitor the changes to the web server and the 5 | hosted applications, logging must be enabled. Along with logging being enabled, 6 | each record must properly contain the changes made and the names of those who 7 | made the changes. 8 | 9 | Allowing anonymous users the capability to change the web server or the 10 | hosted application will not generate proper log information that can then be 11 | used for forensic reporting in the case of a security issue. Allowing anonymous 12 | users to make changes will also grant change capabilities to anybody without 13 | forcing a user to authenticate before the changes can be made. 14 | " 15 | 16 | desc 'check', "Review the NGINX web server documentation and configuration 17 | to determine if anonymous users can make changes to the web server or any 18 | applications hosted by the web server. 19 | 20 | Obtain a list of the user accounts for the system, noting the privileges for each account. 21 | 22 | Verify with the System Administrator (SA) or the Information System Security Officer (ISSO) that 23 | all privileged accounts are mission essential and documented. 24 | 25 | Verify with the SA or the ISSO that all non-administrator access to shell scripts and operating 26 | system functions are mission essential and documented. 27 | 28 | If there are no valid login shells, this check is Not Applicable. 29 | 30 | If undocumented privileged accounts are present, this is a finding. 31 | 32 | If undocumented access to shell scripts or operating system functions is present (i.e. anonymous users 33 | can make changes), this is a finding. 34 | " 35 | desc 'fix', "Ensure non-administrators (e.g. anonymous) are not allowed access to the directory tree, 36 | the shell, or other operating system functions and utilities." 37 | impact 0.5 38 | tag "severity": 'medium' 39 | tag "gtitle": 'SRG-APP-000211-WSR-000031' 40 | tag "gid": 'V-55993' 41 | tag "rid": 'SV-70247r2_rule' 42 | tag "stig_id": 'SRG-APP-000211-WSR-000031' 43 | tag "fix_id": 'F-60871r1_fix' 44 | tag "cci": ['CCI-001082'] 45 | tag "nist": %w(SC-2) 46 | 47 | valid_login_shells = command("grep '^[^#]' /etc/shells").stdout.split("\n") 48 | 49 | if valid_login_shells.empty? 50 | impact 0.0 51 | describe 'This check is NA because the there are no valid login shells.' do 52 | skip 'This check is NA because the there are no valid login shells.' 53 | end 54 | else 55 | valid_login_shells.each do |shell| 56 | describe 'Unauthorized users' do 57 | it 'should not have shell access.' do 58 | expect(users.shells(/#{shell}/).usernames).to(be_in(input('sys_admin').clone << input('nginx_owner'))) 59 | end 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /controls/V-55995.rb: -------------------------------------------------------------------------------- 1 | control 'V-55995' do 2 | title "NGINX web server accounts accessing the directory tree, the shell, or other 3 | operating system functions and utilities must only be administrative accounts." 4 | desc "As a rule, accounts on a web server are to be kept to a minimum. Only 5 | administrators, web managers, developers, auditors, and web authors require 6 | accounts on the machine hosting the web server. The resources to which these 7 | accounts have access must also be closely monitored and controlled. Only the 8 | system administrator needs access to all the system's capabilities, while the 9 | web administrator and associated staff require access and control of the web 10 | content and web server configuration files." 11 | 12 | desc 'check', "Review the NGINX web server documentation and configuration to 13 | determine what web server accounts are available on the hosting server. 14 | 15 | Obtain a list of the user accounts for the system, noting the priviledges for 16 | each account. 17 | 18 | Verify with the system administrator or the ISSO that all privileged accounts are 19 | mission essential and documented. 20 | 21 | Verify with the system administrator or the ISSO that all non-administrator access 22 | to shell scripts and operating system functions are mission essential and documented. 23 | 24 | If there are no valid login shells, this check is Not Applicable. 25 | 26 | If undocumented privileged accounts are found, this is a finding. 27 | 28 | If undocumented access to shell scripts or operating system functions is found, 29 | this is a finding. 30 | " 31 | desc 'fix', "Ensure non-administrators are not allowed access to thedirectory tree, 32 | the shell, or other operating system functions and utilities." 33 | 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000211-WSR-000030' 37 | tag "gid": 'V-55995' 38 | tag "rid": 'SV-70249r2_rule' 39 | tag "stig_id": 'SRG-APP-000211-WSR-000030' 40 | tag "fix_id": 'F-60873r1_fix' 41 | tag "cci": ['CCI-001082'] 42 | tag "nist": %w(SC-2) 43 | 44 | valid_login_shells = command("grep '^[^#]' /etc/shells").stdout.split("\n") 45 | 46 | if valid_login_shells.empty? 47 | impact 0.0 48 | describe 'This check is NA because the there are no valid login shells.' do 49 | skip 'This check is NA because the there are no valid login shells.' 50 | end 51 | else 52 | valid_login_shells.each do |shell| 53 | describe 'Unauthorized users' do 54 | it 'should not have shell access.' do 55 | expect(users.shells(/#{shell}/).usernames).to(be_in(input('sys_admin').clone << input('nginx_owner'))) 56 | end 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /controls/V-55997.rb: -------------------------------------------------------------------------------- 1 | control 'V-55997' do 2 | title "The NGINX web server must be tuned to handle the operational requirements of 3 | the hosted application." 4 | desc "A Denial of Service (DoS) can occur when the web server is so 5 | overwhelmed that it can no longer respond to additional requests. A web server 6 | not properly tuned may become overwhelmed and cause a DoS condition even with 7 | expected traffic from users. To avoid a DoS, the web server must be tuned to 8 | handle the expected traffic for the hosted applications." 9 | 10 | desc 'check', "Review the NGINX web server documentation and deployed configuration 11 | to determine what parameters are set to tune the web server. 12 | 13 | If there are no websites configured or if NGINX is not configured to serve files, 14 | this check is Not Applicable. 15 | 16 | To view the timeout values enter the following commands: 17 | # grep ''client_body_timeout'' on the nginx.conf file and any separate included 18 | configuration files 19 | # grep ''client_header_timeout'' on the nginx.conf file and any separate included 20 | configuration files 21 | 22 | If the values of each are not set to 10 seconds (10s) or less, this is a finding.' 23 | " 24 | desc 'fix', "Configure the NGINX web server to include the 'client_body_timeout' and 25 | 'client_header_timeout' directives in the NGINX configuration file(s). 26 | Set the value of 'client_body_timeout' and 'client_header_timeout to be 27 | 10 seconds or less to mitigate the effects of several types of denial of 28 | service attacks: 29 | 30 | client_body_timeout 10s; 31 | client_header_timeout 10s; 32 | " 33 | impact 0.5 34 | tag "severity": 'medium' 35 | tag "gtitle": 'SRG-APP-000435-WSR-000148' 36 | tag "gid": 'V-55997' 37 | tag "rid": 'SV-70251r2_rule' 38 | tag "stig_id": 'SRG-APP-000435-WSR-000148' 39 | tag "fix_id": 'F-60875r2_fix' 40 | tag "cci": ['CCI-002385'] 41 | tag "nist": %w(SC-5) 42 | 43 | if nginx_conf.params['http'].nil? 44 | impact 0.0 45 | describe 'This check is NA because no websites have been configured.' do 46 | skip 'This check is NA because no websites have been configured.' 47 | end 48 | else 49 | nginx_conf.params['http'].each do |http| 50 | describe 'The http context client_header_timeout value' do 51 | it 'should exist and should be set to 10 (seconds) or less.' do 52 | expect(http).to(include 'client_header_timeout') 53 | expect(http['client_header_timeout'].join.to_i).to(be <= 10) 54 | end 55 | end 56 | describe 'The http context client_body_timeout value' do 57 | it 'should exist and should be set to 10 (seconds) or less.' do 58 | expect(http).to(include 'client_body_timeout') 59 | expect(http['client_body_timeout'].join.to_i).to(be <= 10) 60 | end 61 | end 62 | end 63 | end 64 | 65 | if nginx_conf.servers.nil? 66 | impact 0.0 67 | describe 'This check is NA because NGINX has not been configured to serve files.' do 68 | skip 'This check is NA because NGINX has not been configured to serve files.' 69 | end 70 | else 71 | nginx_conf.servers.each do |server| 72 | describe 'The server context client_header_timeout value' do 73 | it 'should be set to 10 (seconds) or less, if found.' do 74 | unless server.params['client_header_timeout'].nil? 75 | expect(server.params['client_header_timeout'].join.to_i).to(be <= 10) 76 | end 77 | end 78 | end 79 | describe 'The server context client_body_timeout value' do 80 | it 'should be set to 10 (seconds) or less, if found' do 81 | unless server.params['client_body_timeout'].nil? 82 | expect(server.params['client_body_timeout'].join.to_i).to(be <= 10) 83 | end 84 | end 85 | end 86 | end 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /controls/V-56005.rb: -------------------------------------------------------------------------------- 1 | control 'V-56005' do 2 | title "Web server cookies, such as session cookies, sent to the client using 3 | SSL/TLS must not be compressed." 4 | desc "A cookie is used when a web server needs to share data with the 5 | client's browser. The data is often used to remember the client when the client 6 | returns to the hosted application at a later date. A session cookie is a 7 | special type of cookie used to remember the client during the session. The 8 | cookie will contain the session identifier (ID) and may contain authentication 9 | data to the hosted application. To protect this data from easily being 10 | compromised, the cookie can be encrypted. 11 | 12 | When a cookie is sent encrypted via SSL/TLS, an attacker must spend a great 13 | deal of time and resources to decrypt the cookie. If, along with encryption, 14 | the cookie is compressed, the attacker can now use a combination of plaintext 15 | injection and inadvertent information leakage through data compression to 16 | reduce the time needed to decrypt the cookie. This attack is called Compression 17 | Ratio Info-leak Made Easy (CRIME). 18 | 19 | Cookies shared between the web server and the client when encrypted should 20 | not also be compressed. 21 | " 22 | 23 | desc 'check', "Review the web server documentation and deployed configuration 24 | to determine whether cookies are being sent to the client using SSL/TLS. 25 | 26 | If the transmission is through a SSL/TLS connection, but the cookie is not 27 | being compressed, this finding is Not Applicable. 28 | 29 | If it is determined that the web server is not required to perform session 30 | management, this check is Not Applicable. 31 | 32 | SSL/TLS compression has been disabled by default since NGINX version 1.3.2. 33 | Execute the following command to get the current version of NGINX running: 34 | # nginx -v 35 | 36 | If the current version of NGINX running is older than 1.3.2, this is a finding. 37 | " 38 | desc 'fix', "Upgrade to the lastest stable version of NGINX web server to 39 | ensure Web server cookies, such as session cookies, are not compressed." 40 | 41 | impact 0.5 42 | tag "severity": 'medium' 43 | tag "gtitle": 'SRG-APP-000439-WSR-000153' 44 | tag "gid": 'V-56005' 45 | tag "rid": 'SV-70259r2_rule' 46 | tag "stig_id": 'SRG-APP-000439-WSR-000153' 47 | tag "fix_id": 'F-60883r1_fix' 48 | tag "cci": ['CCI-002418'] 49 | tag "nist": %w(SC-8) 50 | 51 | if input('performs_session_management') == false 52 | impact 0.0 53 | describe 'This check is NA because session management is not required.' do 54 | skip 'This check is NA because session management is not required.' 55 | end 56 | else 57 | describe nginx do 58 | its('version') { should cmp >= '1.3.2' } 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /controls/V-56007.rb: -------------------------------------------------------------------------------- 1 | control 'V-56007' do 2 | title "Cookies exchanged between the web server and the client, such as 3 | session cookies, must have cookie properties set to prohibit client-side 4 | scripts from reading the cookie data." 5 | desc "A cookie can be read by client-side scripts easily if cookie 6 | properties are not set properly. By allowing cookies to be read by the 7 | client-side scripts, information such as session identifiers could be 8 | compromised and used by an attacker who intercepts the cookie. Setting cookie 9 | properties (i.e. HttpOnly property) to disallow client-side scripts from 10 | reading cookies better protects the information inside the cookie." 11 | 12 | desc 'check', "Review the NGINX web server documentation and deployed 13 | configuration to determine how to disable client-side scripts from reading 14 | cookies. 15 | 16 | If it is determined that the web server is not required to perform session 17 | management, this check is Not Applicable. 18 | 19 | If NGINX is not configured to serve files or if the required directive(s) 20 | cannot be found in the NGINX configuration files, this check is Not Applicable. 21 | 22 | Check for the following: 23 | # grep the 'proxy_cookie_path' directive in the location context of the 24 | nginx.conf and any separated include configuration file. 25 | 26 | If the 'proxy_cookie_path' directive exists and is not set to the 'HTTPOnly' 27 | property, this is a finding. 28 | " 29 | desc 'fix', " 30 | If the 'proxy_cookie_path' directive exists in the NGINX configuration file(s), 31 | configure it to include the 'HTTPOnly' property. 32 | 33 | Example: 34 | proxy_cookie_path / '/; HTTPOnly; Secure'" 35 | impact 0.5 36 | tag "severity": 'medium' 37 | tag "gtitle": 'SRG-APP-000439-WSR-000154' 38 | tag "gid": 'V-56007' 39 | tag "rid": 'SV-70261r2_rule' 40 | tag "stig_id": 'SRG-APP-000439-WSR-000154' 41 | tag "fix_id": 'F-60885r1_fix' 42 | tag "cci": ['CCI-002418'] 43 | tag "nist": %w(SC-8) 44 | 45 | if input('performs_session_management') == false 46 | impact 0.0 47 | describe 'This check is NA because session management is not required.' do 48 | skip 'This check is NA because session management is not required.' 49 | end 50 | elsif nginx_conf.servers.nil? 51 | impact 0.0 52 | describe 'This check is NA because NGINX has not been configured to serve files.' do 53 | skip 'This check is NA because NGINX has not been configured to serve files.' 54 | end 55 | else 56 | nginx_conf.locations.each do |location| 57 | if location.params['proxy_cookie_path'].nil? 58 | impact 0.0 59 | describe 'This check is NA because the proxy_cookie_path directive is not configured.' do 60 | skip 'This check is NA because the proxy_cookie_path directive is not configured.' 61 | end 62 | else 63 | describe "The 'proxy_cookie_path'" do 64 | it 'should be configured to HTTPOnly and Secure' do 65 | expect(location.params['proxy_cookie_path'].join).to(include '/; HTTPOnly; Secure') 66 | end 67 | end 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /controls/V-56009.rb: -------------------------------------------------------------------------------- 1 | control 'V-56009' do 2 | title "Cookies exchanged between the NGINX web server and the client, such as 3 | session cookies, must have cookie properties set to force the encryption of 4 | cookies." 5 | desc "Cookies can be sent to a client using TLS/SSL to encrypt the cookies, 6 | but TLS/SSL is not used by every hosted application since the data being 7 | displayed does not require the encryption of the transmission. To safeguard 8 | against cookies, especially session cookies, being sent in plaintext, a cookie 9 | can be encrypted before transmission. To force a cookie to be encrypted before 10 | transmission, the cookie Secure property can be set." 11 | 12 | desc 'check', "Review the NGINX web server documentation and deployed configuration 13 | to verify that cookies are encrypted before transmission. 14 | 15 | If it is determined that the web server is not required to perform session 16 | management, this check is Not Applicable. 17 | 18 | If NGINX is not configured to serve files or if the required directive(s) 19 | cannot be found in the NGINX configuration files, this check is Not Applicable. 20 | 21 | Check for the following: 22 | # grep the 'proxy_cookie_path' directive in the location context of the 23 | nginx.conf and any separated include configuration file. 24 | 25 | If the 'proxy_cookie_path' directive exists and is not set to 'Secure', 26 | this is a finding. 27 | " 28 | desc 'fix', "If the 'proxy_cookie_path' directive exists in the NGINX 29 | configuration file(s), configure it to include the 'Secure' property. 30 | 31 | Example: 32 | proxy_cookie_path / '/; HTTPOnly; Secure';" 33 | impact 0.5 34 | tag "severity": 'medium' 35 | tag "gtitle": 'SRG-APP-000439-WSR-000155' 36 | tag "gid": 'V-56009' 37 | tag "rid": 'SV-70263r2_rule' 38 | tag "stig_id": 'SRG-APP-000439-WSR-000155' 39 | tag "fix_id": 'F-60887r1_fix' 40 | tag "cci": ['CCI-002418'] 41 | tag "nist": %w(SC-8) 42 | 43 | if input('performs_session_management') == false 44 | impact 0.0 45 | describe 'This check is NA because session management is not required.' do 46 | skip 'This check is NA because session management is not required.' 47 | end 48 | elsif nginx_conf.servers.nil? 49 | impact 0.0 50 | describe 'This check is NA because NGINX has not been configured to serve files.' do 51 | skip 'This check is NA because NGINX has not been configured to serve files.' 52 | end 53 | else 54 | nginx_conf.locations.each do |location| 55 | if location.params['proxy_cookie_path'].nil? 56 | impact 0.0 57 | describe 'This check is NA because the proxy_cookie_path directive is not configured.' do 58 | skip 'This check is NA because the proxy_cookie_path directive is not configured.' 59 | end 60 | else 61 | describe "The 'proxy_cookie_path'" do 62 | it 'should be configured to HTTPOnly and Secure' do 63 | expect(location.params['proxy_cookie_path'].join).to(include '/; HTTPOnly; Secure') 64 | end 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /controls/V-56011.rb: -------------------------------------------------------------------------------- 1 | control 'V-56011' do 2 | title "A web server must maintain the confidentiality of controlled 3 | information during transmission through the use of an approved TLS version." 4 | desc "Transport Layer Security (TLS) is a required transmission protocol for 5 | a web server hosting controlled information. The use of TLS provides 6 | confidentiality of data in transit between the web server and client. FIPS 7 | 140-2 approved TLS versions must be enabled and non-FIPS-approved SSL versions 8 | must be disabled. 9 | 10 | NIST SP 800-52 defines the approved TLS versions for government 11 | applications. 12 | " 13 | 14 | desc 'check', "Review the NGINX web server documentation and deployed configuration 15 | to determine which version of TLS is being used. 16 | 17 | If NGINX is not configured to serve files, this check is Not Applicable. 18 | 19 | Check for the following: 20 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf and any 21 | separated include configuration file. 22 | 23 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 24 | this check is Not Applicable. 25 | 26 | If the 'ssl_protocols' directive not set to the approved TLS version, this is a finding. 27 | " 28 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration file(s) and 29 | configure it to use only the approved TLS protocols. 30 | 31 | Example: 32 | server { 33 | ssl_protocols TLSv1.2; 34 | } 35 | " 36 | impact 0.5 37 | tag "severity": 'medium' 38 | tag "gtitle": 'SRG-APP-000439-WSR-000156' 39 | tag "gid": 'V-56011' 40 | tag "rid": 'SV-70265r2_rule' 41 | tag "stig_id": 'SRG-APP-000439-WSR-000156' 42 | tag "fix_id": 'F-60889r1_fix' 43 | tag "cci": ['CCI-002418'] 44 | tag "nist": %w(SC-8) 45 | 46 | if nginx_conf.servers.nil? 47 | impact 0.0 48 | describe 'This check is NA because NGINX has not been configured to serve files.' do 49 | skip 'This check is NA because NGINX has not been configured to serve files.' 50 | end 51 | else 52 | nginx_conf.servers.each do |server| 53 | if server.params['ssl_protocols'].nil? 54 | impact 0.0 55 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 56 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 57 | end 58 | else 59 | server.params['ssl_protocols'].each do |protocol| 60 | describe 'Each protocol' do 61 | it 'should be included in the list of protocols approved to encrypt data' do 62 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 63 | end 64 | end 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /controls/V-56013.rb: -------------------------------------------------------------------------------- 1 | control 'V-56013' do 2 | title "The web server must maintain the confidentiality and integrity of 3 | information during preparation for transmission." 4 | desc "Information can be either unintentionally or maliciously disclosed or 5 | modified during preparation for transmission, including, for example, during 6 | aggregation, at protocol transformation points, and during packing/unpacking. 7 | These unauthorized disclosures or modifications compromise the confidentiality 8 | or integrity of the information. 9 | 10 | An example of this would be an SMTP queue. This queue may be added to a web 11 | server through an SMTP module to enhance error reporting or to allow developers 12 | to add SMTP functionality to their applications. 13 | 14 | Any modules used by the web server that queue data before transmission must 15 | maintain the confidentiality and integrity of the information before the data 16 | is transmitted. 17 | " 18 | 19 | desc 'check', "Review the web server documentation and deployed configuration 20 | to determine if the web server maintains the confidentiality and integrity of 21 | information during preparation before transmission. 22 | 23 | If NGINX is not configured to serve files, this check is Not Applicable. 24 | 25 | Check for the following: 26 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf 27 | and any separated include configuration file. 28 | 29 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 30 | this check is Not Applicable. 31 | 32 | If the 'ssl_protocols' directive is not set to the approved TLS version, 33 | this is a finding. 34 | " 35 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration 36 | file(s) and configure it to use the approved TLS protocols to maintain the 37 | confidentiality and integrity of information during preparation for transmission. 38 | 39 | Example: 40 | server { 41 | ssl_protocols TLSv1.2; 42 | }" 43 | impact 0.5 44 | tag "severity": 'medium' 45 | tag "gtitle": 'SRG-APP-000441-WSR-000181' 46 | tag "gid": 'V-56013' 47 | tag "rid": 'SV-70267r2_rule' 48 | tag "stig_id": 'SRG-APP-000441-WSR-000181' 49 | tag "fix_id": 'F-60891r1_fix' 50 | tag "cci": ['CCI-002420'] 51 | tag "nist": ['SC-8 (2)', ''] 52 | 53 | if nginx_conf.servers.nil? 54 | impact 0.0 55 | describe 'This check is NA because NGINX has not been configured to serve files.' do 56 | skip 'This check is NA because NGINX has not been configured to serve files.' 57 | end 58 | else 59 | nginx_conf.servers.each do |server| 60 | if server.params['ssl_protocols'].nil? 61 | impact 0.0 62 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 63 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 64 | end 65 | else 66 | server.params['ssl_protocols'].each do |protocol| 67 | describe 'Each protocol' do 68 | it 'should be included in the list of protocols approved to encrypt data' do 69 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 70 | end 71 | end 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /controls/V-56015.rb: -------------------------------------------------------------------------------- 1 | control 'V-56015' do 2 | title "The web server must maintain the confidentiality and integrity of 3 | information during reception." 4 | desc "Information can be either unintentionally or maliciously disclosed or 5 | modified during reception, including, for example, during aggregation, at 6 | protocol transformation points, and during packing/unpacking. These 7 | unauthorized disclosures or modifications compromise the confidentiality or 8 | integrity of the information. 9 | 10 | Protecting the confidentiality and integrity of received information 11 | requires that application servers take measures to employ approved cryptography 12 | in order to protect the information during transmission over the network. This 13 | is usually achieved through the use of Transport Layer Security (TLS), SSL VPN, 14 | or IPsec tunnel. 15 | 16 | The web server must utilize approved encryption when receiving transmitted 17 | data. 18 | " 19 | 20 | desc 'check', "Review web server configuration to determine if the server 21 | is using a transmission method that maintains the confidentiality and integrity of 22 | information during reception. 23 | 24 | If NGINX is not configured to serve files, this check is Not Applicable. 25 | 26 | Check for the following: 27 | #grep the 'ssl_protocols' directive in the server context of the nginx.conf 28 | and any separated include configuration file. 29 | 30 | If the 'ssl_protocols' directive cannot be found in NGINX configuration files, 31 | this check is Not Applicable. 32 | 33 | If the 'ssl_protocols' directive is not set to the approved TLS version, 34 | this is a finding. 35 | " 36 | desc 'fix', "Add the 'ssl_protocols' directive to the NGINX configuration 37 | file(s) and configure it to use only the approved TLS protocols to maintain 38 | the confidentiality and integrity of information during reception. 39 | 40 | Example: 41 | server { 42 | ssl_protocols TLSv1.2; 43 | }" 44 | impact 0.5 45 | tag "severity": 'medium' 46 | tag "gtitle": 'SRG-APP-000442-WSR-000182 ' 47 | tag "gid": 'V-56015' 48 | tag "rid": 'SV-70269r2_rule' 49 | tag "stig_id": 'SRG-APP-000442-WSR-000182' 50 | tag "fix_id": 'F-60893r1_fix' 51 | tag "cci": ['CCI-002422'] 52 | tag "nist": ['SC-8 (2)', ''] 53 | 54 | if nginx_conf.servers.nil? 55 | impact 0.0 56 | describe 'This check is NA because NGINX has not been configured to serve files.' do 57 | skip 'This check is NA because NGINX has not been configured to serve files.' 58 | end 59 | else 60 | nginx_conf.servers.each do |server| 61 | if server.params['ssl_protocols'].nil? 62 | impact 0.0 63 | describe 'This test is NA because the ssl_protocols directive has not been configured.' do 64 | skip 'This test is NA because the ssl_protocols directive has not been configured.' 65 | end 66 | else 67 | server.params['ssl_protocols'].each do |protocol| 68 | describe 'Each protocol' do 69 | it 'should be included in the list of protocols approved to encrypt data' do 70 | expect(protocol).to(be_in(input('approved_ssl_protocols'))) 71 | end 72 | end 73 | end 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /controls/V-56019.rb: -------------------------------------------------------------------------------- 1 | control 'V-56019' do 2 | title "An NGINX web server utilizing mobile code must meet DoD-defined mobile code 3 | requirements." 4 | desc "Mobile code in hosted applications allows the developer to add 5 | functionality and displays to hosted applications that are fluid, as opposed to 6 | a static web page. The data presentation becomes more appealing to the user, is 7 | easier to analyze, and navigation through the hosted application and data is 8 | much less complicated. 9 | 10 | Some mobile code technologies in use in today's applications are: Java, 11 | JavaScript, ActiveX, PDF, Postscript, Shockwave movies, Flash animations, and 12 | VBScript. The DoD has created policies that define the usage of mobile code on 13 | DoD systems. The usage restrictions and implementation guidance apply to both 14 | the selection and use of mobile code installed on organizational servers and 15 | mobile code downloaded and executed on individual workstations. 16 | 17 | The web server may host applications that contain mobile code and 18 | therefore, must meet the DoD-defined requirements regarding the deployment 19 | and/or use of mobile code. This includes digitally signing applets in order to 20 | provide a means for the client to establish application authenticity. 21 | " 22 | 23 | desc 'check', "Review the web server documentation and deployed configuration 24 | to determine whether mobile code used by hosted applications follows the DoD 25 | policies on the acquisition, development, and/or use of mobile code. 26 | 27 | If the web server does not implement mobile code, this check is Not Applicable. 28 | 29 | If the web server does implement mobile code but is not configured to follow 30 | the DoD policies on mobile code, this is a finding. 31 | " 32 | desc 'fix', "Configure the web server to follow the DoD policies on mobile 33 | code." 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000206-WSR-000128' 37 | tag "gid": 'V-56019' 38 | tag "rid": 'SV-70273r2_rule' 39 | tag "stig_id": 'SRG-APP-000206-WSR-000128' 40 | tag "fix_id": 'F-60897r1_fix' 41 | tag "cci": ['CCI-001166'] 42 | tag "nist": ['SC-18 (1)', ''] 43 | 44 | if input('implements_mobile_code') == false 45 | impact 0.0 46 | describe 'This check is NA because NGINX does not implement mobile code.' do 47 | skip 'This check is NA because NGINX does not implement mobile code.' 48 | end 49 | else 50 | describe "This test requires a Manual Review: Verify the web server is configured 51 | to follow DoD policies on mobile code by reviewing the NGINX documentation." do 52 | skip "This test requires a Manual Review: Verify the web server is configured 53 | to follow DoD policies on mobile code by reviewing the NGINX documentation." 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /controls/V-56021.rb: -------------------------------------------------------------------------------- 1 | control 'V-56021' do 2 | title "The NGINX web server must invalidate session identifiers upon hosted 3 | application user logout or other session termination." 4 | desc "Captured sessions can be reused in \"replay\" attacks. This 5 | requirement limits the ability of adversaries from capturing and continuing to 6 | employ previously valid session IDs. 7 | 8 | Session IDs are tokens generated by web applications to uniquely identify 9 | an application user's session. Unique session IDs help to reduce predictability 10 | of said identifiers. When a user logs out, or when any other session 11 | termination event occurs, the web server must terminate the user session to 12 | minimize the potential for an attacker to hijack that particular user session. 13 | " 14 | 15 | desc 'check', "Review the web server documentation and deployed configuration 16 | to verify that the web server is configured to invalidate session identifiers when a 17 | session is terminated. 18 | 19 | If it is determined that the web server is not required to perform session 20 | management, this check is Not Applicable. 21 | 22 | If the web server does not invalidate session identifiers when a session is 23 | terminated, this is a finding. 24 | " 25 | desc 'fix', "Configure the web server to invalidate session identifiers when 26 | a session is terminated." 27 | impact 0.5 28 | tag "severity": 'medium' 29 | tag "gtitle": 'SRG-APP-000220-WSR-000201' 30 | tag "gid": 'V-56021' 31 | tag "rid": 'SV-70275r2_rule' 32 | tag "stig_id": 'SRG-APP-000220-WSR-000201' 33 | tag "fix_id": 'F-60899r1_fix' 34 | tag "cci": ['CCI-001185'] 35 | tag "nist": ['SC-23 (1)', ''] 36 | 37 | if input('performs_session_management') == false 38 | impact 0.0 39 | describe 'This check is NA because session management is not required.' do 40 | skip 'This check is NA because session management is not required.' 41 | end 42 | else 43 | describe "This test requires a Manual Review: Verify it invalidates session identifiers when a 44 | session is terminated by reviewing the NGINX documentation." do 45 | skip "This test requires a Manual Review: Verify it invalidates session identifiers when a 46 | session is terminated by reviewing the NGINX documentation." 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /controls/V-56025.rb: -------------------------------------------------------------------------------- 1 | control 'V-56025' do 2 | title "Cookies exchanged between the NGINX web server and client, such as session 3 | cookies, must have security settings that disallow cookie access outside the 4 | originating web server and hosted application." 5 | desc "Cookies are used to exchange data between the web server and the 6 | client. Cookies, such as a session cookie, may contain session information and 7 | user credentials used to maintain a persistent connection between the user and 8 | the hosted application since HTTP/HTTPS is a stateless protocol. 9 | 10 | When the cookie parameters are not set properly (i.e., domain and path 11 | parameters), cookies can be shared within hosted applications residing on the 12 | same web server or to applications hosted on different web servers residing on 13 | the same domain. 14 | " 15 | 16 | desc 'check', "Review the NGINX web server documentation and configuration to 17 | determine if cookies between the web server and client are accessible by applications 18 | or web servers other than the originating pair. 19 | 20 | If it is determined that the web server is not required to perform session management, 21 | this check is Not Applicable. 22 | 23 | If NGINX is not configured to serve files or if the required directive(s) 24 | cannot be found in the NGINX configuration files, this check is Not Applicable. 25 | 26 | Check for the following: 27 | # grep the 'proxy_cookie_path' directive in the location context 28 | of the nginx.conf and any separated include configuration file. 29 | 30 | If the 'proxy_cookie_path' directive exists and is not set to the 'HTTPOnly' and 31 | 'Secure' properties, this is a finding. 32 | 33 | # grep ‘proxy_cookie_domain’ directive in the location context 34 | of the nginx.conf and any separated include configuration file. 35 | 36 | If the 'proxy_cookie_domain' directive is found and not set to 'off', this is a finding. 37 | " 38 | desc 'fix', "If the 'proxy_cookie_path' directive exists in the NGINX configuration 39 | file(s), configure it to include the 'HTTPOnly' and 'Secure' properties. 40 | 41 | Example: 42 | proxy_cookie_path / '/; HTTPOnly; Secure'; 43 | 44 | Ensure the 'proxy_cookie_domain' directive is set to 'off' if it exists." 45 | impact 0.5 46 | tag "severity": 'medium' 47 | tag "gtitle": 'SRG-APP-000223-WSR-000011' 48 | tag "gid": 'V-56025' 49 | tag "rid": 'SV-70279r2_rule' 50 | tag "stig_id": 'SRG-APP-000223-WSR-000011' 51 | tag "fix_id": 'F-60903r1_fix' 52 | tag "cci": ['CCI-001664'] 53 | tag "nist": ['SC-23 (3)', ''] 54 | 55 | if input('performs_session_management') == false 56 | impact 0.0 57 | describe 'This check is NA because session management is not required.' do 58 | skip 'This check is NA because session management is not required.' 59 | end 60 | elsif nginx_conf.servers.nil? 61 | impact 0.0 62 | describe 'This check is NA because NGINX has not been configured to serve files.' do 63 | skip 'This check is NA because NGINX has not been configured to serve files.' 64 | end 65 | else 66 | nginx_conf.locations.each do |location| 67 | if location.params['proxy_cookie_path'].nil? 68 | impact 0.0 69 | describe 'This check is NA because the proxy_cookie_path directive is not configured.' do 70 | skip 'This check is NA because the proxy_cookie_path directive is not configured.' 71 | end 72 | else 73 | describe "The 'proxy_cookie_path'" do 74 | it 'should be configured to HTTPOnly and Secure' do 75 | expect(location.params['proxy_cookie_path'].join).to(include '/; HTTPOnly; Secure') 76 | end 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /controls/V-56027.rb: -------------------------------------------------------------------------------- 1 | control 'V-56027' do 2 | title "The web server must only accept client certificates issued by DoD PKI 3 | or DoD-approved PKI Certification Authorities (CAs)." 4 | desc "Non-DoD approved PKIs have not been evaluated to ensure that they have 5 | security controls and identity vetting procedures in place which are sufficient 6 | for DoD systems to rely on the identity asserted in the certificate. PKIs 7 | lacking sufficient security controls and identity vetting procedures risk being 8 | compromised and issuing certificates that enable adversaries to impersonate 9 | legitimate users." 10 | 11 | desc 'check', " 12 | Review the web server deployed configuration to determine if the web server 13 | will accept client certificates issued by unapproved PKIs. The authoritative 14 | list of DoD-approved PKIs is published at 15 | http://iase.disa.mil/pki-pke/interoperability. 16 | 17 | If there are no websites configured or if NGINX is not configured to serve files, 18 | this check is Not Applicable. 19 | 20 | Check for the following: 21 | #grep 'ssl_client_certifcate' directive in the http and server context of the 22 | nginx.conf file and any separated include configuration file. 23 | 24 | If the 'ssl_client_certifcate' directive cannot be found in NGINX configuration files, 25 | this check is Not Applicable. 26 | 27 | Examine the contents of this file to determine if the trusted Cas are DoD approved. 28 | If the trusted CA that is used to authenticate users to the website does not lead 29 | to an approved DoD CA, this is a finding. 30 | " 31 | desc 'fix', "Configure the web server’s trust store to trust only DoD-approved PKIs 32 | (e.g., DoD PKI, DoD ECA, and DoD-approved external partners)." 33 | 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000427-WSR-000186' 37 | tag "gid": 'V-56027' 38 | tag "rid": 'SV-70281r2_rule' 39 | tag "stig_id": 'SRG-APP-000427-WSR-000186' 40 | tag "fix_id": 'F-60905r1_fix' 41 | tag "cci": ['CCI-002470'] 42 | tag "nist": ['SC-23 (5)', ''] 43 | 44 | if nginx_conf.params['http'].nil? 45 | impact 0.0 46 | describe 'This check is NA because no websites have been configured.' do 47 | skip 'This check is NA because no websites have been configured.' 48 | end 49 | else 50 | nginx_conf.http.entries.each do |http| 51 | describe http.params['ssl_client_certificate'] do 52 | it { should_not be_nil } 53 | end 54 | if http.params['ssl_client_certificate'].nil? 55 | impact 0.0 56 | describe 'This test is NA because the ssl_client_certificate directive has not been configured.' do 57 | skip 'This test is NA because the ssl_client_certificate directive has not been configured.' 58 | end 59 | else 60 | http.params['ssl_client_certificate'].each do |cert| 61 | describe x509_certificate(cert.join) do 62 | it { should_not be_nil } 63 | its('subject.C') { should cmp 'US' } 64 | its('subject.O') { should cmp 'U.S. Government' } 65 | end 66 | describe x509_certificate(cert.join).subject.CN[0..2] do 67 | it { should be_in input('dod_approved_pkis') } 68 | end 69 | end 70 | end 71 | end 72 | end 73 | if nginx_conf.servers.nil? 74 | impact 0.0 75 | describe 'This check is NA because NGINX has not been configured to serve files.' do 76 | skip 'This check is NA because NGINX has not been configured to serve files.' 77 | end 78 | else 79 | nginx_conf.servers.each do |server| 80 | next if server.params['ssl_client_certificate'].nil? 81 | 82 | server.params['ssl_client_certificate'].each do |cert| 83 | describe x509_certificate(cert.join) do 84 | it { should_not be_nil } 85 | its('subject.C') { should cmp 'US' } 86 | its('subject.O') { should cmp 'U.S. Government' } 87 | end 88 | describe x509_certificate(cert.join).subject.CN[0..2] do 89 | it { should be_in input('dod_approved_pkis') } 90 | end 91 | end 92 | end 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /controls/V-56029.rb: -------------------------------------------------------------------------------- 1 | control 'V-56029' do 2 | title "The NGINX web server must augment re-creation to a stable and known 3 | baseline." 4 | desc "Making certain that the web server has not been updated by an 5 | unauthorized user is always a concern. Adding patches, functions, and modules 6 | that are untested and not part of the baseline opens the possibility for 7 | security risks. The web server must offer, and not hinder, a method that allows 8 | for the quick and easy reinstallation of a verified and patched baseline to 9 | guarantee the production web server is up-to-date and has not been modified to 10 | add functionality or expose security risks. 11 | 12 | When the web server does not offer a method to roll back to a clean 13 | baseline, external methods, such as a baseline snapshot or virtualizing the web 14 | server, can be used. 15 | " 16 | 17 | desc 'check', " 18 | Review the NGINX web server documentation and deployed configuration to determine 19 | if the web server offers the capability to reinstall from a known state. 20 | 21 | Interview the System Administrator for the NGINX web server. 22 | 23 | Ask for documentation on the disaster recovery methods tested and planned for the 24 | NGINX web server in the event of the necessity for rollback. 25 | 26 | If documentation for a disaster recovery has not been established, this is a finding. 27 | " 28 | desc 'fix', "Prepare documentation for disaster recovery methods for the NGINX web server 29 | in the event of the necessity for rollback. 30 | 31 | Document and test the disaster recovery methods designed." 32 | 33 | impact 0.5 34 | tag "severity": 'medium' 35 | tag "gtitle": 'SRG-APP-000225-WSR-000074' 36 | tag "gid": 'V-56029' 37 | tag "rid": 'SV-70283r2_rule' 38 | tag "stig_id": 'SRG-APP-000225-WSR-000074' 39 | tag "fix_id": 'F-60907r1_fix' 40 | tag "cci": ['CCI-001190'] 41 | tag "nist": %w(SC-24) 42 | 43 | describe "This test requires a Manual Review: Interview the SA and ask for documentation on the 44 | disaster recovery methods for the NGINX web server in the event of the necessity for rollback." do 45 | skip "This test requires a Manual Review: Interview the SA and ask for documentation on the 46 | disaster recovery methods for the NGINX web server in the event of the necessity for rollback." 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /controls/V-56031.rb: -------------------------------------------------------------------------------- 1 | control 'V-56031' do 2 | title 'The NGINX web server must encrypt user identifiers and passwords.' 3 | desc "When data is written to digital media, such as hard drives, mobile 4 | computers, external/removable hard drives, personal digital assistants, 5 | flash/thumb drives, etc., there is risk of data loss and data compromise. User 6 | identities and passwords stored on the hard drive of the hosting hardware must 7 | be encrypted to protect the data from easily being discovered and used by an 8 | unauthorized user to access the hosted applications. The cryptographic 9 | libraries and functionality used to store and retrieve the user identifiers and 10 | passwords must be part of the web server." 11 | 12 | desc 'check', "Review the NGINX web server documentation and deployed configuration 13 | to determine whether the web server is authorizing and managing users. 14 | 15 | If the NGINX web server is not authorizing and managing users, this is check is Not 16 | Applicable. 17 | 18 | If the NGINX web server is the user authenticator and manager, verify that stored 19 | user identifiers and passwords are being encrypted by the web server. If the 20 | user information is not being encrypted when stored, this is a finding. 21 | " 22 | desc 'fix', "Configure the web server to encrypt the user identifiers and 23 | passwords when storing them on digital media." 24 | impact 0.5 25 | tag "severity": 'medium' 26 | tag "gtitle": 'SRG-APP-000429-WSR-000113' 27 | tag "gid": 'V-56031' 28 | tag "rid": 'SV-70285r2_rule' 29 | tag "stig_id": 'SRG-APP-000429-WSR-000113' 30 | tag "fix_id": 'F-60909r1_fix' 31 | tag "cci": ['CCI-002476'] 32 | tag "nist": ['SC-28 (1)', ''] 33 | 34 | if input('manages_auth') == false 35 | impact 0.0 36 | describe 'This check is NA because NGINX does not manage authentication.' do 37 | skip 'This check is NA because NGINX does not manage authentication.' 38 | end 39 | else 40 | describe "This test requires a Manual Review: Verify that user identifiers and passwords 41 | are being encrypted by the web server." do 42 | skip "This test requires a Manual Review: Verify that user identifiers and passwords 43 | are being encrypted by the web server." 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /controls/V-56033.rb: -------------------------------------------------------------------------------- 1 | control 'V-56033' do 2 | title "The web server must install security-relevant software updates within 3 | the configured time period directed by an authoritative source (e.g., IAVM, 4 | CTOs, DTMs, and STIGs)." 5 | desc "Security flaws with software applications are discovered daily. 6 | Vendors are constantly updating and patching their products to address newly 7 | discovered security vulnerabilities. Organizations (including any contractor to 8 | the organization) are required to promptly install security-relevant software 9 | updates (e.g., patches, service packs, and hot fixes). Flaws discovered during 10 | security assessments, continuous monitoring, incident response activities, or 11 | information system error handling must also be addressed expeditiously. 12 | 13 | The web server will be configured to check for and install 14 | security-relevant software updates from an authoritative source within an 15 | identified time period from the availability of the update. By default, this 16 | time period will be every 24 hours. 17 | " 18 | 19 | desc 'check', " 20 | Review the web server documentation and configuration to determine if the 21 | web server checks for patches from an authoritative source at least every 30 22 | days. 23 | 24 | Determine most recent patch level of NGINX with the following command: 25 | 26 | # nginx -v 27 | 28 | If the version is more than one version behind the most recent patch level, 29 | this is a finding. 30 | " 31 | desc 'fix', "Install the current version of the web server software and 32 | maintain appropriate service packs and patches." 33 | 34 | impact 0.5 35 | tag "severity": 'medium' 36 | tag "gtitle": 'SRG-APP-000456-WSR-000187' 37 | tag "gid": 'V-56033' 38 | tag "rid": 'SV-70287r3_rule' 39 | tag "stig_id": 'SRG-APP-000456-WSR-000187' 40 | tag "fix_id": 'F-60911r2_fix' 41 | tag "cci": ['CCI-002605'] 42 | tag "nist": ['SI-2 c'] 43 | ref 'http://nginx.org/en/CHANGES' 44 | 45 | nginx_changelog = inspec.http('http://nginx.org/en/CHANGES').body.lines.map(&:chomp) 46 | nginx_changelog_clean = nginx_changelog.select { |line| line.include? 'Changes with nginx' } 47 | 48 | nginx_latest_release = nginx_changelog_clean.first.split[3] 49 | nginx_previous_release = nginx_changelog_clean[1].split[3] 50 | allowed_nginx_version = input('org_allowed_nginx_version') 51 | nginx_installed_version = inspec.nginx.version 52 | 53 | if (nginx_latest_release.nil? || nginx_latest_release.empty?) && (allowed_nginx_version.nil? || allowed_nginx_version.empty?) 54 | describe "Your installed NGINX version is: #{nginx_installed_version}. You must review this control Manually. Either set or pass the `nginx_version` input to the profile, 55 | or ensure your system can reach 'http://nginx.org/en/CHANGES' to get the latest released version of NGINX" do 56 | skip "Your installed NGINX version is: #{nginx_installed_version}. You must review this control Manually. Either set or pass the `nginx_version` input to the profile, 57 | or ensure your system can reach 'http://nginx.org/en/CHANGES' to get the latest released version of NGINX" 58 | end 59 | else 60 | describe.one do 61 | describe "NGINX version v#{nginx_installed_version} installed is" do 62 | unless nginx_latest_release.nil? || nginx_previous_release.nil? 63 | describe "not more then one patch level behind v#{nginx_previous_release}" do 64 | subject { nginx_installed_version } 65 | it { should cmp >= nginx_previous_release } 66 | end 67 | end 68 | unless allowed_nginx_version.empty? 69 | describe "greater then or equal to the organization approved version v#{allowed_nginx_version}" do 70 | subject { nginx_installed_version } 71 | it { should cmp >= allowed_nginx_version } 72 | end 73 | end 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /controls/V-61353.rb: -------------------------------------------------------------------------------- 1 | control 'V-61353' do 2 | title "The web server must remove all export ciphers to protect the 3 | confidentiality and integrity of transmitted information." 4 | desc "During the initial setup of a Transport Layer Security (TLS) 5 | connection to the web server, the client sends a list of supported cipher 6 | suites in order of preference. The web server will reply with the cipher suite 7 | it will use for communication from the client list. If an attacker can 8 | intercept the submission of cipher suites to the web server and place, as the 9 | preferred cipher suite, a weak export suite, the encryption used for the 10 | session becomes easy for the attacker to break, often within minutes to hours." 11 | 12 | desc 'check', " 13 | Review the web server documentation and deployed configuration to determine 14 | if export ciphers are removed. 15 | 16 | If NGINX is not configured to serve files, this check is Not Applicable. 17 | 18 | Check for the following: 19 | 20 | # grep the 'ssl_prefer_server_cipher' directive in each server context of 21 | the nginx.conf and any separated include configuration file. 22 | 23 | Verify that the 'ssl_prefer_server_cipher' directive is set to 'on'. 24 | If the directive is not set to 'on', this is a finding. 25 | 26 | # grep the 'ssl_ciphers' directive in each server context of the nginx.conf 27 | and any separated include configuration file. 28 | 29 | If the 'ssl_ciphers' directive is configured to include any export ciphers, 30 | this is a finding. 31 | 32 | If the 'ssl_prefer_server_cipher' and 'ssl_ciphers' directives cannot be found 33 | in NGINX configuration files, this check is Not Applicable. 34 | 35 | " 36 | desc 'fix', "Include the 'ssl_prefer_server_cipher' directive in all server 37 | context of the NGINX configuration file(s) and set the directive to 'on'. 38 | The 'ssl_ciphers' directive should not include any export ciphers. " 39 | impact 0.5 40 | tag "severity": 'medium' 41 | tag "gtitle": 'SRG-APP-000439-WSR-000188 ' 42 | tag "gid": 'V-61353' 43 | tag "rid": 'SV-75835r1_rule' 44 | tag "stig_id": 'SRG-APP-000439-WSR-000188' 45 | tag "fix_id": 'F-67255r1_fix' 46 | tag "cci": ['CCI-002418'] 47 | tag "nist": %w(SC-8) 48 | 49 | if nginx_conf.servers.nil? 50 | impact 0.0 51 | describe 'This check is NA because NGINX has not been configured to serve files.' do 52 | skip 'This check is NA because NGINX has not been configured to serve files.' 53 | end 54 | else 55 | nginx_conf.servers.each do |server| 56 | if server.params['ssl_prefer_server_ciphers'].nil? 57 | impact 0.0 58 | describe 'This test is NA because the ssl_prefer_server_ciphers directive has not been configured.' do 59 | skip 'This test is NA because the ssl_prefer_server_ciphers directive has not been configured.' 60 | end 61 | else 62 | server.params['ssl_prefer_server_ciphers'].each do |prefer_ciphers| 63 | describe 'The ssl_prefer_server_cipher' do 64 | it 'should be set to on.' do 65 | expect(prefer_ciphers).to(cmp('on')) 66 | end 67 | end 68 | end 69 | end 70 | if server.params['ssl_ciphers'].nil? 71 | impact 0.0 72 | describe 'This test is NA because the ssl_ciphers directive has not been configured.' do 73 | skip 'This test is NA because the ssl_ciphers directive has not been configured.' 74 | end 75 | else 76 | ciphers_found = [] 77 | server.params['ssl_ciphers'].each do |ciphers| 78 | ciphers[0].to_s.split("\:").each do |cipher| 79 | ciphers_found << cipher 80 | end 81 | end 82 | ciphers_found.uniq! 83 | ciphers_found.each do |cipher| 84 | describe 'Each cipher' do 85 | it 'found in configuration should be included in the list of ciphers approved to encrypt data' do 86 | expect(cipher).to(be_in(input('approved_ssl_ciphers'))) 87 | end 88 | end 89 | end 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /hardened.threshold.yml: -------------------------------------------------------------------------------- 1 | compliance: 2 | min: 50 -------------------------------------------------------------------------------- /kitchen.docker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: docker 4 | use_sudo: false 5 | privileged: true 6 | 7 | transport: 8 | name: docker 9 | 10 | provisioner: 11 | name: ansible_playbook 12 | hosts: all 13 | require_ansible_repo: true 14 | require_chef_for_busser: false 15 | require_ruby_for_busser: false 16 | galaxy_ignore_certs: true 17 | roles_path: spec/ansible/nginx-hardening 18 | requirements_path: spec/ansible/nginx-hardening/requirements.yml 19 | additional_copy_path: 20 | - spec/ansible/nginx-hardening/vars 21 | extra_vars_file: /tmp/kitchen/vars/docker.vars.yml 22 | 23 | verifier: 24 | name: inspec 25 | sudo: true 26 | load_plugins: true 27 | inspec_tests: 28 | - path: . 29 | 30 | platforms: 31 | - name: ubuntu-18.04 32 | driver: 33 | image: ubuntu:bionic-20220128 34 | provision_command: 35 | - apt-get update 36 | - apt-get install -y systemd-sysv vim nginx w3m w3m-img 37 | - update-rc.d ssh defaults 38 | - service ssh start 39 | - update-rc.d nginx defaults 40 | - service nginx start 41 | 42 | suites: 43 | - name: hardened 44 | provisioner: 45 | playbook: spec/ansible/nginx-hardening/hardening-playbook.yml 46 | verifier: 47 | reporter: 48 | - cli 49 | - json:spec/results/hardened-test-result.json 50 | - name: vanilla 51 | provisioner: 52 | playbook: spec/ansible/nginx-hardening/vanilla-playbook.yml 53 | verifier: 54 | reporter: 55 | - cli 56 | - json:spec/results/vanilla-test-result.json 57 | -------------------------------------------------------------------------------- /kitchen.ec2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: ec2 4 | associate_public_ip: true 5 | instance_type: c5.large 6 | ebs_optimized: true 7 | block_device_mappings: 8 | - device_name: /dev/sda1 9 | ebs: 10 | delete_on_termination: true 11 | volume_size: 30 12 | volume_type: gp2 13 | interface: public 14 | require_chef_for_busser: false 15 | privileged: true 16 | 17 | provisioner: 18 | name: ansible_playbook 19 | hosts: all 20 | require_ansible_repo: true 21 | require_chef_for_busser: false 22 | require_ruby_for_busser: false 23 | ansible_verbose: true 24 | galaxy_ignore_certs: true 25 | roles_path: ./spec/ansible/nginx-hardening 26 | requirements_path: ./spec/ansible/nginx-hardening/requirements.yml 27 | additional_copy_path: 28 | - spec/ansible/nginx-hardening/vars 29 | extra_vars_file: /tmp/kitchen/vars/ec2.vars.yml 30 | 31 | transport: 32 | name: ssh 33 | 34 | verifier: 35 | name: inspec 36 | sudo: true 37 | load_plugins: true 38 | inspec_tests: 39 | - path: . 40 | 41 | platforms: 42 | - name: ubuntu-18.04 43 | lifecycle: 44 | pre_converge: 45 | - remote: sudo apt-get -y update 46 | - remote: sudo apt-get -y install nginx 47 | - remote: sudo systemctl start nginx 48 | suites: 49 | - name: hardened 50 | provisioner: 51 | playbook: ./spec/ansible/nginx-hardening/hardening-playbook.yml 52 | verifier: 53 | reporter: 54 | - cli 55 | - json:spec/results/hardened-test-result.json 56 | - name: vanilla 57 | provisioner: 58 | playbook: ./spec/ansible/nginx-hardening/vanilla-playbook.yml 59 | verifier: 60 | reporter: 61 | - cli 62 | - json:spec/results/vanilla-test-result.json 63 | -------------------------------------------------------------------------------- /kitchen.vagrant.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | driver_config: 5 | ssl_verify_mode: ":verify_none" 6 | 7 | provisioner: 8 | name: ansible_playbook 9 | hosts: all 10 | require_ansible_repo: true 11 | require_chef_for_busser: false 12 | require_ruby_for_busser: false 13 | galaxy_ignore_certs: true 14 | roles_path: spec/ansible/nginx-hardening 15 | requirements_path: spec/ansible/nginx-hardening/requirements.yml 16 | additional_copy_path: 17 | - spec/ansible/nginx-hardening/vars 18 | extra_vars_file: /tmp/kitchen/vars/vagrant.vars.yml 19 | 20 | verifier: 21 | name: inspec 22 | sudo: true 23 | load_plugins: true 24 | inspec_tests: 25 | - path: . 26 | 27 | platforms: 28 | - name: ubuntu-18.04 29 | lifecycle: 30 | post_create: 31 | - remote: sudo apt-get -y update 32 | - remote: sudo apt-get -y install nginx apt-utils 33 | - remote: sudo systemctl start nginx 34 | suites: 35 | - name: hardened 36 | provisioner: 37 | playbook: spec/ansible/nginx-hardening/hardening-playbook.yml 38 | verifier: 39 | reporter: 40 | - cli 41 | - json:spec/results/hardened-test-result.json 42 | - name: vanilla 43 | provisioner: 44 | playbook: spec/ansible/nginx-hardening/vanilla-playbook.yml 45 | verifier: 46 | reporter: 47 | - cli 48 | - json:spec/results/vanilla-test-result.json 49 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/ansible.cfg: -------------------------------------------------------------------------------- 1 | # config file for ansible -- http://ansible.com/ 2 | # ============================================== 3 | 4 | # nearly all parameters can be overridden in ansible-playbook 5 | # or with command line flags. ansible will read ANSIBLE_CONFIG, 6 | # ansible.cfg in the current working directory, .ansible.cfg in 7 | # the home directory or /etc/ansible/ansible.cfg, whichever it 8 | # finds first 9 | 10 | [defaults] 11 | ansible_managed = Ansible managed: {file} modified on %Y-%m-%d by {uid} on {host} 12 | 13 | role_path = /vagrant 14 | scp_if_ssh = True 15 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx_client_body_buffer_size: '1k' 3 | nginx_remove_default_site: true 4 | nginx_client_max_body_size: '1k' 5 | nginx_keepalive_timeout: '5 5' 6 | nginx_server_tokens: 'off' 7 | nginx_client_header_buffer_size: "1k" 8 | nginx_large_client_header_buffers: "2 1k" 9 | nginx_client_body_timeout: "10" 10 | nginx_client_header_timeout: "10" 11 | nginx_send_timeout: "10" 12 | nginx_limit_conn_zone: "$binary_remote_addr zone=default:10m" 13 | nginx_limit_conn: "default 5" 14 | nginx_limit_rate: "50k" 15 | nginx_time_stamp_format: "UTC" 16 | nginx_listen: "127.0.0.1:443 ssl" 17 | nginx_add_header: [ 18 | # vvoid clickjacking 19 | "X-Frame-Options SAMEORIGIN", 20 | # disable content-type sniffing 21 | "X-Content-Type-Options nosniff", 22 | # XSS filter 23 | "X-XSS-Protection \"1; mode=block\"", 24 | "Strict-Transport-Security max-age=15768000", 25 | "Content-Security-Policy \"script-src 'self'; object-src 'self'\"" ] 26 | 27 | nginx_set_cookie_flag: "* HttpOnly secure" 28 | nginx_ssl_prefer_server_ciphers: "on" 29 | nginx_ssl_protocols: "TLSv1.2" 30 | nginx_ssl_ciphers: "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:HIGH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS" 31 | nginx_ssl_session_tickets: "off" 32 | nginx_ssl_verify_client: "on" 33 | nginx_ssl_verify_depth: "1" 34 | nginx_dh_size: "2048" 35 | nginx_ssl_cert: "/etc/ssl/nginx-selfsigned.crt" 36 | nginx_ssl_cert_key: "/etc/ssl/nginx-selfsigned.key" 37 | nginx_ssl_client_cert: "/etc/ssl/nginx-selfsigned.pem" 38 | 39 | nginx_disallowed_mime_type: [ 40 | 'text/mathml', 41 | 'text/vnd.sun.j2me.app-descriptor', 42 | 'text/vnd.wap.wml', 43 | 'application/java-archive', 44 | 'application/mac-binhex40', 45 | 'application/postscript', 46 | 'application/vnd.wap.wmlc', 47 | 'application/vnd.google-earth.kml+xml', 48 | 'application/vnd.google-earth.kmz', 49 | 'application/x-7z-compressed', 50 | 'application/x-cocoa', 51 | 'application/x-java-archive-diff', 52 | 'application/x-java-jnlp-file', 53 | 'application/x-makeself', 54 | 'application/x-perl', 55 | 'application/x-pilot', 56 | 'application/x-redhat-package-manager', 57 | 'application/x-sea', 58 | 'application/x-shockwave-flash', 59 | 'application/x-stuffit', 60 | 'application/x-sit', 61 | 'application/x-xpinstall', 62 | 'application/octet-stream' 63 | ] 64 | 65 | nginx_disallowed_file_list: [ 66 | '/usr/share/man/man8/nginx.8.gz' 67 | ] 68 | 69 | charset_required: "utf-8" -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart nginx 2 | service: 3 | name: "nginx" 4 | state: restarted 5 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/hardening-playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | become: yes 3 | become_method: enable 4 | roles: 5 | - nginx-hardening -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: "Sebastian Gumprich" 4 | description: 'This Ansible role provides secure nginx configurations. http://dev-sec.io/' 5 | company: Hardening Framework Team 6 | license: Apache License 2.0 7 | min_ansible_version: '2.5' 8 | platforms: 9 | - name: EL 10 | versions: 11 | - 6 12 | - 7 13 | - name: Ubuntu 14 | versions: 15 | - xenial 16 | - bionic 17 | - name: Debian 18 | versions: 19 | - stretch 20 | - buster 21 | galaxy_tags: 22 | - system 23 | - security 24 | - hardening 25 | - nginx 26 | dependencies: [] 27 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/requirements.yml: -------------------------------------------------------------------------------- 1 | - src: nginxinc.nginx 2 | - src: geerlingguy.nginx 3 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/templates/hardening.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed|comment }} 2 | # Additional configuration for Nginx. 3 | 4 | server { 5 | client_header_buffer_size {{ nginx_client_header_buffer_size }}; 6 | large_client_header_buffers {{ nginx_large_client_header_buffers }}; 7 | send_timeout {{ nginx_send_timeout }}; 8 | ssl_ciphers '{{ nginx_ssl_ciphers }}'; 9 | ssl_session_tickets {{ nginx_ssl_session_tickets }}; 10 | ssl_dhparam /etc/nginx/dh{{ nginx_dh_size }}.pem; 11 | {% for header in nginx_add_header %} 12 | add_header {{ header }}; 13 | {% endfor %} 14 | 15 | location / { 16 | root {{ nginx_site_root }}; 17 | auth_request /auth; 18 | deny all; 19 | limit_conn {{ nginx_limit_conn }}; 20 | limit_rate {{ nginx_limit_rate }}; 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/tests/official-nginx-role-debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings 3 | hosts: localhost 4 | vars: 5 | - nginx_main_template_enable: true 6 | - nginx_main_template: 7 | template_file: nginx.conf.j2 8 | conf_file_name: nginx.conf 9 | conf_file_location: /etc/nginx/ 10 | user: www-data 11 | worker_processes: auto 12 | error_level: warn 13 | worker_connections: 1024 14 | http_enable: true 15 | http_settings: 16 | keepalive_timeout: 65 17 | cache: false 18 | rate_limit: false 19 | keyval: false 20 | stream_enable: false 21 | http_global_autoindex: false 22 | pre_tasks: 23 | - apt_repository: 24 | repo: "deb http://ftp.debian.org/debian jessie-backports main" 25 | state: present 26 | when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8' 27 | - set_fact: 28 | nginx_default_release: "jessie-backports" 29 | when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8' 30 | - package: name="{{item}}" state=installed 31 | with_items: 32 | - "systemd" 33 | ignore_errors: true 34 | - apt: name="{{item}}" state=installed update_cache=true 35 | with_items: 36 | - "systemd" 37 | ignore_errors: true 38 | roles: 39 | - nginxinc.nginx 40 | - ansible-nginx-hardening -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/tests/official-nginx-role-redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings 3 | hosts: localhost 4 | pre_tasks: 5 | - package: name="{{item}}" state=installed 6 | with_items: 7 | - "systemd" 8 | ignore_errors: true 9 | - apt: name="{{item}}" state=installed update_cache=true 10 | with_items: 11 | - "systemd" 12 | ignore_errors: true 13 | roles: 14 | - nginxinc.nginx 15 | - ansible-nginx-hardening -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings 3 | hosts: localhost 4 | vars: 5 | - nginx_ppa_use: true 6 | - nginx_ppa_version: stable 7 | pre_tasks: 8 | - apt_repository: 9 | repo: "deb http://ftp.debian.org/debian jessie-backports main" 10 | state: present 11 | when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8' 12 | - set_fact: 13 | nginx_default_release: "jessie-backports" 14 | when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8' 15 | - package: name="{{item}}" state=installed 16 | with_items: 17 | - "systemd" 18 | ignore_errors: true 19 | - apt: name="{{item}}" state=installed update_cache=true 20 | with_items: 21 | - "systemd" 22 | ignore_errors: true 23 | roles: 24 | - geerlingguy.nginx 25 | - ansible-nginx-hardening 26 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/vanilla-playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | become: yes 3 | become_method: enable 4 | tasks: 5 | - name: Start service nginx, if not started 6 | service: 7 | name: nginx 8 | state: started 9 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/vars/docker.vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx_bin: '/usr/sbin/nginx' 3 | nginx_conf_base: '/etc/nginx' 4 | nginx_modules_path: '/usr/lib/nginx/modules' 5 | nginx_site_root: '/var/www/html' 6 | nginx_prefix: '/usr/share/nginx' 7 | nginx_log_path: '/var/log/nginx' 8 | nginx_pid: '/var/run/nginx.pid' -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/vars/ec2.vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx_pid: '/run/nginx.pid' 3 | nginx_modules_path: '/usr/lib/nginx/modules' 4 | nginx_prefix: '/usr/share/nginx' 5 | nginx_site_root: '/usr/share/nginx/html' 6 | nginx_log_path: '/var/log/nginx' 7 | nginx_bin: '/usr/sbin/nginx' 8 | nginx_conf_base: '/etc/nginx' 9 | nginx_site_root: '/usr/share/nginx/html' -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | -------------------------------------------------------------------------------- /spec/ansible/nginx-hardening/vars/vagrant.vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx_pid: '/run/nginx.pid' 3 | nginx_modules_path: '/usr/lib/nginx/modules' 4 | nginx_prefix: '/usr/share/nginx' 5 | nginx_site_root: '/usr/share/nginx/html' 6 | nginx_log_path: '/var/log/nginx' 7 | nginx_bin: '/usr/sbin/nginx' 8 | nginx_conf_base: '/etc/nginx' 9 | nginx_site_root: '/usr/share/nginx/html' -------------------------------------------------------------------------------- /vanilla.threshold.yml: -------------------------------------------------------------------------------- 1 | compliance: 2 | min: 1 --------------------------------------------------------------------------------