Challenge

A small web app sitting behind nginx, with the source meant to stay out of reach.

Solution

nginx and the upstream do not agree on how a request path normalizes, and that gap lets a crafted path slide past the location rules and serve files that were supposed to be private. The flag name says as much.

Reaching the Dockerfile is enough. The flag is baked straight into it as an environment variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
FROM node:20-bookworm-slim

RUN apt-get update \
    && apt-get install -y nginx tini \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY src ./src
COPY public ./public

COPY default.conf /etc/nginx/sites-available/default
COPY start.sh /start.sh

ENV FLAG="ictf{path_normalization_to_the_rescue}"

ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/start.sh"]

Flag

ictf{path_normalization_to_the_rescue}