Multiple Cross Site Scripting Vulnerabilities
Base Metric | score | severity |
---|---|---|
overall | 9 | critical |
Type: Vulnerability
Status: fixed
Reporting Date: 2023.04.10
Due to usage of dangerouslySetInnerHTML
in the client
it is possible
to execute arbitrary javascript in the application context.
This requires a malicious README.md
in one of the synced repositories.
Description
The frontend client
has several instances of dangerouslySetInnerHTML
, which
bypasses the shadow DOM of React and allows the input to be directly rendered.
If the input is controlled by the user without further sanitization cross site
scripting attacks are possible.
The most impactful component using the dangerouslySetInnerHTML
function is
the README.md
preview of a synced repository.
After opening a malicious repository, the arbitrary HTML content is rendered and executed. This is a stored XSS1.
client/src/pages/Repository/RepositoryOverview.tsx#L87-L112
</div>
{readme ? (
<div>
<Accordion
title={'Readme'}
icon={<FileIcon filename={readme.path} />}
>
<div className="py-4 text-xs overflow-x-auto px-4 readme">
<div
dangerouslySetInnerHTML={{ __html: readme.contents }}
onClick={(e) => {
// @ts-ignore
const { href } = e.target;
if (href) {
e.preventDefault();
openLink(href);
}
}}
/>
</div>
</Accordion>
</div>
) : (
''
)}
</div>
To render the markdown the remarkable2 library with enabled HTML rendering is used. This allows direct rendering of HTML inside the markdown content.
const md = new Remarkable({
html: true,
Proof of Concept to crash the application:
mkdir -p test_repo
cd test_repo
git init
- Place the below content into
README.md
<input id="path" oninput="window.__TAURI_INVOKE__(`tauri`,{__tauriModule:`Process`,message:{cmd:`exit`,exitCode: 1}}).then(console.log)" type="text"/>
git stage README.md && git commit -m "Initial Commit"
- Sync this repository with
bloop
- Inspect the repository inside
bloop
and observe the application crashing
The direct rendering is also used in /client/src/components/CodeBlock/SemanticSearch/Answer/index.tsx#L89
and /client/src/pages/NLResults/Message.tsx#L139
,
where the same proof of concept would work, but the attack vectors
are different.
The highlightedAnswer
from both instances seems to require the user to provide
the payload, which could be classified as a self-xss3.
Impact
Due to several unused Tauri APIs exposed it is possible to:
- Crash the application
- Trick users into allowing filesystem access
- Trick users into entering their github credentials
- Read and exfiltrate all synced repositories
- Modify all synced repositories
- Execute all enabled Tauri commands
- Intercept and exfiltrate all user interaction
Recommendation
This issue can be fixed in multiple ways, depending on the importance of HTML content being rendered.
- Disable the HTML feature of the markdown renderer
OR
- Sanitize the input after rendering with libraries like dompurify4
We recommend to disable the HTML input, as the sanitization process is only meant to reduce but not to erase the risk of unwanted HTML to be processed and rendered.
Retest Notes
The issue was fixed in the critical instance by sanitizing the input with sanitize-html
in PR 967.
The self-XSS instances were not fixed yet but they require user interaction and do not pose immediate risk.