├── .travis.yml ├── Gemfile ├── controls ├── nginx-service-checks.rb ├── V-26294.rb ├── V-26368.rb ├── V-26287.rb ├── V-2261.rb ├── V-2246.rb ├── V-26299.rb ├── V-2234.rb ├── V-13727.rb ├── V-2242.rb ├── V-26285.rb ├── V-2232.rb ├── V-13737.rb ├── V-6485.rb ├── V-new.rb ├── V-2251.rb ├── V-13732.rb ├── V-26396.rb ├── V-2257.rb ├── V-2236.rb ├── V-2247.rb ├── V-2243.rb ├── V-13613.rb ├── V-13738.rb ├── V-2271.rb ├── V-6724.rb ├── V-2255.rb ├── V-26326.rb ├── V-13735.rb ├── V-13726.rb ├── V-13621.rb ├── V-2230.rb ├── V-26305.rb ├── V-13724.rb ├── V-2248.rb ├── V-13736.rb ├── V-13672.rb ├── V-13620.rb ├── V-6577.rb ├── V-2256.rb ├── V-60707.rb └── V-2259.rb ├── .rubocop.yml ├── Rakefile ├── LICENSE ├── CHANGELOG.md ├── .gitignore ├── inspec.yml ├── libraries └── linux_updates.rb └── README.md /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | cache: bundler 4 | rvm: 5 | - 2.3.3 6 | 7 | bundler_args: --without integration 8 | script: bundle exec rake 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'highline', '~> 1.6.0' 4 | gem 'inspec', '~> 1' 5 | gem 'rack', '1.6.4' 6 | gem 'rake' 7 | gem 'rubocop', '~> 0.46.0' 8 | 9 | group :tools do 10 | gem 'github_changelog_generator', '~> 1.12.0' 11 | end 12 | -------------------------------------------------------------------------------- /controls/nginx-service-checks.rb: -------------------------------------------------------------------------------- 1 | 2 | control 'nginx-service-check' do 3 | title 'Ensure the NGINX Service is configured and running' 4 | impact 0.9 5 | desc 'Ensure the NGINX Service is configured correctly and setup correctly' 6 | 7 | tag nist: ['CM-6', 'Rev_4'] 8 | 9 | describe "The NGINX service for levels 3 - 5" do 10 | subject { service('nginx').runlevels(3, 5) } 11 | it { should be_enabled } 12 | end 13 | 14 | describe service('nginx') do 15 | it { should be_enabled } 16 | it { should be_running } 17 | it { should be_installed } 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | AllCops: 3 | Exclude: 4 | - vendor/**/* 5 | - "*/puppet/Puppetfile" 6 | - "*/puppet/.tmp/**/*" 7 | TargetRubyVersion: 2.5 8 | Documentation: 9 | Enabled: false 10 | AlignParameters: 11 | Enabled: true 12 | HashSyntax: 13 | Enabled: true 14 | LineLength: 15 | Enabled: false 16 | EmptyLinesAroundBlockBody: 17 | Enabled: false 18 | MethodLength: 19 | Max: 40 20 | NumericLiterals: 21 | MinDigits: 10 22 | Metrics/BlockLength: 23 | Max: 35 24 | Metrics/CyclomaticComplexity: 25 | Max: 10 26 | Metrics/PerceivedComplexity: 27 | Max: 10 28 | Metrics/AbcSize: 29 | Max: 30 30 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # encoding: utf-8 3 | 4 | require 'rake/testtask' 5 | require 'rubocop/rake_task' 6 | 7 | # Rubocop 8 | desc 'Run Rubocop lint checks' 9 | task :rubocop do 10 | RuboCop::RakeTask.new 11 | end 12 | 13 | # lint the project 14 | desc 'Run robocop linter' 15 | task lint: [:rubocop] 16 | 17 | # run tests 18 | task default: [:lint, 'test:check'] 19 | 20 | namespace :test do 21 | # run inspec check to verify that the profile is properly configured 22 | task :check do 23 | dir = File.join(File.dirname(__FILE__)) 24 | sh("bundle exec inspec check #{dir}") 25 | end 26 | end 27 | 28 | # Automatically generate a changelog for this project. Only loaded if 29 | # the necessary gem is installed. By default its picking up the version from 30 | # inspec.yml. You can override that behavior with s`rake changelog to=1.2.0` 31 | begin 32 | require 'yaml' 33 | metadata = YAML.load_file('inspec.yml') 34 | v = ENV['to'] || metadata['version'] 35 | puts "Generate changelog for version #{v}" 36 | require 'github_changelog_generator/task' 37 | GitHubChangelogGenerator::RakeTask.new :changelog do |config| 38 | config.future_release = v 39 | end 40 | rescue LoadError 41 | puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks' 42 | end 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 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 STIGs. 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. -------------------------------------------------------------------------------- /controls/V-26294.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26294" do 30 | title "Web server status module must be disabled." 31 | 32 | desc "The ngx_http_status_module provides configuration information on 33 | thecurrent server and performance statistics. While having server 34 | configuration and status information available as a web page may be 35 | convenient, it is recommended that these modules not be enabled." 36 | 37 | impact 0.5 38 | tag "severity": "medium" 39 | tag "gtitle": "WA00510" 40 | tag "gid": "V-26294" 41 | tag "rid": "SV-33218r1_rule" 42 | tag "stig_id": "WA00510 A22" 43 | tag "nist": ["AC-3", "Rev_4"] 44 | 45 | tag "check": "Enter the following command: 46 | 47 | nginx -V 48 | 49 | This will provide a list of all loaded modules. If the following module is 50 | found, this is a finding. 51 | 52 | ngx_http_status_module" 53 | 54 | tag "fix": "Disable any modules that are not needed. 55 | 56 | Use the configure script (available in the nginx download package) to exclude 57 | modules using the --without {module_name} option to reject unneeded modules." 58 | 59 | nginx_path = input('nginx_path') 60 | 61 | begin 62 | describe nginx do 63 | its('modules') { should_not include 'ngx_http_status' } 64 | end 65 | rescue Exception => msg 66 | describe "Exception: #{msg}" do 67 | it { should be_nil } 68 | end 69 | end 70 | 71 | end 72 | -------------------------------------------------------------------------------- /controls/V-26368.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26368" do 30 | title "Automatic directory indexing must be disabled." 31 | 32 | desc "The ngx_http_autoindex_module module processes requests ending with the 33 | slash character (‘/’) and produces a directory listing. Usually a request is 34 | passed to the ngx_http_autoindex_module module when the 35 | ngx_http_index_module module cannot find an index file. To an attacker, this 36 | can reveal files and subdirectory names giving clues as to the type or 37 | configuration of the nginx server, or information not intended to be 38 | presented." 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA00515" 43 | tag "gid": "V-26368" 44 | tag "rid": "SV-33219r1_rule" 45 | tag "stig_id": "WA00515 A22" 46 | tag "nist": ["CM-2", "Rev_4"] 47 | 48 | tag "check": "Enter the following command: 49 | 50 | nginx -V 51 | 52 | This will provide a list of all loaded modules.If the following module is 53 | found, this is a finding. 54 | 55 | ngx_autoindex_module" 56 | 57 | tag "fix": "Disable any modules that are not needed. 58 | 59 | Use the configure script (available in the nginx download package) to exclude 60 | modules using the --without {module_name} option to reject unneeded modules." 61 | 62 | nginx_path = input('nginx_path') 63 | 64 | begin 65 | describe nginx do 66 | its('modules') { should_not include 'ngx_autoindex' } 67 | end 68 | rescue Exception => msg 69 | describe "Exception: #{msg}" do 70 | it { should be_nil } 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /controls/V-26287.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26287" do 30 | title "Web Distributed Authoring and Versioning (WebDAV) must be disabled." 31 | 32 | desc "Ngx_http_dav_module supports WebDAV ('Web-based Distributed Authoring 33 | and Versioning') functionality for nginx. WebDAV is an extension to the HTTP 34 | protocol which allows clients to create, move, and delete files and 35 | resources on the web server. WebDAV is not widely used, and has serious 36 | security concerns as it may allow clients to modify unauthorized files on 37 | the web server. Therefore, the WebDav module ngx_http_dav_module should be 38 | disabled." 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA00505" 43 | tag "gid": "V-26287" 44 | tag "rid": "SV-33216r1_rule" 45 | tag "stig_id": "WA00505 A22" 46 | tag "nist": ["AC-3", "Rev_4"] 47 | 48 | tag "check": "Enter the following command: 49 | 50 | nginx -V 51 | 52 | This will provide a list of all loaded modules. If the following module is 53 | found, this is a finding. 54 | 55 | ngx_http_dav_module" 56 | 57 | tag "fix": "Disable any modules that are not needed. 58 | 59 | Use the configure script (available in the nginx download package) to exclude 60 | modules using the --without {module_name} option to reject unneeded modules." 61 | 62 | nginx_path = input('nginx_path') 63 | 64 | begin 65 | describe nginx do 66 | its('modules') { should_not include 'ngx_http_dav' } 67 | end 68 | rescue Exception => msg 69 | describe "Exception: #{msg}" do 70 | it { should be_nil } 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /controls/V-2261.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2261" do 30 | title "A public web server must limit email to outbound only." 31 | 32 | desc" Incoming E-mail has been known to provide hackers with access to 33 | servers. Disabling the incoming mail service prevents this type of attacks. 34 | Additionally, Email represents the main use of the Internet. It is 35 | specialized application that requires the dedication of server resources. To 36 | combine this type of transaction processing function with the file serving 37 | role of the web server creates an inherent conflict. Supporting mail 38 | services on a web server opens the server to the risk of abuse as an email 39 | relay. falseWeb AdministratorECSC-1 " 40 | 41 | impact 0.5 42 | tag "severity": "medium" 43 | tag "gtitle": "WG330" 44 | tag "gid": "V-2261" 45 | tag "rid": "SV-32937r1_rule" 46 | tag "stig_id": "WG330 A22" 47 | tag "nist": ["CM-6", "Rev_4"] 48 | 49 | tag "check": "\"To determine if email applications are excepting incoming 50 | connections (on standard ports)enter the following command: 51 | 52 | telnet localhost 25 53 | 54 | review the command results, If an e-mail program is installed and that program 55 | has been configured to accept inbound email, this is a finding.\" " 56 | 57 | tag "fix": "Configure the email application to not allow incoming connections." 58 | 59 | 60 | begin 61 | describe port(25) do 62 | it { should_not be_listening } 63 | end 64 | 65 | describe package('postfix') do 66 | it { should_not be_installed } 67 | end 68 | 69 | rescue Exception => msg 70 | describe "Exception: #{msg}" do 71 | it { should be_nil } 72 | end 73 | end 74 | 75 | 76 | 77 | end 78 | -------------------------------------------------------------------------------- /controls/V-2246.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | 30 | control "V-2246" do 31 | title "Web server software must be a vendor-supported version." 32 | desc "Many vulnerabilities are associated with older versions of 33 | web server software. As hot fixes and patches are issued, these solutions 34 | are included in the next version of the server software. Maintaining the web 35 | server at a current version makes the efforts of a malicious user to exploit 36 | the web service more difficult." 37 | impact 0.7 38 | tag "severity": "high" 39 | tag "gtitle": "WG190" 40 | tag "gid": "V-2246" 41 | tag "rid": "SV-36441r2_rule" 42 | tag "stig_id": "WG190 A22" 43 | tag "nist": ["CM-6", "Rev_4"] 44 | 45 | tag "check": "To determine the version of the nginx software that is running 46 | on the system. Use the command: 47 | 48 | nginx -v 49 | 50 | If the version of nginx is not at the following version or higher, this is a 51 | finding. 52 | 53 | nginx version: nginx/1.12.0 54 | 55 | Note: In some situations, the nginx software that is being used is supported 56 | by another vendor, such as nginx.com. The versions of the software in these 57 | cases may not match the above mentioned version numbers. If the site can 58 | provide vendor documentation showing the version of the web server is 59 | supported, this would not be a finding. " 60 | 61 | tag "fix": "Install the current version of the web server software and 62 | maintain appropriate service packs and patches." 63 | 64 | nginx_min_ver = input('nginx_min_ver') 65 | 66 | nginx_path = input('nginx_path') 67 | 68 | begin 69 | describe nginx do 70 | its('version'){ should cmp >= nginx_min_ver } 71 | end 72 | rescue Exception => msg 73 | describe "Exception: #{msg}" do 74 | it { should be_nil } 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [2.0.2](https://github.com/dev-sec/nginx-baseline/tree/2.0.2) (2017-05-08) 4 | [Full Changelog](https://github.com/dev-sec/nginx-baseline/compare/2.0.1...2.0.2) 5 | 6 | **Merged pull requests:** 7 | 8 | - update metadata [\#16](https://github.com/dev-sec/nginx-baseline/pull/16) ([chris-rock](https://github.com/chris-rock)) 9 | - restrict ruby testing to version 2.3.3 and update gemfile [\#15](https://github.com/dev-sec/nginx-baseline/pull/15) ([atomic111](https://github.com/atomic111)) 10 | 11 | ## [2.0.1](https://github.com/dev-sec/nginx-baseline/tree/2.0.1) (2016-12-22) 12 | [Full Changelog](https://github.com/dev-sec/nginx-baseline/compare/2.0.0...2.0.1) 13 | 14 | **Closed issues:** 15 | 16 | - Tests skipped if command nginx not in PATH [\#12](https://github.com/dev-sec/nginx-baseline/issues/12) 17 | 18 | **Merged pull requests:** 19 | 20 | - readme update, change log & tooling [\#14](https://github.com/dev-sec/nginx-baseline/pull/14) ([chris-rock](https://github.com/chris-rock)) 21 | - fix typo [\#11](https://github.com/dev-sec/nginx-baseline/pull/11) ([rndmh3ro](https://github.com/rndmh3ro)) 22 | 23 | ## [2.0.0](https://github.com/dev-sec/nginx-baseline/tree/2.0.0) (2016-05-03) 24 | [Full Changelog](https://github.com/dev-sec/nginx-baseline/compare/1.0.0...2.0.0) 25 | 26 | **Merged pull requests:** 27 | 28 | - migrate to inspec profile [\#10](https://github.com/dev-sec/nginx-baseline/pull/10) ([atomic111](https://github.com/atomic111)) 29 | 30 | ## [1.0.0](https://github.com/dev-sec/nginx-baseline/tree/1.0.0) (2015-10-15) 31 | **Merged pull requests:** 32 | 33 | - update urls [\#9](https://github.com/dev-sec/nginx-baseline/pull/9) ([chris-rock](https://github.com/chris-rock)) 34 | - add json format option [\#8](https://github.com/dev-sec/nginx-baseline/pull/8) ([atomic111](https://github.com/atomic111)) 35 | - fix testing for the nginx deployment [\#7](https://github.com/dev-sec/nginx-baseline/pull/7) ([ehaselwanter](https://github.com/ehaselwanter)) 36 | - fix testing repo [\#6](https://github.com/dev-sec/nginx-baseline/pull/6) ([ehaselwanter](https://github.com/ehaselwanter)) 37 | - Update common [\#5](https://github.com/dev-sec/nginx-baseline/pull/5) ([arlimus](https://github.com/arlimus)) 38 | - updating common files [\#4](https://github.com/dev-sec/nginx-baseline/pull/4) ([arlimus](https://github.com/arlimus)) 39 | - fix rubocop issues [\#3](https://github.com/dev-sec/nginx-baseline/pull/3) ([atomic111](https://github.com/atomic111)) 40 | - added test for multiple instances [\#2](https://github.com/dev-sec/nginx-baseline/pull/2) ([atomic111](https://github.com/atomic111)) 41 | - update nginx with tests and requirements [\#1](https://github.com/dev-sec/nginx-baseline/pull/1) ([arlimus](https://github.com/arlimus)) 42 | 43 | 44 | 45 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.lock 2 | *.gem 3 | *.rbc 4 | 5 | !Gemfile.lock 6 | .attribute.yml 7 | 8 | /.config 9 | /coverage/ 10 | /InstalledFiles 11 | /pkg/ 12 | /spec/reports/ 13 | /spec/examples.txt 14 | inspec-azure.plan 15 | inspec-aws-*.plan 16 | 17 | 18 | *.tfstate 19 | *.tfstate.* 20 | .terraform/ 21 | terraform.tfvars 22 | 23 | .kitchen/ 24 | .kitchen.local.yml 25 | kitchen.local.yml 26 | 27 | .vagrant 28 | 29 | inspec-deprecations-in-cfg.txt 30 | inspec-deprecations-in-lib.txt 31 | 32 | # Docker 33 | *.retry 34 | .backup 35 | 36 | 37 | # OSX 38 | # General 39 | .DS_Store 40 | .AppleDouble 41 | .LSOverride 42 | 43 | # Icon must end with two \r 44 | Icon 45 | 46 | # Thumbnails 47 | ._* 48 | 49 | # Files that might appear in the root of a volume 50 | .DocumentRevisions-V100 51 | .fseventsd 52 | .Spotlight-V100 53 | .TemporaryItems 54 | .Trashes 55 | .VolumeIcon.icns 56 | .com.apple.timemachine.donotpresent 57 | 58 | # Directories potentially created on remote AFP share 59 | .AppleDB 60 | .AppleDesktop 61 | Network Trash Folder 62 | Temporary Items 63 | .apdisk 64 | 65 | # Logs 66 | *.log 67 | 68 | 69 | ## Documentation cache and generated files: 70 | /.yardoc/ 71 | /_yardoc/ 72 | /doc/ 73 | /rdoc/ 74 | 75 | # Ignore bundler config 76 | /.bundle/ 77 | /vendor/ 78 | /vendor/bundle 79 | vendor/cookbooks 80 | 81 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 82 | .rvmrc 83 | .packer 84 | 85 | # for a library or gem, you might want to ignore these files since the code is 86 | # intended to run in multiple environments; otherwise, check them in: 87 | .ruby-version 88 | .ruby-gemset 89 | 90 | 91 | ## JetBrain 92 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 93 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 94 | .idea/ 95 | 96 | ## Specific to RubyMotion: 97 | .dat* 98 | .repl_history 99 | *.bridgesupport 100 | 101 | # File-based project format 102 | *.iws 103 | 104 | # IntelliJ 105 | out/ 106 | 107 | # mpeltonen/sbt-idea plugin 108 | .idea_modules/ 109 | 110 | # Crashlytics plugin (for Android Studio and IntelliJ) 111 | com_crashlytics_export_strings.xml 112 | crashlytics.properties 113 | crashlytics-build.properties 114 | fabric.properties 115 | 116 | # JIRA plugin 117 | atlassian-ide-plugin.xml 118 | 119 | 120 | # Build Folder 121 | /build/ 122 | /build-iPhoneOS/ 123 | /build-iPhoneSimulator/ 124 | 125 | 126 | # Ignore rendered files from docs/ 127 | source/docs/reference/ 128 | examples/meta-profile/vendor/ 129 | habitat/VERSION 130 | habitat/results 131 | /lib/bundler/man/ 132 | 133 | 134 | # USER 135 | /.gitignoredir/ 136 | /tmp/ 137 | /test/tmp/ 138 | /test/version_tmp/ 139 | /.emacs.desktop 140 | .gitter 141 | *.elc 142 | nbproject 143 | auto-save-list 144 | tramp 145 | /.direnv 146 | /.envrc 147 | results/ 148 | contrib/* 149 | 150 | -------------------------------------------------------------------------------- /controls/V-26299.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26299" do 30 | title "The web server must not be configured as a proxy server." 31 | 32 | desc "The ngx_http_proxy_module allow the server to act as a proxy (either 33 | forward or reverse proxy) of http and other protocols with additional proxy 34 | modules loaded. If the nginx installation is not intended to proxy requests 35 | to or from another network then the proxy module should not be loaded. Proxy 36 | servers can act as an important security control when properly configured, 37 | however a secure proxy server is not within the scope of this STIG. A web 38 | server should be primarily a web server or a proxy server but not both, for 39 | the same reasons that other multi-use servers are not recommended. Scanning 40 | for web servers that will also proxy requests is a very common attack, as 41 | proxy servers are useful for anonymizing attacks on other servers, or 42 | possibly proxying requests into an otherwise protected network." 43 | 44 | impact 0.5 45 | tag "severity": "medium" 46 | tag "gtitle": "WA00520" 47 | tag "gid": "V-26299" 48 | tag "rid": "SV-33220r1_rule" 49 | tag "stig_id": "WA00520 A22" 50 | tag "nist": ["AC-3", "Rev_4"] 51 | 52 | tag "check": "Enter the following command: 53 | 54 | nginx -V 55 | 56 | This will provide a list of all loaded modules. If the following module is 57 | found, this is a finding. 58 | 59 | ngx_http_proxy_module" 60 | 61 | tag "fix": "Disable any modules that are not needed. 62 | 63 | Use the configure script (available in the nginx download package) to exclude 64 | modules using the --without {module_name} option to reject unneeded modules." 65 | 66 | nginx_path = input('nginx_path') 67 | 68 | begin 69 | describe nginx do 70 | its('modules') { should_not include 'ngx_http_proxy' } 71 | end 72 | rescue Exception => msg 73 | describe "Exception: #{msg}" do 74 | it { should be_nil } 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /controls/V-2234.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2234" do 30 | 31 | title "Public web server resources must not be shared with private assets." 32 | 33 | desc "It is important to segregate public web server resources from private 34 | resources located behind the DoD DMZ in order to protect private assets. 35 | When folders, drives or other resources are directly shared between the 36 | public web server and private servers the intent of data and resource 37 | segregation can be compromised. 38 | 39 | In addition to the requirements of the DoD Internet-NIPRNet DMZ STIG that 40 | isolates inbound traffic from the external network to the internal network, 41 | resources such as printers, files, and folders/directories will not be shared 42 | between public web servers and assets located within the internal network. 43 | " 44 | 45 | impact 0.0 46 | tag "severity": "medium" 47 | tag "gtitle": "WG040" 48 | tag "gid": "V-2234" 49 | tag "rid": "SV-32957r1_rule" 50 | tag "stig_id": "WG040 A22" 51 | tag "nist": ["SC-7", "Rev_4"] 52 | 53 | tag "check": "Determine whether the public web server has a two-way trusted 54 | relationship with any private asset located within the network. Private web 55 | server resources (e.g., drives, folders, printers, etc.) will not be 56 | directly mapped to or shared with public web servers. 57 | 58 | If sharing is selected for any web folder, this is a finding. 59 | 60 | The following checks indicate inappropriate sharing of private resources with 61 | the public web server: 62 | 63 | If private resources (e.g., drives, partitions, folders/directories, printers, 64 | etc.) are shared with the public web server, then this is a finding. " 65 | 66 | tag "fix": "Configure the public web server to not have a trusted 67 | relationship with any system resource that is also not accessible to the 68 | public. Web content is not to be shared via Microsoft shares or NFS mounts." 69 | 70 | only_if { false } # this will always skip 71 | end 72 | -------------------------------------------------------------------------------- /controls/V-13727.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13727" do 30 | title "The worker_processes StartServers directive must be set properly." 31 | 32 | desc "These requirements are set to mitigate the effects of several types of 33 | denial of service attacks. Although there is some latitude concerning the 34 | settings themselves, the requirements attempt to provide reasonable limits 35 | for the protection of the web server. If necessary, these limits can be 36 | adjusted to accommodate the operational requirement of a given system." 37 | 38 | impact 0.5 39 | tag "severity": "medium" 40 | tag "gtitle": "WA000-WWA026" 41 | tag "gid": "V-13727" 42 | tag "rid": "SV-36645r2_rule" 43 | tag "stig_id": "WA000-WWA026 A22" 44 | tag "nist": ["CM-6", "Rev_4"] 45 | 46 | tag "check": "To view the worker_processes directive value enter the 47 | following command: 48 | 49 | grep ""worker_processes"" on the nginx.conf file and any separate included 50 | configuration files 51 | 52 | If the value of ""worker_processes"" is not set to auto or explicitly set, 53 | this is a finding: 54 | 55 | worker_processes auto; 56 | 57 | worker_processes defines the number of worker processes. The optimal value 58 | depends on many factors including (but not limited to) the number of CPU 59 | cores, the number of hard disk drives that store data, and load pattern. When 60 | one is in doubt, setting it to the number of available CPU cores would be a 61 | good start (the value “auto” will try to autodetect it)." 62 | 63 | tag "fix": "Edit the configuration file and set the value of 64 | ""worker_processes"" to the value of auto or a value of 1 or higher: 65 | 66 | worker_processes auto;" 67 | 68 | nginx_conf_file = input('nginx_conf_file') 69 | 70 | begin 71 | describe nginx_conf(nginx_conf_file).params['worker_processes'] do 72 | it { should cmp [['auto']] } 73 | end 74 | rescue Exception => msg 75 | describe "Exception: #{msg}" do 76 | it { should be_nil } 77 | end 78 | end 79 | 80 | end 81 | -------------------------------------------------------------------------------- /controls/V-2242.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2242" do 30 | 31 | title "A public web server, if hosted on the NIPRNet, must be isolated in an 32 | accredited DoD DMZ Extension." 33 | 34 | desc "To minimize exposure of private assets to unnecessary risk by 35 | attackers, public web servers must be isolated from internal systems.Public 36 | web servers are by nature more vulnerable to attack from publically based 37 | sources, such as the public Internet. Once compromised, a public web server 38 | might be used as a base for further attack on private resources, unless 39 | additional layers of protection are implemented. Public web servers must be 40 | located in a DoD DMZ Extension, if hosted on the NIPRNet, with carefully 41 | controlled access. Failure to isolate resources in this way increase risk 42 | that private assets are exposed to attacks from public sources." 43 | 44 | impact 0.5 45 | tag "severity": "medium" 46 | tag "gtitle": "WA060" 47 | tag "gid": "V-2242" 48 | tag "rid": "SV-32932r2_rule" 49 | tag "stig_id": "WA060 A22" 50 | tag "nist": ["SC-7", "Rev_4"] 51 | 52 | tag "check": "Interview the SA or web administrator to see where the public 53 | web server is logically located in the data center. Review the site’s 54 | network diagram to see how the web server is connected to the LAN. Visually 55 | check the web server hardware connections to see if it conforms to the 56 | site’s network diagram. An improperly located public web server is a 57 | potential threat to the entire network.If the web server is not isolated in 58 | an accredited DoD DMZ Extension, this is a finding." 59 | 60 | tag "fix": "Logically relocate the public web server to be isolated from 61 | internal systems. In addition, ensure the public web server does not have 62 | trusted connections with assets outside the confines of the demilitarized 63 | zone (DMZ) other than application and/or database servers that are a part of 64 | the same system as the web server." 65 | 66 | only_if { 67 | false 68 | } 69 | 70 | end 71 | -------------------------------------------------------------------------------- /controls/V-26285.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26285" do 30 | title "Active software modules must be minimized." 31 | 32 | desc "Modules are the source of nginx httpd servers core and dynamic 33 | capabilities. Thus not every module available is needed for operation. Most 34 | installations only need a small subset of the modules available. By 35 | minimizing the enabled modules to only those that are required, we reduce 36 | the number of doors and have therefore reduced the attack surface of the web 37 | site. Likewise having fewer modules means less software that could have 38 | vulnerabilities." 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA00500" 43 | tag "gid": "V-26285" 44 | tag "rid": "SV-33215r1_rule" 45 | tag "stig_id": "WA00500 A22" 46 | tag "nist": ["CM-2", "Rev_4"] 47 | 48 | tag "check": "Enter the following command: 49 | 50 | nginx -V 51 | 52 | This will provide a list of the loaded modules. Validate that all displayed 53 | modules are required for operations. If any module is not required for 54 | operation, this is a finding. 55 | 56 | Note: The following modules are needed for basic web function and do not need 57 | to be reviewed: 58 | 59 | ngx_http_* modules, except for modules excluded in the following rules below" 60 | 61 | tag "fix": "Disable any modules that are not needed. 62 | 63 | Use the configure script (available in the nginx download package) to exclude 64 | modules using the --without {module_name} option to reject unneeded modules." 65 | 66 | nginx_path = input('nginx_path') 67 | 68 | nginx_authorized_modules = input('nginx_authorized_modules') 69 | 70 | nginx_unauthorized_modules = input('nginx_unauthorized_modules') 71 | 72 | begin 73 | describe nginx do 74 | its('modules') { should be_in nginx_authorized_modules } 75 | end 76 | describe nginx do 77 | its('modules') { should_not be_in nginx_unauthorized_modules } 78 | end 79 | rescue Exception => msg 80 | describe "Exception: #{msg}" do 81 | it { should be_nil } 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /controls/V-2232.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2232" do 30 | 31 | title "The web server password(s) must be entrusted to the SA or Web 32 | Manager." 33 | 34 | desc "Normally, a service account is established for the web server. This is 35 | because a privileged account is not desirable and the server is designed to 36 | run for long uninterrupted periods of time. The SA or Web Manager will need 37 | password access to the web server to restart the service in the event of an 38 | emergency as the web server is not to restart automatically after an 39 | unscheduled interruption.If the password is not entrusted to an SA or web 40 | manager the ability to ensure the availability of the web server is 41 | compromised." 42 | 43 | impact 0.5 44 | tag "severity": "medium" 45 | tag "gtitle": "WG050" 46 | tag "gid": "V-2232" 47 | tag "rid": "SV-32788r1_rule" 48 | tag "stig_id": "WG050 A22" 49 | tag "nist": ["AC-2", "Rev_4"] 50 | 51 | tag "check": "The reviewer should make a note of the name of the account 52 | being used for the web service. This information may be needed later in the 53 | SRR. There may also be other server services running related to the web server 54 | in support of a particular web application, these passwords must be entrusted 55 | to the SA or Web Manager as well. Query the SA or Web Manager to determine if 56 | they have the web service password(s). 57 | 58 | If the web services password(s) are not entrusted to the SA or Web Manager, 59 | this is a finding. 60 | 61 | NOTE: For installations that run as a service, or without a password, the SA 62 | or Web Manager having an Admin account on the system would meet the intent of 63 | this check. " 64 | 65 | tag "fix": "Ensure the SA or Web Manager are entrusted with the web 66 | service(s) password." 67 | 68 | nginx_owner = input('nginx_owner') 69 | 70 | begin 71 | describe passwd.users(nginx_owner).passwords do 72 | it { should_not cmp ['']} 73 | end 74 | rescue Exception => msg 75 | describe "Exception: #{msg}" do 76 | it { should be_nil } 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /controls/V-13737.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13737" do 30 | title "The HTTP request header fields must be limited. " 31 | 32 | desc "Buffer overflow attacks are carried out by a malicious attacker sending 33 | amounts of data that the web server cannot store in a given size buffer. The 34 | eventual overflow of this buffer can overwrite system memory. Subsequently 35 | an attacker may be able to elevate privileges and take control of the 36 | server. The NGINX directive ""large_client_header_buffers"" limits the 37 | maximum number and size of buffers used for reading large client request 38 | header thereby limiting the chances for a buffer overflow. " 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA000-WWA062" 43 | tag "gid": "V-13737" 44 | tag "rid": "SV-32757r1_rule" 45 | tag "stig_id": "WA000-WWA062 A22" 46 | tag "nist": ["CM-6", "Rev_4"] 47 | 48 | tag "check": "To view the large_client_header_buffers value enter the 49 | following command: 50 | 51 | grep ""large_client_header_buffers"" on the nginx.conf file and any separate 52 | included configuration files 53 | 54 | If the value of large_client_header_buffers is not set to 2 buffers at 1k, 55 | this is a finding. " 56 | 57 | tag "fix": "Edit the configuration file to set the 58 | large_client_header_buffers to 2 buffers and 1k." 59 | 60 | nginx_conf_file = input('nginx_conf_file') 61 | 62 | begin 63 | nginx_conf_handle = nginx_conf(nginx_conf_file) 64 | 65 | describe nginx_conf_handle do 66 | its ('params') { should_not be_empty } 67 | end 68 | 69 | nginx_conf_handle.http.entries.each do |http| 70 | describe http.params['large_client_header_buffers'] do 71 | it { should cmp [['2','1k']] } 72 | end 73 | end 74 | 75 | nginx_conf_handle.servers.entries.each do |server| 76 | describe server.params['large_client_header_buffers'] do 77 | it { should cmp [['2','1k']] } 78 | end unless server.params['large_client_header_buffers'].nil? 79 | end 80 | 81 | rescue Exception => msg 82 | describe "Exception: #{msg}" do 83 | it { should be_nil } 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /controls/V-6485.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-6485" do 30 | 31 | title "Web server content and configuration files must be part of a routine 32 | backup program." 33 | 34 | desc"Backing up web server data and web server application software after 35 | upgrades or maintenance ensures that recovery can be accomplished up to the 36 | current version. It also provides a means to determine and recover from 37 | subsequent unauthorized changes to the software and data. 38 | 39 | A tested and verifiable backup strategy will be implemented for web server 40 | software as well as all web server data files. Backup and recovery procedures 41 | will be documented and the Web Manager or SA for the specific application will 42 | be responsible for the design, test, and implementation of the procedures. 43 | 44 | The site will have a contingency processing plan/disaster recovery plan that 45 | includes web servers. The contingency plan will be periodically tested in 46 | accordance with DoDI 8500.2 requirements. 47 | 48 | The site will identify an off-site storage facility in accordance with DoDI 49 | 8500.2 requirements. Off-site backups will be updated on a regular basis and 50 | the frequency will be documented in the contingency plan. " 51 | 52 | impact 0.3 53 | tag "severity": "low" 54 | tag "gtitle": "WA140" 55 | tag "gid": "V-6485" 56 | tag "rid": "SV-32964r2_rule" 57 | tag "stig_id": "WA140 A22" 58 | tag "nist": ["CP-9", "Rev_4"] 59 | 60 | tag "check": "Interview the Information Systems Security Officer (ISSO), SA, 61 | Web Manager, Webmaster or developers as necessary to determine whether or 62 | not a tested and verifiable backup strategy has been implemented for web 63 | server software as well as all web server data files. 64 | 65 | Proposed Questions: Who maintains the backup and recovery procedures? Do you 66 | have a copy of the backup and recovery procedures? Where is the off-site 67 | backup location? Is the contingency plan documented? When was the last time 68 | the contingency plan was tested? Are the test dates and results documented? 69 | 70 | If there is not a backup and recovery process for the web server, this is a 71 | finding. " 72 | 73 | tag "fix": "Document the backup procedures." 74 | 75 | only_if { 76 | false 77 | } 78 | end 79 | -------------------------------------------------------------------------------- /controls/V-new.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-new" do 30 | 31 | title "The web server must restrict SSL protocols." 32 | 33 | desc "During the initial setup of a Transport Layer Security (TLS) connection to the web server, the client sends a list of supported cipher suites in order of preference. The web server will reply with the cipher suite it will use for communication from the client list. If an attacker can intercept the submission of cipher suites to the web server and place, as the preferred cipher suite, a weak export suite, the encryption used for the session becomes easy for the attacker to break, often within minutes to hours." 34 | 35 | impact 0.5 36 | tag "severity": "medium" 37 | tag "gtitle": "WG345" 38 | tag "gid": "V-60707" 39 | tag "rid": "SV-75159r1_rule" 40 | tag "stig_id": "WG345 A22" 41 | tag "nist": ["SC-8", "Rev_4"] 42 | 43 | tag "check": "Review the nginx.conf file and any separate included configuration files. 44 | 45 | Ensure the following entry exists: 46 | 47 | server { 48 | # SSL protocols TLS v1~TLSv1.2 are allowed. Disabed SSLv3 49 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 50 | } 51 | 52 | If the entry is not found, this is a finding." 53 | 54 | tag "fix": "Review the nginx.conf file and any separate included 55 | configuration files. 56 | 57 | Edit to ensure the following entry exists: 58 | 59 | server { 60 | # SSL protocols TLS v1~TLSv1.2 are allowed. Disabed SSLv3 61 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 62 | } 63 | " 64 | 65 | nginx_conf_file = input('nginx_conf_file') 66 | 67 | begin 68 | nginx_conf_handle = nginx_conf(nginx_conf_file) 69 | 70 | describe nginx_conf_handle do 71 | its ('params') { should_not be_empty } 72 | end 73 | 74 | nginx_conf_handle.http.entries.each do |http| 75 | describe http.params['ssl_protocols'] do 76 | it { should cmp [["TLSv1", "TLSv1.1", "TLSv1.2"]] } 77 | end 78 | end 79 | 80 | nginx_conf_handle.servers.entries.each do |server| 81 | describe server.params['ssl_protocols'] do 82 | it { should cmp [["TLSv1", "TLSv1.1", "TLSv1.2"]] } 83 | end unless server.params['ssl_protocols'].nil? 84 | end 85 | 86 | rescue Exception => msg 87 | describe "Exception: #{msg}" do 88 | it { should be_nil } 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /controls/V-2251.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | 26 | only_if do 27 | package('nginx').installed? || command('nginx').exist? 28 | end 29 | 30 | control "V-2251" do 31 | 32 | title "All utility programs, not necessary for operations, must be removed 33 | or disabled. " 34 | 35 | desc "Just as running unneeded services and protocols is a danger to the 36 | web server at the lower levels of the OSI model, running unneeded utilities 37 | and programs is also a danger at the application layer of the OSI model. 38 | Office suites, development tools, and graphical editors are examples of such 39 | programs that are troublesome. Individual productivity tools have no 40 | legitimate place or use on an enterprise, production web server and they are 41 | also prone to their own security risks." 42 | 43 | impact 0.3 44 | tag "severity": "low" 45 | tag "gtitle": "WG130" 46 | tag "gid": "V-2251" 47 | tag "rid": "SV-32955r2_rule" 48 | tag "stig_id": "WG130 A22" 49 | tag "nist": ["CM-6", "Rev_4"] 50 | 51 | tag "check": "If the site requires the use of a particular piece of 52 | software, the ISSO will need to maintain documentation identifying this 53 | software as necessary for operations. The software must be operated at the 54 | vendor’s current patch level and must be a supported vendor release. If 55 | programs or utilities that meet the above criteria are installed on the Web 56 | Server, and appropriate documentation and signatures are in evidence, this is 57 | not a finding. 58 | 59 | Determine whether the web server is configured with unnecessary software. 60 | 61 | Determine whether processes other than those that support the web server are 62 | loaded and/or run on the web server. 63 | 64 | Examples of software that should not be on the web server are all web 65 | development tools, office suites (unless the web server is a private web 66 | development server), compilers, and other utilities that are not part of the 67 | web server suite or the basic operating system. 68 | 69 | Check the directory structure of the server and ensure that additional, 70 | unintended, or unneeded applications are not loaded on the system. 71 | 72 | If, after review of the application on the system, there is no justification 73 | for the identified software, this is a finding." 74 | 75 | tag "fix": "Remove any unnecessary applications." 76 | 77 | describe "Skip Message" do 78 | skip "This control must me verified manually." 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /controls/V-13732.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13732" do 30 | title "The ""disable_symlinks"" setting must be on." 31 | desc "The disable_symlinks directive determines how symbolic links should be 32 | treated when opening files.A symbolic link allows a file or a directory to 33 | be referenced using a symbolic name raising a potential hazard if symbolic 34 | linkage is made to a sensitive area. When web scripts are executed and 35 | symbolic links are allowed, the web user could be allowed to access 36 | locations on the web server that are outside the scope of the web document 37 | root or home directory." 38 | 39 | impact 0.5 40 | tag "severity": "medium" 41 | tag "gtitle": "WA000-WWA052" 42 | tag "gid": "V-13732" 43 | tag "rid": "SV-40129r1_rule" 44 | tag "stig_id": "WA000-WWA052 A22" 45 | tag "nist": ["CM-6", "Rev_4"] 46 | 47 | tag "check": "To view the disable_symlinks directive value enter the 48 | following command: 49 | 50 | grep ""disable_symlinks"" on the nginx.conf file and any separate included 51 | configuration files 52 | 53 | If the value of ""disable_symlinks"" is not set to on, this is a finding: 54 | 55 | disable_symlinks on; 56 | 57 | If any component of the pathname is a symbolic link, access to a file is 58 | denied. " 59 | 60 | tag "fix": "Edit the configuration file and set the value of 61 | ""disable_symlinks"" to on: 62 | 63 | disable_symlinks on;" 64 | 65 | nginx_conf_file = input('nginx_conf_file') 66 | 67 | begin 68 | nginx_conf_handle = nginx_conf(nginx_conf_file) 69 | 70 | describe nginx_conf_handle do 71 | its ('params') { should_not be_empty } 72 | end 73 | 74 | nginx_conf_handle.http.entries.each do |http| 75 | describe http.params['disable_symlinks'] do 76 | it { should cmp [['on']] } 77 | end 78 | end 79 | 80 | nginx_conf_handle.servers.entries.each do |server| 81 | describe server.params['disable_symlinks'] do 82 | it { should cmp [['on']] } 83 | end unless server.params['disable_symlinks'].nil? 84 | end 85 | 86 | nginx_conf_handle.locations.entries.each do |location| 87 | describe location.params['disable_symlinks'] do 88 | it { should cmp [['on']] } 89 | end unless location.params['disable_symlinks'].nil? 90 | end 91 | 92 | rescue Exception => msg 93 | describe "Exception: #{msg}" do 94 | it { should be_nil } 95 | end 96 | end 97 | 98 | end 99 | -------------------------------------------------------------------------------- /controls/V-26396.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26396" do 30 | title "HTTP request methods must be limited." 31 | 32 | desc "The HTTP 1.1 protocol supports several request methods which are 33 | rarely used and potentially high risk. " 34 | 35 | impact 0.5 36 | tag "severity": "medium" 37 | tag "gtitle": "WA00565 " 38 | tag "gid": "V-26396" 39 | tag "rid": "SV-33236r1_rule" 40 | tag "stig_id": "WA00565 A22" 41 | tag "nist": ["SC-3", "Rev_4"] 42 | 43 | tag "check": "Review the nginx.conf file and any separate included 44 | configuration files. 45 | 46 | For every location (except root), ensure the following entry exists: 47 | 48 | ## Only GET, Post, PUT are allowed## 49 | if ($request_method !~ ^(GET|PUT|POST)$ ) { 50 | return 444; 51 | } 52 | ## In this case, it does not accept other HTTP methods such as HEAD, 53 | DELETE, SEARCH, TRACE ## 54 | 55 | If the entry is not found for every location, this is a finding." 56 | 57 | tag "fix": "Review the nginx.conf file and any separate included 58 | configuration files. 59 | 60 | For every location (except root), edit to add the following entry: 61 | 62 | ## Only GET, Post, PUT are allowed## 63 | if ($request_method !~ ^(GET|PUT|POST)$ ) { 64 | return 444; 65 | } 66 | ## In this case, it does not accept other HTTP methods such as HEAD, DELETE, 67 | SEARCH, TRACE ## 68 | " 69 | 70 | nginx_conf_file = input('nginx_conf_file') 71 | 72 | begin 73 | 74 | describe nginx_conf(nginx_conf_file) do 75 | its ('params') { should_not be_empty } 76 | end 77 | 78 | nginx_conf(nginx_conf_file).locations.entries.each do |location| 79 | unless location.params["_"].eql?(["/"]) 80 | describe location.params['if'] do 81 | it { should_not be_nil } 82 | 83 | end 84 | location.params['if'].each do |ifcondition| 85 | describe ifcondition do 86 | it { should_not be_nil } 87 | 88 | its(['_']) { should cmp ["($request_method", "!~", "^(GET|PUT|POST)$", ")"]} 89 | its(['return']) { should cmp [["444"]] } 90 | end 91 | end unless location.params['if'].nil? 92 | end 93 | end 94 | rescue Exception => msg 95 | describe "Exception: #{msg}" do 96 | it { should be_nil } 97 | end 98 | end 99 | 100 | end 101 | -------------------------------------------------------------------------------- /controls/V-2257.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2257" do 30 | 31 | title "Administrative users and groups that have access rights to the web 32 | server must be documented." 33 | 34 | desc"There are typically several individuals and groups that are involved in 35 | running a production web server.These accounts must be restricted to only 36 | those necessary to maintain web services, review the server’s operation, and 37 | the operating system.By minimizing the amount of user and group accounts on 38 | a web server the total attack surface of the server is 39 | minimized.Additionally, if the required accounts aren’t documented no known 40 | standard is created.Without a known standard the ability to identify 41 | required accounts is diminished, increasing the opportunity for error when 42 | such a standard is needed (i.e. COOP, IR, etc.)." 43 | 44 | impact 0.3 45 | tag "severity": "low" 46 | tag "gtitle": "WA120" 47 | tag "gid": "V-2257" 48 | tag "rid": "SV-32951r1_rule" 49 | tag "stig_id": "WA120 A22" 50 | tag "nist": ["AC-2", "Rev_4"] 51 | 52 | tag "check": "Proposed Questions: How many user accounts are associated with 53 | the Web server operation and maintenance? 54 | 55 | Where are these accounts documented? 56 | 57 | Use the command line utility more /etc/passwd to identify the accounts on the 58 | web server. 59 | 60 | Query the SA or Web Manager regarding the use of each account and each group. 61 | 62 | If the documentation does not match the users and groups found on the server, 63 | this is a finding. " 64 | 65 | tag "fix": "Document the administrative users and groups which have access 66 | rights to the web server in the web site SOP or in an equivalent document." 67 | 68 | sys_admin = input('sys_admin') 69 | 70 | nginx_owner = input('nginx_owner') 71 | 72 | nginx_conf_file = input('nginx_conf_file') 73 | 74 | begin 75 | authorized_sa_user_list = sys_admin.clone << nginx_owner 76 | 77 | unless nginx_conf(nginx_conf_file).params['user'].nil? 78 | describe nginx_conf(nginx_conf_file).params['user'].flatten do 79 | it{ should be_in authorized_sa_user_list} 80 | end 81 | else 82 | describe 'Parameter \'user\' not found in the configuration file' do 83 | skip 'Parameter \'user\' not found in the configuration file' 84 | end 85 | end 86 | 87 | rescue Exception => msg 88 | describe "Exception: #{msg}" do 89 | it { should be_nil } 90 | end 91 | end 92 | 93 | end 94 | -------------------------------------------------------------------------------- /controls/V-2236.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2236" do 30 | 31 | title "Installation of a compiler on production web server is prohibited." 32 | 33 | desc "The presence of a compiler on a production server facilitates the 34 | malicious user’s task of creating custom versions of programs and installing 35 | Trojan Horses or viruses. For example, the attacker’s code can be uploaded 36 | and compiled on the server under attack." 37 | 38 | impact 0.5 39 | tag "severity": "medium" 40 | tag "gtitle": "WG080" 41 | tag "gid": "V-2236" 42 | tag "rid": "SV-32956r3_rule" 43 | tag "stig_id": "WG080 A22" 44 | tag "nist": ["CM-6", "Rev_4"] 45 | 46 | tag "check": "Query the SA and the Web Manager to determine if a compiler is 47 | present on the server.If a compiler is present, this is a finding. 48 | 49 | NOTE: If the web server is part of an application suite and a compiler is 50 | needed for installation, patching, and upgrading of the suite or if the 51 | compiler is embedded and can't be removed without breaking the suite, document 52 | the installation of the compiler with the ISSO/ISSM and verify that the 53 | compiler is restricted to administrative users only. If documented and 54 | restricted to administrative users, this is not a finding. " 55 | 56 | tag "fix": "Remove any compiler found on the production web server, but if 57 | the compiler program is needed to patch or upgrade an application suite in a 58 | production environment or the compiler is embedded and will break the suite 59 | if removed, document the compiler installation with the ISSO/ISSM and ensure 60 | that the compiler is restricted to only administrative users." 61 | 62 | 63 | disallowed_compiler_list = input('disallowed_compiler_list') 64 | 65 | begin 66 | if inspec.os.family.eql?("redhat") 67 | compiler_list = command('yum search all compiler').stdout.scan(/^(\S+)\s:\s/).flatten 68 | elsif inspec.os.family.eql?("debian") 69 | compiler_list = command('apt-cache search compiler').stdout.scan(/^(\S+)\s-\s/).flatten 70 | end 71 | 72 | 73 | compiler_list.each do |compiler| 74 | describe package(compiler) do 75 | it { should_not be_installed } 76 | end 77 | end 78 | 79 | disallowed_compiler_list.each do |compiler| 80 | describe package(compiler) do 81 | it { should_not be_installed } 82 | end 83 | end 84 | 85 | rescue Exception => msg 86 | describe "Exception: #{msg}" do 87 | it { should be_nil } 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /controls/V-2247.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2247" do 30 | 31 | title "Administrators must be the only users allowed access to the directory 32 | tree, the shell, or other operating system functions and utilities." 33 | 34 | desc "As a rule, accounts on a web server are to be kept to a minimum. Only 35 | administrators, web managers, developers, auditors, and web authors require 36 | accounts on the machine hosting the web server. This is in addition to the 37 | anonymous web user account. The resources to which these accounts have 38 | access must also be closely monitored and controlled. Only the SA needs 39 | access to all the system’s capabilities, while the web administrator and 40 | associated staff require access and control of the web content and web 41 | server configuration files. The anonymous web user account must not have 42 | access to system resources as that account could then control the server." 43 | 44 | impact 0.7 45 | tag "severity": "high" 46 | tag "gtitle": "WG200" 47 | tag "gid": "V-2247" 48 | tag "rid": "SV-36456r2_rule" 49 | tag "stig_id": "WG200 A22" 50 | tag "nist": ["AC-6", "Rev_4"] 51 | 52 | tag "check": "Obtain a list of the user accounts for the system, noting the 53 | priviledges for each account. 54 | 55 | Verify with the system administrator or the ISSO that all privileged accounts 56 | are mission essential and documented. 57 | 58 | Verify with the system administrator or the ISSO that all non-administrator 59 | access to shell scripts and operating system functions are mission essential 60 | and documented. 61 | 62 | If undocumented privileged accounts are found, this is a finding. 63 | 64 | If undocumented access to shell scripts or operating system functions is 65 | found, this is a finding." 66 | 67 | tag "fix": "Ensure non-administrators are not allowed access to the 68 | directory tree, the shell, or other operating system functions and 69 | utilities." 70 | 71 | sys_admin = input('sys_admin') 72 | 73 | nginx_owner = input('nginx_owner') 74 | 75 | begin 76 | 77 | authorized_sa_user_list = sys_admin.clone << nginx_owner 78 | 79 | describe users.shells(/bash/).usernames do 80 | it { should be_in authorized_sa_user_list} 81 | end 82 | 83 | if users.shells(/bash/).usernames.empty? 84 | describe "Skip Message" do 85 | skip "Skipped: no users found with shell acccess." 86 | end 87 | end 88 | rescue Exception => msg 89 | describe "Exception: #{msg}" do 90 | it { should be_nil } 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /controls/V-2243.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2243" do 30 | 31 | title "A private web server must be located on a separate controlled access 32 | subnet." 33 | 34 | desc "Private web servers, which host sites that serve controlled access 35 | data, must be protected from outside threats in addition to insider threats. 36 | Insider threat may be accidental or intentional but, in either case, can 37 | cause a disruption in service of the web server. To protect the private web 38 | server from these threats, it must be located on a separate controlled 39 | access subnet and must not be a part of the public DMZ that houses the 40 | public web servers. It also cannot be located inside the enclave as part of 41 | the local general population LAN." 42 | 43 | impact 0.5 44 | tag "severity": "medium" 45 | tag "gtitle": "WA070" 46 | tag "gid": "V-2243" 47 | tag "rid": "SV-32935r1_rule" 48 | tag "stig_id": "WA070 A22" 49 | tag "nist": ["SC-7", "Rev_4"] 50 | 51 | tag "check": "Verify the site’s network diagram and visually check the web 52 | server, to ensure that the private web server is located on a separate 53 | controlled access subnet and is not a part of the public DMZ that houses the 54 | public web servers. In addition, the private web server needs to be isolated 55 | via a controlled access mechanism from the local general population LAN." 56 | 57 | tag "fix": "Isolate the private web server from the public DMZ and separate 58 | it from the internal general population LAN." 59 | 60 | require "ipaddr" 61 | 62 | dmz_subnet = input('dmz_subnet') 63 | 64 | nginx_conf_file = input('nginx_conf_file') 65 | 66 | # collect and test each listen IPs from nginx_conf 67 | 68 | begin 69 | nginx_conf_handle = nginx_conf(nginx_conf_file) 70 | 71 | describe nginx_conf_handle do 72 | its ('params') { should_not be_empty } 73 | end 74 | 75 | nginx_conf_handle.servers.entries.each do |server| 76 | server.params['listen'].each do |listen| 77 | describe listen.join do 78 | it { should match %r([0-9]+(?:\.[0-9]+){3}|[a-zA-Z]:[0-9]+) } 79 | end 80 | server_ip = listen.join.split(':').first 81 | server_ip = server_ip.eql?('localhost') ? '127.0.0.1' : server_ip 82 | 83 | describe IPAddr.new(dmz_subnet) === IPAddr.new(server_ip) do 84 | it { should be false} 85 | end unless (IPAddr.new(server_ip) rescue nil).nil? 86 | 87 | end unless server.params['listen'].nil? 88 | end 89 | 90 | rescue Exception => msg 91 | describe "Exception: #{msg}" do 92 | it { should be_nil } 93 | end 94 | end 95 | end 96 | -------------------------------------------------------------------------------- /controls/V-13613.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13613" do 30 | 31 | title "The Web site software used with the web server must have all 32 | applicable security patches applied and documented." 33 | 34 | desc "The IAVM process does not address all patches that have been identified 35 | for the host operating system or, in this case, the web server software 36 | environment. Many vendors have subscription services available to notify 37 | users of known security threats. The site needs to be aware of these fixes 38 | and make determinations based on local policy and what software features are 39 | installed, if these patches need to be applied. 40 | 41 | In some cases, patches also apply to middleware and database systems. 42 | Maintaining the security of web servers requires frequent reviews of security 43 | notices. Many security notices mandate the installation of a software patch to 44 | overcome security vulnerabilities. 45 | 46 | SAs and ISSOs should regularly check the vendor support web site for patches 47 | and information related to the web server software. All applicable security 48 | patches will be applied to the operating system and to the web server 49 | software. Security patches are deemed applicable if the product is installed, 50 | even if it is not used or is disabled. " 51 | 52 | impact 0.5 53 | tag "severity": "medium" 54 | tag "gtitle": "WA230" 55 | tag "gid": "V-13613" 56 | tag "rid": "SV-32969r2_rule" 57 | tag "stig_id": "WA230 A22" 58 | tag "nist": ["CM-6", "Rev_4"] 59 | 60 | tag "check": "Query the web administrator to determine if the site has a 61 | detailed process as part of its configuration management plan to stay 62 | compliant with all security-related patches. 63 | 64 | Proposed Questions: How does the SA stay current with web server vendor 65 | patches? How is the SA notified when a new security patch is issued by the 66 | vendor? (Exclude the IAVM.) What is the process followed for applying patches 67 | to the web server? 68 | 69 | If the site is not in compliance with all applicable security patches, this is 70 | a finding." 71 | 72 | tag "fix": "Establish a detailed process as part of the configuration 73 | management plan to stay compliant with all web server security-related 74 | patches." 75 | 76 | begin 77 | describe linux_update do 78 | it { should be_uptodate } 79 | end 80 | 81 | linux_update.updates.each do |update| 82 | describe package(update['name']) do 83 | its('version') { should eq update['version'] } 84 | end 85 | end 86 | rescue Exception => msg 87 | describe "Exception: #{msg}" do 88 | it { should be_nil } 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /controls/V-13738.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13738" do 30 | title "The HTTP request header field size must be limited." 31 | 32 | desc "Buffer overflow attacks are carried out by a malicious attacker 33 | sending amounts of data that the web server cannot store in a given size 34 | buffer. The eventual overflow of this buffer can overwrite system memory. 35 | Subsequently an attacker may be able to elevate privileges and take control 36 | of the server. The NGINX directive ""client_header_buffer_size"" limits the 37 | buffer size for reading client request header thereby limiting the chances 38 | for a buffer overflow. " 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA000-WWA064" 43 | tag "gid": "V-13738" 44 | tag "rid": "SV-32766r2_rule" 45 | tag "stig_id": "WA000-WWA064 A22" 46 | tag "nist": ["CM-6", "Rev_4"] 47 | 48 | tag "check": "To view the client_header_buffer_size value enter the 49 | following command: 50 | 51 | grep ""client_header_buffer_size"" on the nginx.conf file and any separate 52 | included configuration files 53 | 54 | If the value of client_header_buffer_size is not set to 1k or less, this is a 55 | finding. " 56 | 57 | tag "fix": "Edit the configuration file to set the client_header_buffer_size 58 | to 1k or less." 59 | 60 | nginx_conf_file = input('nginx_conf_file') 61 | 62 | begin 63 | 64 | def to_bytes(size) 65 | return size if size.nil? 66 | size_bytes = size.to_i 67 | size_bytes = size_bytes*1024 if size.match('K') || size.match('k') 68 | size_bytes = size_bytes*1024*1024 if size.match('M') || size.match('m') 69 | return size_bytes 70 | end 71 | 72 | nginx_conf_handle = nginx_conf(nginx_conf_file) 73 | 74 | describe nginx_conf_handle do 75 | its ('params') { should_not be_empty } 76 | end 77 | 78 | nginx_conf_handle.http.entries.each do |http| 79 | describe http.params['client_header_buffer_size'] do 80 | it { should_not be_nil } 81 | 82 | end 83 | describe to_bytes(http.params['client_header_buffer_size'].join) do 84 | it { should cmp <= 1024 } 85 | end unless http.params['client_header_buffer_size'].nil? 86 | end 87 | 88 | nginx_conf_handle.servers.entries.each do |server| 89 | describe to_bytes(server.params['client_header_buffer_size'].join) do 90 | it { should cmp <= 1024 } 91 | end unless server.params['client_header_buffer_size'].nil? 92 | end 93 | 94 | rescue Exception => msg 95 | describe "Exception: #{msg}" do 96 | it { should be_nil } 97 | end 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /controls/V-2271.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2271" do 30 | title "Monitoring software must include CGI or equivalent programs in its 31 | scope." 32 | desc "By their very nature, CGI type files permit the anonymous web user to 33 | interact with data and perhaps store data on the web server. In many cases, 34 | CGI scripts exercise system-level control over the server’s resources. These 35 | files make appealing targets for the malicious user. If these files can be 36 | modified or exploited, the web server can be compromised. These files must 37 | be monitored by a security tool that reports unauthorized changes to these 38 | files." 39 | impact 0.5 40 | tag "severity": "medium" 41 | tag "gtitle": "WG440" 42 | tag "gid": "V-2271" 43 | tag "rid": "SV-32927r2_rule" 44 | tag "stig_id": "WG440 A22" 45 | tag "nist": ["AU-6", "AC-3", "Rev_4"] 46 | 47 | tag "check": "CGI or equivalent files must be monitored by a security tool 48 | that reports unauthorized changes. It is the purpose of such software to 49 | monitor key files for unauthorized changes to them. The reviewer should 50 | query the ISSO, the SA, and the web administrator and verify the information 51 | provided by asking to see the template file or configuration file of the 52 | software being used to accomplish this security task. Example file 53 | extensions for files considered to provide active content are, but not 54 | limited to, .cgi, .asp, .aspx, .class, .vb, .php, .pl, and .c. 55 | 56 | If the site does not have a process in place to monitor changes to CGI program 57 | files, this is a finding." 58 | 59 | tag "fix": "Use a monitoring tool to monitor changes to the CGI or 60 | equivalent directory. This can be done with something as simple as a script or 61 | batch file that would identify a change in the file." 62 | 63 | monitoringsoftware = input('monitoring_software') 64 | 65 | begin 66 | if virtualization.system == 'docker' 67 | describe "Since this nginx instance is running in a container, perform manual review to determine if and how the system monitors changes to the CGI or 68 | equivalent directory." do 69 | skip "Since this nginx instance is running in a container, perform manual review to determine if and how the system monitors changes to the CGI or 70 | equivalent directory." 71 | end 72 | else 73 | describe.one do 74 | monitoringsoftware.each do |software| 75 | describe package(software) do 76 | it{ should be_installed } 77 | end 78 | end 79 | end 80 | end 81 | rescue Exception => msg 82 | describe "Exception: #{msg}" do 83 | it { should be_nil } 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /controls/V-6724.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-6724" do 30 | title "Web server and/or operating system information must be protected." 31 | 32 | desc "The web server response header of an HTTP response can contain several 33 | fields of information including the requested HTML page. The information 34 | included in this response can be web server type and version, operating 35 | system and version, and ports associated with the web server. This provides 36 | the malicious user valuable information without the use of extensive 37 | tools." 38 | 39 | impact 0.3 40 | tag "severity": "low" 41 | tag "gtitle": "WG520" 42 | tag "gid": "V-6724" 43 | tag "rid": "SV-36672r1_rule" 44 | tag "stig_id": "WG520 A22" 45 | tag "nist": ["CM-6", "Rev_4"] 46 | 47 | tag "check": "Enter the following command: 48 | 49 | grep ""server_tokens"" on the nginx.conf file and any separate included 50 | configuration files 51 | 52 | The Directive server_tokens must be set to ""off"" (ex. server_tokens off;). 53 | This directive disables emitting nginx version on error pages and in the 54 | “Server” response header field. 55 | 56 | If the web server or operating system information are sent to the client via 57 | the server response header or the directive does not exist, this is a finding. 58 | 59 | Note: The default value is set to on." 60 | 61 | tag "fix": "server_tokens must be set to 'off'." 62 | 63 | nginx_conf_file = input('nginx_conf_file') 64 | 65 | begin 66 | nginx_conf_handle = nginx_conf(nginx_conf_file) 67 | 68 | describe nginx_conf_handle do 69 | its ('params') { should_not be_empty } 70 | end 71 | 72 | nginx_conf_handle.http.entries.each do |http| 73 | describe http.params['server_tokens'] do 74 | it { should cmp [['off']] } 75 | end 76 | end 77 | 78 | nginx_conf_handle.servers.entries.each do |server| 79 | describe.one do 80 | describe server.params['server_tokens'] do 81 | it { should be nil } 82 | end 83 | describe server.params['server_tokens'] do 84 | it { should cmp [['off']] } 85 | end 86 | end 87 | end 88 | nginx_conf_handle.locations.entries.each do |location| 89 | describe.one do 90 | describe location.params['server_tokens'] do 91 | it { should be nil } 92 | end 93 | describe location.params['server_tokens'] do 94 | it { should cmp [['off']] } 95 | end 96 | end 97 | end 98 | 99 | rescue Exception => msg 100 | describe "Exception: #{msg}" do 101 | it { should be_nil } 102 | end 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /controls/V-2255.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2255" do 30 | 31 | title "The web server’s htpasswd files (if present) must reflect proper 32 | ownership and permissions" 33 | 34 | desc "In addition to OS restrictions, access rights to files and directories 35 | can be set on a web site using the web server software.That is, in addition 36 | to allowing or denying all access rights, a rule can be specified that 37 | allows or denies partial access rights.For example, users can be given read- 38 | only access rights to files, to view the information but not change the 39 | files. 40 | 41 | This check verifies that the htpasswd file is only accessible by system 42 | administrators or web managers, with the account running the web service 43 | having group permissions of read and execute. htpasswd is a utility used to 44 | provide for password access to web sites." 45 | 46 | impact 0.5 47 | tag "severity": "medium" 48 | tag "gtitle": "WG270" 49 | tag "gid": "V-2255" 50 | tag "rid": "SV-36478r2_rule" 51 | tag "stig_id": "WG270 A22" 52 | tag "nist": ["AC-3", "Rev_4"] 53 | tag "check": "To locate the htpasswd file enter the following command: 54 | 55 | Find / -name htpasswd Permissions should be r-x r - x - - - (550) 56 | 57 | If permissions on htpasswd are greater than 550, this is a finding. 58 | 59 | Owner should be the SA or Web Manager account, if another account has access 60 | to this file, this is a finding. " 61 | 62 | tag "fix": "The SA or Web Manager account 63 | should own the htpasswd file and permissions should be set to 550." 64 | 65 | nginx_owner = input('nginx_owner') 66 | 67 | sys_admin = input('sys_admin') 68 | 69 | nginx_group = input('nginx_group') 70 | 71 | sys_admin_group = input('sys_admin_group') 72 | 73 | begin 74 | 75 | authorized_sa_user_list = sys_admin.clone << nginx_owner 76 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 77 | 78 | htpasswd = command('find / -name .htpasswd').stdout.chomp 79 | htpasswd.split.each do |htpwd| 80 | describe file(htpwd) do 81 | its('owner') { should be_in authorized_sa_user_list } 82 | its('group') { should be_in authorized_sa_group_list } 83 | it { should_not be_writable } 84 | it { should_not be_readable.by('others') } 85 | it { should_not be_executable.by('others') } 86 | end 87 | end 88 | 89 | if htpasswd.empty? 90 | describe "Skip Message" do 91 | skip "Skipped: .htpasswd file not found" 92 | end 93 | end 94 | 95 | rescue Exception => msg 96 | describe "Exception: #{msg}" do 97 | it { should be_nil } 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /controls/V-26326.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26326" do 30 | 31 | title "The web server must be configured to listen on a specific IP address 32 | and port." 33 | 34 | desc "The nginx listen directive specifies the IP addresses and port numbers 35 | the nginx web server will listen for requests. Rather than be unrestricted 36 | to listen on all IP addresses available to the system, the specific IP 37 | address or addresses intended must be explicitly specified. Specifically a 38 | Listen directive with no IP address specified, or with an IP address of 39 | zero’s should not be used. Having multiple interfaces on web servers is 40 | fairly common, and without explicit Listen directives, the web server is 41 | likely to be listening on an inappropriate IP address / interface that were 42 | not intended for the web server. Single homed system with a single IP 43 | addressed are also required to have an explicit IP address in the Listen 44 | directive, in case additional interfaces are added to the system at a later 45 | date." 46 | 47 | impact 0.5 48 | tag "severity": "medium" 49 | tag "gtitle": "WA00555" 50 | tag "gid": "V-26326" 51 | tag "rid": "SV-33228r1_rule" 52 | tag "stig_id": "WA00555 A22" 53 | tag "nist": ["CM-7", "Rev_4"] 54 | 55 | tag "check": "Enter the following command: 56 | 57 | grep ""Listen""on the nginx.conf file and any separate included 58 | configuration files. 59 | 60 | Review the results for the followingdirective: listen 61 | 62 | For any enabled Listen directives ensure they specify both an IP address and 63 | port number. 64 | 65 | If the Listen directive is found with only an IP address, or only a port 66 | number specified, this is finding. If the IP address is all zeros (i.e. 67 | 0.0.0.0:80 or [::ffff:0.0.0.0]:80, this is a finding. If the Listen 68 | directive does not exist, this is a finding." 69 | 70 | tag "fix": "Edit the nginx.conf file and set the ""listen"" directive to 71 | listen on a specific IP address and port. " 72 | 73 | nginx_conf_file = input('nginx_conf_file') 74 | 75 | begin 76 | 77 | describe nginx_conf(nginx_conf_file) do 78 | its ('params') { should_not be_empty } 79 | end 80 | 81 | nginx_conf(nginx_conf_file).servers.entries.each do |server| 82 | server.params['listen'].each do |listen| 83 | describe listen.join do 84 | it { should match %r([0-9]+(?:\.[0-9]+){3}|[a-zA-Z]:[0-9]+) } 85 | end 86 | describe listen.join.split(':').first do 87 | it { should_not cmp '0.0.0.0' } 88 | it { should_not cmp '[::ffff:0.0.0.0]' } 89 | end 90 | end unless server.params['listen'].nil? 91 | end 92 | rescue Exception => msg 93 | describe "Exception: #{msg}" do 94 | it { should be_nil } 95 | end 96 | end 97 | 98 | end 99 | -------------------------------------------------------------------------------- /controls/V-13735.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13735" do 30 | title "Directory indexing must be disabled on directories not containing index files." 31 | 32 | desc"autoindex and random_index directives can be applied to further 33 | restrict access to file and directories.If a URL which maps to a directory 34 | is requested, and there is no DirectoryIndex (e.g., index.html) in that 35 | directory, then enabling these directives will return a formatted listing of 36 | the directory which is not acceptable. 37 | 38 | autoindex enables or disables the directory listing output. The 39 | ngx_http_random_index_module module processes requests ending with the slash 40 | character (‘/’) and picks a random file in a directory to serve as an index 41 | file. The module is processed before the ngx_http_index_module module." 42 | 43 | impact 0.5 44 | tag "severity": "medium" 45 | tag "gtitle": "WA000-WWA058" 46 | tag "gid": "V-13735" 47 | tag "rid": "SV-32755r1_rule" 48 | tag "stig_id": "WA000-WWA058 A22" 49 | tag "nist": ["CM-6", "Rev_4"] 50 | 51 | tag "check": "To view the autoindex and random_index values enter the 52 | following commands: 53 | 54 | grep ""autoindex"" on the nginx.conf file and any separate included 55 | configuration files 56 | 57 | grep ""random_index"" on the nginx.conf file and any separate included 58 | configuration files 59 | 60 | If the values of each are not set to off, this is a finding: 61 | 62 | autoindex off; 63 | 64 | random_index off;" 65 | 66 | tag "fix": "Edit the configuration file and set the values to off: 67 | 68 | autoindex off; 69 | 70 | random_index off;" 71 | 72 | nginx_conf_file = input('nginx_conf_file') 73 | 74 | begin 75 | nginx_conf_handle = nginx_conf(nginx_conf_file) 76 | 77 | describe nginx_conf_handle do 78 | its ('params') { should_not be_empty } 79 | end 80 | 81 | nginx_conf_handle.http.entries.each do |http| 82 | describe http.params['autoindex'] do 83 | it { should cmp [['off']] } 84 | end 85 | end 86 | 87 | nginx_conf_handle.servers.entries.each do |server| 88 | describe server.params['autoindex'] do 89 | it { should cmp [['off']] } 90 | end unless server.params['autoindex'].nil? 91 | end 92 | 93 | nginx_conf_handle.locations.entries.each do |location| 94 | describe location.params['autoindex'] do 95 | it { should cmp [['off']] } 96 | end unless location.params['autoindex'].nil? 97 | describe location.params['random_index'] do 98 | it { should cmp [['off']] } 99 | end 100 | end 101 | 102 | rescue Exception => msg 103 | describe "Exception: #{msg}" do 104 | it { should be_nil } 105 | end 106 | end 107 | 108 | end 109 | -------------------------------------------------------------------------------- /inspec.yml: -------------------------------------------------------------------------------- 1 | name: nginx-baseline 2 | title: nginx-baseline 3 | maintainer: DevSec Hardening Framework Team 4 | copyright: DevSec Hardening Framework Team 5 | copyright_email: hello@dev-sec.io 6 | license: Apache 2 license 7 | summary: "Inspec Validation Profile for Nginx STIG" 8 | version: 2.0.4 9 | inspec_version: ">= 4.0" 10 | supports: 11 | - os-family: unix 12 | 13 | inputs: 14 | - name: nginx_conf_file 15 | description: Path for the nginx configuration file 16 | type: String 17 | value: '/etc/nginx/nginx.conf' 18 | 19 | - name: nginx_backup_repository 20 | description: Path to nginx backup repository 21 | type: String 22 | value: '/usr/share/nginx/html' 23 | 24 | - name: dmz_subnet 25 | description: Subnet of the DMZ 26 | type: String 27 | value: '62.0.0.0/24' 28 | 29 | - name: nginx_min_ver 30 | description: Minimum Web vendor-supported version. 31 | type: String 32 | value: '1.12.0' 33 | 34 | - name: nginx_owner 35 | description: Nginx owner 36 | type: String 37 | value: 'nginx' 38 | 39 | - name: nginx_group 40 | description: The Nginx group 41 | type: String 42 | value: 'nginx' 43 | 44 | - name: sys_admin 45 | description: The system adminstrator 46 | type: Array 47 | value: ['root','centos'] 48 | 49 | - name: sys_admin_group 50 | description: The system adminstrator group 51 | type: String 52 | value: 'root' 53 | 54 | - name: authorized_user_list 55 | description: List of non admin user accounts 56 | type: Array 57 | value: ['user'] 58 | 59 | - name: monitoring_software 60 | description: Monitoring software for CGI or equivalent programs 61 | type: Array 62 | value: ['audit', 'auditd'] 63 | 64 | - name: disallowed_packages_list 65 | description: List of disallowed packages 66 | type: Array 67 | value: ['postfix'] 68 | 69 | - name: disallowed_compiler_list 70 | description: List of disallowed compilers 71 | type: Array 72 | value: ['gcc'] 73 | 74 | - name: dod_approved_pkis 75 | description: DoD-approved PKIs (e.g., DoD PKI, DoD ECA, and DoD-approved external partners 76 | type: Array 77 | value: ['DoD', 'ECA'] 78 | 79 | - name: nginx_disallowed_file_list 80 | description: File list of documentation, sample code, example applications, and tutorials 81 | type: Array 82 | value: [ '/usr/share/man/man8/nginx.8.gz'] 83 | 84 | - name: nginx_allowed_file_list 85 | description: File list of allowed documentation, sample code, example applications, and tutorials 86 | type: Array 87 | value: [] 88 | 89 | - name: nginx_authorized_modules 90 | description: List of authorized nginx modules 91 | type: Array 92 | value: ['http_addition', 93 | 'http_auth_request', 94 | 'http_dav', 95 | 'http_flv', 96 | 'http_gunzip', 97 | 'http_gzip_static', 98 | 'http_mp4', 99 | 'http_random_index', 100 | 'http_realip', 101 | 'http_secure_link', 102 | 'http_slice', 103 | 'http_ssl', 104 | 'http_stub_status', 105 | 'http_sub', 106 | 'http_v2', 107 | 'mail_ssl', 108 | 'stream_realip', 109 | 'stream_ssl', 110 | 'stream_ssl_preread' 111 | ] 112 | 113 | - name: nginx_unauthorized_modules 114 | description: List of unauthorized nginx modules 115 | type: Array 116 | value: [] 117 | 118 | - name: nginx_path 119 | description: Path for the nginx binary 120 | type: String 121 | value: '/usr/sbin/nginx' 122 | 123 | - name: ocsp_server 124 | description: domain and port to the OCSP Server 125 | type: String 126 | value: 'login.live.com:443' 127 | 128 | - name: crl_udpate_frequency 129 | description: Frequency at which CRL is updated in days 130 | type: Numeric 131 | value: 7 132 | -------------------------------------------------------------------------------- /controls/V-13726.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13726" do 30 | title "The KeepAliveTimeout directive must be defined." 31 | 32 | desc "The number of seconds Apache will wait for a subsequent request before 33 | closing the connection. Once a request has been received, the timeout value 34 | specified by the Timeout directive applies. Setting KeepAliveTimeout to a 35 | high value may cause performance problems in heavily loaded servers. The 36 | higher the timeout, the more server processes will be kept occupied waiting 37 | on connections with idle clients. These requirements are set to mitigate the 38 | effects of several types of denial of service attacks. " 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WA000-WWA024" 43 | tag "gid": "V-13726" 44 | tag "rid": "SV-32877r1_rule" 45 | tag "stig_id": "WA000-WWA024 A22" 46 | tag "nist": ["CM-6", "Rev_4"] 47 | 48 | tag "check": "To view the keepalive_timeout directive value enter the 49 | following command: 50 | 51 | grep ""keepalive_timeout"" on the nginx.conf file and any separate included 52 | configuration files 53 | 54 | If the value of ""keepalive_timeout"" is not set to 5 (seconds) or less, this 55 | is a finding: 56 | 57 | keepalive_timeout 5 5; 58 | 59 | The first parameter sets a timeout during which a keep-alive client connection 60 | will stay open on the server side. The zero value disables keep-alive client 61 | connections. The second parameter sets a value in the “Keep-Alive: 62 | timeout=time” response header field. The “Keep-Alive: timeout=time” header 63 | field is recognized by Mozilla and Konqueror. " 64 | 65 | tag "fix": "Edit the configuration file and set the value of 66 | ""keepalive_timeout"" to the value of 5 or less: 67 | 68 | keepalive_timeout 5 5;" 69 | 70 | nginx_conf_file = input('nginx_conf_file') 71 | 72 | begin 73 | nginx_conf_handle = nginx_conf(nginx_conf_file) 74 | 75 | describe nginx_conf_handle do 76 | its ('params') { should_not be_empty } 77 | end 78 | 79 | nginx_conf_handle.http.entries.each do |http| 80 | describe http.params['keepalive_timeout'] do 81 | it { should cmp [['5', '5']] } 82 | end 83 | end 84 | 85 | nginx_conf_handle.servers.entries.each do |server| 86 | describe server.params['keepalive_timeout'] do 87 | it { should cmp [['5', '5']] } 88 | end unless server.params['keepalive_timeout'].nil? 89 | end 90 | 91 | nginx_conf_handle.locations.entries.each do |location| 92 | describe location.params['keepalive_timeout'] do 93 | it { should cmp [['5', '5']] } 94 | end unless location.params['keepalive_timeout'].nil? 95 | end 96 | 97 | rescue Exception => msg 98 | describe "Exception: #{msg}" do 99 | it { should be_nil } 100 | end 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /controls/V-13621.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13621" do 30 | 31 | title "All web server documentation, sample code, example applications, and 32 | tutorials must be removed from a production web server." 33 | 34 | desc "Web server documentation, sample code, example applications, and 35 | tutorials may be an exploitable threat to a web server. A production web 36 | server may only contain components that are operationally necessary (e.g., 37 | compiled code, scripts, web-content, etc.). Delete all directories that 38 | contain samples and any scripts used to execute the samples. If there is a 39 | requirement to maintain these directories at the site on non-production 40 | servers for training purposes, have permissions set to only allow access to 41 | authorized users (i.e., web administrators and systems administrators). 42 | Sample applications or scripts have not been evaluated and approved for use 43 | and may introduce vulnerabilities to the system." 44 | 45 | impact 0.7 46 | tag "severity": "high" 47 | tag "gtitle": "WG385" 48 | tag "gid": "V-13621" 49 | tag "rid": "SV-32933r1_rule" 50 | tag "stig_id": "WG385 A22" 51 | tag "nist": ["CM-6", "Rev_4"] 52 | 53 | tag "check": "Query the SA to determine if all directories that contain 54 | samples and any scripts used to execute the samples have been removed from 55 | the server. Each web server has its own list of sample files. This may 56 | change with the software versions, but the following are some examples of 57 | what to look for (This should not be the definitive list of sample files, 58 | but only an example of the common samples that are provided with the 59 | associated web server. This list will be updated as additional information 60 | is discovered.): 61 | 62 | ls -Ll /usr/share/man/man8/nginx.8.gz 63 | 64 | If there is a requirement to maintain these directories at the site for 65 | training or other such purposes, have permissions or set the permissions to 66 | only allow access to authorized users. If any sample files are found on the 67 | web server, this is a finding." 68 | 69 | nginx_disallowed_file_list = input('nginx_disallowed_file_list') 70 | 71 | nginx_exception_files = input('nginx_allowed_file_list') 72 | 73 | nginx_owner = input('nginx_owner') 74 | 75 | sys_admin = input('sys_admin') 76 | 77 | nginx_group = input('nginx_group') 78 | 79 | sys_admin_group = input('sys_admin_group') 80 | 81 | begin 82 | 83 | authorized_sa_user_list = sys_admin.clone << nginx_owner 84 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 85 | 86 | nginx_disallowed_file_list.each do |file| 87 | describe file(file) do 88 | it { should_not exist } 89 | end 90 | end 91 | 92 | nginx_exception_files.each do |file| 93 | describe file(file) do 94 | its('owner') { should be_in authorized_sa_user_list } 95 | its('group') { should be_in authorized_sa_group_list } 96 | it { should_not be_executable } 97 | it { should_not be_writable.by('group') } 98 | it { should_not be_readable.by('others') } 99 | it { should_not be_writable.by('others') } 100 | end 101 | end 102 | rescue Exception => msg 103 | describe "Exception: #{msg}" do 104 | it { should be_nil } 105 | end 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /controls/V-2230.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control 'V-2230' do 30 | 31 | title 'Backup interactive scripts on the production web server are prohibited.' 32 | 33 | desc "Copies of backup files will not execute on the server, but they can 34 | be read by the anonymous user if special precautions are not taken. Such 35 | backup copies contain the same sensitive information as the actual script 36 | being executed and, as such, are useful to malicious users. Techniques and 37 | systems exist today that search web servers for such files and are able to 38 | exploit the information contained in them." 39 | 40 | impact 0.3 41 | tag "severity": "low" 42 | tag "gtitle": "WG420" 43 | tag "gid": "V-2230" 44 | tag "rid": "SV-6930r1_rule" 45 | tag "stig_id": "WG420 A22" 46 | tag "nist": ["CM-6", "Rev_4"] 47 | 48 | tag "check": "Search for backup copies of CGI scripts on the web server or 49 | ask the SA or the Web Administrator if they keep backup copies of CGI 50 | scripts on the web server. 51 | 52 | Common backup file extensions are: *.bak, *.old, *.temp, *.tmp, *.backup, .?* 53 | 54 | Commands to help find: find /nginx -name '.?*' -not -name .ht* -or -name '*~' 55 | -or -name '* 56 | 57 | find /usr/local/nginx/html/ -name '.?*' -not-name.ht* -or-name '*~' -or-name '*.bak 58 | *' -or-name '*.old*' 59 | 60 | If files with these extensions are found in either the document directory or 61 | the home directory of the web server, this is a finding. 62 | 63 | If files with these extensions are stored in a repository (not in the document 64 | root) as backups for the web server, this is a finding. 65 | 66 | If files with these extensions have no relationship with web activity, such as 67 | a backup batch file for operating system utility, and they are not accessible 68 | by the web application, this is not a finding. " 69 | 70 | tag "fix": "Ensure that CGI backup scripts are not left on the production 71 | web server." 72 | 73 | nginx_conf_file = input('nginx_conf_file') 74 | 75 | nginx_backup_repository = input('nginx_backup_repository') 76 | 77 | begin 78 | dirs = ['/home', nginx_backup_repository] 79 | 80 | nginx_conf_handle = nginx_conf(nginx_conf_file) 81 | 82 | describe nginx_conf_handle do 83 | its ('params') { should_not be_empty } 84 | end 85 | 86 | nginx_conf_handle.http.entries.each do |http| 87 | dirs.push(http.params['root']) unless http.params['root'].nil? 88 | end 89 | 90 | nginx_conf_handle.servers.entries.each do |server| 91 | dirs.push(server.params['root']) unless server.params['root'].nil? 92 | end 93 | 94 | nginx_conf_handle.locations.entries.each do |location| 95 | dirs.push(location.params['root']) unless location.params['root'].nil? 96 | end 97 | 98 | dirs.flatten! 99 | dirs.uniq! 100 | 101 | dirs.each do |dir| 102 | next unless directory(dir).exist? 103 | describe "List of backup NINGX and/or CGI scripts found in #{dir}" do 104 | subject { command("find #{dir} -name '.?*' -not-name '.ht*' -or-name '*~' -or-name '*.bak' -or-name '*.old*'").stdout.chomp.split } 105 | it { should be_empty } 106 | end 107 | end 108 | rescue Exception => msg 109 | describe "Exception: #{msg}" do 110 | it { should be_nil } 111 | end 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /controls/V-26305.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-26305" do 30 | title "The process ID (PID) file must be properly secured." 31 | 32 | desc "The pid directive sets the file path to the process ID file to which 33 | the server records the process id of the server, which is useful for sending 34 | a signal to the server process or for checking on the health of the process. 35 | If the PID file is placed in a writable directory, other accounts could 36 | create a denial of service attack and prevent the server from starting by 37 | creating a PID file with the same name." 38 | 39 | impact 0.5 40 | tag "severity": "medium" 41 | tag "gtitle": "WA00530" 42 | tag "gid": "V-26305" 43 | tag "rid": "SV-33222r1_rule" 44 | tag "stig_id": "WA00530 A22" 45 | tag "nist": ["AC-3", "Rev_4"] 46 | 47 | tag "check": "To find the pid file: 48 | 49 | grep ""pid""+N52 The pid directive will indicate the location of the pid file 50 | (typical default: /usr/sbin/nginx.pid) 51 | 52 | Verify the permissions and ownership on the folder containing the PID file. If 53 | any user accounts other than root, auditor, or the account used to run the web 54 | server have permission to, or ownership of, this folder, this is a finding. If 55 | the PID file is located in the web server Root this is a finding." 56 | 57 | tag "fix": "Modify the location, permissions, and/or ownership for the PID 58 | file folder. " 59 | 60 | nginx_conf_file = input('nginx_conf_file') 61 | 62 | nginx_owner = input('nginx_owner') 63 | 64 | sys_admin = input('sys_admin') 65 | 66 | nginx_group = input('nginx_group') 67 | 68 | sys_admin_group = input('sys_admin_group') 69 | 70 | begin 71 | 72 | authorized_sa_user_list = sys_admin.clone << nginx_owner 73 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 74 | 75 | webserver_roots = [] 76 | nginx_conf_handle = nginx_conf(nginx_conf_file) 77 | 78 | describe nginx_conf_handle do 79 | its ('params') { should_not be_empty } 80 | end 81 | 82 | nginx_conf_handle.http.entries.each do |http| 83 | webserver_roots.push(http.params['root']) unless http.params['root'].nil? 84 | end 85 | nginx_conf_handle.servers.entries.each do |server| 86 | webserver_roots.push(server.params['root']) unless server.params['root'].nil? 87 | end 88 | nginx_conf_handle.locations.entries.each do |location| 89 | webserver_roots.push(location.params['root']) unless location.params['root'].nil? 90 | end 91 | 92 | webserver_roots.flatten! 93 | webserver_roots.uniq! 94 | 95 | describe file(nginx_conf_handle.params['pid'].join) do 96 | it { should exist } 97 | its('owner') { should be_in authorized_sa_user_list } 98 | its('group') { should be_in authorized_sa_group_list } 99 | it { should_not be_executable } 100 | it { should_not be_readable.by('others') } 101 | it { should_not be_writable.by('others') } 102 | end unless nginx_conf_handle.params['pid'].nil? 103 | 104 | webserver_roots.each do |root| 105 | describe nginx_conf_handle.params['pid'].join do 106 | it { should_not match root } 107 | end unless nginx_conf_handle.params['pid'].nil? 108 | end 109 | 110 | rescue Exception => msg 111 | describe "Exception: #{msg}" do 112 | it { should be_nil } 113 | end 114 | end 115 | 116 | end 117 | -------------------------------------------------------------------------------- /controls/V-13724.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13724" do 30 | title "The client body and header timeout directives must be properly set." 31 | 32 | desc "The timeout requirements are set to mitigate the effects of several 33 | types of denial of service attacks. Although there is some latitude 34 | concerning the settings themselves, the requirements attempt to provide 35 | reasonable limits for the protection of the web server. If necessary, these 36 | limits can be adjusted to accommodate the operational requirement of a given 37 | system. 38 | 39 | client_body_timeout defines a timeout for reading client request body. The 40 | timeout is set only for a period between two successive read operations, not 41 | for the transmission of the whole request body. If a client does not transmit 42 | anything within this time, the 408 (Request Time-out) error is returned to the 43 | client. 44 | 45 | client_header_timeout defines a timeout for reading client request header. If 46 | a client does not transmit the entire header within this time, the 408 47 | (Request Time-out) error is returned to the client. " 48 | 49 | impact 0.5 50 | tag "severity": "medium" 51 | tag "gtitle": "WA000-WWA020" 52 | tag "gid": "V-13724" 53 | tag "rid": "SV-32977r1_rule" 54 | tag "stig_id": "WA000-WWA020 A22" 55 | tag "nist": ["CM-6", "Rev_4"] 56 | 57 | tag "check": "To view the timeout values enter the following commands: 58 | 59 | grep ""client_body_timeout"" on the nginx.conf file and any separate included 60 | configuration files 61 | 62 | grep ""client_header_timeout"" on the nginx.conf file and any separate 63 | included configuration files 64 | 65 | If the values of each are not set to 10 seconds (10s) or less, this is a 66 | finding." 67 | 68 | 69 | tag "fix": "Edit the configuration file and set the value of 10 seconds or 70 | less: 71 | 72 | client_body_timeout 10s; 73 | 74 | client_header_timeout 10s;" 75 | 76 | nginx_conf_file = input('nginx_conf_file') 77 | 78 | begin 79 | nginx_conf_handle = nginx_conf(nginx_conf_file) 80 | 81 | describe nginx_conf_handle do 82 | its ('params') { should_not be_empty } 83 | end 84 | 85 | nginx_conf_handle.http.entries.each do |http| 86 | describe http.params['client_header_timeout'] do 87 | it { should_not be_nil } 88 | end 89 | describe http.params['client_header_timeout'].flatten do 90 | it { should cmp <= 10 } 91 | end unless http.params['client_header_timeout'].nil? 92 | 93 | describe http.params['client_body_timeout'] do 94 | it { should_not be_nil } 95 | 96 | end 97 | describe http.params['client_body_timeout'].flatten do 98 | it { should cmp <= 10 } 99 | end unless http.params['client_body_timeout'].nil? 100 | end 101 | 102 | nginx_conf_handle.servers.entries.each do |server| 103 | describe server.params['client_header_timeout'].flatten do 104 | it { should cmp <= 10 } 105 | end unless server.params['client_header_timeout'].nil? 106 | describe server.params['client_body_timeout'].flatten do 107 | it { should cmp <= 10 } 108 | end unless server.params['client_body_timeout'].nil? 109 | end 110 | 111 | 112 | rescue Exception => msg 113 | describe "Exception: #{msg}" do 114 | it { should be_nil } 115 | end 116 | end 117 | end 118 | -------------------------------------------------------------------------------- /controls/V-2248.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2248" do 30 | 31 | title "Web administration tools must be restricted to the web manager and 32 | the web manager’s designees." 33 | 34 | desc"All automated information systems are at risk of data loss due to 35 | disaster or compromise. Failure to provide adequate protection to the 36 | administration tools creates risk of potential theft or damage that may 37 | ultimately compromise the mission.Adequate protection ensures that server 38 | administration operates with less risk of losses or operations outages.The 39 | key web service administrative and configuration tools must be accessible 40 | only by the authorized web server administrators. All users granted this 41 | authority must be documented and approved by the ISSO. Access to the IIS 42 | Manager will be limited to authorized users and administrators." 43 | 44 | impact 0.5 45 | tag "severity": "medium" 46 | tag "gtitle": "WG220" 47 | tag "gid": "V-2248" 48 | tag "rid": "SV-32948r2_rule" 49 | tag "stig_id": "WG220 A22" 50 | tag "nist": ["AC-3", "AC-6", "Rev_4"] 51 | 52 | tag "check": "Determine which tool or control file is used to control the 53 | configuration of the web server. 54 | 55 | If the control of the web server is done via control files, verify who has 56 | update access to them. If tools are being used to configure the web server, 57 | determine who has access to execute the tools. 58 | 59 | If accounts other than the SA, the web manager, or the web manager designees 60 | have access to the web administration tool or control files, this is a 61 | finding. " 62 | 63 | tag "fix": "Determine which tool or control file is used to control the 64 | configuration of the web server. 65 | 66 | If the control of the web server is done via control files, verify who has 67 | update access to them. If tools are being used to configure the web server, 68 | determine who has access to execute the tools. 69 | 70 | If accounts other than the SA, the web manager, or the web manager designees 71 | have access to the web administration tool or control files, this is a 72 | finding. " 73 | 74 | nginx_conf_file = input('nginx_conf_file') 75 | 76 | nginx_owner = input('nginx_owner') 77 | 78 | sys_admin = input('sys_admin') 79 | 80 | nginx_conf_file = input('nginx_conf_file') 81 | 82 | nginx_group = input('nginx_group') 83 | 84 | sys_admin_group = input('sys_admin_group') 85 | 86 | begin 87 | 88 | authorized_sa_user_list = sys_admin.clone << nginx_owner 89 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 90 | 91 | nginx_conf_handle = nginx_conf(nginx_conf_file) 92 | nginx_conf_handle.params 93 | 94 | describe nginx_conf_handle do 95 | its ('params') { should_not be_empty } 96 | end 97 | 98 | nginx_conf_handle.contents.keys.each do |file| 99 | describe file(file) do 100 | its('owner') { should be_in authorized_sa_user_list } 101 | its('group') { should be_in authorized_sa_group_list } 102 | it { should_not be_executable } 103 | it { should_not be_readable.by('others') } 104 | it { should_not be_writable.by('others') } 105 | end 106 | end 107 | 108 | if nginx_conf_handle.contents.keys.empty? 109 | describe "Skip Message" do 110 | skip "Skipped: no conf files included." 111 | end 112 | end 113 | rescue Exception => msg 114 | describe "Exception: #{msg}" do 115 | it { should be_nil } 116 | end 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /libraries/linux_updates.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # copyright: 2016, Christoph Hartmann 3 | # copyright: 2016, Dominik Richter 4 | # license: MPLv2 5 | # 6 | # This Source Code Form is subject to the terms of the Mozilla Public 7 | # License, v. 2.0. If a copy of the MPL was not distributed with this 8 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 | 10 | require 'json' 11 | 12 | class LinuxUpdateManager < Inspec.resource(1) 13 | name 'linux_update' 14 | desc 'Use the linux_update InSpec audit resource to test for available or installed updates' 15 | 16 | def initialize 17 | if inspec.os.redhat? 18 | @update_mgmt = RHELUpdateFetcher.new(inspec) 19 | elsif inspec.os.debian? 20 | @update_mgmt = UbuntuUpdateFetcher.new(inspec) 21 | end 22 | return skip_resource 'The `linux_update` resource is not supported on your OS.' if @update_mgmt.nil? 23 | end 24 | 25 | def updates 26 | return [] if @update_mgmt.nil? 27 | u = @update_mgmt.updates 28 | return [] if u.nil? || u.empty? 29 | u['available'] 30 | end 31 | 32 | def uptodate? 33 | return nil if @update_mgmt.nil? 34 | u = @update_mgmt.updates 35 | return false if u.nil? || !u['available'].empty? 36 | true 37 | end 38 | 39 | def packages 40 | return [] if @update_mgmt.nil? 41 | p = @update_mgmt.packages 42 | return [] if p.nil? || u.empty? 43 | p['installed'] 44 | end 45 | 46 | def to_s 47 | 'Linux Update' 48 | end 49 | end 50 | 51 | class UpdateFetcher 52 | def initialize(inspec) 53 | @inspec = inspec 54 | end 55 | 56 | def packages 57 | [] 58 | end 59 | 60 | def updates 61 | [] 62 | end 63 | 64 | def parse_json(script) 65 | cmd = @inspec.bash(script) 66 | begin 67 | JSON.parse(cmd.stdout) 68 | rescue JSON::ParserError => _e 69 | return [] 70 | end 71 | end 72 | end 73 | 74 | class UbuntuUpdateFetcher < UpdateFetcher 75 | def packages 76 | ubuntu_packages = ubuntu_base + <<-EOH 77 | echo -n '{"installed":[' 78 | dpkg-query -W -f='${Status}\\t${Package}\\t${Version}\\t${Architecture}\\n' |\\ 79 | grep '^install ok installed\\s' |\\ 80 | awk '{ printf "{\\"name\\":\\""$4"\\",\\"version\\":\\""$5"\\",\\"arch\\":\\""$6"\\"}," }' | rev | cut -c 2- | rev | tr -d '\\n' 81 | echo -n ']}' 82 | EOH 83 | parse_json(ubuntu_packages) 84 | end 85 | 86 | def updates 87 | ubuntu_updates = ubuntu_base + <<-EOH 88 | echo -n '{"available":[' 89 | DEBIAN_FRONTEND=noninteractive apt-get upgrade --dry-run | grep Inst | tr -d '[]()' |\\ 90 | awk '{ printf "{\\"name\\":\\""$2"\\",\\"version\\":\\""$4"\\",\\"repo\\":\\""$5"\\",\\"arch\\":\\""$6"\\"}," }' | rev | cut -c 2- | rev | tr -d '\\n' 91 | echo -n ']}' 92 | EOH 93 | parse_json(ubuntu_updates) 94 | end 95 | 96 | private 97 | 98 | def ubuntu_base 99 | base = <<-EOH 100 | #!/bin/sh 101 | DEBIAN_FRONTEND=noninteractive apt-get update >/dev/null 2>&1 102 | readlock() { cat /proc/locks | awk '{print $5}' | grep -v ^0 | xargs -I {1} find /proc/{1}/fd -maxdepth 1 -exec readlink {} \\; | grep '^/var/lib/dpkg/lock$'; } 103 | while test -n "$(readlock)"; do sleep 1; done 104 | echo " " 105 | EOH 106 | base 107 | end 108 | end 109 | 110 | class RHELUpdateFetcher < UpdateFetcher 111 | def packages 112 | rhel_packages = <<-EOH 113 | sleep 2 && echo " " 114 | echo -n '{"installed":[' 115 | rpm -qa --queryformat '"name":"%{NAME}","version":"%{VERSION}-%{RELEASE}","arch":"%{ARCH}"\\n' |\\ 116 | awk '{ printf "{"$1"}," }' | rev | cut -c 2- | rev | tr -d '\\n' 117 | echo -n ']}' 118 | EOH 119 | parse_json(rhel_packages) 120 | end 121 | 122 | def updates 123 | rhel_updates = <<-EOH 124 | #!/bin/sh 125 | python -c 'import sys; sys.path.insert(0, "/usr/share/yum-cli"); import cli; list = cli.YumBaseCli().returnPkgLists(["updates"]);res = ["{\\"name\\":\\""+x.name+"\\", \\"version\\":\\""+x.version+"-"+x.release+"\\",\\"arch\\":\\""+x.arch+"\\",\\"repository\\":\\""+x.repo.id+"\\"}" for x in list.updates]; print "{\\"available\\":["+",".join(res)+"]}"' 126 | EOH 127 | # puts rhel_updates 128 | cmd = @inspec.bash(rhel_updates) 129 | unless cmd.exit_status == 0 130 | # essentially we want https://github.com/chef/inspec/issues/1205 131 | # STDERR.puts 'Could not determine patch status.' 132 | return nil 133 | end 134 | 135 | first = cmd.stdout.index('{') 136 | res = cmd.stdout.slice(first, cmd.stdout.size - first) 137 | begin 138 | JSON.parse(res) 139 | rescue JSON::ParserError => _e 140 | return [] 141 | end 142 | end 143 | end 144 | -------------------------------------------------------------------------------- /controls/V-13736.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13736" do 30 | title "The HTTP request message body size must be limited." 31 | 32 | desc"Buffer overflow attacks are carried out by a malicious attacker sending 33 | amounts of data that the web server cannot store in a given size buffer. The 34 | eventual overflow of this buffer can overwrite system memory. Subsequently 35 | an attacker may be able to elevate privileges and take control of the 36 | server. The NGINX directive ""client_body_buffer_size"" and 37 | ""client_max_body_size"" limits the size of the client request body buffer 38 | and body content respectively, thereby limiting the chances for a buffer 39 | overflow. " 40 | 41 | impact 0.5 42 | tag "severity": "medium" 43 | tag "gtitle": "WA000-WWA060" 44 | tag "gid": "V-13736" 45 | tag "rid": "SV-32756r1_rule" 46 | tag "stig_id": "WA000-WWA060 A22" 47 | tag "nist": ["CM-6", "Rev_4"] 48 | 49 | tag "check": "To view the client_body_buffer_size value enter the following 50 | command: 51 | 52 | grep ""client_body_buffer_size"" on the nginx.conf file and any separate 53 | included configuration files 54 | 55 | grep ""client_max_body_size"" on the nginx.conf file and any separate included 56 | configuration files 57 | 58 | If the values of each are not set to 100k or less, this is a finding. " 59 | 60 | 61 | tag "fix": "Edit the configuration file to set the client_body_buffer_size 62 | and client_max_body_size to 100k or less." 63 | 64 | nginx_conf_file = input('nginx_conf_file') 65 | 66 | begin 67 | 68 | def to_bytes(size) 69 | return size if size.nil? 70 | size_bytes = size.to_i 71 | size_bytes = size_bytes*1024 if size.match('K') || size.match('k') 72 | size_bytes = size_bytes*1024*1024 if size.match('M') || size.match('m') 73 | return size_bytes 74 | end 75 | 76 | 77 | nginx_conf_handle = nginx_conf(nginx_conf_file) 78 | 79 | describe nginx_conf_handle do 80 | its ('params') { should_not be_empty } 81 | end 82 | 83 | nginx_conf_handle.http.entries.each do |http| 84 | describe http.params['client_body_buffer_size'] do 85 | it { should_not be_nil } 86 | end 87 | describe to_bytes(http.params['client_body_buffer_size'].join) do 88 | it { should cmp <= 100*1024 } 89 | end unless http.params['client_body_buffer_size'].nil? 90 | 91 | describe to_bytes(http.params['client_max_body_size'].join) do 92 | it { should_not be_nil } 93 | end 94 | describe to_bytes(http.params['client_max_body_size'].join) do 95 | it { should cmp <= 100*1024 } 96 | end unless http.params['client_max_body_size'].nil? 97 | end 98 | 99 | nginx_conf_handle.servers.entries.each do |server| 100 | describe to_bytes(server.params['client_body_buffer_size'].join) do 101 | it { should cmp <= 100*1024 } 102 | end unless server.params['client_body_buffer_size'].nil? 103 | 104 | describe to_bytes(server.params['client_max_body_size'].join) do 105 | it { should cmp <= 100*1024 } 106 | end unless server.params['client_max_body_size'].nil? 107 | end 108 | 109 | nginx_conf_handle.locations.entries.each do |location| 110 | describe to_bytes(location.params['client_body_buffer_size'].join) do 111 | it { should cmp <= 100*1024 } 112 | end unless location.params['client_body_buffer_size'].nil? 113 | 114 | describe to_bytes(location.params['client_max_body_size'].join) do 115 | it { should cmp <= 100*1024 } 116 | end unless location.params['client_max_body_size'].nil? 117 | end 118 | 119 | 120 | rescue Exception => msg 121 | describe "Exception: #{msg}" do 122 | it { should be_nil } 123 | end 124 | end 125 | 126 | end 127 | -------------------------------------------------------------------------------- /controls/V-13672.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13672" do 30 | 31 | title "The private web server must use an approved DoD certificate 32 | validation process." 33 | 34 | desc "Without the use of a certificate validation process, the site is 35 | vulnerable to accepting certificates that have expired or have been revoked. 36 | This would allow unauthorized individuals access to the web server. This also 37 | defeats the purpose of the multi-factor authentication provided by the PKI 38 | process. " 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WG145" 43 | tag "gid": "V-13672" 44 | tag "rid": "SV-32954r2_rule" 45 | tag "stig_id": "WG145 A22" 46 | tag "nist": ["IA-5", "SC-12", "Rev_4"] 47 | 48 | tag "check": "The reviewer should query the ISSO, the SA, the web 49 | administrator, or developers as necessary to determine if the web server is 50 | configured to utilize an approved DoD certificate validation process. 51 | 52 | The web administrator should be questioned to determine if a validation 53 | process is being utilized on the web server. 54 | 55 | To validate this, the reviewer can ask the web administrator to describe the 56 | validation process being used. They should be able to identify either the use 57 | of certificate revocation lists (CRLs) or Online Certificate Status Protocol 58 | (OCSP). 59 | 60 | If the production web server is accessible, the SA or the web administrator 61 | should be able to demonstrate the validation of good certificates and the 62 | rejection of bad certificates. 63 | 64 | If CRLs are being used, the SA should be able to identify how often the CRL is 65 | updated and the location from which the CRL is downloaded. 66 | 67 | If the web administrator cannot identify the type of validation process being 68 | used, this is a finding." 69 | 70 | tag "fix": "Configure DoD Private Web Servers to conduct certificate 71 | revocation checking utilizing certificate revocation lists (CRLs) or Online 72 | Certificate Status Protocol (OCSP)." 73 | 74 | nginx_conf_file = input('nginx_conf_file') 75 | 76 | ocsp_server = input('ocsp_server') 77 | 78 | crl_udpate_frequency = input('crl_udpate_frequency') 79 | 80 | begin 81 | require 'time' 82 | 83 | #@todo complete ocsp verification test 84 | # oscp_status = command("openssl s_client -connect #{ocsp_server} -tls1 -tlsextdebug -status 2>&1 < /dev/null").stdout 85 | # 86 | # describe oscp_status do 87 | # it { should match %r(OCSP Response Status: successful)} 88 | # end 89 | 90 | def days_since_crl_update(cert) 91 | ((Time.new - Time.at(file(cert).mtime.to_f)) / 86400) 92 | end 93 | 94 | nginx_conf_handle = nginx_conf(nginx_conf_file) 95 | 96 | describe nginx_conf_handle do 97 | its ('params') { should_not be_empty } 98 | end 99 | 100 | nginx_conf_handle.http.entries.each do |http| 101 | describe http.params['ssl_crl'] do 102 | it { should_not be_nil } 103 | end 104 | http.params['ssl_crl'].each do |cert| 105 | describe file(cert.join) do 106 | it { should be_file } 107 | end 108 | describe days_since_crl_update(cert.join) do 109 | it { should cmp < crl_udpate_frequency } 110 | end 111 | end unless http.params['ssl_crl'].nil? 112 | end 113 | 114 | nginx_conf_handle.servers.entries.each do |server| 115 | server.params['ssl_crl'].each do |cert| 116 | describe file(cert.join) do 117 | it { should be_file } 118 | end 119 | describe days_since_crl_update(cert.join) do 120 | it { should cmp < crl_udpate_frequency } 121 | end 122 | end unless server.params['ssl_crl'].nil? 123 | end 124 | 125 | rescue Exception => msg 126 | describe "Exception: #{msg}" do 127 | it { should be_nil } 128 | end 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /controls/V-13620.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-13620" do 30 | 31 | title "A private web server’s list of CAs in a trust hierarchy must lead to 32 | an authorizedDoD PKI Root CA." 33 | 34 | desc "A PKI certificate is a digital identifier that establishes the identity 35 | of an individual or a platform. A server that has a certificate provides 36 | users with third-party confirmation of authenticity. Most web browsers 37 | perform server authentication automatically and the user is notified only if 38 | the authentication fails. The authentication process between the server and 39 | the client is performed using the SSL/TLS protocol. Digital certificates are 40 | authenticated, issued, and managed by a trusted Certificate Authority (CA). 41 | 42 | The use of a trusted certificate validation hierarchy is crucial to the 43 | ability to control access to a site’s server and to prevent unauthorized 44 | access. Only DoD-approved PKIs will be utilized. " 45 | 46 | impact 0.5 47 | tag "severity": "medium" 48 | tag "gtitle": "WG355" 49 | tag "gid": "V-13620" 50 | tag "rid": "SV-32936r1_rule" 51 | tag "stig_id": "WG355 A22" 52 | tag "nist": ["IA-5", "SC-12", "Rev_4"] 53 | 54 | tag "check": "Enter the following command: 55 | 56 | find / -name ssl.conf note the path of the file. 57 | 58 | grep ""ssl_client_certificate"" in conf files in context http,server 59 | 60 | Review the results to determine the path of the ssl_client_certificate. 61 | 62 | more /path/of/ca-bundle.crt 63 | 64 | Examine the contents of this file to determine if the trusted CAs are DoD 65 | approved. If the trusted CA that is used to authenticate users to the web site 66 | does not lead to an approved DoD CA, this is a finding. 67 | 68 | NOTE: There are non DoD roots that must be on the server in order for it to 69 | function. Some applications, such as anti-virus programs, require root CAs to 70 | function. DoD approved certificate can include the External Certificate 71 | Authorities (ECA), if approved by the DAA. The PKE InstallRoot 3.06 System 72 | Administrator Guide (SAG), dated 8 Jul 2008, contains a complete list of DoD, 73 | ECA, and IECA CAs." 74 | 75 | tag "fix": "Configure the web server’s trust store to trust only DoD- 76 | approved PKIs (e.g., DoD PKI, DoD ECA, and DoD-approved external partners)." 77 | 78 | nginx_conf_file = input('nginx_conf_file') 79 | 80 | dod_approved_pkis = input('dod_approved_pkis') 81 | 82 | begin 83 | nginx_conf_handle = nginx_conf(nginx_conf_file) 84 | 85 | describe nginx_conf_handle do 86 | its ('params') { should_not be_empty } 87 | end 88 | 89 | nginx_conf_handle.http.entries.each do |http| 90 | describe http.params['ssl_client_certificate'] do 91 | it { should_not be_nil } 92 | end 93 | http.params['ssl_client_certificate'].each do |cert| 94 | describe x509_certificate(cert.join) do 95 | it { should_not be_nil } 96 | 97 | its('subject.C') { should cmp 'US' } 98 | its('subject.O') { should cmp 'U.S. Government' } 99 | end 100 | describe x509_certificate(cert.join).subject.CN[0..2] do 101 | it { should be_in dod_approved_pkis } 102 | end 103 | end unless http.params['ssl_client_certificate'].nil? 104 | end 105 | 106 | #TODO: Update these per feedback from David 107 | nginx_conf_handle.servers.entries.each do |server| 108 | server.params['ssl_client_certificate'].each do |cert| 109 | describe x509_certificate(cert.join) do 110 | it { should_not be_nil } 111 | 112 | its('subject.C') { should cmp 'US' } 113 | its('subject.O') { should cmp 'U.S. Government' } 114 | end 115 | describe x509_certificate(cert.join).subject.CN[0..2] do 116 | it { should be_in dod_approved_pkis } 117 | end 118 | end unless server.params['ssl_client_certificate'].nil? 119 | end 120 | 121 | rescue Exception => msg 122 | describe "Exception: #{msg}" do 123 | it { should be_nil } 124 | end 125 | end 126 | end 127 | -------------------------------------------------------------------------------- /controls/V-6577.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-6577" do 30 | 31 | title "A web server must be segregated from other services." 32 | 33 | desc"The web server installation and configuration plan should not support 34 | the co-hosting of multiple services such as Domain Name Service (DNS), 35 | e-mail, databases, search engines, indexing, or streaming media on the same 36 | server that is providing the web publishing service.By separating these 37 | services additional defensive layers are established between the web service 38 | and the applicable application should either be compromised. 39 | 40 | Disallowed or restricted services in the context of this vulnerability applies 41 | to services that are not directly associated with the delivery of web content. 42 | An operating system that supports a web server will not provide other services 43 | (e.g., domain controller, e-mail server, database server, etc.). Only those 44 | services necessary to support the web server and its hosted sites are 45 | specifically allowed and may include, but are not limited to, operating 46 | system, logging, anti-virus, host intrusion detection, administrative 47 | maintenance, or network requirements. " 48 | 49 | impact 0.5 50 | tag "severity": "medium" 51 | tag "gtitle": "WG204" 52 | tag "gid": "V-6577" 53 | tag "rid": "SV-32950r1_rule" 54 | tag "stig_id": "WG204 A22" 55 | tag "nist": ["SC-2", "Rev_4"] 56 | 57 | tag "check": "Request a copy of and review the web server’s installation and 58 | configuration plan. Ensure that the server is in compliance with this plan. 59 | If the server is not in compliance with the plan, this is a finding. 60 | 61 | Query the SA to ascertain if and where the additional services are installed. 62 | 63 | Confirm that the additional service or application is not installed on the 64 | same partition as the operating systems root directory or the web document 65 | root. If it is, this is a finding." 66 | 67 | tag "fix": "Request a copy of and review the web server’s installation and 68 | configuration plan. Ensure that the server is in compliance with this plan. 69 | If the server is not in compliance with the plan, this is a finding. 70 | 71 | Query the SA to ascertain if and where the additional services are installed. 72 | 73 | Confirm that the additional service or application is not installed on the 74 | same partition as the operating systems root directory or the web document 75 | root. If it is, this is a finding." 76 | 77 | nginx_conf_file = input('nginx_conf_file') 78 | 79 | begin 80 | # collect root directores from nginx_conf 81 | webserver_roots = [] 82 | nginx_conf_handle = nginx_conf(nginx_conf_file) 83 | 84 | describe nginx_conf_handle do 85 | its ('params') { should_not be_empty } 86 | end 87 | 88 | nginx_conf_handle.http.entries.each do |http| 89 | webserver_roots.push(http.params['root']) unless http.params['root'].nil? 90 | end 91 | 92 | nginx_conf_handle.servers.entries.each do |server| 93 | webserver_roots.push(server.params['root']) unless server.params['root'].nil? 94 | end 95 | 96 | nginx_conf_handle.locations.entries.each do |location| 97 | webserver_roots.push(location.params['root']) unless location.params['root'].nil? 98 | end 99 | 100 | webserver_roots.flatten! 101 | webserver_roots.uniq! 102 | 103 | services = command('systemctl list-unit-files --type service').stdout.scan(/^(.+).service/).flatten 104 | 105 | services.each do |service| 106 | service_path = service(service).params['ExecStart'].scan(/path=(.+)[\s][;][\s]argv/).join unless service(service).params['ExecStart'].nil? 107 | describe service_path do 108 | it { should_not cmp '/' } 109 | end 110 | webserver_roots.each do |root| 111 | describe service_path do 112 | it { should_not match root } 113 | end 114 | end 115 | end 116 | 117 | if services.empty? 118 | describe "Skip Message" do 119 | skip "Skipped: no services found." 120 | end 121 | end 122 | rescue Exception => msg 123 | describe "Exception: #{msg}" do 124 | it { should be_nil } 125 | end 126 | end 127 | 128 | end 129 | -------------------------------------------------------------------------------- /controls/V-2256.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2256" do 30 | title "The access control files are owned by a privileged web server account." 31 | 32 | desc " This check verifies that the key web server system configuration files 33 | are owned by the SA or Web Manager controlled account. These same files 34 | which control the configuration of the web server, and thus its behavior, 35 | must also be accessible by the account which runs the web service. If these 36 | files are altered by a malicious user, the web server would no longer be 37 | under the control of its managers and owners; properties in the web server 38 | configuration could be altered to compromise the entire server platform." 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WG280" 43 | tag "gid": "V-2256" 44 | tag "rid": "SV-6880r1_rule" 45 | tag "stig_id": "WG280" 46 | tag "nist": ["AC-3", "Rev_4"] 47 | 48 | tag "check": "This check verifies that the SA or Web Manager controlled 49 | account owns the key web server files. These same files, which control the 50 | configuration of the web server, and thus its behavior, must also be 51 | accessible by the account that runs the web service process. 52 | 53 | If it exists, the following file need to be owned by a privileged account. 54 | 55 | .htaccess .htpasswd nginx.conf and its included configuration files 56 | 57 | Use the command find / -name nginx.conf to find the file. grep ""include"" on 58 | the nginx.conf file to identify included configuration files. Change to the 59 | directories that contain the nginx.conf and included configuration files. Use 60 | the command ls -l on these files to determine ownership of the file 61 | 62 | -The Web Manager or the SA should own all the system files and directories. 63 | -The configurable directories can be owned by the WebManager or equivalent 64 | -user. 65 | 66 | Permissions on these files should be 660 or more restrictive. 67 | 68 | If root or an authorized user does not own the web system files and the 69 | permission are not correct, this is a finding." 70 | 71 | tag "fix": "The site needs to ensure that the owner should be the non- 72 | privileged web server account or equivalent which runs the web service; 73 | however, the group permissions represent those of the user accessing the web 74 | site that must execute the directives in .htacces." 75 | 76 | nginx_conf_file = input('nginx_conf_file') 77 | 78 | nginx_owner = input('nginx_owner') 79 | 80 | sys_admin = input('sys_admin') 81 | 82 | nginx_group = input('nginx_group') 83 | 84 | sys_admin_group = input('sys_admin_group') 85 | 86 | begin 87 | 88 | authorized_sa_user_list = sys_admin.clone << nginx_owner 89 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 90 | 91 | access_control_files = [ '.htaccess', 92 | '.htpasswd'] 93 | 94 | nginx_conf_handle = nginx_conf(nginx_conf_file) 95 | nginx_conf_handle.params 96 | 97 | describe nginx_conf_handle do 98 | its ('params') { should_not be_empty } 99 | end 100 | 101 | access_control_files.each do |file| 102 | file_path = command("find / -name #{file}").stdout.chomp 103 | 104 | if file_path.empty? 105 | describe "Skip Message" do 106 | skip "Skipped: Access control file #{file} not found" 107 | end 108 | end 109 | 110 | file_path.split.each do |file| 111 | describe file(file) do 112 | its('owner') { should be_in authorized_sa_user_list } 113 | its('group') { should be_in authorized_sa_group_list } 114 | it { should_not be_executable } 115 | it { should_not be_readable.by('others') } 116 | it { should_not be_writable.by('others') } 117 | end 118 | end 119 | end 120 | 121 | nginx_conf_handle.contents.keys.each do |file| 122 | describe file(file) do 123 | its('owner') { should be_in authorized_sa_user_list } 124 | its('group') { should be_in authorized_sa_group_list } 125 | it { should_not be_executable } 126 | it { should_not be_readable.by('others') } 127 | it { should_not be_writable.by('others') } 128 | end 129 | end 130 | 131 | if nginx_conf_handle.contents.keys.empty? 132 | describe "Skip Message" do 133 | skip "Skipped: no conf files included." 134 | end 135 | end 136 | 137 | webserver_roots = [] 138 | 139 | nginx_conf_handle.http.entries.each do |http| 140 | webserver_roots.push(http.params['root']) unless http.params['root'].nil? 141 | end 142 | 143 | nginx_conf_handle.servers.entries.each do |server| 144 | webserver_roots.push(server.params['root']) unless server.params['root'].nil? 145 | end 146 | 147 | nginx_conf_handle.locations.entries.each do |location| 148 | webserver_roots.push(location.params['root']) unless location.params['root'].nil? 149 | end 150 | 151 | webserver_roots.flatten! 152 | webserver_roots.uniq! 153 | 154 | webserver_roots.each do |dir| 155 | if file(dir).directory? 156 | describe file(dir) do 157 | its('owner') { should be_in authorized_sa_user_list } 158 | its('group') { should be_in authorized_sa_group_list } 159 | its('sticky'){ should be true } 160 | end 161 | else 162 | describe "The setting \"#{dir}\" found in the configuration file is not a directory" do 163 | skip "The setting \"#{dir}\" found in the configuration file is not a directory" 164 | end 165 | end 166 | end 167 | 168 | if webserver_roots.empty? 169 | describe "Skip Message" do 170 | skip "Skipped: no web root directories found." 171 | end 172 | end 173 | 174 | rescue Exception => msg 175 | describe "Exception: #{msg}" do 176 | it { should be_nil } 177 | end 178 | end 179 | 180 | end 181 | -------------------------------------------------------------------------------- /controls/V-60707.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-60707" do 30 | title "The web server must remove all export ciphers from the cipher suite." 31 | 32 | desc "During the initial setup of a Transport Layer Security (TLS) connection 33 | to the web server, the client sends a list of supported cipher suites in 34 | order of preference.The web server will reply with the cipher suite it will 35 | use for communication from the client list.If an attacker can intercept the 36 | submission of cipher suites to the web server and place, as the preferred 37 | cipher suite, a weak export suite, the encryption used for the session 38 | becomes easy for the attacker to break, often within minutes to hours." 39 | 40 | impact 0.5 41 | tag "severity": "medium" 42 | tag "gtitle": "WG345" 43 | tag "gid": "V-60707" 44 | tag "rid": "SV-75159r1_rule" 45 | tag "stig_id": "WG345 A22" 46 | tag "nist": ["SC-8", "Rev_4"] 47 | 48 | tag "check": "Review the nginx.conf file and any separate included 49 | configuration files. 50 | 51 | Ensure the following entry exists: 52 | 53 | server { # enables server-side protection from BEAST attacks 54 | ssl_prefer_server_ciphers on; 55 | 56 | # Disabled insecure ciphers suite. For example, MD5, DES, RC4, PSK 57 | ssl_ciphers ""ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA- 58 | AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA- 59 | AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256 60 | :DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES- 61 | CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM- 62 | SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES- 63 | CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:@STRENGTH""; 64 | 65 | # -!MEDIUM:exclude encryption cipher suites using 128 bit encryption. LOW: 66 | # -!exclude encryption cipher suites using 64 or 56 bit encryption algorithms 67 | # -!EXPORT: exclude export encryption algorithms including 40 and 56 bits 68 | # -!algorithms. aNULL: exclude the cipher suites offering no authentication. 69 | # -!This is currently the anonymous DH algorithms and anonymous ECDH 70 | # -!algorithms. 71 | # These cipher suites are vulnerable to a ""man in the middle"" attack 72 | # and so their use is normally discouraged. 73 | # -!eNULL:exclude the ""NULL"" ciphers that is those offering no encryption. 74 | # Because these offer no encryption at all and are a security risk 75 | # they are disabled unless explicitly included. 76 | # @STRENGTH:sort the current cipher list in order of encryption algorithm key 77 | # @length. 78 | 79 | 80 | 81 | If the entry is not found, this is a finding." 82 | 83 | tag "fix": "Review the nginx.conf file and any separate included 84 | configuration files. 85 | 86 | Edit to ensure the following entry exists: 87 | 88 | server { 89 | # enables server-side protection from BEAST attacks 90 | ssl_prefer_server_ciphers on; 91 | 92 | # Disabled insecure ciphers suite. For example, MD5, DES, RC4, PSK 93 | ssl_ciphers ""ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA- 94 | AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA- 95 | AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256 96 | :DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES- 97 | CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM- 98 | SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES- 99 | CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:@STRENGTH""; 100 | 101 | # -!MEDIUM:exclude encryption cipher suites using 128 bit encryption. 102 | # -!LOW: exclude encryption cipher suites using 64 or 56 bit encryption algorithms 103 | # -!EXPORT: exclude export encryption algorithms including 40 and 56 bits algorithms. 104 | # -!aNULL: exclude the cipher suites offering no authentication. This is currently the anonymous DH algorithms and anonymous ECDH algorithms. 105 | # These cipher suites are vulnerable to a ""man in the middle"" attack and so their use is normally discouraged. 106 | # -!eNULL:exclude the ""NULL"" ciphers that is those offering no encryption. 107 | # Because these offer no encryption at all and are a security risk they are disabled unless explicitly included. 108 | # @STRENGTH:sort the current cipher list in order of encryption algorithm key length. 109 | } 110 | " 111 | 112 | nginx_conf_file = input('nginx_conf_file') 113 | 114 | begin 115 | disabled_ssl_ciphers = ['aNULL', 'eNULL', 'EXPORT', 'DES', 'MD5', 'PSK', 'RC4'] 116 | nginx_conf_handle = nginx_conf(nginx_conf_file) 117 | 118 | describe nginx_conf_handle do 119 | its ('params') { should_not be_empty } 120 | end 121 | 122 | nginx_conf_handle.http.entries.each do |http| 123 | describe http.params['ssl_prefer_server_ciphers'] do 124 | it { should cmp [['on']] } 125 | end 126 | describe http.params['ssl_ciphers'] do 127 | it { should_not be_nil } 128 | end 129 | 130 | unless http.params['ssl_ciphers'].nil? 131 | disabled_ssl_ciphers.each do |cipher| 132 | describe http.params['ssl_ciphers'].join do 133 | it { should match "!#{cipher}" } 134 | end 135 | end 136 | describe http.params['ssl_ciphers'].join do 137 | it { should match '@STRENGTH' } 138 | end 139 | end 140 | end 141 | 142 | nginx_conf_handle.servers.entries.each do |server| 143 | describe server.params['ssl_prefer_server_ciphers'] do 144 | it { should cmp [['on']] } 145 | end unless server.params['ssl_prefer_server_ciphers'].nil? 146 | 147 | unless server.params['ssl_ciphers'].nil? 148 | disabled_ssl_ciphers.each do |cipher| 149 | describe server.params['ssl_ciphers'].join do 150 | it { should match "!#{cipher}" } 151 | end 152 | end 153 | describe server.params['ssl_ciphers'].join do 154 | it { should match '@STRENGTH' } 155 | end 156 | end 157 | end 158 | 159 | rescue Exception => msg 160 | describe "Exception: #{msg}" do 161 | it { should be_nil } 162 | end 163 | end 164 | end 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx-baseline 2 | 3 | InSpec Profile to validate the secure configuration of nginx-baseline, adapted from [DISA's](https://iase.disa.mil/stigs/Pages/index.aspx) Apache 2.2 Server STIG checks. 4 | 5 | #### Container-Ready: Profile updated to adapt checks when the running against a containerized instance of nginx, based on reference container: https://ironbank.dso.mil/repomap/opensource/nginx 6 | 7 | ## Getting Started 8 | It is intended and recommended that InSpec run this profile from a __"runner"__ host (such as a DevOps orchestration server, an administrative management system, or a developer's workstation/laptop) against the target remotely over __ssh__. 9 | 10 | The latest versions and installation options are available at the [InSpec](http://inspec.io/) site. 11 | 12 | ## Tailoring to Your Environment 13 | The following inputs must be configured in an inputs ".yml" file for the profile to run correctly for your specific environment. More information about InSpec inputs can be found in the [InSpec Profile Documentation](https://www.inspec.io/docs/reference/profiles/). 14 | 15 | ```yaml 16 | # Path for the nginx configuration file 17 | nginx_conf_file: '' 18 | 19 | # Path to nginx backup repository 20 | nginx_backup_repository: '' 21 | 22 | # Subnet of the DMZ 23 | dmz_subnet: '' 24 | 25 | # Minimum Web vendor-supported version. 26 | nginx_min_ver: '' 27 | 28 | # Nginx owner 29 | nginx_owner: '' 30 | 31 | # The Nginx group 32 | nginx_group: '' 33 | 34 | # The system adminstrator 35 | sys_admin: [] 36 | 37 | # The system adminstrator group 38 | sys_admin_group: '' 39 | 40 | # List of non admin user accounts 41 | authorized_user_list: [] 42 | 43 | # Monitoring software for CGI or equivalent programs 44 | monitoring_software: [] 45 | 46 | # List of disallowed packages 47 | disallowed_packages_list: [] 48 | 49 | # disallowed_compiler_list 50 | disallowed_compiler_list: [] 51 | 52 | # DoD-approved PKIs (e.g., DoD PKI, DoD ECA, and DoD-approved external partners 53 | dod_approved_pkis: [] 54 | 55 | # File list of documentation, sample code, example applications, and tutorials 56 | nginx_disallowed_file_list: [] 57 | 58 | # File list of allowed documentation, sample code, example applications, and tutorials 59 | nginx_allowed_file_list: [] 60 | 61 | # List of authorized nginx modules 62 | nginx_authorized_modules: [] 63 | 64 | # List of unauthorized nginx modules 65 | nginx_unauthorized_modules: [] 66 | 67 | # Path for the nginx binary 68 | nginx_path: '' 69 | 70 | # domain and port to the OCSP Server 71 | ocsp_server: '' 72 | 73 | # crl_udpate_frequency 74 | crl_udpate_frequency: 7 75 | ``` 76 | 77 | # Running This Baseline Directly from Github 78 | 79 | Against a remote target using **_ssh_** with escalated privileges (if escalated privileges are needed) (i.e., InSpec installed on a separate runner host) 80 | ```bash 81 | inspec exec https://github.com/mitre/nginx-baseline/archive/master.tar.gz -t ssh://TARGET_USERNAME:TARGET_PASSWORD@TARGET_IP:TARGET_PORT --sudo --sudo-password= --input-file --reporter json: 82 | ``` 83 | 84 | Against a remote target using using **_ssh_** with a **_pem key_** with escalated privileges (if escalated privileges are needed) (i.e., InSpec installed on a separate runner host) 85 | ```bash 86 | inspec exec https://github.com/mitre/nginx-baseline/archive/master.tar.gz -t ssh://TARGET_USERNAME@TARGET_IP:TARGET_PORT --sudo -i --input-file --reporter json: 87 | ``` 88 | 89 | Against a **_locally_**-hosted instance with escalated privileges (if escalated privileges are needed) (i.e., InSpec installed on the target) 90 | ```bash 91 | sudo inspec exec https://github.com/mitre/nginx-baseline/archive/master.tar.gz --input-file --reporter json: 92 | ``` 93 | 94 | Against a **_docker-containerized_** instance: 95 | ```bash 96 | inspec exec https://github.com/mitre/nginx-baseline/archive/master.tar.gz -t docker://instance_id --input-file --reporter json: 97 | ``` 98 | 99 | ### Different Run Options 100 | 101 | [Full exec options](https://docs.chef.io/inspec/cli/#options-3) 102 | 103 | ## Running This Baseline from a local Archive copy 104 | 105 | If your runner is not always expected to have direct access to GitHub, use the following steps to create an archive bundle of this baseline and all of its dependent tests: 106 | 107 | (Git is required to clone the InSpec profile using the instructions below. Git can be downloaded from the [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) site.) 108 | 109 | When the __"runner"__ host uses this profile baseline for the first time, follow these steps: 110 | 111 | ``` 112 | mkdir profiles 113 | cd profiles 114 | git clone https://github.com/mitre/nginx-baseline 115 | inspec archive nginx-baseline 116 | inspec exec -t ssh://TARGET_USERNAME:TARGET_PASSWORD@TARGET_IP:TARGET_PORT --sudo --sudo-password= --input-file --reporter json: 117 | ``` 118 | _(execute using the same methods discussed above, substituting the name of the generated archive in place of "https://github.com/mitre/nginx-baseline/archive/master.tar.gz")_ 119 | 120 | For every successive run, follow these steps to always have the latest version of this baseline: 121 | 122 | ``` 123 | cd nginx-baseline 124 | git pull 125 | cd .. 126 | inspec archive nginx-baseline --overwrite 127 | inspec exec -t ssh://TARGET_USERNAME:TARGET_PASSWORD@TARGET_IP:TARGET_PORT --sudo --sudo-password= --input-file --reporter json: 128 | ``` 129 | _(execute using the same methods discussed above, substituting the name of the generated archive in place of "https://github.com/mitre/nginx-baseline/archive/master.tar.gz")_ 130 | 131 | ## Viewing the JSON Results 132 | 133 | The JSON results output file can be loaded into __[heimdall-lite](https://heimdall-lite.mitre.org/)__ for a user-interactive, graphical view of the InSpec results. 134 | 135 | The JSON InSpec results file may also be loaded into a __[full heimdall server](https://github.com/mitre/heimdall)__, allowing for additional functionality such as to store and compare multiple profile runs. 136 | 137 | ## Authors 138 | * Patrick Muench 139 | * Dominik Richter 140 | * Christoph Hartmann 141 | * Rony Xavier - [rx294](https://github.com/rx294) 142 | * Aaron Lippold 143 | 144 | ## Special Thanks 145 | * Mohamed El-Sharkawi - [HackerShark](https://github.com/HackerShark) 146 | * Shivani Karikar - [karikarshivani](https://github.com/karikarshivani) 147 | 148 | ## NOTICE 149 | 150 | © 2018-2020 The MITRE Corporation. 151 | 152 | Approved for Public Release; Distribution Unlimited. Case Number 18-3678. 153 | 154 | ## NOTICE 155 | 156 | MITRE hereby grants express written permission to use, reproduce, distribute, modify, and otherwise leverage this software to the extent permitted by the licensed terms provided in the LICENSE.md file included with this project. 157 | 158 | ## NOTICE 159 | 160 | This software was produced for the U. S. Government under Contract Number HHSM-500-2012-00008I, and is subject to Federal Acquisition Regulation Clause 52.227-14, Rights in Data-General. 161 | 162 | No other use other than that granted to the U. S. Government, or to those acting on behalf of the U. S. Government under that Clause is authorized without the express written permission of The MITRE Corporation. 163 | 164 | For further information, please contact The MITRE Corporation, Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539, (703) 983-6000. 165 | 166 | ## NOTICE 167 | 168 | DISA STIGs are published by DISA IASE, see: https://iase.disa.mil/Pages/privacy_policy.aspx 169 | -------------------------------------------------------------------------------- /controls/V-2259.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | =begin 4 | ----------------- 5 | Benchmark: APACHE SERVER 2.2 for Unix 6 | Status: Accepted 7 | 8 | All directives specified in this STIG must be specifically set (i.e. the 9 | server is not allowed to revert to programmed defaults for these directives). 10 | Included files should be reviewed if they are used. Procedures for reviewing 11 | included files are included in the overview document. The use of .htaccess 12 | files are not authorized for use according to the STIG. However, if they are 13 | used, there are procedures for reviewing them in the overview document. The 14 | Web Policy STIG should be used in addition to the Apache Site and Server STIGs 15 | in order to do a comprehensive web server review. 16 | 17 | Release Date: 2015-08-28 18 | Version: 1 19 | Publisher: DISA 20 | Source: STIG.DOD.MIL 21 | uri: http://iase.disa.mil 22 | ----------------- 23 | =end 24 | 25 | only_if do 26 | package('nginx').installed? || command('nginx').exist? 27 | end 28 | 29 | control "V-2259" do 30 | 31 | title "Web server system files must conform to minimum file permission 32 | requirements." 33 | 34 | desc "This check verifies that the key web server system configuration files 35 | are owned by the SA or the web administrator controlled account. These same 36 | files that control the configuration of the web server, and thus its 37 | behavior, must also be accessible by the account that runs the web service. 38 | If these files are altered by a malicious user, the web server would no 39 | longer be under the control of its managers and owners; properties in the 40 | web server configuration could be altered to compromise the entire server 41 | platform." 42 | 43 | impact 0.5 44 | tag "severity": "medium" 45 | tag "gtitle": "WG300" 46 | tag "gid": "V-2259" 47 | tag "rid": "SV-32938r1_rule" 48 | tag "stig_id": "WG300 A22" 49 | tag "nist": ["AC-3", "AC-6", "Rev_4"] 50 | 51 | tag "check": "Nginx directory and file permissions and ownership should be 52 | set per the following table.. The installation directories may vary from one 53 | installation to the next.If used, the WebAmins group should contain only 54 | accounts of persons authorized to manage the web server configuration, 55 | otherwise the root group should own all Nginx files and directories. 56 | 57 | If the files and directories are not set to the following permissions or more 58 | restrictive, this is a finding. 59 | 60 | grep for the ""root"" directive on the nginx.conf file and any separate 61 | included configuration files to find the Nginx root directory 62 | 63 | /usr/sbin/nginx root WebAdmin 550/550 64 | /etc/nginx/ root WebAdmin 770/660 65 | /etc/nginx/conf.d root WebAdmin 770/660 66 | /etc/nginx/modules root WebAdmin 770/660 67 | /usr/share/nginx/html root WebAdmin 775/664 68 | /var/log/nginx root WebAdmin 750/640 69 | 70 | NOTE: The permissions are noted as directories / files" 71 | 72 | tag "fix": "Use the chmod command to set permissions on the web server 73 | system directories and files as follows. 74 | 75 | /usr/sbin/nginx root WebAdmin 550/550 76 | /etc/nginx/ root WebAdmin 770/660 77 | /etc/nginx/conf.d root WebAdmin 770/660 78 | /etc/nginx/modules root WebAdmin 770/660 79 | /usr/share/nginx/html root WebAdmin 775/664 80 | /var/log/nginx root WebAdmin 750/640 81 | " 82 | 83 | nginx_conf_file = input('nginx_conf_file') 84 | 85 | nginx_owner = input('nginx_owner') 86 | 87 | sys_admin = input('sys_admin') 88 | 89 | nginx_group = input('nginx_group') 90 | 91 | sys_admin_group = input('sys_admin_group') 92 | 93 | # TODO: should we consider the sticky bits on this? see previous commit 94 | begin 95 | authorized_sa_user_list = sys_admin.clone << nginx_owner 96 | authorized_sa_group_list = sys_admin_group.clone << nginx_group 97 | 98 | describe.one do 99 | describe file('/usr/sbin/nginx') do 100 | its('owner') { should be_in authorized_sa_user_list } 101 | its('group') { should be_in authorized_sa_group_list } 102 | it { should_not be_writable } 103 | it { should_not be_readable.by('others') } 104 | it { should_not be_executable.by('others') } 105 | end 106 | describe file('/usr/sbin/nginx') do 107 | it { should be_owned_by nginx_owner } 108 | its('group') { should cmp nginx_group } 109 | it { should_not be_writable } 110 | it { should_not be_readable.by('others') } 111 | it { should_not be_executable.by('others') } 112 | end 113 | end 114 | describe.one do 115 | describe file('/etc/nginx/') do 116 | its('owner') { should be_in authorized_sa_user_list } 117 | its('group') { should be_in authorized_sa_group_list } 118 | it { should_not be_readable.by('others') } 119 | it { should_not be_writable.by('others') } 120 | it { should_not be_executable.by('others') } 121 | end 122 | describe file('/etc/nginx/') do 123 | it { should be_owned_by nginx_owner } 124 | its('group') { should cmp nginx_group } 125 | it { should_not be_executable } 126 | it { should_not be_readable.by('others') } 127 | it { should_not be_writable.by('others') } 128 | end 129 | end 130 | describe.one do 131 | describe file('/etc/nginx/conf.d') do 132 | its('owner') { should be_in authorized_sa_user_list } 133 | its('group') { should be_in authorized_sa_group_list } 134 | it { should_not be_readable.by('others') } 135 | it { should_not be_writable.by('others') } 136 | it { should_not be_executable.by('others') } 137 | end 138 | describe file('/etc/nginx/conf.d') do 139 | it { should be_owned_by nginx_owner } 140 | its('group') { should cmp nginx_group } 141 | it { should_not be_executable } 142 | it { should_not be_readable.by('others') } 143 | it { should_not be_writable.by('others') } 144 | end 145 | end 146 | describe.one do 147 | describe file('/etc/nginx/modules') do 148 | its('owner') { should be_in authorized_sa_user_list } 149 | its('group') { should be_in authorized_sa_group_list } 150 | it { should_not be_readable.by('others') } 151 | it { should_not be_writable.by('others') } 152 | it { should_not be_executable.by('others') } 153 | end 154 | describe file('/etc/nginx/modules') do 155 | it { should be_owned_by nginx_owner } 156 | its('group') { should cmp nginx_group } 157 | it { should_not be_executable } 158 | it { should_not be_readable.by('others') } 159 | it { should_not be_writable.by('others') } 160 | end 161 | describe file('/etc/nginx/modules') do 162 | it { should_not exist } 163 | end 164 | end 165 | describe.one do 166 | describe file('/usr/share/nginx/html') do 167 | its('owner') { should be_in authorized_sa_user_list } 168 | its('group') { should be_in authorized_sa_group_list } 169 | it { should_not be_writable.by('others') } 170 | end 171 | describe file('/usr/share/nginx/html') do 172 | it { should be_owned_by nginx_owner } 173 | its('group') { should cmp nginx_group } 174 | it { should_not be_executable } 175 | it { should_not be_writable.by('others') } 176 | end 177 | end 178 | describe.one do 179 | describe file('/var/log/nginx') do 180 | its('owner') { should be_in authorized_sa_user_list } 181 | its('group') { should be_in authorized_sa_group_list } 182 | it { should_not be_writable.by('group') } 183 | it { should_not be_readable.by('others') } 184 | it { should_not be_writable.by('others') } 185 | it { should_not be_executable.by('others') } 186 | end 187 | describe file('/var/log/nginx') do 188 | it { should be_owned_by nginx_owner } 189 | its('group') { should cmp nginx_group } 190 | it { should_not be_executable } 191 | it { should_not be_writable.by('group') } 192 | it { should_not be_readable.by('others') } 193 | it { should_not be_writable.by('others') } 194 | end 195 | end 196 | 197 | rescue Exception => msg 198 | describe "Exception: #{msg}" do 199 | it { should be_nil } 200 | end 201 | end 202 | 203 | end 204 | --------------------------------------------------------------------------------