This is the second part of:

In this exercise, we are going to create a small script that will help us safeguard the security of the information in the projects of our Jira Server or Datacenter. To do this, we will create a “Job” in Scriptrunner within our Jira Server or Datacenter. Adaptavist Scriptrunner is required in order to complete this exercise.

As you well know, Jira Server and Datacenter projects and its permission schemes can be configured to have different levels of access. For example, we can give more open access to the internal people of our company and on the other hand, we can have more limited access for external people or outsourcers.

To maintain that security we use Jira groups.

What is the problem?

The Jira projects are managed globally by Jira Admins and locally by Jira Project Admins assigning roles to users inside the projects. This can lead to information leakage problems and for this we need to create mechanisms that inform us of possible leaks, in such a way that the Security Office of our company can take action.

What do we need to start?

To start with, we are going to create a scheduled script (a “Job”) that will check for any leaks in Jira every day (obtaining the content of a stored JQL filter with the list of the issues not in allowed projects). If there is a leak, the script will send an email to the Security Office and also will send a message to a Slack channel. In this exercise you will see 2 ways to make REST calls abroad and you will also see how to send an email from code.

You will see two REST calls. In one of them we will use CURL, that means that your Jira System Administrator must install CURL in the system. CURL exists and is used since 1998! It is my favorite tool for integrations, they are a legend! https://curl.se/

In the other REST call, we’ll send a message through Slack and use the RESTClient class to invoke a WebHook from our Slack channel.

Let us begin!

For the recipe we need:

– A limited access level user (belonging to the Jira group of external or outsourcer) for when we call CURL to see what the user can see in Jira: “user:password” encoded in base64 will be necessary.

– Know the access URL to the REST access point of our Jira. Example: https://jira.example.com

– An email where we will send the Security alert when it occurs

– A Slack WebHook. See more in: How to create a Slack Bot in 5 minutes

JQL filter with the list of the issues not in allowed projects (use NOT IN in the JQL)

And now the Job script code 😀

import groovy.json.JsonSlurper; 
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

import com.atlassian.jira.config.properties.APKeys
import groovyx.net.http.RESTClient
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.URIBuilder

import com.atlassian.mail.Email
import com.atlassian.mail.server.MailServerManager
import com.atlassian.mail.server.SMTPMailServer

MailServerManager mailServerManager = ComponentAccessor.getMailServerManager()
SMTPMailServer mailServer = mailServerManager.getDefaultSMTPMailServer()


def sout = new StringBuilder(), serr = new StringBuilder()
def proc = ""
proc = ("curl -H 'Authorization: Basic BASE64-ENCODED-USER:PASS' -H 'Accept: application/json' -H 'Content-Type: application/json' https://jira.example.com/rest/api/2/search?jql=filter=XXX") 
def proc2 = [ 'bash', '-c', proc].execute()
proc2.consumeProcessOutput(sout, serr)
proc2.waitFor();
def result = sout.toString()
def error = serr.toString(); 
def jsonSlurper = new JsonSlurper()
def seleccion = jsonSlurper.parseText(result)
//TotalSize must be 4
def size = seleccion.total
log.debug("Size=" + size )

def today = new Date().format('yyyy-MM-dd');

if (size  != 0) {
    try {
    	log.debug("Sending email to Security Office and Raul")
    	Email email = new Email("no-reply@example.com")
		email.setMimeType("text/html")
		email.setTo("mraddon@example.com, security-office@example.com") 
 		email.setSubject("ALERT POSSIBLE JIRA PROJECT LEAK! " + today );	
    	email.setBody("Try to access with a low access profile user to the filter=XXX. The low access profile users only must see the project in (XX, YY) and we found other projects visible. Please fix it asap ")
    	mailServer.send(email)
    } catch (Exception e) {
        
    }



    final String webhookURL = "https://hooks.slack.com/services/ZZZ/YYY/XXXX"
    final String channelOrUserId = "#event-alerts"
    def baseUrl = ComponentAccessor.applicationProperties.getString(APKeys.JIRA_BASEURL)
    def message = "ALERT POSSIBLE JIRA PROJECT LEAK! "+ today + "Try to access with a low access profile user to the filter=XXX. The low access profile users only must see the project in (XX, YY) and we found other projects visible. Please fix it asap " 
    def client = new RESTClient("https://hooks.slack.com")
    def data = [:]

    data.put("channel", channelOrUserId)
    data.put("text", message)
    data.put("iron_emoji", ":ghost:")
    log.debug("Enviado a Slack")
    def response = client.post(
        path: new URIBuilder(webhookURL).path,
        contentType: ContentType.HTML,
        body: data,
        requestContentType: ContentType.JSON) as HttpResponseDecorator

    assert response.status == 200 : "Request failed with status $response.status. $response.entity.content.text"
}

A hug
MrAddon by TecnoFor
.

Posted by:.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s