Help with Scripted Rest API
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-15-2025 03:49 AM
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."
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-15-2025 04:13 AM
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 ..
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'
};
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-15-2025 04:27 AM
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.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-16-2025 04:29 AM
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.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-09-2025 01:10 AM
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.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader