API Reference
ByteHide Shield provides a REST API that allows you to obfuscate JavaScript code programmatically. This approach is useful for integration into custom build tools, development workflows, or when the CLI and build tool plugins don't fit your needs.
API Endpoint
The main endpoint for obfuscating JavaScript code is:
https://shield.microservice.bytehide.com/api/start/YOUR_PROJECT_TOKEN/js
Authentication
Authentication is handled through your project token, which should be included in the endpoint URL path.
Request Format
The API accepts POST requests with a JSON body containing the following properties:
Property | Type | Required | Description |
---|---|---|---|
code | string | Yes | The source code you want to obfuscate |
config | object | No | Configuration options for the obfuscator |
obfuscationID | string | No | ID to maintain consistent identifier names between multiple requests |
Example Request
const https = require('https');
const PROJECT_TOKEN = 'your-project-token';
const sourceCode = `
function hello() {
console.log("Hello, world!");
}
hello();
`;
const obfuscationConfig = {
stringArray: true,
stringArrayEncoding: ['base64'],
controlFlowFlattening: true
};
const payload = JSON.stringify({
code: sourceCode,
config: obfuscationConfig,
obfuscationID: 'my-project-v1' // Optional: for consistent obfuscation across multiple files
});
const options = {
hostname: 'shield.microservice.bytehide.com',
port: 443,
path: `/api/start/${PROJECT_TOKEN}/js`,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(payload, 'utf8')
}
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
const response = JSON.parse(data);
console.log('Obfuscated code:', response.output);
// You can also access response.sourceMap and response.symbols if needed
});
});
req.on('error', (error) => {
console.error('Error:', error);
});
req.write(payload);
req.end();
Response Format
The API returns a JSON object with the following properties:
Property | Type | Description |
---|---|---|
output | string | The obfuscated JavaScript code |
sourceMap | string | Source map for the obfuscated code (if enabled in config) |
symbols | object | Identifier names cache for consistent obfuscation |
Example Response
{
"output": "var _0x2a43=['log','Hello,\\x20world!'];function _0x4cb1(_0x2f5faf,_0x4c9a6d){_0x4cb1=function(_0x1e4fd3,_0x5a0b3c){_0x1e4fd3=_0x1e4fd3-0x10e;var _0x162e16=_0x2a43[_0x1e4fd3];return _0x162e16;};return _0x4cb1(_0x2f5faf,_0x4c9a6d);}(function(){var _0x5ddc31=_0x4cb1;function _0x476a90(){var _0x3ad9cb=_0x4cb1;console[_0x3ad9cb(0x10e)](_0x3ad9cb(0x10f));}_0x476a90();}());",
"sourceMap": "{\"version\":3,\"file\":\"output.js\",\"sources\":[\"input.js\"],\"names\":[\"hello\",\"console\",\"log\"],\"mappings\":\"...\"}",
"symbols": {
"globalIdentifiers": {
"hello": "_0x476a90"
}
}
}
Error Handling
The API returns appropriate HTTP status codes for different scenarios:
Status Code | Description |
---|---|
200 | Success |
400 | Bad request (e.g., missing code property) |
401 | Unauthorized (invalid project token) |
500 | Server error during obfuscation |
Error Response Example
{
"error": "Error: Unexpected token < in JSON at position 0"
}
Or for validation errors:
{
"code": "The code property should include the source code to protect and it's required."
}
Maintaining Consistent Obfuscation
When obfuscating multiple files that reference each other, it's important to maintain consistent renaming of identifiers. You can achieve this by:
- Sending an
obfuscationID
with your requests - The API will store the identifier mappings for that ID
- Use the same ID for all related files to ensure consistent naming
This is especially useful for:
- Splitting large applications into multiple obfuscation requests
- Incrementally obfuscating files while preserving references
- Ensuring consistent obfuscation across build processes
Configuration Options
You can provide any valid Shield configuration option in the config
object. See the Configuration Files documentation for all available options.
Basic Configuration Example
const config = {
stringArray: true,
stringArrayThreshold: 0.75,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
selfDefending: true
};
Integration Examples
Node.js Integration with fs
const fs = require('fs');
const https = require('https');
const path = require('path');
const PROJECT_TOKEN = 'your-project-token';
const inputFile = 'src/app.js';
const outputFile = 'dist/app.js';
// Read the source code
const sourceCode = fs.readFileSync(inputFile, 'utf8');
const payload = JSON.stringify({
code: sourceCode,
config: {
stringArray: true,
controlFlowFlattening: true,
selfDefending: true
}
});
const options = {
hostname: 'shield.microservice.bytehide.com',
port: 443,
path: `/api/start/${PROJECT_TOKEN}/js`,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(payload, 'utf8')
}
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
const response = JSON.parse(data);
// Create output directory if it doesn't exist
const outputDir = path.dirname(outputFile);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Write the obfuscated code to the output file
fs.writeFileSync(outputFile, response.output);
console.log(`Obfuscated code written to ${outputFile}`);
// Optionally save the source map
if (response.sourceMap) {
fs.writeFileSync(`${outputFile}.map`, response.sourceMap);
console.log(`Source map written to ${outputFile}.map`);
}
});
});
req.on('error', (error) => {
console.error('Error:', error);
});
req.write(payload);
req.end();
Using in a Build Script
// build.js
const fs = require('fs');
const https = require('https');
const path = require('path');
const glob = require('glob');
const PROJECT_TOKEN = process.env.BYTEHIDE_TOKEN;
const OBFUSCATION_ID = 'project-v1.0.0';
// Find all JavaScript files
const files = glob.sync('dist/**/*.js');
// Obfuscate each file
async function obfuscateFiles() {
for (const file of files) {
const sourceCode = fs.readFileSync(file, 'utf8');
await new Promise((resolve, reject) => {
const payload = JSON.stringify({
code: sourceCode,
config: {
stringArray: true,
controlFlowFlattening: true
},
obfuscationID: OBFUSCATION_ID
});
const options = {
hostname: 'shield.microservice.bytehide.com',
port: 443,
path: `/api/start/${PROJECT_TOKEN}/js`,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(payload, 'utf8')
}
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const response = JSON.parse(data);
fs.writeFileSync(file, response.output);
console.log(`Obfuscated: ${file}`);
resolve();
} catch (err) {
reject(err);
}
});
});
req.on('error', (error) => {
reject(error);
});
req.write(payload);
req.end();
});
}
}
obfuscateFiles().then(() => {
console.log('All files obfuscated successfully!');
}).catch(err => {
console.error('Error during obfuscation:', err);
process.exit(1);
});
Rate Limiting and Performance
- The API has rate limits based on your ByteHide subscription plan
- For large files or heavy obfuscation options, the API might take longer to respond
- Consider implementing retry logic for large files or when processing many files
Security Considerations
- Always use HTTPS to communicate with the API
- Keep your project token secure and don't expose it in client-side code
- Consider using environment variables to store your project token
- The API securely processes your code, but for extremely sensitive code, consider using the CLI tool in a controlled environment
By using the ByteHide Shield API, you can integrate powerful JavaScript obfuscation capabilities into any workflow or tool.