services can lead to unauthorized access to containers or escalation of privilege inside of containers.
Double quote to prevent globbing and word splitting
Within the command, variable references and command substitutions go through word splitting and pathname expansion (globbing).
This causes issues if the variable contains whitespaces or shell pathname expansion (glob) characters like *.
Allowing shell scripts execution during package installation is security-sensitive
ncies, package managers like npm
will
automatically execute shell scripts distributed along with the source code.
Post-install scripts, for example, are a common way to execute malicious code
at install time whenever a package is compromised.
Exposing administration services is security-sensitive
services can lead to unauthorized access to containers or escalation of privilege inside of containers.
A port that is commonly used for administration services is marked as being open through the EXPOSE command. Administration services like SSH might contain vulnerabilities, hard-coded credentials, or other security issues that increase the attack surface of a Docker deployment. Even if the ports of the services do not get forwarded to the host system, by default they are reachable from other containers in the same network. A malicious actor that gets access to one container could use such services to escalate access and privileges.
Removing the EXPOSE command is not sufficient to be secure. The port is still open and the service accessible. To be secure, no administration services should be started. Instead, try to access the required information from the host system. For example, if the administration service is included to access logs or debug a service, you can do this from the host system instead. Docker allows you to read out any file that is inside of a container and to spawn a shell inside of a container if necessary.
Allowing downgrades to a clear-text protocol is security-sensitive
ot enforced here. As it is possible for the HTTP client to follow redirects, such redirects might lead to websites using HTTP.
As HTTP is a clear-text protocol, it is considered insecure. Due to its lack of encryption, attackers that are able to sniff traffic from the network can read, modify, or corrupt the transported content. Therefore, allowing redirects to HTTP can lead to several risks:
Exposure of sensitive data
Malware-infected software updates or installers
Corruption of critical information
Even in isolated networks, such as segmented cloud or offline environments, it is important to ensure the usage of HTTPS. If not, then insider threats with access to these environments might still be able to monitor or tamper with communications.
Running containers as a privileged user is security-sensitive
privileged user weakens their runtime security, allowing any user whose code runs on the container to perform administrative actions. + In Linux containers, the privileged user is usually named root. In Windows containers, the equivalent is ContainerAdministrator.
A malicious user can run code on a system either thanks to actions that could be deemed legitimate - depending on internal business logic or operational management shells - or thanks to malicious actions. For example, with arbitrary code execution after exploiting a service that the container hosts.
Suppose the container is not hardened to prevent using a shell, interpreter, or Linux capabilities. In this case, the malicious user can read and exfiltrate any file (including Docker volumes), open new network connections, install malicious software, or, worse, break out of the container’s isolation context by exploiting other components.
This means giving the possibility to attackers to steal important infrastructure files, intellectual property, or personal data.
Depending on the infrastructure’s resilience, attackers may then extend their attack to other services, such as Kubernetes clusters or cloud providers, in order to maximize their reach.
Cache should be cleaned after package installation
Docker images should only contain necessary data. The package index is optional for the correct working of the installed software. Storing an index also increases the size of the Docker image. It should be reduced to speed up deployments and reduce storage and bandwidth.
Package update should not be executed without installing it
Leaving unnecessary files in Docker image increases its size. The Docker images should be small and only contain necessary data. The cache index is obsolete after installation.
Permissions of sensitive mount points should be restrictive
Docker offers a feature to mount files and directories for specific RUN instructions when building Docker images. This feature can be used to provide secrets to commands that are executed during the build without baking them into the image. Additionally, it can be used to access SSH agents during the build.
The mode option is an octal value that allows you to specify the permissions for a particular file or directory. By default, on Docker, when mounting a secret, it is set to 0400.
For ssh, it is set by default to 0600:
The first digit 0 stands for special permissions (like setuid, setgid and sticky bit) and in this case means that no special permissions are set.
The following 6 (4+2 in octal format) means that the owner has read (4) and write (2) permissions
00 means that the group and others have no permissions.
If the others bit is set to a value other than 0 at build-time, any other process can access it when the RUN command is executed: the secrets are vulnerable to supply chain attacks that aim to siphon secrets from containers.
Disabling builder sandboxes is security-sensitive
oxes can lead to unauthorized access of the host system by malicious programs.
By default, programs executed by a RUN statement use only a subset of capabilities which are considered safe: this is called sandbox mode.
If you disable the sandbox with the —security=insecure option, the executed command can use the full set of Linux capabilities. This can lead to a container escape. For example, an attacker with the SYS_ADMIN capability is able to mount devices from the host system.
This vulnerability allows an attacker who controls the behavior of the ran command to access the host system, break out of the container and penetrate the infrastructure.
After a successful intrusion, the underlying systems are exposed to:
theft of intellectual property and/or personal data
extortion
denial of service
Allowing non-root users to modify resources copied to an image is security-sensitive
issions for a file or directory copied to the Docker image have been assigned to a user other than root.
Write permissions enable malicious actors, who have a foothold on the container, to tamper with the resource and thus potentially manipulate the container’s expected behavior. Manipulating files could disrupt services or aid in escalating privileges inside the container.
This also breaches the container immutability principle as it facilitates container changes during its life. Immutability, a container best practice, allows for a more reliable and reproducible behavior of Docker containers.
If a user is given ownership on a file but no write permissions, the user can still modify it by using his ownership to change the file permissions first. This is why both ownership and write permissions should be avoided.
WORKDIR instruction should be used instead of cd commands
In Dockerfile, instructions RUN, CMD, and ENTRYPOINT can contain long shell scripts chaining multiple commands, including the cd command for changing directories. Using WORKDIR instruction instead reduces the complexity of the above instructions and makes them easier to read, understand, troubleshoot, and maintain.
Using ENV or ARG to handle secrets is security-sensitive
o handle secrets can lead to sensitive information being disclosed to an inappropriate sphere.
The ARG and ENV instructions in a Dockerfile are used to configure the image build and the container environment respectively. Both can be used at image build time, during the execution of commands in the container, and ENV can also be used at runtime.
In most cases, build-time and environment variables are used to propagate configuration items from the host to the image or container. A typical example for an environmental variable is the PATH variable, used to configure where system executables are searched for.
Using ARG and ENV to propagate configuration entries that contain secrets causes a security risk. Indeed, in most cases, artifacts of those values are kept in the final image. The secret information leak can happen either in the container environment itself, the image metadata or the build environment logs.
The concrete impact of such an issue highly depends on the secret’s purpose and the exposure sphere:
Financial impact if a paid service API key is disclosed and used.
Application compromise if an application’s secret, like a session signing key, is disclosed.
Infrastructure component takeover, if a system secret, like a remote access key, is leaked.
Deprecated instructions should not be used
Languages and technologies evolve, which leads to deprecation of some features. At some day they may be removed. It is important to use up-to-date constructs to avoid issues by migration to newer version of technology.
Consent flag should be set to avoid manual input
Suppose a package manager invocation is part of a script that is executed automatically, and non-interactive mode is not enabled. Then, execution is aborted because there is no confirming manual input. As a result, instructions, such as installation or update of packages, cannot be performed in an automated way. This applies, among others, to the package manager used in Debian-based systems, Advanced Package Tool (APT).
A space before the equal sign in key-value pair may lead to unintended behavior
A few Docker instructions (like ARG, ENV, LABEL) may contain key-value pairs in form of <key>=<value>. The equal sign should not be followed by a space. The space before the equal sign may lead to unintended behavior. This is critical, especially for multiple key-value pairs, e.g. key1 = value1 key2 = value2, will lead to the key key1 with the value = value1 key2 = value2. In most cases it is unintended.
Instructions should be upper case
While Dockerfile instructions are not case-sensitive, adhering to uppercase conventions for instructions helps enhance clarity and collaboration within development teams. This ensures that instructions are more easily distinguishable from arguments and contributes to effective collaboration.
Pulling an image based on its digest is security-sensitive
t uniquely and immutably identifies a container image. A tag, on the other hand, is a mutable reference to a container image.
This tag can be updated to point to another version of the container at any point in time. In general, the use of image digests instead of tags is intended to keep determinism stable within a system or infrastructure for reliability reasons.
The problem is that pulling such an image prevents the resulting container from being updated or patched in order to remove vulnerabilities or significant bugs.
Using remote artifacts without authenticity and integrity checks is security-sensitive
without authenticity and integrity checks can lead to the unexpected installation of malicious software in the built container image.
In the build environment, where Dockerfiles are compiled into container images, malicious code could gain access to sensitive data, such as build secrets or source code, and durably poison the resulting image.
In the runtime environments where the container images are executed, malicious code could access and modify all runtime data and use the container as a pivot to attack the surrounding network environment.
By ensuring that a remote artifact is exactly what it is supposed to be before it is used, the environment is protected from unexpected changes before or after it is downloaded. That is to say if it has been replaced by malware:
on the website where it is published.
in the environment where it is used.
Important note: HTTPS protects data in transit from one host to another. It provides authenticity and integrity checks for the network stream, not for the downloaded artifact itself.
Access variable which is not available in the current scope
The variables defined by ARG instruction have a scope from the definition to the end of the build stage where it was defined. If it was defined in the beginning of the Dockerfile (outside of any build stage), then its scope is restricted to only FROM instructions. Outside of their scope, variables will be resolved to empty string which may lead to unintended behaviour.
Dockerfile should only have one ENTRYPOINT and CMD instruction
Multiple ENTRYPOINT or CMD instructions in a file can lead to confusion as we may think they are all applied. This is not the case, as only the last one is applied.
Automatically installing recommended packages is security-sensitive
packages automatically can lead to vulnerabilities in the Docker image.
Potentially unnecessary packages are installed via a known Debian package manager. These packages will increase the attack surface of the created container as they might contain unidentified vulnerabilities or malicious code. Those packages could be used as part of a broader supply chain attack. In general, the more packages are installed in a container, the weaker its security posture is. Depending on the introduced vulnerabilities, a malicious actor accessing such a container could use these for privilege escalation. Removing unused packages can also significantly reduce your Docker image size.
To be secure, remove unused packages where possible and ensure images are subject to routine vulnerability scans.
Expanded filenames should not become options
Within the command, arguments and filenames as options are passed as strings. Programs may misinterpret files as arguments if the file name starts with a single or double dash. When filenames are specified using glob, files whose names begin with a dash are not included in the scope. For example, if a file is named “-f” and passed as an argument to a command such as “rm”, it may be interpreted as a command line option instead of a file, causing unexpected behaviour. This issue affects all instructions processing shell commands.
Environment variables should not be unset on a different layer than they were set
The environment variables often contain secrets, tokens, and other sensitive information. They are present in the containers and could be dumped anytime. Calling unset doesn’t prevent this information from being hidden for other commands.
Recursively copying context directories is security-sensitive
image from a Dockerfile, a context directory is used and sent to the Docker daemon before the actual build starts. This context directory usually contains the Dockerfile itself, along with all the files that will be necessary for the build to succeed. This generally includes:
the source code of applications to set up in the container.
configuration files for other software components.
other necessary packages or components.
The COPY and ADD directives in the Dockerfiles are then used to actually copy content from the context directory to the image file system.
When COPY or ADD are used to recursively copy entire top-level directories or multiple items whose names are determined at build-time, unexpected files might get copied to the image filesystem. It could affect their confidentiality.
Using host operating system namespaces is security-sensitive
stem namespaces can lead to compromise of the host system. Opening network services of the local host system to the container creates a new attack surface for attackers.
Host network sharing could provide a significant performance advantage for workloads that require critical network performance. However, the successful exploitation of this attack vector could have a catastrophic impact on confidentiality within the host.
Delivering code in production with debug features activated is security-sensitive
Development tools and frameworks usually have options to make debugging easier for developers. Although these features are useful during development, they should never be enabled for applications deployed in production. Debug instructions or error messages can leak detailed information about the system, like the application’s path or file names.
Using clear-text protocols is security-sensitive
Clear-text protocols such as `ftp, telnet, or http lack encryption of transported data, as well as the capability to build an authenticated connection. It means that an attacker able to sniff traffic from the network can read, modify, or corrupt the transported content. These protocols are not secure as they expose applications to an extensive range of risks:
sensitive data exposure
traffic redirected to a malicious endpoint
malware-infected software update or installer
execution of client-side code
corruption of critical information
Even in the context of isolated networks like offline environments or segmented cloud environments, the insider threat exists. Thus, attacks involving communications being sniffed or tampered with can still happen.
For example, attackers could successfully compromise prior security layers by:
bypassing isolation mechanisms
compromising a component of the network
getting the credentials of an internal IAM account (either from a service account or an actual person)
In such cases, encrypting communications would decrease the chances of attackers to successfully leak data or steal credentials from other network components. By layering various security practices (segmentation and encryption, for example), the application will follow the defense-in-depth principle.
Note that using the http` protocol is being deprecated by major web browsers.
In the past, it has led to the following vulnerabilities:
Track uses of TODO tags
Setting loose POSIX file permissions is security-sensitive
In Unix file system permissions, the “others
” category refers to all
users except the owner of the file system resource and the members of the group
assigned to this resource.
Granting permissions to this category can lead to unintended access to files or directories that could allow attackers to obtain sensitive information, disrupt services or elevate privileges.
Using weak hashing algorithms is security-sensitive
Cryptographic hash algorithms such as MD2, MD4, MD5, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160 and SHA-1 are no longer considered secure, because it is possible to have collisions
(little computational effort is enough to find two or more different inputs that produce the same hash).