String Array
Protection ID: stringArray
String Array is a fundamental obfuscation technique that extracts string literals from your code and places them in a special array. These strings are then accessed by reference, making it difficult for attackers to understand the purpose and functionality of your code.
This protection is available in all editions of ByteHide Shield.
How It Works
The String Array protection works by:
- Extracting string literals from your source code
- Placing these strings in a separate array
- Replacing original strings with calls to access the array
- Optionally encoding the strings using methods like XOR, base64 or RC4
- Adding various transformations to make the array harder to analyze
This approach makes it significantly more difficult to understand the purpose of functions and code blocks by hiding textual clues that would otherwise help in reverse engineering.
Parameters
Enabled boolean : Enables String Array protection. true by default
Threshold number : Sets the probability (from 0 to 1) that a string literal will be moved to the string array. 0.75 by default
Encoding string[] : Specifies the encoding methods to use for strings in the array. ['xor'] by default
- Available values:
'none'
,'base64'
,'rc4'
,'xor'
'xor'
is the recommended option as it provides an advanced XOR-based encryption derived from RC4 with better performance
- Available values:
Rotate boolean : Shifts the string array by random positions. true by default
Shuffle boolean : Randomly shuffles items in the string array. true by default
Index Shift boolean : Adds an additional shift for all string array calls. true by default
Calls Transform boolean : Transforms calls to the string array, making them harder to identify. false by default
Calls Transform Threshold number : Controls how many calls are transformed (from 0 to 1). 0.5 by default
Wrappers Count number : Number of wrappers for the string array in each scope. 1 by default
Wrappers Type string : Type of wrappers used. 'variable' by default
- Available values:
'variable'
,'function'
- Available values:
The String Array protection offers extensive customization. The default XOR encoding offers a good balance between security and performance. For maximum security at a higher performance cost, consider using RC4 encoding.
Configuration Examples
Basic Configuration (shield.config.json)
{
"stringArray": true,
"stringArrayThreshold": 0.75
}
Advanced Configuration
{
"stringArray": true,
"stringArrayThreshold": 0.8,
"stringArrayEncoding": ["xor", "rc4"],
"stringArrayRotate": true,
"stringArrayShuffle": true,
"stringArrayCallsTransform": true,
"stringArrayCallsTransformThreshold": 0.6,
"stringArrayWrappersCount": 3,
"stringArrayWrappersType": "function"
}
Build Tool Integration (Webpack)
// webpack.config.js
const ByteHideShieldPlugin = require('@bytehide/webpack-shield');
module.exports = {
// ... other webpack config
plugins: [
new ByteHideShieldPlugin({
projectToken: 'your-project-token',
config: {
stringArray: true,
stringArrayThreshold: 0.85,
stringArrayEncoding: ["xor"],
stringArrayRotate: true,
stringArrayShuffle: true
}
})
]
}
Code Transformation Example
Original Code
function authenticateUser(username, password) {
const validUsername = "admin";
const validPassword = "securePassword123";
if (username === validUsername && password === validPassword) {
console.log("Authentication successful");
return {
status: "success",
message: "Welcome to the dashboard",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
};
} else {
console.log("Authentication failed");
return {
status: "error",
message: "Invalid username or password",
token: null
};
}
}
Transformed Code (with String Array)
const _0x3a7e = [
'admin',
'securePassword123',
'log',
'Authentication successful',
'status',
'success',
'message',
'Welcome to the dashboard',
'token',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Authentication failed',
'error',
'Invalid username or password'
];
function _0x28ac(_0x5b4f12, _0x48c71c) {
return _0x28ac = function(_0x3a7ef5, _0x28acb0) {
_0x3a7ef5 = _0x3a7ef5 - 0x12d;
let _0x21e88e = _0x3a7e[_0x3a7ef5];
return _0x21e88e;
}, _0x28ac(_0x5b4f12, _0x48c71c);
}
const _0x481df3 = _0x28ac;
function authenticateUser(username, password) {
const _0x48c71c = _0x28ac;
const _0x53cc31 = _0x48c71c(0x12d);
const _0x2e028d = _0x48c71c(0x12e);
if (username === _0x53cc31 && password === _0x2e028d) {
console[_0x48c71c(0x12f)](_0x48c71c(0x130));
return {
[_0x48c71c(0x131)]: _0x48c71c(0x132),
[_0x48c71c(0x133)]: _0x48c71c(0x134),
[_0x48c71c(0x135)]: _0x48c71c(0x136)
};
} else {
console[_0x48c71c(0x12f)](_0x48c71c(0x137));
return {
[_0x48c71c(0x131)]: _0x48c71c(0x138),
[_0x48c71c(0x133)]: _0x48c71c(0x139),
[_0x48c71c(0x135)]: null
};
}
}
Transformed Code (with String Array and XOR Encoding)
const _0x3f7b = [
'TN5c7uA=', // Encoded: 'admin'
'KL9F6sZ0pH4xVq3R', // Encoded: 'securePassword123'
'H9k=', // Encoded: 'log'
'UM1D4pX7tRw3Je8nKv6h', // Encoded: 'Authentication successful'
'Za3v', // Encoded: 'status'
'Vf7x', // Encoded: 'success'
'Hn9p4s', // Encoded: 'message'
'LK3R8pB1nMs5Ke2z', // Encoded: 'Welcome to the dashboard'
'Nf2c', // Encoded: 'token'
'JM9E5qNwtR3xVe8z', // Encoded: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'
'UM1D4pX7tRw3Je8nF', // Encoded: 'Authentication failed'
'Ws7i', // Encoded: 'error'
'GP5T6sZ8tLw4Re9uKo8' // Encoded: 'Invalid username or password'
];
function _0x21e4(_0x5df722, _0x21b33f) {
const _0x3f7bc5 = _0x3f7b;
_0x21e4 = function(_0x21e48e, _0x4b8671) {
_0x21e48e = _0x21e48e - 0x1af;
let _0x166332 = _0x3f7bc5[_0x21e48e];
if (_0x21e4['xorKey'] === undefined) {
_0x21e4['xorKey'] = 0x7B;
_0x21e4['decode'] = function(_0x276a3b) {
const _0x549a3d = atob(_0x276a3b);
let _0x42f8a7 = '';
for (let _0x329a14 = 0; _0x329a14 < _0x549a3d.length; _0x329a14++) {
_0x42f8a7 += String.fromCharCode(_0x549a3d.charCodeAt(_0x329a14) ^ _0x21e4['xorKey']);
}
return _0x42f8a7;
};
}
return _0x21e4['decode'](_0x166332);
};
return _0x21e4(_0x5df722, _0x21b33f);
}
function authenticateUser(username, password) {
const _0x3e64f2 = _0x21e4;
const _0x1fd2ac = _0x3e64f2(0x1af);
const _0x2e7bba = _0x3e64f2(0x1b0);
if (username === _0x1fd2ac && password === _0x2e7bba) {
console[_0x3e64f2(0x1b1)](_0x3e64f2(0x1b2));
return {
[_0x3e64f2(0x1b3)]: _0x3e64f2(0x1b4),
[_0x3e64f2(0x1b5)]: _0x3e64f2(0x1b6),
[_0x3e64f2(0x1b7)]: _0x3e64f2(0x1b8)
};
} else {
console[_0x3e64f2(0x1b1)](_0x3e64f2(0x1b9));
return {
[_0x3e64f2(0x1b3)]: _0x3e64f2(0x1ba),
[_0x3e64f2(0x1b5)]: _0x3e64f2(0x1bb),
[_0x3e64f2(0x1b7)]: null
};
}
}
When to Use
String Array protection is beneficial in almost all scenarios and is recommended as a baseline protection for any application. It's particularly valuable for:
- Sensitive constants: Hiding API keys, endpoints, and other sensitive values
- User interface text: Making it harder to identify screens and functionality
- Error messages: Obscuring detailed error information that might help attackers
- Business logic: Making the overall code functionality harder to comprehend
For optimal results:
- Use a higher threshold (0.8+) for critical code containing sensitive information
- Use the default XOR encoding for a good balance of security and performance
- Consider using RC4 encoding for highly sensitive data where performance is less critical
- Use function wrappers for higher security at the cost of performance
Compatibility Notes
String Array protection is highly compatible with all JavaScript environments:
- Browser compatibility: Works in all browsers with minimal performance impact
- Mobile performance: The default XOR implementation has minimal impact on performance
- Bundle size: Increases bundle size, but the impact is usually manageable
- Node.js: Fully compatible with server-side JavaScript
When using RC4 encoding, avoid also enabling Unicode Escape Sequence as this can greatly increase code size. The XOR encoding is recommended for most use cases as it provides good security with better performance.
Related Protections
For maximum security, combine String Array with:
Force Transform Strings
The forceTransformStrings
option allows you to ensure specific strings are always transformed into the string array, even if they would normally be excluded by the stringArrayThreshold
setting:
{
"stringArray": true,
"stringArrayThreshold": 0.5, // Only 50% of strings will be transformed
"forceTransformStrings": [
"license-key", // Exact match
"api-\\w+", // RegExp pattern for API strings
"secret_token_\\d+" // RegExp pattern for token strings
]
}
This option accepts an array of strings or regular expression patterns that identify string literals you want to ensure are always transformed, regardless of the stringArrayThreshold
setting.
Important Notes:
- The
forceTransformStrings
option affects only strings that wouldn't normally be transformed by thestringArrayThreshold
setting - This option has priority over the
reservedStrings
option (strings matching both will be transformed) - However, it doesn't override conditional comments (if you've explicitly disabled obfuscation for a section with comments)
This is particularly useful when you want most string transformations to be controlled by the threshold percentage, but you have specific sensitive strings that must always be protected.
Performance Considerations
String Array protection can impact runtime performance, especially with additional options enabled:
- Low Impact: Basic String Array with no encoding
- Medium Impact: String Array with encoding and moderate threshold (0.5-0.7)
- High Impact: String Array with encoding, high threshold (>0.8), and transform options
For performance-sensitive applications, consider using a lower threshold value and limiting encoding to critical strings.
Examples
Basic Protection
{
"stringArray": true,
"stringArrayThreshold": 0.75
}
Maximum Protection
{
"stringArray": true,
"stringArrayThreshold": 1,
"stringArrayEncoding": ["rc4"],
"stringArrayRotate": true,
"stringArrayShuffle": true,
"stringArrayWrappersType": "function",
"stringArrayWrappersCount": 5
}
Balanced Approach
{
"stringArray": true,
"stringArrayThreshold": 0.6,
"stringArrayEncoding": ["base64"],
"forceTransformStrings": [
"license",
"api-key",
"token"
],
"reservedStrings": [
"https://cdn",
"data:image"
]
}
By properly configuring String Array protection, you can significantly increase the difficulty of reverse engineering your JavaScript code while managing the performance impact.