System Security Archives - ServiceNow Guru https://servicenowguru.com/tag/system-security/ ServiceNow Consulting Scripting Administration Development Tue, 08 Oct 2024 21:26:35 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 https://servicenowguru.com/wp-content/uploads/2024/05/cropped-SNGuru-Icon-32x32.png System Security Archives - ServiceNow Guru https://servicenowguru.com/tag/system-security/ 32 32 Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/ https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/#comments Mon, 10 Jun 2024 14:03:48 +0000 https://servicenowguru.com/?p=15397 This article is the 1st in a series of posts that aim to demystify the complex world of cryptography within ServiceNow. In this installment, we dive into the foundational topics of URL encoding, base64 encoding, hashing, symmetric and asymmetric encryption, hybrid encryption, and digital signatures. These cryptographic principles are essential for understanding the more advanced

The post Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission appeared first on ServiceNow Guru.

]]>
This article is the 1st in a series of posts that aim to demystify the complex world of cryptography within ServiceNow. In this installment, we dive into the foundational topics of URL encoding, base64 encoding, hashing, symmetric and asymmetric encryption, hybrid encryption, and digital signatures.

These cryptographic principles are essential for understanding the more advanced topics we will explore in subsequent articles, including a detailed look at SAML 2.0 in our second piece. This series aims to provide both newcomers and seasoned developers with a thorough understanding of cryptographic techniques used in ServiceNow.

Now, let’s begin our journey by exploring the fundamental concept of URL encoding.

Understanding URL Encoding

URL encoding is important in web development because it ensures that special characters in URLs are properly handled for internet transmission. Let’s break down the basics of URL encoding and its importance.

Why URL Encoding is Necessary?

When you construct a URL, you can’t include certain characters directly, such as spaces, question marks (?), and equals signs (=). These characters have different purposes within the URL syntax. To include them in the URL’s parameters and values, you need to encode them into a specific format.

The URL Encoding Process

URL encoding changes special characters into a text-based format so URLs can be safely sent and understood by web servers and browsers.

Example

Consider the following text that we want to include as part of a URL: “Hello World?“.  Through the URL encoding algorithm, this text is transformed into the following encoded format: “Hello%20World%3F
Here, the space is encoded as “%20“, and the question mark is encoded as “%3F“.

 

Not Encryption, but Transformation:

It’s important to understand that URL encoding is not a form of encryption. Its purpose is to convert text into a format that can be safely included in a URL, ensuring proper transmission rather than hiding the data.

Usage in ServiceNow

  1. REST API Requests: ServiceNow REST APIs often need URL encoding to handle special characters in request parameters, query strings, or resource identifiers (specific records, tables, or endpoints within the ServiceNow instance). URL encoding ensures the data in API requests is correctly formatted and interpreted by the ServiceNow instance.
  2. Integration URLs: URLs used in ServiceNow integrations, such as inbound or outbound web service integrations, may require URL encoding to manage special characters in endpoint URLs or request payloads. This encoding helps ensure smooth data exchange between ServiceNow and external systems.
  3. UI Actions and Script URLs: When setting up UI actions or script URLs in ServiceNow, URL encoding may be necessary to encode dynamic parameters or values containing special characters. This ensures that dynamically generated URLs in UI actions or scripts are correctly formatted and interpreted by the platform.

After understanding the importance of URL encoding, let’s shift our focus to another essential encoding technique utilized in ServiceNow: Base64 encoding.

Base64 Encoding in ServiceNow

Why Base64 Encoding is Necessary?

In ServiceNow, Base64 encoding addresses the need to convert binary data, such as images, compressed data, or compiled data, into a textual representation. This conversion enables the embedding of binary data into various text-based formats, such as HTML, CSS, or XML files, facilitating seamless integration and transmission across different systems and platforms.

The Base64 Encoding Process

Base64 encoding converts binary data into a text-based format using a specific encoding algorithm. This process transforms binary data into a set of ASCII characters, allowing you to safely transmit it over protocols that only support text data. Conversely, Base64 decoding reverses this process, converting the encoded text back into its original binary form.

Example

Imagine a scenario where a ServiceNow application needs to transmit binary data, such as an image file, over an HTTP request. Before transmission, the binary data undergoes Base64 encoding to convert it into a text-based representation. This encoded data can then be included in the HTTP request payload. Upon receiving the request, the ServiceNow instance decodes the Base64 encoded data to reconstruct the original binary file.

Base64 Encoding & Decoding Scripts

// Base64 Encoding Example
var binaryData = new GlideStringUtil();
var base64EncodedData = binaryData.base64Encode('Hello World'); // Base64 encode data
gs.info('Base64 Encoded Data: ' + base64EncodedData); // Log Base64 encoded data// Base64 Decoding Example
var base64EncodedData = 'SGVsbG8gV29ybGQ/'; // Base64 encoded data
var binaryData = GlideStringUtil.base64Decode(base64EncodedData); // Decode Base64 data
gs.info('Decoded Binary Data: ' + binaryData); // Log decoded binary data

Usage in ServiceNow

  1. Attachment Handling: When you upload file attachments to a ServiceNow record, ServiceNow converts the files to Base64 format before storing or sending them using REST. When you download these attachments, ServiceNow changes the Base64 data back to the original file format.
  2. Integration Payloads: In integrations between ServiceNow and external systems, you use Base64 encoding to send binary data, like images or documents, over HTTP requests or other communication methods. This ensures smooth data exchange between ServiceNow and other platforms.

Also, you often send binary data through HTTP POST requests, especially in authentication systems like SAML or OpenID Connect. In these cases, you usually convert the binary data to Base64 format before sending it via HTTP POST. If you use the Base64-encoded data in a URL, you also need to URL encode it. This process ensures that binary data is securely and reliably transmitted over text-based protocols.

Now that we’ve explored the essential encoding techniques used in ServiceNow, let’s delve into the world of hashing, a fundamental cryptographic process that ensures data integrity and security.

Hashing in Cryptography

In cryptography, hashing stands as a fundamental concept, forming the foundation of many security protocols and mechanisms. At its core, a cryptographic hashing function transforms any input data into a fixed-size text representation known as a hash or digest using hashing algorithms like SHA-256/512 or MD5. This is an irreversible process and it ensures data integrity and uniqueness.

Applications of Hashing

  1. Password Security: When storing passwords in a database, systems use hashing algorithms like SHA-256 or SHA-512 to hash the password along with any optional salt (a prefix or a postfix). To authenticate logins, the system hashes the password entered by the user using the same algorithm and compares it with the hashed password stored in the database. This ensures passwords are securely stored and enables secure logins.
  2. Data Integrity Verification: You can also hash files to generate a digest. The hashed value or digest of the file will not change unless someone tampers with the file. This helps verify data integrity during transmission.
  3. Message Authentication: Hashing ensures that messages are authentic and have maintained their integrity during transmission. In authentication systems, hashes are used to verify that the message has not been changed or tampered with.

Hashing in ServiceNow

ServiceNow prioritizes data security and integrity by using hashing algorithms like SHA-256 and SHA-512 to strengthen authentication and verify data integrity.

Hashing is also important in protocols like SAML 2.0 for checking data integrity and message authentication. We will discuss this more in the next article on SAML 2.0.

Unlocking Encryption: Key-Based Symmetric and Asymmetric Techniques

The primary goal of encryption is to safeguard confidentiality, ensuring that only intended recipients can understand the transmitted data.

In this article, we will delve into key-based encryption—a method extensively utilized in contemporary digital environments, including by platforms like ServiceNow.

We will explore two predominant types of encryption: symmetric and asymmetric, each with its unique advantages and challenges. Due to these characteristics, the industry has developed hybrid encryption, which combines the strengths of both symmetric and asymmetric methods. By understanding these three encryption types, we can better appreciate why ServiceNow adopts them and how they can help address challenges that may arise when dealing with this topic within the platform.

Let’s now explore each of them.

Symmetric Encryption: A Real-Time Approach

In symmetric encryption, you use a single key for both encrypting and decrypting data. This method is fast, uses less CPU power, and keeps the encrypted text (cipher) the same size as the original text. Such efficiency makes symmetric encryption best for applications where real-time encryption and decryption are crucial, such as secure communication channels (e.g., VPNs) or data streaming services (e.g., Netflix).

However, symmetric encryption presents a significant challenge: securely sharing the encryption key between the sender and the recipient. Without a secure mechanism for key distribution, the integrity of encrypted communication may be compromised. This necessity highlights the importance of encryption protocols and the ongoing need for robust security measures, including key management systems and secure channels for key exchange.

One commonly used algorithm in symmetric encryption is the Advanced Encryption Standard (AES). AES allows for various key lengths, such as AES-128, AES-192, and AES-256, with ServiceNow predominantly using AES-128 due to its balance between security and efficiency

Strengths of Symmetric Encryption:

  • Faster processing compared to asymmetric encryption.
  • Maintains the size of the encrypted text equal to the original plaintext.
  • Ideal for real-time encryption and decryption scenarios.

Weaknesses of Symmetric Encryption:

  • Requires secure distribution of encryption keys.
  • Vulnerable to key interception or compromise.
  • Limited scalability for large-scale encryption operations.

Example: Symmetric Encryption

In the context of symmetric encryption, let’s consider a scenario involving two users: Alice (the sender) and Bob (the recipient). They communicate over the internet, represented by a cloud icon, and exchange sensitive information securely using symmetric encryption.

 

Asymmetric Encryption: Securing Communications with Keys

To address the limitations of symmetric encryption, especially the challenge of securely sharing the secret key, cryptographers developed asymmetric encryption, also known as public-key encryption. This method uses two keys for each participant: a private key and a public key. Asymmetric encryption enhances security by allowing secure communication without the need for exchanging secret keys beforehand.

In asymmetric encryption, each participant generates a unique pair of keys: a private key and a public key. The private key is kept secure by the owner and never shared, acting as a digital signature to confirm the owner’s identity and authenticity. The public key, on the other hand, is shared freely, allowing others to send secure communications without compromising security.

The RSA algorithm is the most widely used method in asymmetric encryption. It involves a private key and a public key. Data encrypted with the public key can only be decrypted with the corresponding private key, ensuring confidentiality and security. Likewise, data signed with the private key can be verified with the public key, guaranteeing authenticity and integrity.

Now, let’s illustrate how asymmetric encryption works in practice with a scenario involving Alice and Bob:

Example: Secure Email Communication

Alice, a business executive, needs to send a confidential email containing financial reports to Bob, her colleague. To ensure the privacy and integrity of the email contents, both Alice and Bob utilize asymmetric encryption:

  • Key Generation: Both Alice and Bob generate their own pairs of asymmetric encryption keys: a Private key and a corresponding Public key. Each individual keeps their Private key securely stored and never shares it with anyone, while freely distributing their Public key to others.
  • Encryption: Before sending the email, Alice encrypts the contents using Bob’s Public key. This process transforms the plaintext email into ciphertext, ensuring that only Bob, with his corresponding Private key, can decrypt and read the message. The encrypted email is then sent to Bob via the email service provider.
  • Reception by Bob: Upon receiving the encrypted email, Bob uses his Private key to decrypt the contents. Only Bob’s Private key, known only to him, can successfully decrypt the ciphertext, revealing the original plaintext email.
  • Response: If Bob needs to respond to Alice’s email, he can encrypt his reply using Alice’s Public key. This ensures that only Alice, with her corresponding Private key, can decrypt and read the message, maintaining the security of their communication.

By leveraging asymmetric encryption with RSA keys, Alice and Bob can securely exchange sensitive information via email, confident in the confidentiality, authenticity, and integrity of their communication.

In practical implementations, the distribution and verification of public keys are facilitated by digital certificates issued by trusted Certificate Authorities (CAs). These certificates, conforming to the X.509 standard, bind public keys to identities, providing a reliable means of authentication and trust in the digital world.

Strengths of Asymmetric Encryption:

  • Private key is never shared, enhancing security.
  • Facilitates secure digital signatures and key exchange protocols.
  • Enables secure communication over insecure channels without pre-shared keys.

Weaknesses of Asymmetric Encryption:

  • Increased computational overhead compared to symmetric encryption.
  • Larger key sizes lead to larger ciphertexts and slower processing speeds.
  • Key management and distribution can pose logistical challenges in large-scale deployments.

Through asymmetric encryption with individual pairs of asymmetric encryption keys, Alice and Bob can securely exchange sensitive information via email, protecting the confidentiality, authenticity, and integrity of their email correspondence.

Hybrid Encryption: Combining the Best of Both Worlds

While symmetric encryption excels in real-time encryption and decryption scenarios, and asymmetric encryption provides secure key exchange, both methods have their limitations. Symmetric encryption requires a secure channel for key distribution, while asymmetric encryption introduces computational overhead. Hybrid encryption combines the strengths of both approaches, maximizing security in data transmission.

In hybrid encryption, symmetric encryption encrypts the actual data, while asymmetric encryption securely exchanges the symmetric key. This approach minimizes computational overhead and ensures secure key distribution, making it ideal for applications where both efficiency and security are important.

Let’s delve deeper into how hybrid encryption works through an example of secure email communication between Alice and Bob:

Example: Secure Email Communication

Alice, needing to send a large financial report to Bob, initiates the hybrid encryption process:

  • Key Generation: Alice generates a random secret key and uses symmetric encryption (e.g., AES 256) to encrypt the email contents, including any attachments.
  • Encryption of Secret Key: Alice encrypts the random secret key using Bob’s public key, ensuring that only Bob can decrypt it.
  • Secure Transfer: Alice sends the AES-encrypted data and the asymmetrically encrypted secret key to Bob through the email service provider.
  • Reception by Bob: Upon receiving the encrypted data and secret key, Bob decrypts the asymmetrically encrypted key using his private key, obtaining the original secret key. Finally, Bob uses the decrypted secret key to decrypt the AES-encrypted data, recovering the plaintext email and any attachments.

Applications automatically handle encryption and decryption using libraries. For example, when generating a SAML request, ServiceNow generates encrypted data and key information using packages, stores them in XML format, and sends them using HTTP post. ServiceNow also base64 encodes these encrypted pieces to keep the data intact during transmission.

Hybrid encryption combines the strengths of both symmetric and asymmetric methods. This approach ensures secure and efficient data exchange, providing strong protection for data as it travels.

Digital Signatures: Ensuring Data Integrity and Authenticity

In addition to encryption, digital signatures play a crucial role in securing data transmission, providing integrity and authentication. While encryption safeguards the confidentiality of data, digital signatures verify the origin and integrity of the message.

Let’s delve into how digital signatures work and how they complement encryption:

Utilizing Hashing Algorithms: Digital signatures leverage hashing algorithms to condense messages into smaller, fixed-size representations, ensuring efficient processing. These algorithms generate a unique fingerprint or digest of the original message, preserving its integrity.

Signature Generation: Suppose Alice intends to send a message to Bob. Alice first generates the message and then applies a hashing algorithm to produce a digest of the message. Next, she encrypts this digest using her private key, creating the signature. This signature serves as proof of authenticity and integrity for the message.

Signature Verification: Upon receiving the message and signature, Bob employs Alice’s public key to decrypt the signature, revealing the original digest. Independently, Bob calculates a hash of the received message. If the calculated hash matches the decrypted digest, two critical aspects are verified:

  • Integrity: Any alteration to the message would result in a different hash, ensuring that the message remains unchanged since Alice signed it.
  • Authentication: Since only Alice’s private key could have generated the signature, decrypting it with Alice’s public key confirms its authenticity. This authentication mechanism proves that Alice is the true sender of the message.

Application of Signatures: While we often associate signatures with messages, they extend beyond text-based communication. Signatures can authenticate various data forms, such as certificates, software, emails, and more. The essence of signatures lies in providing both integrity and authentication, irrespective of the data type.

Let’s illustrate the digital signature process using Alice and Bob:

Example: Signing a Data Message

Imagine Alice needs to sign a critical document or data message and send it to Bob securely. Here’s how digital signatures come into play:

  • Message Creation: Alice prepares the document or data message that needs to be signed. It could be any digital content, such as a contract, a software update, or an important report.
  • Signature Generation by Alice: Before sending the data message, Alice computes a hash (digest) of the message using a hashing algorithm like SHA256. This hash serves as a unique representation of the content. Alice then encrypts this hash using her private key, generating the digital signature.
  • Sending the Signed Message: Alice sends the data message along with the digital signature to Bob. The message contains both the original content and the attached signature.
  • Verification by Bob: Upon receiving the data message, Bob extracts the message and the attached digital signature. Using Alice’s public key, which he previously obtained or can access from a trusted source, Bob decrypts the digital signature, obtaining the hash of the original message.
  • Hash Calculation by Bob: Independently, Bob calculates the hash of the received message using the same hashing algorithm (SHA256). This calculation results in a hash value.
  • Comparing Hashes: Bob compares the hash value obtained from his calculation with the decrypted hash obtained from Alice’s digital signature. If the two hash values match, Bob can be confident that the message has not been altered since Alice signed it. This verifies the integrity of the data message.
  • Authentication: Additionally, since only Alice’s private key could have produced the digital signature that Bob successfully decrypted with Alice’s public key, Bob can authenticate that the message indeed originated from Alice.

By using digital signatures in data transmission, Alice and Bob can ensure their communication is both genuine and intact, adding more security beyond encryption.

This example shows how digital signatures make data exchange safer by keeping messages unchanged and verifying the sender’s identity.

While this example only uses digital signatures without encryption, combining both techniques often boosts security. For instance, in SAML scenarios, Alice can first sign the data with her private key, then encrypt it with Bob’s public key before sending it. Bob would then decrypt the message with his private key and verify its origin with Alice’s public key.

This hybrid method, mixing digital signatures and encryption, fully protects sensitive data during transmission, ensuring both integrity and authenticity. We’ll explore these scenarios more in our next article on SAML 2.0.

Conclusion

In this article, we explored the essential cryptographic technologies necessary for securing applications within ServiceNow. Understanding these principles sets the stage for our next discussion on SAML 2.0, where we’ll dive deeper into how these cryptographic measures are applied in implementing secure Single Sign-On (SSO) solutions. Stay tuned for more advanced topics that will further enhance your security posture in ServiceNow.

The post Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/feed/ 1
Edge Encryption and Tokenization Explained https://servicenowguru.com/system-definition/edge-encryption-tokenization-explained/ Wed, 05 Jun 2024 16:48:11 +0000 https://servicenowguru.com/?p=15898 Introduction Many people may not fully grasp what edge encryption is or how it specifically applies to platforms like ServiceNow. The intent of this writeup is not to replace ServiceNow's technical docs on edge encryption, but to give you a solid understanding of what edge encryption and tokenization actually can do for your instance's

The post Edge Encryption and Tokenization Explained appeared first on ServiceNow Guru.

]]>

Introduction

Many people may not fully grasp what edge encryption is or how it specifically applies to platforms like ServiceNow. The intent of this writeup is not to replace ServiceNow’s technical docs on edge encryption, but to give you a solid understanding of what edge encryption and tokenization actually can do for your instance’s security posture.

Edge encryption is more than just a buzzword; it represents a potentially critical layer of security that protects sensitive data at the boundaries of your network. As cyber threats become increasingly sophisticated, ensuring that data is encrypted as it enters and exits your network is essential. Without this, any data intercepted during transit could be exploited by malicious actors, leading to data breaches, financial loss, and damage to your organization’s reputation.

Two example scenarios that come to mind are healthcare systems that may be storing PHI within the HCLS module, and retail companies storing customer PII within the CSM module. Many organizations may want to keep this plaintext data out of their instance’s database completely, but still have it accessible for platform functionality. Failing to properly secure this data can have severe consequences, not only for compliance but also for the overall security and efficiency of your business operations. With edge encryption, you own your own keys and proxy servers to give you full visibility into the encryption/decryption process.

Regulations are getting stricter all the time, including data residency requirements. In addition to standard edge encryption, adding a tokenization database on your own network to the mix allows your sensitive data to live within your network and then even the ciphertext on your instance is not derived from the sensitive data (more on that in the article). The coolest thing about tokenization is that the end-user is none the wiser, as the tokenized data is swapped in their response before it’s rendered to them!

Understanding and implementing edge encryption is not just about protecting data—it’s about adding an additional layer to your platform’s  ‘defense in depth’ strategy.

But What Does It Mean?

Edge Encryption Defined

Edge Encryption is a security mechanism that encrypts sensitive data as it enters and exits a network boundary, ensuring the data is unreadable if intercepted during transit. It allows organizations to maintain control over their encryption keys and manage the data encryption process within their own infrastructure, rather than in the cloud. This is more common in highly regulated environments where highly sensitive data is being exchanged. Tokenization is an optional function that is highly valuable when sensitive data must reside within the customer’s network and NEVER be stored within the instance. Tokenization replaces sensitive data elements with a non-sensitive equivalent, called a token, which has no exploitable value. For example, a social security number can be replaced with a randomly generated string of characters that has no inherent value outside the specific context. This ensures that even if data is intercepted, it cannot be used maliciously.

Edge Encryption is a crucial security mechanism that encrypts data as it enters and exits a network boundary, ensuring that it remains unreadable if intercepted during transit. But why should you care about edge encryption? The consequences of not understanding and implementing this technology can be dire, including data breaches, loss of sensitive information, and compliance violations. On the other hand, understanding and utilizing edge encryption can empower your organization to maintain control over encryption keys and manage the data encryption process within your own infrastructure, rather than relying on cloud services. This is particularly vital in highly regulated environments where the exchange of highly sensitive data is common.

Tokenization Defined

Furthermore, tokenization is an optional yet highly valuable function that can enhance data security. When sensitive data must remain within the customer’s network and never be stored within an instance, tokenization replaces sensitive data elements with a non-sensitive equivalent, called a token, which has no exploitable value. For example, a social security number can be replaced with a randomly generated string of characters that holds no inherent value outside its specific context. This ensures that even if data is intercepted, it cannot be used maliciously.

Hover Over Each Step To Learn More

Components

Client: The client is the user or system that initiates a request to ServiceNow.

Load Balancer: The load balancer is a device or software that distributes incoming network traffic across multiple servers to ensure no single server becomes overwhelmed. It optimizes resource use, maximizes throughput, minimizes response time, and avoids overload.

Proxy Servers: Proxy servers act as intermediaries between the client and ServiceNow. They handle client requests by forwarding them to the appropriate server and can provide additional services such as encryption, caching, and request filtering.

Database for Tokenization (Optional): This optional component is used to store tokens that replace sensitive data elements. Tokenization helps protect sensitive information by substituting it with non-sensitive equivalents that can be mapped back to the original data if necessary.

ServiceNow Instance: Where the actual processing and storage of data occur. It handles the requests from the client, processes them, and returns the responses.

Zooming In On Tokenization

Tokenization involves replacing sensitive data (such as social security numbers in the below example) with unique tokens before the data is sent to and stored in the ServiceNow instance. These tokens are meaningless outside the specific context, thereby protecting the actual data even if it is intercepted and decrypted without authorization.

When implementing tokenization, your proxy servers rely on a MySQL database located within your network. This database, shared by all proxy servers, stores mappings between the clear text values and their corresponding tokens. It’s crucial to maintain regular backups of this database to avoid data loss, as losing the database means losing the ability to restore clear text values from tokens.

Here’s a comparison of how an SSN value would be stored after edge encryption with tokenization enabled versus without:

Edge Encryption Benefits

  • Encrypts sensitive data at the network edge, ensuring data remains secure both in transit and at rest.
  • Meets requirements for data residency and sovereignty by ensuring sensitive data does not leave the customer’s environment in a readable form.
  • Customers maintain complete control over encryption keys, which are managed within their infrastructure.
  • The average additional latency introduced by the encryption process is around 40ms per transaction, which is relatively low.
  • Edge Encryption also works with mobile devices
  • Offers tokenization capabilities for additional security layers, especially useful for patterns like social security numbers and credit card information.
  • Supports load-balanced configurations to ensure high availability and continuity of encryption services.
  • Provides the ability to configure which data gets encrypted, with options for field-level encryption.
  • Users interact with data as they normally would

Edge Encryption Considerations

  • Complex Setup and Maintenance: Requires a careful and sometimes complex setup of proxy servers within the customer’s network.
  • Infrastructure Requirements: Customers need to provision and maintain the necessary infrastructure for the Edge Encryption proxies and tokenization databases.
  • Limited Field Types: Edge Encryption only supports encryption for string, journal, and date fields and not for other data types like choice fields or system fields.
  • Server-Side Processing Limitations: Encrypted data cannot be used for server-side processing, such as in business rules or scripts that need to evaluate the data.
  • Customization Needs: Custom HTTP requests or integrations may require additional encryption rules to be written.
  • Key Management Responsibilities: Customers must take on the responsibility of key management, including key rotation.
  • Potential Performance Impacts for Attachments: Encrypting attachments can have a more significant performance impact, especially for larger files.
  • Impact on Reporting and Searching: Reporting capabilities can be limited, and global searches are not supported for encrypted data unless accessed through the proxy.

Key Management

Effective key management is crucial for maintaining the security of Edge Encryption. As a ServiceNow administrator, you are responsible for providing and managing the encryption keys used in this process. When setting up Edge Encryption, you need to decide whether to use AES 128-bit or AES 256-bit encryption, with a default AES 128-bit key required even if not utilized. Key storage options include file systems, Java KeyStore, or Enterprise Key Management (EKM), each with its own considerations for security and accessibility. Regular key rotation is essential to ensure ongoing security, and it may be necessary to perform a mass encryption job to re-encrypt data with new keys. Additionally, before removing an encryption key, it is critical to decrypt all associated data to prevent data loss. Key management is an extremely critical topic to understand both at a technical and functional level. Mistakes can cause major losses of data when managing your own keys. If it isn’t obvious already, it’s critical to pay attention to the documentation when implementing. If a partner is implementing for you, ensure you have the appropriate technical and architectural documentation for handoff to your team.

Conclusion

In summary, edge encryption provides an additional layer of protection by ensuring that sensitive data is encrypted as it enters and exits your network, mitigating the risk of data breaches and unauthorized access. The ability to maintain control over your encryption keys and manage the encryption process within your own infrastructure, rather than relying on a third party, offers significant security and compliance advantages.

Tokenization adds an additional layer of security to edge encryption by replacing sensitive data with non-sensitive tokens, ensuring that even if data stored on the instance is intercepted and decrypted, it will not be useful. This approach is particularly valuable for organizations handling highly sensitive information, such as healthcare systems storing PHI or retail companies managing customer PII. By combining edge encryption with tokenization, you can meet stringent regulatory requirements and enhance your overall data protection strategy.

Ultimately, integrating edge encryption into your ServiceNow instance not only safeguards your data but also reinforces your organization’s defense in depth strategy. As cyber threats continue to evolve, adopting these advanced security measures is not just beneficial—it’s necessary for maintaining the integrity and trustworthiness of your digital operations. By taking proactive steps to implement edge encryption and tokenization, you can protect your sensitive information, ensure compliance, and provide a secure environment for your users and stakeholders.

The post Edge Encryption and Tokenization Explained appeared first on ServiceNow Guru.

]]>
Leveraging User Criteria in your custom applications https://servicenowguru.com/scripting/leveraging-user-criteria-custom-applications/ https://servicenowguru.com/scripting/leveraging-user-criteria-custom-applications/#comments Mon, 03 Jun 2024 12:44:36 +0000 https://servicenowguru.com/?p=15374 User Criteria (UC) have been around on the ServiceNow platform for quite some time now. They were a welcome extension to providing a more flexible way for controlling the set of users who should or shouldn’t have access to specific records. With UCs you can define a grouping of users either by name, groups they

The post Leveraging User Criteria in your custom applications appeared first on ServiceNow Guru.

]]>
User Criteria (UC) have been around on the ServiceNow platform for quite some time now. They were a welcome extension to providing a more flexible way for controlling the set of users who should or shouldn’t have access to specific records. With UCs you can define a grouping of users either by name, groups they belong to, roles they have, or through a script.

Standard User Criteria definition form.

You can then take that UC and add/configure it on a record as having the ability to ‘can read’ or ‘cannot read’ a specific record or group of records. Probably the best known examples of this are in the OOB knowledge base and service catalog applications.

KB article can read/cannot read attributes.

Available For/Not Available For related lists on catalog items.

But what if you wanted to be able to use UCs in your custom applications? The following will provide a roadmap on how you can do this!

Lets review how UCs are used for security by using the concrete example from the knowledge base. For the Knowledge Base application there are can/cannot read attributes (KB article image shown above) on the knowledge base record as well as the individual article record.  On the knowledge base record the UCs are associated as related records and shown in the ‘Can Read’/’Cannot Read’ related lists.  On the knowledge base articles there are ‘Can Read’/’Cannot Read’ glidelist attributes directly on the record. The way the OOB security has been implemented to use those UC lists for determining if a user can read a specific knowledge article is that:

  • A user can NOT be in either the knowledge base or knowledge articles cannot read UCs to be able to read the article.
  • If there is a can read UC on the knowledge base, the user must be in the UC to read articles in the knowledge base.
  • If there is a can read UC on the knowledge article, the user must be in the UC to read the article.
  • If there are no UCs defined on either the knowledge base or article, the article is readable by any user.

This is generally the way the service catalog works as well with the catalog and catalog item.

There are other OOB applications using UCs as well….but what if you wanted to be able to use UCs in other places to control access that aren’t part of OOB applications? To do this you’d need some way of evaluating a user’s inclusion in a UC. Thankfully there is a scriptable object that does just that: UserCriteriaLoader.

UserCriteriaLoader was a utility Mike Sherman (also a long-time ServiceNow employee) and I found while trying to develop the security model for a project we were working on. It’s relatively easy to use and just needs some fairly straightforward wrappers to make it reusable for our needs.

UserCriteriaLoader has several functions on it but the main one we are going to make use of is userMatches(). The userMatches() function takes the sys_id of a user you’re checking and an array of UC sys_id’s to check against. The function then evaluates the user against those UCs and returns true/false indicating if the user is in at least one of the UCs. Something like the following:

var user = gs.getUserId();
var uc_array = [“<uc_sys_id_1>”, “<uc_sys_id_2>”, “<uc_sys_id_3>”];
var ret = sn_uc.UserCriteriaLoader.userMatches( user, uc_array);


The above is a great start as it gives you the base capability to evaluate a user’s inclusion in a set of UCs, but what we really want is a utility that wrappers the above to give us a generic way of evaluating users against UCs in the way that UCs tend to be applied to records.

The script include below gives us a reusable utility to do this in the two primary ways we found UCs to be applied to a record:

  • A glidelist directly on the record
  • A related list with references to the record and to UC’s


UserCriteriaLoader.userMatches() requires the user’s sys_user record sys_id and an array of UC record sys_ids. The ‘trick’ to the utility is converting either the glidelist or a list of related records into that array of UC record sys_ids. Let’s look at some specific examples of how to use each function.

//'UserCriteriaLoader.userMatches()' Sample Usage
var gr = new GlideRecord("my_custom_table"); //Table name of record for which are evaluating access
gr.get(""); //sys_id of record for which you are evaluating access
var user_can_read = new UserCriteria(gs.getUserID(), gr).evalUCGlideList("my_can_read", "my_cannot_read");

The above would return true/false depending on the user’s inclusion in the can/cannot read UCs. A couple of things to note:

  • The cannot read parameter on the function is optional.  If not included it is assumed that the user is NOT part of any cannot read UCs.
  • If given a cannot read parameter, the function will take it into account by determining if the given user is part of the cannot read UC(s) and if they are returning false as the ‘answer’ as being included in any can read UCs would no longer matter for functionality to be consistent with the way OOB applications us UCs.
  • The above is somewhat contrived as one of the biggest use cases is where you’d already HAVE a glide record to work with as part of the platform (BRs & ACLs mainly).

Usage when the UCs are associated via a related list is a bit more complicated….but just because data model is a more complicated. The overall approach is the same in that we want to build an array of UCs for the can read and cannot read related lists and feed them to base function. 

var gr = new GlideRecord("my_custom_table");
gr.get("");
var user_can_read = new UserCriteria(gs.getUserID(), gr).evalUCRelatedList("m2mCanTable", "canGrRefFieldName", "canUCRefFieldName", "m2mCannotTable", "cannotGrRefFieldName", "cannotUCRefFieldName");

//m2mCanTable: name of the table that contains the list of can read UCs related to the record in my_custom_table.
//canGrRefFieldName: reference to a record on my_custom_table.
//canUCRefFieldName: reference to a UC record
//m2mCannotTable: name of the table that contains the list of cannot read UCs related to the record in my_custom_table.
//cannotGrRefFieldName: reference to a record on my_custom_table
//cannotUCRefFieldName: reference to a UC record

Hopefully, this is helpful and gives the ServiceNow community an extra tool in their toolbox to solve their problems with the power of the ServiceNow platform!

NOTE:

  • UserCriteriaLoader is NOT documented on docs.servicenow.com or in developer.servicenow.com. However, if you search in OOB script includes you will see it being used. So a bit of ‘buyer beware’ but we believe it’s relatively safe to use….i.e. while not formally documented it seems unlikely that ServiceNow would deprecate the object/functions.
  • The script include given was factored for the use case/need we had at the time, it can certainly be reworked to fit your needs…but the building blocks are there for most use cases.

var UserCriteria = Class.create();
UserCriteria.prototype = {
    /**
    name: initialize
    description: Initializes the UserCriteria object by setting the user sys_id and the GlideRecord.
    param: {String} [userSysId] - sys_id of the user we want to check.
    param: {GlideRecord} [grToCheck] - GlideRecord of the record we want to check against.
    example:
    var matches = new UserCriteria(userSysID, grToCheck)
    returns: {UserCriteria} returns a initialized UserCriteria Object.
    */
    initialize: function(userSysId, grToCheck) {
        this.userSysId = userSysId;
        this.grToCheck = grToCheck;
    },

    /**
    name: evalUCGlideList
    description: Takes the field names on the table/GlideRecord that are GlideList(s) pointing too User Criteria for "Can" & "Cannot".
    param: {String} [ucCanField] - The field name of the GlideList for the "Can" User Criteria.
    param: {String} [ucCannotField] - The field name of the GlideList for the "Cannot" User Criteria.
    example:
    var matches = new UserCriteria(userSysID, grToCheck).evalUCGlideList("<can_read_uc_glidelist_field>", "<cannot_read_uc_glidelist_field>");
    returns: {boolean} Returns true if user passed in is part of any of the user criteria in the GlideList. 
    */
    evalUCGlideList: function(ucCanField, ucCannotField) {
        var ret = false;
        if (ucCannotField)
            ret = (!this._matchesUCListField(ucCannotField, false) && this._matchesUCListField(ucCanField, true));
        else
            ret = (this._matchesUCListField(ucCanField, true));

        return ret;

    },

    /**
    name: evalUCRelatedList
    description: Takes m2m tables for can and can't mappings, with ref field names of "connectors", that connects a record to User Criteria and returns true/false indicating a users access depending on related lists.
    param: {String} [m2mCanTable] - Name of the m2m table connecting the record with User Criteria 'can' access.
    param: {String} [canGrRefFieldName] - Name of the field on the m2m table that points to the GlideRecord (can access).
    param: {String} [canUCRefFieldName] - Name of the field on the m2m table that points to the User Criteria (can access).
    param: {String} [m2mCannotTable] - Name of the m2m table connecting the record with User Criteria for can't access
    param: {String} [cannotGrRefFieldName] - Name of the field on the m2m table that points to the GlideRecord (can't access).
    param: {String} [cannotUCRefFieldName] - Name of the field on the m2m table that points to the User Criteria (can't access).
    example:
    var matches = new UserCriteria(userSysID, grToCheck).evalUCRelatedList(m2mCanTable, canGrRefFieldName, canUCRefFieldName, m2mCannotTable, cannotGrRefFieldName, cannotUCRefFieldName)
    returns: {boolean} Returns true if user passed in is part of any of the user criteria in the GlideList. 
    */
    evalUCRelatedList: function(m2mCanTable, canGrRefFieldName, canUCRefFieldName, m2mCannotTable, cannotGrRefFieldName, cannotUCRefFieldName) {

        var ret = false;
        if (m2mCannotTable)
            ret = (!this._matchesUCListTable(m2mCannotTable, cannotGrRefFieldName, cannotUCRefFieldName, false) && this._matchesUCListTable(m2mCanTable, canGrRefFieldName, canUCRefFieldName, true));
        else
            ret = this._matchesUCListTable(m2mCanTable, canGrRefFieldName, canUCRefFieldName, true);
        return ret;

    },

    /**
    name: _matchesUCListField
    description: Takes the field name on the table/GlideRecord that is a GlideList pointing too User Criteria.
    param: {String} [ucField] - The field name of the GlideList for the User Criteria.
    param: {boolean} [emptyListReturn] - What to return in case the list of criteria is empty (false: for cannot read; true: for can read).

    returns: {boolean} Returns true if user passed in is part of any of the user criteria in the GlideList. 
    */
    _matchesUCListField: function(ucField, emptyListReturn) {

        var ucArray = [];
        var ucFieldValue = this.grToCheck.getValue(ucField);
        if (ucFieldValue != null)
            ucArray = ucFieldValue.split(",");

        return (ucFieldValue && !gs.isLoggedIn()) ? !emptyListReturn : this._matchesUCList(ucArray, emptyListReturn);

    },

    /**
    name: _matchesUCListTable
    description: Takes a m2m table, with ref field names of "connectors", that connects a record to User Criteria and returns true/false indicating if the user is in any of the User Criteria.
    param: {String} [m2mTable] - Name of the m2m table connecting the record with User Criteria
    param: {String} [grRefFieldName] - Name of the field on the m2m table that points to the GlideRecord.
    param: {String} [ucRefFieldName] - Name of the field on the m2m table that points to the User Criteria.
    param: {boolean} [emptyListReturn] - What to return in case the list of criteria is empty.
    
    returns: {boolean} Returns true if user passed in is part of any of the user criteria in the GlideList. 
    */
    _matchesUCListTable: function(m2mTable, grRefFieldName, ucRefFieldName, emptyListReturn) {

        //var ret = false;
        var ucArray = this._glideQuerytoArray(m2mTable, grRefFieldName, ucRefFieldName);
        return (ucArray.length > 0 && !gs.isLoggedIn()) ? !emptyListReturn : this._matchesUCList(ucArray, emptyListReturn);

    },


    /**
    name: individualUserCriteriaCheck
    description: Used to check the includance of a user in a single User Criteria. 
    param: {String} [uc] - Sys_id of a single User Criteria
    example:
    var matches = new UserCriteria(userSysID, grToCheck).individualUserCriteriaCheck("<uc_sys_id>")
    returns: {boolean} Returns true if user passed in is part of any of the user criteria. 
    */
    individualUserCriteriaCheck: function(uc) {

        var ucArrayofOne = [uc];
        return this._matchesUCList(ucArrayofOne, false);

    },

    /**
    name: _matchesUCList
    description: Makes call to OOB UserCriteriaLoader for evaluation of user/criteria and takes in to account empty user criteria.
    param: {Array} [ucArray] - Array of relevent User Criteria sys_ids.
    param: {boolean} [emptyListReturn] - what to return if User Criteria array is empty.

    returns: {boolean} boolean if user is in User Criteria passed.
    */
    _matchesUCList: function(ucArray, emptyListReturn) {

        var ret = false;
        if (this.isEmpty(ucArray))
            ret = emptyListReturn;
        else
            ret = sn_uc.UserCriteriaLoader.userMatches(this.userSysId, ucArray);
        return ret;

    },

    /**
    name: isEmpty
    description: Checks if the inpur array is empty or contains only inactive records.
    param: {Array} [ucArray] - Array of relevent User Criteria sys_ids.
    example:
    this.isEmpty(ucArray)
    returns: {boolean} True if array has no elements or if all associated records are inactive.
    */
    isEmpty: function(ucArray) {
        if (ucArray.length == 0) {
            return true;
        }
        var ucGr = new GlideRecord("user_criteria");
        ucGr.addActiveQuery();
        ucGr.addQuery("sys_id", "IN", ucArray);
        ucGr.setLimit(1);
        ucGr.query();
        return !ucGr.hasNext();
    },

    /**
    name: getAllUserCriteria
    description: Given a user sys_id returns the list of User Criteria that user is part of.
    example:
    new UserCriteria(userSysID, grToCheck).getAllUserCriteria()
    returns: {String} - List of User Criteria sys_id's that the user is part of.
    */
    getAllUserCriteria: function() {

        return sn_uc.UserCriteriaLoader.getAllUserCriteria(this.userSysId);

    },

    /**
    name: _glideQuerytoArray
    description: An internal/hidden function used to look up the related User Criteria records and build them in to an array.
    param: {String} [m2mTable] - Name of the m2m table connecting the record with User Criteria
    param: {String} [grRefFieldName] - Name of the field on the m2m table that points to the GlideRecord.
    param: {String} [ucRefFieldName] - Name of the field on the m2m table that points to the User Criteria.
    
    returns: {Array} An array of User Criteria that are related to the record via the m2m table.
    */
    _glideQuerytoArray: function(m2mTable, grRefFieldName, ucRefFieldName) {

        var ucArray = [];
        var grUC = new GlideRecord(m2mTable);
        grUC.addQuery(grRefFieldName, this.grToCheck.sys_id);
        grUC.query();
        while (grUC.next()) {
            ucArray.push(grUC.getValue(ucRefFieldName).toString());
        }

        return ucArray;
    },

    type: 'UserCriteria'
};

 

The post Leveraging User Criteria in your custom applications appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/scripting/leveraging-user-criteria-custom-applications/feed/ 6
What Everybody Should Know About ServiceNow Security https://servicenowguru.com/system-definition/servicenow-security-tips/ https://servicenowguru.com/system-definition/servicenow-security-tips/#comments Thu, 30 Jun 2011 16:56:51 +0000 https://servicenowguru.wpengine.com/?p=3638 Follow these guidelines to make sure you’re using the right security technique for every situation! Security in ServiceNow is a very important, but often very confusing subject to get the hang of. ACLs, business rules, client scripts, and UI policies can all affect the security in your system to varying levels. Improper use of any

The post What Everybody Should Know About ServiceNow Security appeared first on ServiceNow Guru.

]]>
Follow these guidelines to make sure you’re using the right security technique for every situation!

Security in ServiceNow is a very important, but often very confusing subject to get the hang of. ACLs, business rules, client scripts, and UI policies can all affect the security in your system to varying levels. Improper use of any of these security mechanisms can cause you some pretty serious problems so it’s important to know what you’re doing. In my experience as a ServiceNow consultant and administrator I’ve learned some things about ServiceNow security that I want all of my clients to know. I’ll explain these things in this article.


ServiceNow Security

Although they are often a critical part of the overall security approach for a ServiceNow instance, this article will not address the details of security restrictions that are initiated outside of a ServiceNow system. These restrictions generally fall into the following categories…

What this article will address are the details of security restrictions within the system that affect the fields on a form or list, and rows within tables.

1 – Meet your new best friend…The Access Control List (ACL)

The Contextual Security Manager should be your FIRST AND PRIMARY line of defense when it comes to security in ServiceNow. If an element or record really needs to be secured from all angles, this is the way to do it! You need to become very familiar with how to use ACLs.

2 – Client scripts and UI policies ARE NOT security!

I feel like I should have put a few more exclamation points in on this one.:) This is such an important point to make though because it’s a very common point of confusion for people getting started with ServiceNow.

It’s very simple to set up a client script or UI policy to make a field read only. This works great when you’re looking at a form because that’s the only place where client scripts and UI policies run! What isn’t as obvious is that this “security” can easily be bypassed in a variety of ways. I’m not going to detail all of these, but I will show you the most common scenario…list editing. The following screenshots show the difference in a list between a field that has been secured by an ACL and and field that has been secured by a client script or UI policy. The client script method has no effect in any place other than a loaded form so it doesn’t secure anything in the list.

Priority field locked down by an ACL

Priority Field ACL Security

State field “locked down” by a client script or UI policy

State Field Client Script UI Policy Security

While it is possible to supplement a client script or UI policy with a ‘list_edit’ ACL, this is still a poor substitute for a truly locked-down field through the use of a full ‘write’ ACL. The bottom line here is that if it really needs to be secure, client-side methods aren’t going to do the job. Client-side methods obviously have their place, but they are designed for masking certain field inputs on a form to control the process of record creation, not permanent security of a field.

3 – Don’t use dictionary settings for security

Each dictionary entry in the system has a few fields that could potentially be used to secure fields in the system. There is a ‘Read only’ checkbox, and ‘Read roles’, ‘Write roles’, ‘Create roles’, and ‘Delete roles’ fields available. The ‘Read only’ checkbox will work, but it will interfere with any ACL security that you put in place and it’s almost guaranteed to cause serious grief for someone trying to troubleshoot a security issue with that element. The ‘roles’ fields only work with the extremely old simple security model that was used several years ago before contextual security ACLs came along. Contextual security ACLs have been the default security model for several years now. The best advice I can give here is to remove these fields from your dictionary form and don’t use them. :)

If you have an instance that was created several years ago and still uses simple security, this should be readily apparent by the absence of the ‘System Security’ application in the left nav. You’re killing yourself by using the old security model and you really need to upgrade. Contact ServiceNow customer support for assistance.

 

4 – Pay attention to the ‘Row-level read’ ACL exception

There is a major exception to the use of ACLs when it comes to the read operation. It’s probably best to illustrate this with a screenshot of something that you might have seen before…
Row Level Read ACL Problem

What this screenshot illustrates is that ACLs securing the read operation for an entire row (TABLENAME instead of TABLENAME.FIELDNAME or TABLENAME.*) do not work well if you’re limiting access to some of the records within a table. The records aren’t visible, but you end up with a list that only shows you the records available for each page in the list (along with a count of all of the records that the user isn’t seeing) rather than a normal, compressed list of just those results that are available. ‘Row-level read’ ACLs should only be used when you want to restrict or grant access to every record in a table to a certain set of users. Any situation that only limits access to some of the records in a table requires the use of a ‘Before query’ business rule to avoid this problem.

I’ve written a couple of articles on ServiceNowGuru explaining how ‘Row-level read’ business rules work. You should read these articles for more details.
Controlling record access with ‘before query’ business rules
Fixing the ‘Before query’ business rule flaw

‘Before query’ business rules are also a great way to set up company or department separation in your instance. It is extremely rare for a company to need to implement something like domain separation. It’s almost always completely overkill and can be avoided through the use of a few ‘Before query’ business rules on the tables that need to be separated. You should only consider domain separation or company separation if you are working with an MSP or if you simply cannot get ‘Before query’ business rules to work.

 

5 – ‘Before’ business rules and onSubmit client scripts can be used to prevent record submission

There may be specific scenarios where you want to prevent the insertion or update of a record based on something going on in that record or form. In these cases you may use a business rule or client script to accomplish your goal. Full details on this technique can be found here.

6 – Don’t forget to add ACLs for new tables you create

It’s inevitable that you’ll need to create new tables in your ServiceNow instance. It’s important to remember that ACLs for tables don’t automatically get created for you so you have to create them if you want that table to be secure. Usually it’s enough to create some simple read, write, and delete row-level ACLs but it will depend on your setup and the purpose of the particular table.

7 – Introducing or modifying any top-level (*.*) ACL can cause SERIOUS problems

Top Level ACLs

Top-level ACLs impact the entire security structure of your system. It’s just usually not a good idea to modify them or introduce new ones, so leave them alone.

8 – Understand the ACL rule search order and precedence

This information is critical if you’re working with ACLs because there is a hierarchy of tables and fields and a precedence between different types of rules that needs to be considered. If you’ll educate yourself on this ordering, you’ll be able to make sense of contextual security much more quickly.

The post What Everybody Should Know About ServiceNow Security appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/servicenow-security-tips/feed/ 8
Identifying the Client or Session IP Address https://servicenowguru.com/scripting/identifying-client-session-ip-address/ https://servicenowguru.com/scripting/identifying-client-session-ip-address/#comments Mon, 28 Feb 2011 15:28:09 +0000 https://servicenowguru.wpengine.com/?p=3421 As a Service-now administrator or consultant, you may run into situations where it is necessary to identify the IP address of a user session before performing some action. These situations are almost always security-related. For example, you may want to restrict the ‘Delete’ operation for Change request tickets to users at a specific location, or

The post Identifying the Client or Session IP Address appeared first on ServiceNow Guru.

]]>
As a Service-now administrator or consultant, you may run into situations where it is necessary to identify the IP address of a user session before performing some action. These situations are almost always security-related. For example, you may want to restrict the ‘Delete’ operation for Change request tickets to users at a specific location, or you may want to show a particular UI action button to users whose sessions originate from a particular IP address.

I haven’t seen this type of request very often, but it is pretty simple to get this type of information in Service-now. This post shows you how.

To get the IP address of a user session you simply have to use the ‘getClientIP()’ method to pull the IP address from the current user’s session object.

//Return the current user session's IP address in string format
gs.getSession().getClientIP().toString();

Here’s another example that shows how you could use this in a security ACL script.

//Only allow permission for sessions with '101.11.41.134' IP address
var answer = false;
if(gs.getSession().getClientIP().toString() == '101.11.41.134'){
   answer = true;
}
answer;

This information is also available via the user transaction log. You can see the full transaction log by navigating to ‘System Logs -> Transactions (All User) or by navigating to ‘User Administration -> Logged in Users’ and opening one of the user session records. This method is sometimes more useful since the transactions are grouped by user session in a related list at the bottom of the transaction record.

User Transaction Log Entry

The post Identifying the Client or Session IP Address appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/scripting/identifying-client-session-ip-address/feed/ 8
Fixing the Fatal Flaw of Before Query Business Rules https://servicenowguru.com/business-rules-scripting/fixing-before-query-business-rules-flaw/ https://servicenowguru.com/business-rules-scripting/fixing-before-query-business-rules-flaw/#comments Wed, 05 Jan 2011 16:30:07 +0000 https://servicenowguru.wpengine.com/?p=3137 While this customization may still be necessary in certain situations, ServiceNow handles this issue in Aspen builds or later without any customization. I’ve written before on SNCGuru about how ‘before query’ business rules can (and should) be used to secure row-level read access to records in Service-now. While this usually works perfectly, there is one

The post Fixing the Fatal Flaw of Before Query Business Rules appeared first on ServiceNow Guru.

]]>
While this customization may still be necessary in certain situations, ServiceNow handles this issue in Aspen builds or later without any customization.

I’ve written before on SNCGuru about how ‘before query’ business rules can (and should) be used to secure row-level read access to records in Service-now. While this usually works perfectly, there is one issue that I’ve seen come up continually that there hasn’t been a good fix for. Over the past few weeks, I’ve seen several incidents and questions about inactive users disappearing from reference fields in Service-now systems. You may have noticed this yourself when you’ve de-activated users or groups in your system. The culprit in these cases is the ‘user query’ or ‘group query’ business rule.

The recommended (but really not great) solution up until this point is to turn the business rule off and use a reference qualifier on the reference field that you need to see the user in. The reason this solution is a bad one is that there are over 300 user reference and list fields in your system! Not only is that a big pain (and a bad idea) to add that reference qualifier to all of those places, but it also does nothing for the countless places (modules, filters, reports, etc.) that have UI elements that work like reference fields but cannot be filtered with a reference qualifier! This isn’t a new problem, but I’ve come up with a new (and extremely simple) solution.

‘Before Query’ business rules usually serve one of two purposes…

  1. Preventing read access to a group of records (security)
  2. Removing records from view so you don’t have to look at irrelevant data in lookups

The problem I’ll touch on in this post arises when you use ‘before query’ business rules to deal with the second point above. A prime example is the ‘user query’ business rule on the ‘User (sys_user)’ table out-of-box. That business rule looks like this…

if (!gs.hasRole("admin")) {
   current.addQuery("active", "true");
}

What this business rule says, in essence, is that users with the ‘admin’ role can read all user records in the system, and everybody else can only read active user records. On the surface, this seems like it’s exactly what you want. There’s no reason for inactive user records to be getting in the way all of the time for your technicians and end users to have to filter through. Even if they can deal with that extra nuisance, you don’t want somebody accidentally logging a ticket for, or assigning a CI to, the ‘John Smith’ that left your company 2 years ago.

Although the goal is a good one, the end result can actually end up being a big mess. If you’ve ever had one of your ‘itil’ users open up an old incident for that long-since-inactive ‘John Smith’ account you’ve seen what happens. ANY of the potentially thousands of reference field entries or filter conditions that reference that inactive user will appear to be blank for anybody without the ‘admin’ role!

Here’s an example screenshot I created of an incident record. In this case, the same user (ITIL User) opened up an incident and is also the Caller and Assignee. Right after the incident was created however, ITIL User was made inactive. The next non-admin user to open the incident would see a record with blank entries in reference fields wherever the user was listed. The values (sys_ids) are still there, but the system isn’t able to query for the inactive user because the user performing the query isn’t an admin! This results in what looks like an empty field because there isn’t a display value shown for the referenced record.

Service-now user_query Problem

How to fix the problem…

So, the obvious question becomes, “How do I fix it?”. The fix is actually a pretty simple one, but I think it helps to understand how ‘before query’ business rules work first. When the system performs a query to display a list of records, a lookup filter, or a reference field display value, it constructs the query the same way you would if you were to write a GlideRecord query in your own script.

current = new GlideRecord('sys_user');
current.addQuery(QUERY_CONDITIONS_HERE);
current.query();

A ‘before query’ business rule on a given table gets run immediately before the ‘current.query()’ line…when the query actually gets executed. So a ‘before query’ business rule gets run before the query execution, but NOT before the initial query conditions get built. What this means is that you have a chance in your ‘before query’ business rule to evaluate whatever query conditions exist and make certain decisions about how to modify the query!
For this particular case, it means that I can check to see if the query is a generic query to bring up a list, or a specific query on a SYS_ID value to pull up a specific record. When the system queries for user records to display in reference fields, filters, and report conditions the query actually looks like this at the time it hits the ‘user_query’ business rule.

current = new GlideRecord('sys_user');
current.addQuery('sys_id', USER_RECORD_SYS_ID);

Notice the absence of the ‘current.query()’ line. When a ‘before query’ business rule is run, that line hasn’t happened yet. Poking around the GlideRecord API a bit, I was able to find a method that allowed me to get the encoded query and evaluate it. What I discovered is that any time the system makes queries for reference fields, etc. the encoded query string always starts with ‘sys_id=’.

So, here’s the fix. Simply wrap your ‘addQuery’ lines in your ‘before query’ business rule in an ‘if’ statement as shown below. Any specific record queries (like those for reference fields, filters, and report conditions) will be allowed. Any other list query (like a standard list of users in a record list or reference popup) will be filtered just like normal!

if (!gs.hasRole("admin")) {
   //Check to see if this is a query for a specific ID
   if (current.getEncodedQuery().indexOf('sys_id=') != 0) {
      current.addQuery("active", "true");
   }
}

The post Fixing the Fatal Flaw of Before Query Business Rules appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/business-rules-scripting/fixing-before-query-business-rules-flaw/feed/ 22
Allow Group Managers to Manage Group Members https://servicenowguru.com/system-definition/group-managers-manage-group-members/ https://servicenowguru.com/system-definition/group-managers-manage-group-members/#comments Mon, 09 Aug 2010 19:48:22 +0000 https://servicenowguru.wpengine.com/?p=1882 I often get the request to set up access for group managers to be able to manage the members of their groups in ServiceNow. This configuration isn’t too difficult to set up but it does involve a few different pieces. It’s also important to consider your group setup in your system before allowing access in

The post Allow Group Managers to Manage Group Members appeared first on ServiceNow Guru.

]]>
I often get the request to set up access for group managers to be able to manage the members of their groups in ServiceNow. This configuration isn’t too difficult to set up but it does involve a few different pieces. It’s also important to consider your group setup in your system before allowing access in this way. If you are bringing in group memberships from a data source like LDAP for example, the last thing you want is to have your managers manually changing those group memberships within ServiceNow. The configuration shown below could be easily customized to allow access only to non-LDAP groups if you needed to do both however.



This solution requires you to modify the out-of-box ACLs for the ‘sys_user_grmember’ table. You’ll also need to modify the ‘Omit Edit Condition’ field for the ‘Group Members’ related list on the ‘Group’ form. These configurations are outlined below.

Write and Delete ACLs (‘sys_user_grmember’)
The following script can be used within your Write and Delete ACLs on the ‘sys_user_grmember’ table. No other roles or conditions are necessary for this configuration.

var answer = false; //Restrict access by default
if(gs.hasRole('user_admin') || current.group.manager == gs.getUserID()){
answer = true; //Allow access if user has 'user_admin' role or is group manager
}

Create ACL(‘sys_user_grmember’)
The create ACL works a little bit differently because we don’t have access to ‘current.group.manager’ before the record is created. Because of this, you need to open up create permissions to the role that your group managers will have. Typically these managers will have the ‘itil’ role anyway so you can just set up your ‘create’ ACL with the ‘itil’ role defined in the related list at the bottom of the ACL.
‘Restrict Changes to Group Managers’ business rule
Opening up the create ACL is necessary for this configuration to work, but needs to be backed up by some additional security in the form of a ‘before’ business rule. The business rule performs a secondary check on insert/update of the group member record to ensure that the user is actually a group manager or has the ‘user_admin’ role. If not, it aborts the insert/update and alerts the user.Name: Restrict Changes to Group Managers
Table: Group Member [sys_user_grmember]
Name: Restrict Changes to Group Managers
Before: True
Insert/Update: True
Script:

(function executeRule(current, previous /*null when async*/) {
if(!gs.hasRole('user_admin') && current.group.manager != gs.getUserID()){
//Abort the insert or update
gs.addErrorMessage('You do not have permission to modify this group membership.');
current.setAbortAction(true);
}})(current, previous);
List Control ‘Omit Edit Condition’
The final piece of controlling ‘Create’ access is to limit the visibility of the ‘Edit’ button on the ‘Group Members’ related list on the ‘Group’ form. You can manage this by right-clicking the related list header and selecting ‘Personalize -> List control’ from the context menu. You can place this script in the ‘Omit Edit Condition’ field to restrict visibility of the ‘Edit’ button on the related list to those who have the ‘user_admin’ role or are listed as the manager of the given group.

If the ‘Omit Edit Condition’ field is not visible you can add it by personalizing the ‘List Control’ form
var answer = true; //Hide the 'Edit' button by default
if(gs.hasRole('user_admin') || parent.manager == gs.getUserID()){
answer = false; //Show the 'Edit' button if user has 'user_admin' role or is group manager
}
answer;

That should do it! You may also want to create a ‘Groups’ module that is available for the role that your group managers have. This will allow your group managers easy access to the groups in the system (and with a filter access to the groups that they manage).

The post Allow Group Managers to Manage Group Members appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/group-managers-manage-group-members/feed/ 32
Controlling record access using ‘Before Query’ business rules https://servicenowguru.com/business-rules-scripting/controlling-record-access-before-query-business-rules/ https://servicenowguru.com/business-rules-scripting/controlling-record-access-before-query-business-rules/#comments Mon, 04 Jan 2010 17:44:48 +0000 https://servicenowguru.wpengine.com/?p=514 System security is probably one of the more challenging things to implement in Service-now.com.  While an out-of-box ServiceNow instance comes with the core security built-in, any implementation will inevitably have customizations in this area.  At some point, I plan on writing a basic security guide to help administrators and consultants make informed decisions about how

The post Controlling record access using ‘Before Query’ business rules appeared first on ServiceNow Guru.

]]>
System security is probably one of the more challenging things to implement in Service-now.com.  While an out-of-box ServiceNow instance comes with the core security built-in, any implementation will inevitably have customizations in this area.  At some point, I plan on writing a basic security guide to help administrators and consultants make informed decisions about how security should be implemented in their systems.

I’ve now added the security guide I promised! Check out the ‘What Everybody Should Know about ServiceNow Security‘ article for more details!

One little-known, but extremely useful access control method is to use business rules to restrict record access in your system.  You can do this by creating what I call a ‘Before Query’ business rule.  These business rules have a ‘When’ value of ‘Before’ and also have the ‘Query’ checkbox selected.  ‘Before Query’ business rules are only used when you need to restrict access to certain rows within a table for certain groups of individuals.  Because the security is controlled by a script, the restriction can be applied based on roles, group membership, company or department information from the user record, or pretty much anything else that you can derive about the user trying to access a set of records.  There are a few of these business rules out-of-box that serve as great examples of how to implement security in this way.  When I need to implement security with a ‘Before Query’ business rule, I usually start with the ‘incident query’ business rule as my template.

The purpose of the ‘incident query’ business rule is to limit the access of records (rows) on the ‘Incident’ table.  Specifically, it says that you need to have the ‘itil’ role to access incident records unless you are the person listed as the Caller or Opened by on the Incident.  It is because of this business rule that your end-users can only see their own incident records in the system!  Below is the script (along with comments explaining exactly how it works).

if (!gs.hasRole('itil') && gs.getSession().isInteractive()) { //Check if the user has the 'itil' role and if the session is an actual user session
   //If they DON'T have the 'itil' role then do the following...
   var u = gs.getUserID(); //Get the sys_id value of the current user
   var q = current.addQuery('caller_id', u); //Modify the current query on the incident table so that if the user is listed in the 'caller_id' field they can see the record
   q.addOrCondition('opened_by', u); //Also allow the user access if they are the one who opened the incident (even if they aren't the caller)
   gs.print('query restricted to user: ' + u);
}

Here’s another example. This time we will restrict visibility to records if the user is a member of the current assignment group.

if (gs.getSession().isInteractive()) {          
   //Restrict to caller or members of assigned group...
   var u = gs.getUserID(); //Get the sys_id value of the current user
   var g = getMyGroups(); //Get the list of the current user groups
   var q = current.addQuery('caller_id', u).addOrCondition('assignment_group', getMyGroups()); //Modify the current query on the incident table
}
Any time you’re working with ‘Before Query’ business rules you’ll want to be sure you account for a specific scenario you may encounter when you’re referencing the records you’re limiting access to. Setting things up incorrectly may mean that you end up with blank reference fields!

The post Controlling record access using ‘Before Query’ business rules appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/business-rules-scripting/controlling-record-access-before-query-business-rules/feed/ 33
One Field Shared Between Many Tables https://servicenowguru.com/scripting/one-field-shared-between-many-tables/ https://servicenowguru.com/scripting/one-field-shared-between-many-tables/#comments Fri, 01 Jan 2010 00:06:58 +0000 https://servicenowguru.wpengine.com/?p=594 One common problem I encounter with Service-now deployments has to do with the sharing of a field between many tables extended off of the same parent table. Because the Task table and the Configuration Item table make heavy use of extended tables this is where I see the problem most often. What is the best way to make changes to a shared field for the table that I'm working on, but not impact other tables that may be using the same field?

The post One Field Shared Between Many Tables appeared first on ServiceNow Guru.

]]>
One common problem I encounter with ServiceNow deployments has to do with the sharing of a field between many tables extended off of the same parent table. Because the Task table and the Configuration Item table make heavy use of extended tables this is where I see the problem most often. What is the best way to make changes to a shared field for the table that I’m working on, but not impact other tables that may be using the same field?

Let’s say that I’m in the middle of a Change management deployment and I’m using the ‘Configuration item’ field on my Change form. At the same time, my company is trying to roll out Incident management so there’s also someone from another department trying to make configuration changes to the ‘Configuration item’ field on the Incident form. The Incident management process says that the Configuration item field is optional while Change management says that it should be mandatory. Incident management has a very complex reference qualifier for the field, but Change management doesn’t want a reference qualifier at all. Since there is only one dictionary entry for the Configuration item field, we can’t both have our way if we are making configuration changes on the dictionary entry. Below are a few of the common scenarios where you might see this problem and how you can make it work for all tables that access the shared field.

If there’s a central theme to all of these scenarios it is that you need to pay very close attention to what you’re doing when you personalize the dictionary, label, or choices for any field on an extended table. Chances are that the field you’re personalizing is shared between other tables and you’ll end up impacting another area of the application. Hopefully if you do it’s intentional :).

1- Mandatory fields:

Although there is a checkbox on the dictionary table to make a field mandatory, it should be used ONLY when the field in question should always be mandatory in every situation for every table that uses the field. As this is very rarely the case, it’s usually much more effective just to make the decision early on to use UI policies or Client scripts to make the field mandatory when it should be.

2- Read-only fields:

See #1. The solution to this problem is a little bit different though. Because security in ServiceNow can be applied in a few different ways, you’ll want to make sure to evaluate the options closely. Most of the time, Access Control Rules are your best bet through the System Security application. Depending on the situation (and how critical it is to secure the field in question) you may want to use a UI policy or a Client script to restrict access to the field. Just remember that UI policies and Client scripts only secure an object when it is loaded on the form which may leave your field open via list editing or some other method.

3- Reference qualifiers:

If the field in question is a reference field, then it’s very likely that you’ll end up using a reference qualifier to filter the records presented by the field at some point. If the tables sharing the field don’t all need the same reference qualifier (or if some don’t need one at all) then you’ll want to use an advanced reference qualifier. Constructed properly, an advanced reference qualifier gives you the ability to identify the querying table before reference qualifier is returned. This means that you can give each table its own reference qualifier, or no qualifier at all. Here’s a sample script that could be used for a Configuration item field shared between various task tables.

function myRefQualFunction() {
var answer;
switch (current.getTableName()) {
case 'incident':
answer = 'sys_class_name=cmdb_ci_computer^ORsys_class_name=cmdb_ci_service^';
break;
case 'problem':
answer = 'sys_class_name=cmdb_ci_server^';
break;
case 'change_request':
answer = 'sys_class_name=cmdb_ci_service^';
break;
case 'change_task':
answer = 'sys_class_name=cmdb_ci_service^';
break;
default: answer = '';
}
return answer;
}

4- Labels:

This isn’t a dictionary setting, but the concept here is the same. Before you go and personalize the label for a field, you really need to be aware of all of the places that field is used. Changing the label of the ‘Configuration item’ field on the Incident form to ‘Incident CI’ would work great for incidents, but not so great for Change requests. It is possible to set up a separate label entry for the same field on each individual extended table.

5- Default values:

Setting multiple default values for extended tables has now been made much simpler (as of the Spring 2010 Stable 2 release). The solution outlined below is no longer necessary for instances running on Spring 2010 Stable 2 or later. See here for details on Dictionary Overrides.

There’s only one place to set a true default value for a field…the dictionary entry for the field. Client scripts can set default values, but that value is only applied when the form loads for a particular record. Here’s a script that I’ve used before to set different default values for the ‘State’ field on the Task table. You would place this in the ‘Default value’ field on the dictionary entry of the field in question.

javascript:
switch (current.getTableName()) {
case 'incident': '1'; break;
case 'problem': '2'; break;
case 'change_request': '1'; break;
case 'change_task': '-5'; break;
default: '1';
}

6- Choice lists:

It’s very easy just to right-click on a choice field and select ‘Personalize choices’. While this option is very simple, it doesn’t always supply you with all of the information you need to make an informed decision about how and where the choice should be added. By selecting ‘Show choice list’ you can see exactly how the choice list is set up for all tables involved. Personalizing choices for a choice field is very straight-forward, you just need to be sure of the scope of the choices you are personalizing. A ‘State’ value of ‘Pending acknowledgment’ may make perfect sense in the Incident world, but might not be useful or needed for a Change task. Fortunately, you can specify unique choice values for each extended table that shares the same field.

The post One Field Shared Between Many Tables appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/scripting/one-field-shared-between-many-tables/feed/ 8