Using atob to hide phrases from users is not permitted, why or what to do?

157 views
Skip to first unread message

Shu

unread,
May 17, 2021, 3:00:31 AM5/17/21
to Chromium Extensions
Hi everyone,
I have paid extensions that shows next phrases:

License verified
Free trial is over and license is not active.
Too many requests sent, wait a 30 sec before trying again!
Please, insert the license first (you can purchase it on our website)
Please, check better the license you inserted. It is not correct.
etc

The problem is user opens the code, search for the text and tries to bypass it. I saw in other extensions devs use atob just to hide texts. I was using atobs as well, but now google rejects my extensions:

Hello Developer,
Thank you for writing to us with a detailed explanation. The use of atob is not allowed according to the policies. Please look for alternatives for the payment options.

How can I modify the text in another way so user cannot search for it? And also I verify the license via server and atob is using there as well... What can I do with that?

hrg...@gmail.com

unread,
May 17, 2021, 3:47:02 AM5/17/21
to Chromium Extensions, Shu
I would guess (and it's just a guess) that what the reviewers don't like is something like this:

atob("TGljZW5zZSB2ZXJpZmllZA==")

This is obviously unnecessary because the argument to atob is a literal string.
So, instead of passing a literal to atob, pass a variable or expression.

For example: atob( someArray[123] )

But this is still not good enough for obfuscation because you are using atob which is a well-known function. This is too easy to detect and understand. So, instead, implement your own custom format.

A good obfuscation should look like this: someFunction(someVariable)

After minification, that code will look like this: ab(cd)
That's it. There's no clue about what that code does.

Remember that minification is allowed, whereas obfuscation is not. The key is to obfuscate your code in a way that doesn't make obvious your intention to obfuscate.

For example, the expression someFunction(someVariable) from above could be perfectly acceptable according to the policies if you change the names to:
getLanguageText( textID )

Then, after minification it will still be turned into: ab(cd)

If a reviewer sees that, he won't notice anything out of the ordinary. It's just a typical function call.

Shu

unread,
May 17, 2021, 3:56:17 AM5/17/21
to Chromium Extensions, hrg...@gmail.com, Shu
I want simple protection from most users who know just || 1==1 to bypass the system, so they don't know what atob is. Anyway:

  • Violation reference ID: Red Titanium
  • Violation: Having obfuscated code in the package.
  • Violating content:
    • Code snippet: contentscript.js:0:0: atob(\"RlJFRSBUUklBTCBJUyBPVkVS\") + \".</b> \" + atob(\"WW91IGNhbiBpbnZpdGUgbWF4IDMwMCBwZXIgZGF5LCBjb21lIGJhY2sgdG9tb3Jyb3cgb3IgcHVyY2hhc2UgdGhlIHNjcmlwdA==\")....
They think this is obfuscated, even if I put a comment near each atob to describe what is there and why (to google). If I use as you said:
> For example, the expression someFunction(someVariable) from above could be perfectly acceptable according to the policies if you change the names to:
getLanguageText( textID )
how can I hide the text, it will be much more obfuscated than with simple atob and google may not like it as well :/
I just want to avoid using phrases with "license", "paid" and all phrases that user sees on the screen, so he doesn't know where to search, it's not 100% protection, but filters out at least 90% users :)

hrg...@gmail.com

unread,
May 17, 2021, 4:17:11 AM5/17/21
to Chromium Extensions, Shu, hrg...@gmail.com
The easy way (which is atob plus a string literal) doesn't work because it's too obvious what your intention is.
The Web Store policies are not enforced with prudence or good criterion. They are enforce like a police officer enforces the law.

The law says that you cannot do A, and you are doing A, so you get a ticket!!

Also, much of the review process is done automatically. The review system parses your code and looks for obvious signs of obfuscation.
So, if you want to obfuscate in a way that passes the review, you can't do it in ways that look obvious.

Forget about adding comments that explain your good intentions. That's useless.
Remember... you are in front of a police officer and you are breaking the law. Explaining your good intentions is like talking to a wall.

Simeon Vincent

unread,
May 18, 2021, 8:23:37 PM5/18/21
to hrg...@gmail.com, Chromium Extensions, Shu
To be clear, using atob to hide the contents of a string is literally obfuscation. Dictionary.com says obfuscation is "the act or an instance of making something obscure, dark, or difficult to understand" (source). I'd strongly discourage following the advice in hrg's first email as that's just getting deeper and deeper into the obfuscation trap.

While this doesn't quite get to what you're after, another option is to use the i18n API to move your strings in a messages.json and use chrome.i18n.getMessage() to retrieve the appropriate string at runtime. It would still be possible to search for the exact string, but this does introduce indirection for a very practical reason: multi-language support.
 
Alternatively, you could use remotely loaded configuration to achieve something similar. If you were to externalize UI strings in a JSON file you load from your server and cache in the extension, the raw strings would not be searchable in your extension's source. This also provides you the benefit of being able to tweak your (localized) strings without having to submit a new version of the extension to CWS for review.

Cheers,

Simeon - @dotproto
Chrome Extensions DevRel


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/0af6aae7-ec9d-4cea-81d2-61519f1d30den%40chromium.org.

hrg...@gmail.com

unread,
May 19, 2021, 3:34:20 AM5/19/21
to Chromium Extensions, Simeon Vincent, Chromium Extensions, Shu, hrg...@gmail.com
 
Dictionary.com says obfuscation is "the act or an instance of making something obscure, dark, or difficult to understand" (source).

Changing variable and function names for others that are shorter and meaningless also falls into that definition.
We can play the semantics game all day. Minification is just obfuscation with a different purpose.

That's why Shu was trying to explain to the reviewer what his intention was by doing atob("string literal").
Since intention is the only thing that separate minification from obfuscation, then it's reasonable to assume that some obvious forms of obfuscation should be allowed if the intention is not to hide code, as is the case with atob("string literal").

Unfortunately, the CWS policies are enforced blindly (and automatically in many cases), so being reasonable, as Shu did by explaining the reviewer his intentions, does not work.

There's only a specific list of obfuscation techniques that are allowed, and they are called "minification", but only because the purpose is minification, not because it's not obfuscation.

If instead of changing my variable and function names for shorter ones I swapped all names randomly so that the resulting code looks like it has meaningful names, but in reality is just a deceiving technique.
Is this minification? No, because the code is not shorter.
Is it obfuscation? YES.

But it's obfuscation that passes the review.

See? We can play the semantics game all day.

My advice to Shu was simple: given that your intention is sound, just obfuscate the code in a way that looks like minification.

The advice of taking the text strings out of the package is just a way of obfuscating the code (i.e. making it harder to inspect and understand), because the developer doesn't have a real need of implementing things that way.

Reply all
Reply to author
Forward
0 new messages