OWASP_Application_Security_Verification_Standard_4.0 - scriptCode

Remote service calls

Treat any parameters entering the ScriptCode as untrusted when sending to services

In practice this means that you must strictly follow the API rules provided by the REST client. Among other things it defines how to construct the path as a list of individual address segments. Such an interface may seem unintuitive, but it provides greater security.

Sample code

Bad:

const url = "/api/form/" + context.getFirstParameter("form_id") + "/data";
const response = api.rest.v1.get("host", {pathParams: url.split("/")});

Good:

const pathParams = ["api", "form", context.getFirstParameter("form_id"), "data"];
const response = api.rest.v1.get("host", {pathParams: pathParms});
What are we protecting against?

Correct use of the API will protect us from attacks that modify the target address. Let's follow the sample code, assuming the form_id parameter comes from a form field. If a user types "abc/def" including the "/" in the field, in the first example it will be treated as part of the address and we will ultimately call the service at "/api/form/abc/def/data", which in practice may accidentally hit another service ("/api/form/{x}/{y}/data" instead of "/api/form/{x}/data", so instead of x = "abc/def" we will have x = "abc", y = "def"); whereas the code from the second example will escape that character and call the address "/api/form/abc%2Fdef/data" (so in the address "/api/form/{x}/data" the variable x will take the value "abc/def").

Handling authorization credentials for services

Authorization credentials should never be used directly in ScriptCode. In the case of calling external services (e.g. via api.rest.v1) the platform is responsible for setting the appropriate authorization data in the request to the service. If this is not supported for a given service, a request should be submitted to the PO. For services where implementation is technically impossible or will be time-consuming, consult with developers on how to securely pass the credentials. Regardless of the chosen approach, you must absolutely avoid saving authorization credentials (in code, session variables, process variables, form fields) or sending them to the frontend (form fields - including technical fields, session variables).

How to recognize problematic data? Unfortunately, due to the variety of authentication methods, it is difficult to present a complete list of such data - use common sense and pay special attention to data that grants access to services. Below is a short list of terms to help you identify such data - if you encounter them be alert:

  • login/username and password,

  • token,

  • key,

  • Authorization header,

  • API key,

  • API token,

  • bearer token,

  • JWT token.

Fetching remote resources

All resources we use (e.g.: images, documents, card images, etc.) should come from a trusted source. Most often this source is the eximee platform itself or some banking resource, and it should never be the internet. In most cases eximee restricts the use of resources only to trusted ones (e.g.: in the REST service client you can only refer to services defined by the administrator), however there may be places where such restriction is not implemented (or cannot be implemented). Each time we want to use an external source in the application (in practice some URL) we must verify whether it is a trusted source (comes from the bank's domain, arrived to us in the requirements) - if the source is not trusted, consult its use with the PO. It is unacceptable to use external services to implement functionality that is not available on the platform - in such cases a request for the functionality should be submitted.

Example problem with external resources and its consequences

On one of the printouts we had a requirement to generate a QR code based on application data. Since the platform did not have such functionality the developer decided to use an external API https://api.qrserver.com. During document generation the external service started being called https://api.qrserver.com/v1/create-qr-code/?data=${dataFormatted}&size=140x140 (dataFormatted are the data that were collected on the application), and the result of its call was placed on the printout as an image.

What are the consequences of such practice:

  1. This is an external service, we do not control it, we have no influence over its downtime periods, it may potentially disappear from the internet

  2. The licensing model was not identified - we expose our client and ourselves to legal and financial consequences of using the service in violation of its license

  3. We do not know how this external service works - it may potentially generate malicious code that we place on the printout (in the PDF) and which will be executed at the client

  4. The dataFormatted variable contained data such as the client's address or the amount of a cash deposit in the bank - these are data protected by GDPR and banking law; by using them in the link we passed them to an external entity (causing a data leak) - we expose the bank and ourselves to legal and financial consequences

Sensitive data

Use a sensitive logger to log sensitive data

Sample code

New loggers (preferred method):

New loggers by default treat every passed parameter as sensitive data. To change this behavior you must explicitly use the nonsensitive function on the parameter. Additionally, the new loggers allow placing parameters in a text template (we do not do concatenation like with the old loggers).

Bad:

Good:

Last updated

Was this helpful?