Cyber Security

The different flavours of Docker image security

This article focuses on outlining the difference between some of the common image security scanners out there, what they are scanning for, and what the major differences are.

What is happening?

Container security is on everyone’s lips. After creating the CoGuard-CLI, we were asked a lot about what it does, how it does it, and how it compares to or complements other tools. This article focuses on outlining the difference between some of the common image security scanners out there, what they are scanning for, and what the major differences are.

We have selected the following free or open source tools for this article:

Performing a scan comparison and analysis

To illustrate what each tool finds, we will be scanning the WordPress image.

Snyk

The command run on Snyk was

snyk container test wordpress

Here is an excerpt of Snyk's findings

Trivy

The command used was

docker run aquasec/trivy image wordpress

The output is well organized in a table, and looks like the following


wordpress (debian 11.3)
=======================
Total: 568 (UNKNOWN: 6, LOW: 336, MEDIUM: 113, HIGH: 93, CRITICAL: 20)

┌───────────────────────────┬──────────────────┬──────────┬───────────────────────┬───────────────────────┬──────────────────────────────────────────────────────────────┐
│          Library          │  Vulnerability   │ Severity │   Installed Version   │     Fixed Version     │                            Title                             │
├───────────────────────────┼──────────────────┼──────────┼───────────────────────┼───────────────────────┼──────────────────────────────────────────────────────────────┤
│ apache2                   │ CVE-2022-28615   │ CRITICAL │ 2.4.53-1~deb11u1      │ 2.4.54-1~deb11u1      │ httpd: out-of-bounds read in ap_strcmp_match()               │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-28615                   │
├───────────────────────────┼──────────────────┼──────────┼───────────────────────┼───────────────────────┼──────────────────────────────────────────────────────────────┤
│ apache2                   │ CVE-2022-31813   │ CRITICAL │ 2.4.53-1~deb11u1      │ 2.4.54-1~deb11u1      │ httpd: mod_proxy: X-Forwarded-For dropped by hop-by-hop      │
│                           │                  │          │                       │                       │ mechanism                                                    │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-31813                   │
├───────────────────────────┼──────────────────┼──────────┼───────────────────────┼───────────────────────┼──────────────────────────────────────────────────────────────┤
│ apache2                   │ CVE-2022-26377   │ HIGH     │ 2.4.53-1~deb11u1      │ 2.4.54-1~deb11u1      │ httpd: mod_proxy_ajp: Possible request smuggling             │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-26377                   │
│                           ├──────────────────┤          │                       │                       ├──────────────────────────────────────────────────────────────┤
│                           │ CVE-2022-29404   │          │                       │                       │ httpd: mod_lua: DoS in r:parsebody                           │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-29404                   │
│                           ├──────────────────┤          │                       │                       ├──────────────────────────────────────────────────────────────┤
│                           │ CVE-2022-30522   │          │                       │                       │ httpd: mod_sed: DoS vulnerability                            │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-30522                   │
│                           ├──────────────────┤          │                       │                       ├──────────────────────────────────────────────────────────────┤
│                           │ CVE-2022-30556   │          │                       │                       │ httpd: mod_lua: Information disclosure with websockets       │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-30556                   │
│                           ├──────────────────┼──────────┤                       │                       ├──────────────────────────────────────────────────────────────┤
│                           │ CVE-2022-28614   │ MEDIUM   │                       │                       │ httpd: out-of-bounds read via ap_rwrite()                    │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2022-28614                   │
├───────────────────────────┼──────────────────┼──────────┼───────────────────────┼───────────────────────┼──────────────────────────────────────────────────────────────┤
│ apache2                   │ CVE-2001-1534    │ LOW      │ 2.4.53-1~deb11u1      │                       │ mod_usertrack in Apache 1.3.11 through 1.3.20 generates      │
│                           │                  │          │                       │                       │ session ID's u ...                                           │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2001-1534                    │
│                           ├──────────────────┤          │                       ├───────────────────────┼──────────────────────────────────────────────────────────────┤
│                           │ CVE-2003-1307    │          │                       │                       │ ** DISPUTED ** The mod_php module for the Apache HTTP        │
│                           │                  │          │                       │                       │ Server...                                                    │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2003-1307                    │
│                           ├──────────────────┤          │                       ├───────────────────────┼──────────────────────────────────────────────────────────────┤
│                           │ CVE-2003-1580    │          │                       │                       │ The Apache HTTP Server 2.0.44, when DNS resolution is        │
│                           │                  │          │                       │                       │ enabled for clie...                                          │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2003-1580                    │
│                           ├──────────────────┤          │                       ├───────────────────────┼──────────────────────────────────────────────────────────────┤
│                           │ CVE-2003-1581    │          │                       │                       │ httpd: Injection of arbitrary text into log files when DNS   │
│                           │                  │          │                       │                       │ resolution is...                                             │
│                           │                  │          │                       │                       │ https://avd.aquasec.com/nvd/cve-2003-1581                    │
├───────────────────────────┼──────────────────┼──────────┼───────────────────────┼───────────────────────┼──────────────────────────────────────────────────────────────┤

We truncated the other outputs.

Interpretation

Trivy appears to capture installed libraries on the image, and maps them to known items in the CVE database.

Grype

The command to run Grype on the wordpress image was


docker run anchore/grype wordpress 

The output is also organized in a table.


NAME                       INSTALLED              FIXED-IN               TYPE  VULNERABILITY     SEVERITY   
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-29404    High        
apache2                    2.4.53-1~deb11u1                              deb   CVE-2001-1534     Negligible  
apache2                    2.4.53-1~deb11u1                              deb   CVE-2003-1580     Negligible  
apache2                    2.4.53-1~deb11u1                              deb   CVE-2003-1581     Negligible  
apache2                    2.4.53-1~deb11u1                              deb   CVE-2007-3303     Negligible  
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-31813    Critical    
apache2                    2.4.53-1~deb11u1                              deb   CVE-2007-1743     Negligible  
apache2                    2.4.53-1~deb11u1                              deb   CVE-2008-0456     Negligible  
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-30522    High        
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-28615    Critical    
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-26377    High        
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-28614    Medium      
apache2                    2.4.53-1~deb11u1                              deb   CVE-2003-1307     Negligible  
apache2                    2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-30556    High        
apache2                    2.4.53-1~deb11u1                              deb   CVE-2007-0086     Negligible  
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2007-3303     Negligible  
apache2-bin                2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-30522    High        
apache2-bin                2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-30556    High        
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2008-0456     Negligible  
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2007-0086     Negligible  
apache2-bin                2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-28614    Medium      
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2003-1307     Negligible  
apache2-bin                2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-29404    High        
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2003-1580     Negligible  
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2001-1534     Negligible  
apache2-bin                2.4.53-1~deb11u1       2.4.54-1~deb11u1       deb   CVE-2022-31813    Critical    
apache2-bin                2.4.53-1~deb11u1                              deb   CVE-2003-1581     Negligible

The output is being truncated for this article.

Interpretation

Grype seems to do the same thing as Trivy, namely capture installed libraries on the image, and map them to known items in the CVE database. The number of issues found are also almost identical.

CoGuard

The command to run CoGuard was


coguard docker-image wordpress


The output captured was:


Scan result_jsons: 20 checks failed, 13 High/5 Medium/2 Low
 X Severity 5: apache_deny_root_directory
Documentation: Ensure that the root directory access is specifically denied. Otherwise, it is possible that an attacker can
               gain access to files through root directory mapping. Remediation: Create a  Require all denied
                directive Source:https://httpd.apache.org/docs/2.4/mod/core.html#directory
 X Severity 5: apache_root_directory_options_none
Documentation: With the options directive, one can allow scripts to be executed, follow symlinks, do content negotiation, etc.
               In the root directory, the Options directive should always be set to None. Remediation: Create a 
               Options None  directive Source:https://httpd.apache.org/docs/2.4/mod/core.html#directory
 X Severity 5: apache_enable_ssl
Documentation: We should never have any communication done using unencrypted channels. This check tests if the mod_ssl.so
               module is loaded and that SSLProtocol is set, together with a proper SSL certificate file and a key file.
               Remediation: Load the `mod_ssl.so` modules, and set the `SSLCertificateFile` and `SSLCertificateKeyFile` keys to
               the paths of the respective certificate and key file.
 X Severity 5: apache_load_logging_module
Documentation: Logging is important to monitor the activity on the server and detect anomalies. Remediation: Load the module
               `mod_log_config` module in the configuration Source: https://httpd.apache.org/docs/2.4/mod/mod_log_config.html
 X Severity 5: apache_load_security_module
Documentation: ModSecurity is a module that acts as a web application firewall for monitoring, logging, and access control. It
               should always be loaded and configured Remediation steps: Load the module by adding `LoadModule security2_module
               modules/mod_security2.so` Source: https://www.modsecurity.org/download.html
 X Severity 4: dockerfile_last_user_should_be_non_root
Documentation: When creating a docker container, it is possible to set the user who is actually running the application and any
               command on the container. It is important to specifically use the `USER` directive in any Dockerfile to ensure
               that the user is not root and has unnecessary privileges.  Remediation: Have at least one `USER` directive in
               your Dockerfile, and the last user directive should not reference the root user or root group.  Source:
               https://docs.docker.com/engine/reference/builder/#user
 X Severity 4: apache_content_security_policy_set
Documentation: One of the most effective techniques to prevent cross site scripting attacks is to control where the content is
               served from. This can be achieved by setting specific policies in the `Content-Security-Policy` header.
               Remediation: The value of that header is completely up to the specific web service. In order to pass this check,
               the `httpd.conf` needs to contain a line of the form `Header always append Content-Security-Policy  ` Source: https://wiki.owasp.org/index.php/OWASP_Secure_Headers_Project#csp
 X Severity 4: apache_hsts_header_set
Documentation: There is an HTTP response header that instructs the browser to only communicate with the website using HTTPS,
               the so called HSTS header. This one should be enabled.   Remediation: Apache can automatically set this header
               for every response by setting `Header always append  Strict-Transport-Security "max-age:;
               includeSubdomains"`` Source: https://wiki.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts
 X Severity 4: apache_run_as_separate_user
Documentation: Apache should not be run as root. In fact, it is best to configure the user it is run as.  Remediation: Set the
               `User` and `Group` directives to any user but `root`. Source:
               https://httpd.apache.org/docs/2.4/mod/mod_unixd.html
 X Severity 4: apache_turn_trace_off
Documentation: It is considered best practice to have tracing disabled for Apache HTTP servers. Remediation: Set `TraceEnable`
               to `off` in your configuration Source: https://owasp.org/www-community/attacks/Cross_Site_Tracing
 X Severity 4: apache_x_content_type_header_set
Documentation: There is an HTTP response header that disables the functionality of the browser to detect a content type
               automatically, which poses an attack vector.   Remediation: Apache can automatically set this header for every
               response by setting `Header always append X-Content-Type-Options "nosniff" ` Source:
               https://wiki.owasp.org/index.php/OWASP_Secure_Headers_Project#xcto
 X Severity 4: apache_x_frame_options_same_origin
Documentation: There is an HTTP response header that makes it harder to do clickjacking. Apache can automatically set this
               header for every response by setting `Header always append X-Frame-Options SAMEORIGIN` Source:
               https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
 X Severity 4: apache_x_xss_protection_set
Documentation: There is an HTTP response header that stops pages from loading in modern browsers when reflected cross site
               scripting attacks are detected.   Remediation: Apache can automatically set this header for every response by
               setting `Header always append X-XSS-Protection "1; mode=block"` Source:
               https://wiki.owasp.org/index.php/OWASP_Secure_Headers_Project#xxxsp
 X Severity 3: apache_no_directory_listing
Documentation: When a user puts in a URL to a directory, the contents should not be listed. This may reveal files which the
               hoster does not want the user to know about. Remediation: In each  directive, set Options to None or
               -Indexes. Source: http://httpd.apache.org/docs/current/mod/core.html#directory
 X Severity 3: apache_deny_anything_older_than_http_1_1
Documentation: Many malicious programs will try to send arbitrary requests to your Apache web server. It is important to only
               allow HTTP 1.1 requests, since support for older versions is obsolete. Remediation: Use the Rewrite engine
               module of Apache to filter out requests. Add the following lines: RewriteEngine On RewriteCond %{THE_REQUEST}
               !HTTP/1\.1$ RewriteRule .* - [F] Source:http://httpd.apache.org/docs/current/mod/mod_rewrite.html
 X Severity 3: apache_restrict_ssl_protocol
Documentation: SSL 2.0, 3.0, TLS 1, 1.1 have reportedly several crytographic flaws. Hence, only TLS 1.2 should be used
               Remediation: Set `SSLProtocol` to `-ALL +TLSv1.2`
 X Severity 3: apache_server_tokens_off
Documentation: Even when a user gets to an error page, there should never be more information than necessary displayed on the
               page. By not knowing the specific Apache HTTPd version, an attacker cannot match known issues to a certain
               attack. Remediation: Set `ServerTokens` to `Prod` or `ProductOnly` in your configuration. Source:
               https://httpd.apache.org/docs/2.4/mod/core.html#servertokens
 X Severity 3: dockerfile_create_volume_for_var_log
Documentation: In linux systems, important operating system logs are stored in the `/var/log` subfolder. This folder should
               always be made available to the host through a volume, so that log tracking and log analysis systems can capture
               them.   Remediation: In every Dockerfile, there should be a VOLUME directive which has `/var/log` as an
               argument.  Source: https://docs.docker.com/engine/reference/builder/
 X Severity 2: apache_set_directory_options_none
Documentation: It is recommended to keep the Options for  directives as restrictive as possible, and only set
               Options not to None if really intended Remediation: In every  directive, set `Options` to be `none`.
               Source: https://httpd.apache.org/docs/2.4/mod/core.html#directory
 X Severity 2: dockerfile_container_healthcheck_parameter
Documentation: Dockerfiles have an instruction called `HEALTHCHECK`. It enables a user to define a command to figure out if the
               program(s) running inside the container are working properly. It is generally advisable to have healthchecks in
               place to assist monitoring of running containers.  Remediation: Have at least one `HEALTHCHECK` instruction in
               your Dockerfile.  Source: https://docs.docker.com/engine/reference/builder/#healthcheck



Interpretation

CoGuard detected that Apache was installed on the system, and extracted the configuration file. Security and best practice recommendations were produced based on the contents of the found configuration file. In addition, it also checked the last Dockerfile used to create the image for common mistakes.

Summary

The following table summarizes the findings and differences between each of the scanners:


Trivy and Grype can be seen as equivalent tools, which are the best in class to identify and map installed software to CVEs.

Snyk has run its static analyzer against many major open source projects, and can produce the issues it found by version. The scanner keeps track of versions where potential issues are fixed.

CoGuard’s CLI is detecting configuration files inside the container, and scans them for security and best practice violations.

Summarizing: In order to get a full view on the security of your Docker image, you should use both Snyk and CoGuard, and also either Trivy or Grype, as the latter are equivalent.

Useful links

CoGuard's CLI:  https://github.com/coguardio/coguard-cli

Snyk: https://snyk.io/

Trivy: https://aquasecurity.github.io/trivy/v0.29.2/

Grype: https://github.com/anchore/grype


Written by
Albert Heinle

Static analysis
for config files

Automated tools for discovering, scanning and securing the configuration files for IaC, containers, applications and their interdependencies.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.