Authored by: Anonymous
Introduction
This document provides advice for users responsible for ensuring the ongoing security of their Pega applications. It focuses on the data access security events that are written to the security events log whenever an event occurs that concerns data access, such as failed case access requests and report requests. This document also provides guidance for how to interpret the log's contents. For more information, see Security events log.
Note: Events marked with an asterisk (*) are always enabled.
Data Access Events
Fields common to all events
The following table lists the fields and their values that are the same for all data access events.
Field Name | Value/Description |
---|---|
eventCategory | “Data access event” |
outcome | “Success”
“Failure” |
ipAddress | IP address where the request originated |
nodeID | Node ID on which the request was processed |
operatorID | Operator ID issuing the request |
timestamp | Date and time of the request |
appName | Name of application |
Every open of a Work- class object on the clipboard that succeeds
Advice
Caution: Enabling this setting results in the system logging an excessive number of events. In some of these events, the system logs inadequate information. The following examples display the log entries related to the opening of case objects. The main distinction between the two events is the eventType information.
If enabled, monitor periodically for access to cases that should not be permitted. This requires knowledge of the operator’s access rights and the cases listed in the event log that have been opened. If it is determined that cases have been accessed inappropriately, you may consider blocking access to the IP address or operator issuing the requeues. In addition, determine where the security model (role or attribute based) is misconfigured and permits such access.
Event message fields
Field Name | Value/Description |
---|---|
eventType | “Obj-Open with role based access policy defined”
“Obj-Open with access control policy defined” |
className | Class name of the opened object |
WorkObjectID | Record key of the work (case) instance being accessed |
Example 1
{"actionName":"ACCESS_OPEN","appName":"Company","className":"OG1ZAA-Company-Work-Survey","eventCategory":"Data access event","eventType":"Obj-Open with role based access policy defined","id":"a9bc01be-9f35-4c44-833f-ab2489fee50b","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","requestorIdentity":"20210816T160616","tenantID":"shared","timeStamp":"Tue 2021 Oct 12, 21:29:31:925","workObjectID":"OG1ZAA-COMPANY-WORK S-2001"}
Example 2
{"actionName":"Read","appName":"Company","className":"OG1ZAA-Company-Work-Survey","eventCategory":"Data access event","eventType":"Obj-Open with access control policy defined","id":"0f0eb302-c433-4054-b152-5a24854b952a","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","requestorIdentity":"20210816T160616","tenantID":"shared","timeStamp":"Tue 2021 Oct 12, 21:29:31:925","uid":"1634074171925","workObjectID":"OG1ZAA-COMPANY-WORK S-2001"}
Every SQL query that executed
Advice
Monitor periodically. This setting generates a large volume of security events. It includes queries to open rule instances that contain complex rule-resolution logic. Search for queries that are suspicious, such as queries that would not be expected in production for the application. You must have a solid understanding of SQL to determine expected and unexpected queries.
The system also logs events for search queries which are identified by their event type. For more information, see the Event message fields table. Look for search string values that are suspicious, such as values that appear to be random or for unauthorized data. See Example 3 for a search type event.
Event message fields
Field Name | Value/Description |
---|---|
eventType | “Database query has executed”
“Native sql has executed” “Search” |
sqlQuery | The generated query |
className | Name of class being queried |
ruleName | Name of the rule from which the query is invoked |
requestorIdentity | Last signon date/time |
message | Information about the source of the query |
searchString | String specified by operator for a search based query |
Example 1
{"appName":"Company","className":"Data-Admin-Operator-ID","eventCategory":"Data access event","eventType":"Database query has executed","id":"64e92d1f-57fc-4983-88b7-9635d89b14f7","ipAddress":" Proprietary information hidden","message":"executeQuery that returns clipboardpage has invoked","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"Companyauthor","outcome":"Success","requestorIdentity":"20210803T190228","ruleName":"D_pzOperatorsByWorkGroup","sqlQuery":"SELECT DISTINCT \"PC0\".\"pyworkgroup\" AS \"pyWorkGroup\" , \"PC0\".\"pyuseridentifier\" AS \"pyUserIdentifier\" , \"PC0\".\"pyusername\" AS \"pyUserName\" , \"PC0\".\"pyposition\" AS \"pyPosition\" , \"PC0\".\"pylabel\" AS \"pyLabel\" , \"PC0\".\"pyaccessgroup\" AS \"pyAccessGroup\" , \"PC0\".\"pyreportto\" AS \"pyReportTo\" FROM pegadata.pr_operators \"PC0\" LEFT OUTER JOIN pegadata.pr_index_workgroups \"WG\" ON ( ( \"WG\".\"pyuseridentifier\" \u003d \"PC0\".\"pyuseridentifier\" ) AND \"PC0\".\"pxobjclass\" \u003d ? AND \"WG\".\"pxobjclass\" \u003d ? ) WHERE ( ( \"PC0\".\"pyworkgroup\" \u003d ? OR \"WG\".\"pyworkgroupname\" \u003d ? ) ) AND \"PC0\".\"pxobjclass\" \u003d ? ORDER BY 3 ASC","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 16:00:53:723"}
Example 2
{"appName":"Company","className":"Rule-Application","eventCategory":"Data access event","eventType":"Database query has executed","id":"4f64841f-f6c6-4398-808c-cc414a6adaac","ipAddress":" Proprietary information hidden","message":"executeRDB invoked","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"Companyauthor","outcome":"Success","requestorIdentity":"20210803T190228","sqlQuery":"SELECT pzAppName AS \"pzAppName\" FROM {CLASS:System-Application-Hierarchy-Flat} WHERE pzTopAppHash \u003d {AppChain.pyPreparedValues(1)} ","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 16:00:53:384"}
Example 3
{"appName":"Company","eventCategory":"Data access event","eventType":"Search","id":"d2445625-9b4c-466c-bc25-f7ffae65b26d","indexType":"Work","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","requestorIdentity":"20211012T195547","resultCount":"0","searchString":"s-1","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 16:36:15:087"}
Changes to report definition filters
Advice
Monitor periodically. Determine if there are frequently occurring events for the same operator, report, and filter name. If you have knowledge of the application and its reporting features, identify inappropriate filter changes. The event does not log the filter value.
Fields
Field Name | Value/Description |
---|---|
eventType | “Report filter modified” |
filterName | The name of the report filter |
message | “Report filter has been modified for the report” followed by the report name |
reportClass | Applies to class of the report |
reportID | Full report identifier |
reportName | Name of the report |
Example
{"appName":"Company","eventCategory":"Data access event","eventType":"Report filter modified","filterName":"pyPositiveCount","id":"66d584a9-eda2-4a55-a204-8e3160e50897","ipAddress":" Proprietary information hidden","message":"Report filter has been modified for the report pyListOfBinaryModels","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","reportClass":"DATA-DM-BINARYDISTRIBUTION","reportID":"RULE-OBJ-REPORT-DEFINITION DATA-DM-BINARYDISTRIBUTION PYLISTOFBINARYMODELS #20180713T143502.839 GMT","reportName":"List of binary models","requestorIdentity":"20211012T195547","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 17:39:25:238"}
Search queries
The system logs the Search event type whenever a search is requested by the user. See Example 2 below. With this setting enabled, the log includes additional information in this event type, namely the actual search query. See Example 1 below.
Advice
Monitor periodically. Identify excessive searches from a single operator and search strings that appear suspicious given the application and the operator’s access permissions.
Fields
Field Name | Value/Description |
---|---|
elasticSearchQuery | Full content of the search query |
eventType | “Search” |
indexType | “Data” or “Work” |
resultCount | Number of rows returned |
searchString | Contains the user’s input |
Example 1
{"appName":"Company","elasticSearchQuery":"{\n \"from\" : 0,\n \"size\" : 500,\n \"query\" : {\n \"bool\" : {\n \"must\" : [\n {\n \"query_string\" : {\n \"query\" : \"pyLabel:(*s-1*)^5 OR (*s-1*)\",\n \"default_field\" : \"pyNote\",\n \"fields\" : [ ],\n \"use_dis_max\" : true,\n \"tie_breaker\" : 0.0,\n \"default_operator\" : \"and\",\n \"auto_generate_phrase_queries\" : false,\n \"max_determinized_states\" : 10000,\n \"allow_leading_wildcard\" : true,\n \"enable_position_increments\" : true,\n \"fuzziness\" : \"AUTO\",\n \"fuzzy_prefix_length\" : 0,\n \"fuzzy_max_expansions\" : 50,\n \"phrase_slop\" : 0,\n \"analyze_wildcard\" : true,\n \"escape\" : false,\n \"split_on_whitespace\" : true,\n \"boost\" : 1.0\n }\n }\n ],\n \"filter\" : [\n {\n \"query_string\" : {\n \"query\" : \"pxObjClass:Data-WorkAttach-Note\",\n \"default_field\" : \"pyNote\",\n \"fields\" : [ ],\n \"use_dis_max\" : true,\n \"tie_breaker\" : 0.0,\n \"default_operator\" : \"and\",\n \"auto_generate_phrase_queries\" : false,\n \"max_determinized_states\" : 10000,\n \"allow_leading_wildcard\" : true,\n \"enable_position_increments\" : true,\n \"fuzziness\" : \"AUTO\",\n \"fuzzy_prefix_length\" : 0,\n \"fuzzy_max_expansions\" : 50,\n \"phrase_slop\" : 0,\n \"escape\" : false,\n \"split_on_whitespace\" : true,\n \"boost\" : 1.0\n }\n }\n ],\n \"disable_coord\" : false,\n \"adjust_pure_negative\" : true,\n \"boost\" : 1.0\n }\n },\n \"stored_fields\" : \"*\"\n}","eventCategory":"Data access event","eventType":"Search","id":"41478849-e6da-47cd-a6cb-f83a98dfa22a","indexType":"Data","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","requestorIdentity":"20211015T163143","resultCount":"0","searchString":"pyLabel:(s-1)^5 OR (s-1)","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 20:00:02:864"}
Example 2
{"appName":"Company","eventCategory":"Data access event","eventType":"Search","id":"9f568514-b747-483f-a114-2d7aa32d502f","indexType":"Data","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","requestorIdentity":"20211015T163143","resultCount":"0","searchString":"pyLabel:(s-2)^5 OR (s-2)","tenantID":"shared","timeStamp":"Fri 2021 Oct 15, 20:08:28:449"}
Every open of a Work- class object on the clipboard that fails due to security policies*
Advice
Monitor daily. Repeated attempts by a single operator to open cases may indicate unauthorized attempts to access data. Disable the operator or block the IP address from which the requests originate.
Fields
Field Name | Value/Description |
---|---|
className | Class name of the case type |
eventType | “Obj-Open with role based access policy defined”
“Obj-Open with access control policy defined” |
outcome | “Failure” |
workObjectID | The class name and case ID of the object |
accessControlPolicy | Name of the access control policy that denied access to the case |
accessControlPolicyCondition | Name of the policy condition that was used to deny access to the case |
actionName | The type of the access control policy |
uid | Unique identifier for this access policy decision |
Example 1 (role based policy decision)
{"actionName":"ACCESS_OPEN","appName":"Company","className":"OG1ZAA-Company-Work-Survey","eventCategory":"Data access event","eventType":"Obj-Open with role based access policy defined","id":"8e34225e-a916-465e-81bf-65e7daac06d6","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Failure","requestorIdentity":"20211018T161419","tenantID":"shared","timeStamp":"Tue 2021 Oct 19, 17:35:41:223","workObjectID":"OG1ZAA-COMPANY-WORK S-2001"}
Example 2 (access control policy decision)
{"accessControlPolicy":"SurveyAccess","accessControlPolicyCondition":"CanViewSurvey","actionName":"Read","appName":"Company","className":"OG1ZAA-Company-Work-Survey","eventCategory":"Data access event","eventType":"Obj-Open with access control policy defined","id":"8b2ead92-e7ef-4dd7-936a-2269ad2365bf","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Failure","requestorIdentity":"20211018T161419","tenantID":"shared","timeStamp":"Tue 2021 Oct 19, 17:47:10:799","uid":"1634665630751","workObjectID":"OG1ZAA-COMPANY-WORK S-2001"}
Every report definition that executed*
Advice
Monitor periodically. Locate events with report names that should not typically be run or require specific access permissions. Block the operator or IP address from which the request originates for unauthorized. but permitted, access to reports.
Fields
Field Name | Value/Description |
---|---|
eventType | "Report definition has executed" |
reportClass | Class name of the report definition |
reportID | Fully qualified name of the report definition |
reportName | Name of the report definition |
Example
{"appName":"Company","eventCategory":"Data access event","eventType":"Report definition has executed","id":"fd1ada66-c11f-4b43-b806-152b6833ff46","ipAddress":" Proprietary information hidden","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"CompanyMgr","outcome":"Success","reportClass":"INDEX-TRACKSTATUS","reportID":"RULE-OBJ-REPORT-DEFINITION INDEX-TRACKSTATUS PYDETAILEDLIST #20180713T141250.805 GMT","reportName":"py Detailed List","requestorIdentity":"20211018T161419","tenantID":"shared","timeStamp":"Tue 2021 Oct 19, 18:05:46:053"}
Every malformed request received from client*
Advice
This event is logged whenever Pega is unable to decrypt request content that contains encrypted input in either of the parameters named pzuiactionzzz or pzuiactionrrr. This likely occurs whenever a user is attempting to generate a request containing encrypted data. Such a request should never be successful and therefore should be blocked, either by the IP address or operator ID.
Monitor on a daily basis. If multiple attempts are from a particular IP address or operator, block that operator or IP address. A single, occasional instance of the log entry might indicate a flaw in the application logic. Determine what the user was doing at the time the request failed.
Fields
Field Name | Value/Description |
---|---|
encryptedString | The value of the encrypted portion of the request |
eventType | “Malformed request received from client” |
Message | Error encountered when attempting to decrypt the string |
outcome | “Failure” |
Example
{"appName":"Company","encryptedString":"CXt0cn17U1RBTkRBxUkR9OGE2ZmRlMmI5MGM5ZjdlZGE4MWJkMGFmZjU4YjI4M2RjMzQ1MDE0ZWVkOTk3ZjM4ZDc0ZGM4NjhjNzYwMWUyMmM3M2RkMjk0ZGJjMTZlMGM2ZTg1NTNiMDcxZGY4ZGQ2OWYzNzFlZjAzYWIyOWRjZjBjY2E3ZjJkZjhjZWIyNWE2M2ZhYjU4OTY3ZTk2ODc3ZTE4OTMwYTYxZWFjOGUzZGNhOGJiODEwM2E3NTg1YjMxMjI3YjA2MmEwYjY5M2RlZDVhZGYyYzJhYzYxNmZhZjg5YWNlMDdmMzFjM2FmYzE2NTJjZDgxMWNmZTkyOWI1ZGFlZDYyZGYzMTFmNDUzMQ\u003d\u003d*\u003d","eventCategory":"Data access event","eventType":"Malformed request received from client","id":"d9c3cd58-d890-4d56-8429-0816d2804543","ipAddress":" Proprietary information hidden","message":"java.lang.StringIndexOutOfBoundsException: String index out of range: -2","nodeID":"8b1bb39d3e5c4776c7b62c232ffa4133","operatorID":"Companyauthor","outcome":"Failure","requestorIdentity":"20210803T190228","tenantID":"shared","timeStamp":"Thu 2021 Oct 21, 18:39:57:027"}