Skip to content

Commit

Permalink
feat: documentation polish
Browse files Browse the repository at this point in the history
  • Loading branch information
bchmnn committed Aug 13, 2024
1 parent 9f26bad commit b0c722f
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 12 deletions.
Binary file modified documentation/documentation.pdf
Binary file not shown.
5 changes: 2 additions & 3 deletions documentation/tex/src/crc.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/service/backend/controller/repl.go b/service/backend/controller/repl.go
index 0b0f782..69f75be 100644
index 0b0f782..bd7e2e7 100644
--- a/service/backend/controller/repl.go
+++ b/service/backend/controller/repl.go
@@ -1,6 +1,8 @@
Expand All @@ -11,7 +11,7 @@ index 0b0f782..69f75be 100644
"fmt"
"net/http"
"replme/service"
@@ -44,8 +46,11 @@ func (repl *ReplController) Create(ctx *gin.Context) {
@@ -44,8 +46,10 @@ func (repl *ReplController) Create(ctx *gin.Context) {

util.SLogger.Debugf("[%-25s] Creating new REPL user", fmt.Sprintf("UN:%s..", createReplRequest.Username[:5]))

Expand All @@ -20,7 +20,6 @@ index 0b0f782..69f75be 100644
+ hasher := sha256.New224()
+ hasher.Write([]byte(createReplRequest.Username))
+ hash := hasher.Sum(nil)
+
+ name := hex.EncodeToString(hash)

util.SLogger.Debugf("[%-25s] Created new REPL user", fmt.Sprintf("UN:%s.. | NM:%s..", createReplRequest.Username[:5], name[:5]))
Expand Down
18 changes: 18 additions & 0 deletions documentation/tex/src/dir-structure.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
service/
backend/ - MAIN-BACKEND
controller/ - api controller for auth, devenvs, and repls
database/ - database init
model/ - database models
server/ - server and router
service/ - cleanup, docker interfacing, proxying, and repls
types/
util/
frontend/ - Next.js frontend
image/ - CHILD-BACKEND
controller/ - api controller for auth and terms
server/ - server and router
service/ - user management and terms management
types/
util/
nginx/ - reverse proxy config
postgres/ - database config
22 changes: 15 additions & 7 deletions documentation/tex/src/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
inputencoding=utf8/latin1,
backgroundcolor=\color{gray!10},
frame=single,
numbers=left,
numberstyle=\tiny,
}

Expand All @@ -39,6 +38,7 @@
morecomment=[f][\color{red}]{-},
morecomment=[f][\color{olive}]{+},
captionpos=b,
numbers=left,
}

\lstdefinestyle{go}{
Expand Down Expand Up @@ -70,6 +70,7 @@
breakatwhitespace=true,
basicstyle=\ttfamily,
captionpos=b,
numbers=left,
}

\lstdefinestyle{python}{
Expand All @@ -81,7 +82,8 @@
showstringspaces=false,
tabsize=4,
breaklines=true,
captionpos=b
captionpos=b,
numbers=left,
}

\lstdefinestyle{bash}{
Expand All @@ -93,7 +95,8 @@
showstringspaces=false,
tabsize=4,
breaklines=true,
captionpos=b
captionpos=b,
numbers=left,
}

\usepackage{hyperref}
Expand Down Expand Up @@ -161,6 +164,11 @@ \section{Overview}
To spawn a REPL or compile code in a DEVENV the MAIN-BACKEND interfaces with a docker-in-docker instance (DIND) to create Alpine Linux containers (hereafter ALPINEs). The IO of the command running on the aplines is proxied to the web client by the MAIN-BACKEND. \\

The ALPINEs themselves have another golang+gin backend running on them (hereafter CHILD-BACKEND). The MAIN-BACKEND interfaces with the CHILD-BACKEND to create/authenticate users and spawn commands on the ALPINEs.

\section{Directory Structure}

\lstinputlisting[]{src/dir-structure.txt}

\section{Vulnerability \#1 -- CRC}

\subsection{How it works}
Expand Down Expand Up @@ -357,15 +365,15 @@ \subsection{How it works}
\begin{center}
\robotomonoRegular{GET /api/devenv/<devenvuuid>/files/<filename>}
\end{center}
However, all \robotomonoRegular{/api/devenv/...} endpoints also accept a query parameter \robotomonoRegular{?uuid=<otheruuid>} which overloads the \robotomonoRegular{<devenvuuid>} when specified.
However, all \robotomonoRegular{/api/devenv/...} endpoints also accept a query parameter \robotomonoRegular{?uuid=<otheruuid>} which, when specified, overloads the \robotomonoRegular{<devenvuuid>}.
\lstinputlisting[caption=service/backend/server/router.go\ (lines\ 110-148), style=go, label={lst:devenv-uuid-snippet}]{src/devenv-uuid-snippet.go}
The extracted DEVENV and \robotomonoRegular{uuid} are saved in the current requests context. We can see, that \robotomonoRegular{id} is seemingly sanitized via \robotomonoRegular{util.ExtractUuid}. Instead of using the \robotomonoRegular{devenv} from the context (that definitely belongs to the current user), the eventually executed controller function \robotomonoRegular{GetFileContent} uses the \robotomonoRegular{uuid} to compute the path of the requested file content.
The extracted DEVENV and \robotomonoRegular{uuid} are saved in the current requests context. We can see, that \robotomonoRegular{id} is seemingly sanitized via \robotomonoRegular{util.ExtractUuid}. Instead of using the DEVENV from the context (that definitely belongs to the current user), the eventually executed controller function \robotomonoRegular{GetFileContent} uses the \robotomonoRegular{uuid} to compute the path of the requested file content.
\lstinputlisting[caption=service/backend/controller/devenv.go\ (lines\ 239-262), style=go, label={lst:devenv-file-content-snippet}]{src/devenv-file-content-snippet.go}
Herein lies the second vulnerability. Due to the \robotomonoRegular{util.ExtractUuid} function (seen in Listing \ref{lst:devenv-uuid-snippet}) which does not sanitize user input correctly, the adversary is able use path traversal to retrieve the contents of files belonging to DEVENVs owned by other users.
Herein lies the second vulnerability. Due to the \robotomonoRegular{util.ExtractUuid} function which does not sanitize user input correctly, the adversary is able to use path traversal to retrieve the contents of files belonging to DEVENVs owned by other users.
\lstinputlisting[caption=service/backend/util/encoding.go\ (lines\ 21-29), style=go, label={lst:extract-uuid-snippet}]{src/extract-uuid-snippet.go}
Expand Down Expand Up @@ -397,7 +405,7 @@ \section{Vulnerability \#3 -- Unintended RCE}
\subsection{How it works}
All the ALPINEs share the same DIND network. That means an adversary can send requests to an ALPINEs CHILD-BACKEND from another ALPINE. But, the CHILD-BACKENDs API is secured with an API key, that is randomly generated once for all ALPINEs per service. This API key lies in the environment of the root user of an ALPINE. To register a user on an ALPINE the client sends some username and password key-pair. Without being properly sanitized, the password is forwarded by the MAIN-BACKEND to the target ALPINEs CHILD-BACKEND. The following code is then executed by the CHILD-BACKEND.
All the ALPINEs share the same DIND network. That means an adversary can send requests to an ALPINEs CHILD-BACKEND from another ALPINE. But, the CHILD-BACKENDs API is secured with an API key that is randomly generated once for all ALPINEs per service. This API key lies in the environment of the root user of an ALPINE. To register a user on an ALPINE the client sends some username and password key-pair. Without being properly sanitized, the password is forwarded by the MAIN-BACKEND to the target ALPINEs CHILD-BACKEND. The following code is then executed by the CHILD-BACKEND.
\lstinputlisting[caption=service/image/service/user.go\ (lines\ 148-188), style=go]{src/create-user-snippet.go}
Expand Down
2 changes: 1 addition & 1 deletion documentation/tex/src/path-traversal.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/service/backend/controller/devenv.go b/service/backend/controller/devenv.go
index cd56dbc..eb91a0b 100644
index 90e4940..3cb438e 100644
--- a/service/backend/controller/devenv.go
+++ b/service/backend/controller/devenv.go
@@ -7,7 +7,6 @@ import (
Expand Down
1 change: 0 additions & 1 deletion documentation/tex/src/rce.patch
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ index 161560f..f4fecc6 100644
ctx.JSON(http.StatusBadRequest, gin.H{"error": "Illegal username"})
return
}

0 comments on commit b0c722f

Please sign in to comment.