105 - Bypassing MFA, WebCache Poisoning, and AWS SageMaker
Starts off by detailing a self XSS through JupyterLabs Notebook’s
/lab endpoint, where an attacker can control the page contents. In and of itself this isn’t an issue, an attacker can only control the page contents of a notebook instance they own. It gets more interesting though when you throw cookies into the mix and how they’re used on the AWS endpoint. All JupyterLabs Notebook instances run on the
sagemaker.aws subdomain, and one of the cookies used is the
_xsrf, which is a CSRF token. An attacker can use their code on their own notebook instance to set the
_xsrf cookie that applies to the entirety of the
sagemaker.aws subdomain on a victim’s browser.
This can be used to perform CSRF and open a terminal to the victim’s JupyterLab instance via a cross-origin websocket, since the origin header isn’t checked. While the post points out that in theory, the samesite attribute defaulting to “Lax” on most browsers should have prevented this attack, they mention Chrome has a “2 minute grace period” where cookies that have been set without a samesite attribute can be sent on cross-site requests for two minutes afterwards. This “Lax + POST” support is set to be removed in the future, but currently it’s taken advantage of for this attack.
Fairly weak vulnerability to have, the URL of a remote stylesheet has minimal domain validation on it that was easily bypassed allowing an attacker to load their own stylesheets. It is a bit of a fun issue to have however as this can allow exfiltrating page content and potentially sensitive information like CSRF tokens and use it for a more complicated attack.
There are two things at play with this vulnerability, first is the Symfony has support for
trusted_headers to indicate which headers the framework is okay to trust, and recently support for the
X-Forwarded-Prefix header was added and could be used regardless of whether or not it was in
trusted_headers list. This could create a situation where cache poisoning would be possible as a request could be treated differently on the application trusting an untrusted header. The actual exploitation of this issue would depend on the particular application built on top of Symfony.
A partially authentication user could remove MFA from their account. During the login process when enrolled in the MFA program, a user who logged in with the correct credentials, but had not yet provided the MFA token could access the
/mfa/unenrollment endpoint and remove MFA from the account.
Kubernetes has a feature called “volume subpaths”, which is intended to enable sharing of a volume between multiple containers in a particular pod. Critically, these subpaths are controlled by the user. There have been attacks in the past that have abused this. One they highlight is where a malicious workload would abuse the InitContainer to create a symbolic link of
/etc, so that when another container later on tried to mount that volume and followed the symlink, it would use the host’s
/etc instead of the containerized
/etc. The fix for this involved resolving the subpaths and validating they point inside the volume, and ensure the host path isn’t changeable by the user between validation and when the container runtime uses it (in an effort to prevent Time-of-Check Time-of-Use or TOCTOU issues).
However, the Google team found another route to exploit this issue using another TOCTOU to bypass the validation of the path against a host directory. They still did a symlink attack like the previous attack had done, but they continuously swapped the symlink with a directory using the
RENAME_EXCHANGE option. If the race succeeded, the kubelet sees the path as a directory and thinks it’s safe to access, but the mount utility sees the path as a symlink and follows it.