HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Electron Application with JavaScript Backdoor and Ruby Command-Line Listener

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
backdoorapplicationlinewithjavascriptlistenerelectronrubyandcommand

Problem

I have created an Electron Application with a JavaScript/NodeJS Backdoor and a Ruby command-line listener.

I created this program for remote administration of my home computer securely using a new technology (WebSockets) which I found very interesting.

The program has two parts:

  • The Electron application written in JavaScript which includes a JavaScript backdoor using WebSockets.



  • A Ruby command-line WebSocket listener with the ability to communicate and send commands to the Electron application.



I'd love any general suggestions or fixes!

Feel free to only look at the client or server based on if you only know JavaScript or Ruby.

You may ignore anything that contains TODO because this site is not about fixing non-functioning code.

The project is also available on Github.

To download all the code you can use:

git clone https://github.com/IMcPwn/browser-backdoor


client/main.js (the Electron application)

`/*
* BrowserBackdoor - https://github.com/IMcPwn/browser-backdoor
* BrowserBackdoor is an electron application that uses a JavaScript backdoor (in index.html)
* to connect to the listener (BrowserBackdoorServer).
* For more information visit: http://imcpwn.com

* MIT License

* Copyright (c) 2016 Carleton Stuberg

* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:

* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT

Solution

Bearing in mind that this comes a couple years late and you (the OP) haven't logged in since 9/ 2016, it might not be seen for some time. Also, I don't really have much ruby experience so I will focus this review on the JavaScript code but the comment by @gcampbell about using heredocs sounds like a good suggestion for not having to manually include new line characters in the text.

Feedback

The code looks pretty succinct, though perhaps the error handling (e.g. for the Auto Launch promise fail handler) should be improved (i.e. more than empty functions). There appears to be a little bit of redundancy in the code (see suggestions below) but nothing excessive (e.g. copy-paste).

Suggestions

Simplify manageStartup()

The conditional blocks could be simplified, from:

if (enable) {
    appLauncher.isEnabled().then(function(enabled){
        if(enabled) return;
        return appLauncher.enable();
    }).then(function(err){
        // TODO: Deal with error
    });
} else {
    appLauncher.isEnabled().then(function(enabled){
        if(!enabled) return;
        return appLauncher.disable();
    }).then(function(err){
        // TODO: Deal with error
    }); 
}


Since both cases call appLauncher.isEnabled(), the check of enable can be moved into the promise callback. The real differences are when to return early and which method to call. For returning early, we could write out the logic like below:

if((enable && enabled) || (!enable && !enabled)) {


This can be simplified using the negated value of XOR:

if(!(enable ^ enabled)) {


Then to call the method, we could use another if-else block:

if(enable) {
    return appLauncher.enable();
}
return appLauncher.disable();


Or a ternary operator could be used to branch on the method name:

return appLauncher[enable?'enable':'disable']();


Don't loop through args to find one and continue

Perhaps it is a moot point due to the fact that there may likely not be more than a few arguments but the code to find --startup:

// Accept --startup as command line argument to enable on startup.
process.argv.forEach(function (val, index, array) {
  if (val === "--startup") {
    manageStartup(true);
  }
})


One could simply use Array.includes() to check for that argument:

if (process.argv.includes('--startup')) {
    manageStartup(true);
}


Extra function wrapper

There is an extra function wrapper used here:

// Re-open if all windows are closed.
app.on('window-all-closed', function() {
    createWindow();
});


This could be simplified by simply replacing the name of the function createWindow with the lambda/anonymous callback:

app.on('window-all-closed', createWindow);


It appears that the callback subscribed to the window-all-closed event is passed no arguments but if there were any, those would be passed to createWindow() in that case.

Code Snippets

if (enable) {
    appLauncher.isEnabled().then(function(enabled){
        if(enabled) return;
        return appLauncher.enable();
    }).then(function(err){
        // TODO: Deal with error
    });
} else {
    appLauncher.isEnabled().then(function(enabled){
        if(!enabled) return;
        return appLauncher.disable();
    }).then(function(err){
        // TODO: Deal with error
    }); 
}
if((enable && enabled) || (!enable && !enabled)) {
if(!(enable ^ enabled)) {
if(enable) {
    return appLauncher.enable();
}
return appLauncher.disable();
return appLauncher[enable?'enable':'disable']();

Context

StackExchange Code Review Q#129629, answer score: 2

Revisions (0)

No revisions yet.