Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

TextMesh Pro Rich text exploit with TMP

Discussion in 'UGUI & TextMesh Pro' started by MrLucid72, Jun 13, 2019.

  1. MrLucid72


    Jan 12, 2016

    Seems that unchecking allow rich text still allows lazy rich text like <#color> instead of <color=> among other "short" rich tags. Unchecking that box prevents SOME rich text (eg, color=green>), but not all.

    This is a critical exploit for our game that I can't seem to fix that players discovered. Any ideas? People are faking system messages, private whispers, hiding their name completely by using colors that blend in with the bg, etc.
  2. Stephan_B


    Unity Technologies

    Feb 26, 2017
    How is the text input being provided to the chat? Are you using a TMP Input Field or something else and the issue is in the display using a text component?

    Disabling Rich Text should block all of it but I am not sure how you have this setup.

    Can you provide me with a simple repro scene / project so that I can reproduce something similar for testing?
  3. MrLucid72


    Jan 12, 2016
    Just a TMP InputField for input with a ScrollRect of read-only InputFields for viewing:

    It's really just the InputField writable input that is the only thing to really consider: When I type <#

    Allow rich text editing is unchecked~ Unity info in signature. I'm just about to patch, so I'm under some time pressure for now so I can't make a repro scene yet, but just in case you see anything odd initially ^

    SOME rich text disables, some does not. I'll make a screencast soon.
  4. MrLucid72


    Jan 12, 2016

    As I post this, I realize maybe the inputfield lists don't have the checkbox -- so the no-rich text doesn't actually get stripped, just disabled -- then passed to the scroll list of read only inputs. Gonna try making sure the read only one is checked, too.

    EDIT: Yep, that seems to be it. For system messages, I should set rich text to true at runtime, throw in my message, then set it back to false? What's the best workflow for this? Seems like it was my own misunderstanding about how this worked :p

    Or is there a func to get the stripped version of the text? This was the closest I found, but I couldn't find a result ( ).

    EDIT 2: Got it:

    Thanks for the assistance -- apologies for the time. However, if I may suggest a str.escape() func that would essentially wrap no parse around the string? I could easily make my own, but it may be a nice native feature. Cheers!
    Last edited: Jun 14, 2019
  5. MrLucid72


    Jan 12, 2016
    Hmm, the <noparse> method is actually pretty unfortunate because if people copy text they see, it copies WITH The noparse tags. Some sort of "true" tag strip would be ideal. Would this be enough?

    Regex.Replace(str, "<.*?>", string.Empty); // I saw this in another post, somewhere, but this is pretty generic -- if someone tries to make a heart <3 then later puts >8) this face, everything in between would poof. While it's rare, it's not ideal. However, I'm not sure how the performance would be if I put every use-case of tmp in a giant regex :p

    EDIT: Here's what I got that isn't ideal, but ghettoworks -- if anyone has a better solution, LMK :)
    Code (CSharp):
    1.     public static string StripTmpRichTags(string str)
    2.     {
    3.         //
    4.         //
    5.         return Regex
    6.             .Replace(str, "<.*?>", string.Empty)
    7.             .Replace(System.Environment.NewLine, ""); // 2nd is string replace; not regex
    8.     }
    Last edited: Jun 18, 2019
    Rachan likes this.
  6. Spenceanator_


    Mar 19, 2021
    I'm a little late to the party here but wanted to update. Players were able to find a way to mess with tags regardless of the <noparse> tags + removal of user submitted </noparse> tags. I'm not confident how user friendly this is with chat, but I decided to go with a mixture of methods. Including the one MrLucid posted above.

    With this method I try and remove every tag I know will be malicious and try and parse through the ones I think won't be. That way the players can still have their cake, and other heart emojis too.

    Code (CSharp):
    2. if(inChatText.Contains("<") && inChatText.Contains(">"))
    3.         {
    5.             foreach(Match match in Regex.Matches(inChatText, "<.*?>"))
    6.             {
    7.                 bool endTag = match.Value.Contains(@"/");
    8.                 bool varTag = match.Value.Contains(@"=");
    9.                 bool hexTag = match.Value.Contains(@"#");
    11.                 if(endTag || varTag || hexTag)
    12.                 {
    13.                     inChatText = Regex.Replace(inChatText, match.Value, ""); // Immediately destroy the tag
    14.                 }
    15.                 else // We don't have an easy command to kill, let's check if we should try and destroy whatever is inbetween the brackets
    16.                 {
    17.                     int words = match.ToString().Split().Length;
    18.                     if(words < 3 || match.ToString().Length < 8) // Rich Text tags generally have 1 or 2 words
    19.                         inChatText = Regex.Replace(inChatText, match.Value, "");
    20.                 }
    21.             }
    22.         }
  7. Neiist


    Sep 18, 2012
    Hey @Spenceanator_ I'm also trying to prevent such exploit, what I came up with so far is simply removing "</" as it prevents users from writing </noparse> or any other closing tag, but have you found any other ways to mess things up?
  8. Rachan


    Dec 3, 2012
    This code is working, Thanks!!!