The CreatorCon Call for Content is officially open! Get started here.

Help with Scripted Rest API

Abhijit Das7
Tera Expert

Hi Everyone,

 

I have created a custom Scripted Rest API, using which we post data into work notes of Incident, cases, work orders...etc. Data like screenshot, text, surveys which is in JSON format, and it is coming from third party application.

 

This functionality is working fine but when I try to do Scan Application, I get following scan finding..."REST Web Services writing data directly."

fy.png

 

How should I resolve this scan finding. In place of updating data directly, if I have to pass JSON data from Scripted Rest API to Script Include, how can I do that where I call a script include in scripted rest Api and pass JSON data from Scripted Rest API to Script Include and then update screenshot, text, surveys, etc. in incidents, cases...

 

Thanks in advance

4 REPLIES 4

MackI
Kilo Sage

hi @Abhijit Das7 

 

I hope you are doing good and well.

 

It would be better if you mentioned the third party application name then I can analyze their API Documentation from my library.

 

Anyways ..

 I understand the issue. You have a Scripted REST API that directly updates records (like adding work notes to Incidents), and the ServiceNow Scan feature is flagging this as a potential security risk. You want to refactor your code to pass the JSON payload to a Script Include, which will then handle the data updates, adhering to ServiceNow best practices.

Here's a breakdown of how to resolve the "REST Web Services writing data directly" scan finding and implement the recommended approach using a Script Include:

Understanding the Scan Finding

The scan finding "REST Web Services writing data directly" highlights a potential security vulnerability. Directly updating records within a Scripted REST API resource can make your code:

Less Maintainable: Mixing API logic with data update logic can lead to complex and harder-to-maintain code.
Less Secure: It might be more difficult to implement proper access controls and data validation when updates are done directly within the API resource.
Less Reusable: Separating data update logic into a Script Include promotes reusability across different parts of your application.

Solution: Scripted REST API + Script Include

Here's how to refactor your code to address the scan finding:

1. Create a Script Include (if you don't have one already):

 

 

 

var WorkNoteUtils = Class.create();
WorkNoteUtils.prototype = {
    initialize: function() {},

    addWorkNotesFromJSON: function(record, jsonData) {
        // 1. Parse the JSON data
        var parsedData = JSON.parse(jsonData);

        // 2. Validate the JSON data (IMPORTANT!)
        if (!this.isValidWorkNoteData(parsedData)) {
            gs.error("Invalid JSON data received for work notes.");
            return; // Or throw an error
        }

        // 3. Extract data from the parsed JSON
        var text = parsedData.text;
        var screenshot = parsedData.screenshot; // Assuming you handle screenshots as attachments
        var surveyData = parsedData.survey; // Assuming you have a custom table for survey data

        // 4. Update the record (Incident, Case, etc.)
        record.work_notes = text; // Add text to work notes

        // 5. Handle Screenshot (Attachment) - Example
        if (screenshot) {
            this.addAttachment(record, screenshot);
        }

        // 6. Handle Survey Data (Custom Table) - Example
        if (surveyData) {
            this.createSurveyRecord(record, surveyData);
        }

        record.update();
    },

    // Helper Functions:

    isValidWorkNoteData: function(data) {
        // Implement your validation logic here
        // Check if required fields are present, data types are correct, etc.
        // Example:
        if (gs.nil(data.text)) {
            return false;
        }
        // ... more validation ...
        return true;
    },

    addAttachment: function(record, screenshotData) {
        // Example: Assuming screenshotData is a base64 encoded string
        try {
            var attachment = new GlideSysAttachment();
            var fileName = "screenshot_" + gs.nowDateTime() + ".png"; // Example file name
            var contentType = "image/png"; // Example content type

            // Assuming screenshotData is base64 encoded
            var attachmentId = attachment.write(record, fileName, contentType, GlideStringUtil.base64DecodeAsBytes(screenshotData));
             gs.info("attachmentId"+attachmentId);
        } catch (e) {
            gs.error("Error adding attachment: " + e);
        }
    },

    createSurveyRecord: function(record, surveyData) {
        // Example: Create a record in a custom survey table
        try {
            var surveyRecord = new GlideRecord("u_survey_data"); // Replace u_survey_data with your custom table name
            surveyRecord.initialize();
            surveyRecord.u_related_record = record.getUniqueValue(); // Link to the Incident, Case, etc.
            surveyRecord.u_survey_response = JSON.stringify(surveyData); // Store survey data
            // ... set other fields as needed ...
            surveyRecord.insert();
        } catch (e) {
            gs.error("Error creating survey record: " + e);
        }
    },

    type: 'WorkNoteUtils'
};

 

 

 

2. Modify Your Scripted REST API Resource: ( You need to develop or update your REST API Script )
 
I can provide you details solution in a link , if you tell me details project story and marked my solution approach as Accepted Solution 
 
If you like this opinion and your problem is resolved after reviewing and applying it. Please kindly mark this your best answer (Accepted Solution) ‌🌠‌ OR  mark it  Helpful ‌‌ if you think that you get some insight from this content relevant to your problem and help me to contribute more to this community
 
 
 
 
 
 
2. Modify Your Scripted REST API Resource:
MackI | ServiceNow Technical Consultant | DXC Technology Australia | ServiceNow Practice | LinkedIn Top IT Operation Voice 2023 | Sydney,Australia

Ankur Bawiskar
Tera Patron
Tera Patron

@Abhijit Das7 

the finding tells you the source -> open that scripted rest api and share what's the script.

would like to see how that scripted rest api is performing the job.

1 way to overcome is pass the JSON to script include, invoke it from scripted rest api and let the script include function do the job

This scan finding will be resolved.

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

@Abhijit Das7 

Hope you are doing good.

Did my reply answer your question?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

@Abhijit Das7 

Hope you are doing good.

Did my reply answer your question?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader