javascripthtmlsecurity

Google Script gmail scam?


I'm a little worried and in a hurry and I'm not sure if this is the right place to ask this, but I literally have no idea where else to ask. Long story short, I wanted to clear my gmail account from spam and found the following link while searching for a way to do this: https://www.labnol.org/internet/gmail-unsubscribe/28806/ Like a complete idiot, I followed the instructions blindly without suspecting anything. After completing the steps, nothing really happened (the spreadsheet wasn't filling) so I stopped the script and removed it from my google accounts permissions and started inspecting the code that was used. It consists of three files, the google script:

function getConfig() {
  var params = {
    label:doProperty_("LABEL") || "Unsubscribe"
  };
  return params;
}

function config_() {
  var html = HtmlService.createHtmlOutputFromFile('config')
  .setTitle("Gmail Unsubscriber")
  .setWidth(300).setHeight(200).setSandboxMode(HtmlService.SandboxMode.IFRAME);
  var ss = SpreadsheetApp.getActive();
  ss.show(html);
}

function help_() {
  var html = HtmlService.createHtmlOutputFromFile('help')
  .setTitle("Google Scripts Support")
  .setWidth(350).setHeight(120);
  var ss = SpreadsheetApp.getActive();
  ss.show(html);
}

function createLabel_(name) {

  var label = GmailApp.getUserLabelByName(name);

  if (!label) {
    label = GmailApp.createLabel(name);
  }

  return label;

}

function log_(status, subject, view, from, link) {
  var ss = SpreadsheetApp.getActive();
  ss.getActiveSheet().appendRow([status, subject, view, from, link]);
}

function init_() {
  Browser.msgBox("The Unsubscriber was initialized. Please select the Start option from the Gmail menu to activate.");
  return;
}


function onOpen() {

  var menu = [     
    {name: "Configure", functionName: "config_"},
    null,
    {name: "☎ Help & Support",functionName: "help_"},
    {name: "✖ Stop (Uninstall)",  functionName: "stop_"},
    null
  ];  

  SpreadsheetApp.getActiveSpreadsheet().addMenu("➪ Gmail Unsubscriber", menu);

}

function stop_(e) {

  var triggers = ScriptApp.getProjectTriggers();

  for(var i in triggers) {
    ScriptApp.deleteTrigger(triggers[i]);
  }

  if (!e) {
    Browser.msgBox("The Gmail Unsubscriber has been disabled. You can restart it anytime later."); 
  }  
}


function doProperty_(key, value) {

  var properties = PropertiesService.getUserProperties();

  if (value) {
    properties.setProperty(key, value);
  } else {
    return properties.getProperty(key);
  }

}

function doGmail() {

  try {

    var label = doProperty_("LABEL") || "Unsubscribe";

    var threads = GmailApp.search("label:" + label);

    var gmail = createLabel_(label);

    var url, urls, message, raw, body, formula, status;

    var hyperlink = '=HYPERLINK("#LINK#", "View")';

    var hrefs = new RegExp(/<a[^>]*href=["'](https?:\/\/[^"']+)["'][^>]*>(.*?)<\/a>/gi);

    for (var t in threads)  {

      url = "";

      status = "Could not unsubscribe";

      message = threads[t].getMessages()[0];

      threads[t].removeLabel(gmail);

      raw = message.getRawContent();

      urls = raw.match(/^list\-unsubscribe:(.|\r\n\s)+<(https?:\/\/[^>]+)>/im);

      if (urls) {
        url = urls[2];
        status = "Unsubscribed via header";
      } else {
        body = message.getBody().replace(/\s/g, "");
        while ( (url === "") && (urls = hrefs.exec(body)) ) {
          if (urls[1].match(/unsubscribe|optout|opt\-out|remove/i) || urls[2].match(/unsubscribe|optout|opt\-out|remove/i)) {
            url = urls[1];
            status = "Unsubscribed via link";
          }
        }
      }

      if (url === "") {
        urls = raw.match(/^list\-unsubscribe:(.|\r\n\s)+<mailto:([^>]+)>/im);
        if (urls) {
          url = parseEmail_(urls[2]);
          var subject = "Unsubscribe";
          GmailApp.sendEmail(url, subject, subject);
          status = "Unsubscribed via email";
        }
      }

      if (status.match(/unsubscribed/i)) {
        UrlFetchApp.fetch(url, {muteHttpExceptions: true});
      }

      formula = hyperlink.replace("#LINK", threads[t].getPermalink());

      log_( status, message.getSubject(), formula, message.getFrom(), url );

    }
  } catch (e) {Logger.log(e.toString())}

}


function saveConfig(params) {

  try {

    doProperty_("LABEL", params.label);

    stop_(true);

    ScriptApp.newTrigger('doGmail')
    .timeBased().everyMinutes(15).create();

    return "The Gmail unsubscriber is now active. You can apply the Gmail label " + params.label + " to any email and you'll be unsubscribed in 15 minutes. Please close this window.";    

  } catch (e) {

    return "ERROR: " + e.toString();

  }

}

function parseEmail_(email) {
  var result = email.trim().split("?");
  return result[0];
}

And two other .html files called config.html:

<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">

<script>

  function closeWindow() {
    google.script.host.close();
  }

  function showError(error) {
    document.getElementById("error").innerHTML = error;
  }

  function showConfig(params) {

    if (params.label !== "") 
    document.getElementById("label").value = params.label;

    return;

  }

  function validate() {

      var label = document.getElementById("label").value;

      if (label.trim() === "") {
          showError("Please enter a Gmail label name..");
          return;
      } else {
          showError("Saving configuration, please wait..");
          var params = {
              label: label
          };
          google.script.run.withSuccessHandler(showError).saveConfig(params);
      }
  }

</script>

<form>
    <div class="form-group block">
        <p style="margin-bottom:4px;">Enter Gmail Label Name:</p>
        <input type="text" id="label" name="label" placeholder="Your email address.." style="width: 250px;" />
    </div>


    <p>
        <input class="blue" type="button" value="Save configuration" onclick="validate()" />
        <input class="green" type="button" value="Close window" onclick="google.script.host.close()" />
    </p>

    <p class="error" id="error"></p>

</form>

<script>
  google.script.run.withSuccessHandler(showConfig).getConfig();  
</script>

And lastly help.html:

<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<base target="_blank">
</head>
<div class="block">


  <p>If you are need help with the program, please refer to the <a href="https://www.labnol.org/internet/gmail-unsubscribe/28806/">online tutorial</a>. For support and customization, please submit your requirements at <strong><a href="https://ctrlq.org">ctrlq.org</a></strong>.</p>
</div>

<div class="block">
  <a class="button blue" href="mailto:amit@labnol.org" style="width:120px;">amit@labnol.org</a>
  <a class="button green" href="https://twitter.com/labnol" style="width:120px;margin-right:10px">Tweet @labnol</a>  
<input class="red" type="button" value="Close" onclick="google.script.host.close()" />
</div>

Is there any way that my account could be in any danger?


Solution

  • I am the author of this Google Script and it is completely safe. In fact, you have access to the full source code so you know exactly what it is doing.

    Also, if you like to remove any Google Script from your account, here's how:

    1. Go to https://security.google.com/settings/security/permissions

    2. Click the script you wish to uninstall

    3. Next click Remove and you are done.