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

[core] JS Injection/XSS Vulnerability in SetClipboardText #2954

Closed
3 tasks done
spaceraccoon opened this issue Mar 10, 2023 · 3 comments
Closed
3 tasks done

[core] JS Injection/XSS Vulnerability in SetClipboardText #2954

spaceraccoon opened this issue Mar 10, 2023 · 3 comments

Comments

@spaceraccoon
Copy link

WARNING: Please, read this note carefully before submitting a new issue:

It is important to realise that this is NOT A SUPPORT FORUM, this is for reproducible BUGS with raylib ONLY.

There are lots of generous and helpful people ready to help you out on raylib Discord forum or raylib reddit.

Remember that asking for support questi
Uploading raylib-game-template.zip…
ons here actively takes developer time away from improving raylib.


Please, before submitting a new issue verify and check:

  • I tested it on latest raylib version from master branch
  • I checked there is no similar issue already reported
  • My code has no errors or misuse of raylib

Issue description

The SetClipboardText API is vulnerable to JavaScript injection/cross-site scripting for the web platform because it does not properly escape the ' character, allowing attacker-controlled input to break out of the string and execute arbitrary JavaScript via emscripten_run_script.

// Set clipboard text content
void SetClipboardText(const char *text)
{
#if defined(PLATFORM_DESKTOP)
    glfwSetClipboardString(CORE.Window.handle, text);
#endif
#if defined(PLATFORM_WEB)
    emscripten_run_script(TextFormat("navigator.clipboard.writeText('%s')", text));
#endif
}

If text contains something like ');alert()//, the browser would also execute the alert() function.

I noticed that OpenUrl already implements a check for this but it is missing for SetClipboardText.

// Small security check trying to avoid (partially) malicious code...
    // sorry for the inconvenience when you hit this point...
    if (strchr(url, '\'') != NULL)
    {
        TRACELOG(LOG_WARNING, "SYSTEM: Provided URL is not valid");
    }

This is a good start and prevented OpenUrl from being exploited. I recommend adding a sanitization function to escape any ' characters instead for all 5 calls to emscripten_run_script: https://github.com/search?q=repo%3Araysan5%2Fraylib+emscripten_run_script&type=code.

Environment

Provide your Platform, Operating System, OpenGL version, GPU details where you experienced the issue.

Web

Issue Screenshot

If possible, provide a screenshot that illustrates the issue. Usually an image is better than a thousand words.

Code Example

Uploading raylib-game-template.zip…

Provide minimal reproduction code to test the issue. Please, format the code properly and try to keep it as simple as possible, just focusing on the experienced issue.

  1. Using the source code at https://github.com/raysan5/raylib-game-template, add the line SetClipboardText("asd');alert('fizz');//"); in int main(void) in raylib-game-template/src/raylib_game.c to simulate SetClipboardText being called with malicious user input.
  2. Build using make PLATFORM=PLATFORM_WEB then browse to the hosted raylib_game.html. The alert box will pop.
@spaceraccoon spaceraccoon changed the title [core] JS Injection/XSS Vulnerability in [core] JS Injection/XSS Vulnerability in SetClipboardText Mar 10, 2023
@orcmid
Copy link
Contributor

orcmid commented Mar 10, 2023

That's a good catch with respect to URLs. Will %-encoding get around this protection though?

@spaceraccoon
Copy link
Author

spaceraccoon commented Mar 11, 2023

Hi @orcmid , not so much %-encoding; the problem is in breaking out of the '%s' using the ' character, but a newline character could do the trick as well. One way to sanitize it reliably may be to hex-encode the resulting string e.g. convert ABC' to \\x41\\x42\\x43\\x27 before adding it to the format string template. Then the resulting JavaScript code that is executed would be navigator.clipboard.writeText('\x41\x42\x43\x27').

@raysan5
Copy link
Owner

raysan5 commented Mar 12, 2023

@spaceraccoon thank you very much for reporting! I'm reviewing it right now, at least a basic solution not implying generating new string data, like in OpenURL().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants