Suppose I am a dev and want to harden my web application environment. If my application does not make use of binaries like sh, ls, find, echo etc. should I just remove them from my image?
It might improve security but it's a very strange way of doing things.
What you are suggesting is to start with an image with "unnecessary" software installed and remove some of the stuff you don't need (bash, echo,...). This does not only risk breaking things, it also increases container size because the base layer with the unnecessary tools is still shipped.
A better approach is to start with a minimal image. Not alpine, that's still a full os. The more minimal approach is to use a base image that only contains the required language runtime like googles distoless images https://github.com/GoogleCloudPlatform/distroless . For static binaries, you can even start with an empty image.
That way you get an image that is as small as possible and does not provide the "attack surface" of bash.
You shouldn't remove bash or any executables that exists in the base image. A lot of executables are interlinked, and removing one executables may cause other apparently unrelated executables to fail to run correctly on some corner case. Instead you should use a base image that doesn't contain anything that you don't really need. alpine makes a great minimalist base image, weighing at 5MB, it contains just the most useful stuffs and nothing more.
If you know that your application doesn't use any external binary or shell, or if you know exactly which external binary you will be needing, you may want to consider compiling into a statically linked binary and then basing your container of the scratch image.
The answer is: it depends. Removing bash and all other interpreters reduces the attack surface of the container. The same applies to e.g. compilers, nc, wget, ...
The real question is: is this the best way to spend the money?
- Testing and production images probably diverge
- creating a patched container gets (slightly) harder
- Troubleshooting gets way more difficult
A better way to spend the money might be to harden the application itself by investing in other security measures like regular penetration tests, security monitoring, automated patching, ...
It depends to what extent you are following the Container philosophy. If you don't need it, you should avoid using anything not strictly necessary. You should define and refer to everything you need in the Dockerfile, and the entrypoint of a web server should be the apache (or any other web server you are using) binary itself. But more importantly, take into account that many binaries (as ls, find, etc.) are linked to the base image layer of the container, so you should leave them untouched, or make a more custom base image. Any ubuntu, debian, etc., base image will have this binaries, and tampering the base image is not recommended.
It would be a much more secure approach to define an isolated network for databases, or other backend entities, leaving just the port you are exposing to the world as attack surface.
Obviously, hardening the machine you into what you are containerizing your services is critical.
I would not worry much because of these binaries. I would worry much more about securing the access to the Docker commands to avoid invoking these binaries during the container runtime.
I wanted to add some more resources to the answers so far. In general, it's considered best practice for an OS container image to be as basic as it can possibly be. Removing unneeded shells is just a start. There are multiple hardened OS images out there specifically for a secure container deployment, but there are also many other things to consider, like lowest possible privileges, Read-Only file systems, and much more.
This page: https://access.redhat.com/articles/2958461 Has multiple links to many good articles. Dan Walsh's Red-Hat blog is also very good for deep level information. https://rhelblog.redhat.com/author/dan-walsh/
This page has lots more that is directly helpful to this question in the sense of practices even more useful than removing un-needed applications: https://access.redhat.com/blogs/766093/posts/2334141
And here is a hardened OS for containers. Full disclosure: I haven't used it though, our Systems Engineering worked with my security team to build a gold image for us on our cloud deployment. It's more of an example: https://coreos.com/os/docs/latest/