Skip to content

Dockerfile: "EXPOSE" parsing is too permissive #2173

@thaJeztah

Description

@thaJeztah

I noticed that dispatchExpose() is using nat.ParsePortSpecs() to parse exposed ports;

ps, _, err := nat.ParsePortSpecs(c.Ports)
if err != nil {
return err
}

Because of this, the EXPOSE instruction allows the same format(s) as are accepted by the -p option on docker run / docker create;

[<ip address>:][<host port | host port-range>:]<container port | container port-range>[/<proto>]

Thus, allowing, e.g.:

FROM busybox
EXPOSE 192.168.1.5:8080:80/tcp
EXPOSE 192.168.1.5:8081-8083:81/tcp
EXPOSE 192.168.1.5:8084-8086:84-86/tcp
EXPOSE 192.168.1.5::84-86/tcp
docker build -t foo .
docker inspect --format='{{json .Config.ExposedPorts}}' foo | jq .
{
  "80/tcp": {},
  "81/tcp": {},
  "84/tcp": {},
  "85/tcp": {},
  "86/tcp": {}
}

The documentation however, only documents (https://docs.docker.com/reference/dockerfile/#expose):

EXPOSE <port> [<port>/<protocol>...]

For example:

EXPOSE 80 81/tcp 81/udp
docker inspect --format='{{json .Config.ExposedPorts}}' foo | jq .
{
  "80/tcp": {},
  "81/tcp": {},
  "81/udp": {}
}

I'm not sure about the background for this; as far as I can tell, EXPOSE has never supported <ip address> nor <host port> (based on the first docs that were added for EXPOSE moby/moby#512)

I think we should update the parsing code to match the docs (possibly do a quick search if there's any Dockerfile on GitHub using the invalid format, but I don't think these exist https://grep.app/search?q=EXPOSE%20.%2A%5C%3A.%2A&regexp=true&filter[lang][0]=Dockerfile (only 3 matches)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions