Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Protecting Data Transfer in Documentum REST Services

0.00/5 (No votes)
13 Jun 2023 1  
In this article, we will talk about what web security related configuration parameters help protect the transfer data in the REST API and how to configure them.

Overview

Web security is a field that includes many threat models and counter-attack techniques. Since from Documentum REST Services release 7.3, we have provided users with a number of web security related configuration parameters that help to protect the transfer data in the REST API. In this article, we will talk about what they are, and how to configure them.

The security models covered in this post include:

  • Cross-site request forgery (CSRF)
  • Cross-origin resource sharing (CORS)
  • Request sanitization
  • HTTP strict transport security (HSTS)
  • Cacheable HTTPS response
  • Browser cross-site scripting (XSS)
  • Cross-frame scripting (XFS)
  • Response content sniffing

Cross-site request forgery (CSRF)

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response of a forged request. Here is a simple scenario.

  1. Alice logins to her bank account via web browser and the browser remembers a session cookie (doesn't logout).
  2. Alice visits another website that tells her she can earn some money for free.
  3. Alice clicks below form showing “Win Money!“.
HTML
<form action="https://bank.example.com/transfer.json" method="post">
    <input type="hidden" name="payee" value="MARIA"/>
    <input type="hidden" name="amount" value="100000"/>
    <input type="submit" value="Win Money!" />
</form>
  1. The request is actually redirected to her bank website with a POST method to transfer her
  2. money out from her account.
  3. Alice has no perception on the money lost because she was not asked for a second login.

In Documentum REST Services, we support Client Token cookie authentication for some specific authentication schemes, for instance, Central Authentication Services (CAS), SAML2 Web SSO and so on. The Client Token cookie can be remembered by web browsers until it times out. So the weakness of the cookie preservation exists. To protect Client Token cookie against CSRF attack, we enable CSRF prevention since Documentum REST 7.3.

Client Token authentication with CSRF token

In REST server runtime properties file, there is a parameter to turn on|off CSRF protection for Client Token cookie. The value is true by default, meaning CSRF token is required.

rest.security.csrf.enabled=true

When it is enabled, the Client Token authentication request MUST carry a CSRF token with it, either by a request header or a request query parameter. The CSRF protection design in Documentum REST Services conforms to Synchronizer Token Pattern.

Here is an example with a CSRF token in the request, where DOCUMENTUM-CSRF-TOKEN is set as the CSRF token header name by default.

GET /dctm-rest/repositories/REPO1 
DOCUMENTUM-CSRF-TOKEN: zMp3O7u5mOu37Z1SsiuN9he/OtA7YZlf5cqcMXt9HFA= 
Host: localhost:8080 
cookie: DOCUMENTUM-CLIENT-TOKEN=J9Z3J0IZHfy8ib7GB8SsxbRGTBP4UJtr49…

Here's a request with CSRF token in query parameters, where csrf-token is defined as the parameter name.

GET /dctm-rest/repositories/REPO1?csrf-token=zMp3O7u5mOu37Z1SsiuN9he/OtA7YZlf5cqcMXt9HFA= 
Host: localhost:8080 
cookie: DOCUMENTUM-CLIENT-TOKEN=J9Z3J0IZHfy8ib7GB8SsxbRGTBP4UJtr49…

Configuring CSRF token generation

A CSRF token is negotiated between the client and the server. Documentum REST Services supports to generate the CSRF token either from the client side or from the server side. There is a server runtime property to control this.

rest.security.csrf.generation.method= server | client

When the CSRF token is generated from the server side, the response for the initial authentication (Basic, CAS, SAML2, etc.) returns the CSRF parameters and token in headers. The client is expected to use these parameters for further Client Token authentications.

// Client's initial sign on 
GET /dctm-rest/repositories/REPO1 HTTP/1.1 
Host: localhost:8080 
Authorization: Basic QWRtaW5pc3RyYXRvcjpQYXNzd29yZEAxMjM=
// Server response 
HTTP/1.1 200 
DOCUMENTUM-CSRF-HEADER-NAME: DOCUMENTUM-CSRF-TOKEN 
DOCUMENTUM-CSRF-QUERY-NAME: csrf-token 
DOCUMENTUM-CSRF-TOKEN: 54msohR+0TSZbC6wrUnVUaqAOWpM2eQ7PhOEb8au+F8= 
Set-Cookie: DOCUMENTUM-CLIENT-TOKEN=cblcwodoxcK_MybUbNSejQYeX7U8dgS4F9SZeM4YIjh48…

When the CSRF token is generated from the client side, the request in the initial authentication (Basic, CAS, SAML2, etc.) provides the CSRF parameters and token in the headers. Documentum REST server takes these parameters into the generation of a Client Token cookie. The client is expected to use these parameters for further Client Token authentication.

// Client's further request 
GET /dctm-rest/repositories/REPO1 HTTP/1.1 
Host: localhost:8080 
Authorization: Basic QWRtaW5pc3RyYXRvcjpQYXNzd29yZEAxMjM= 
DOCUMENTUM-CSRF-HEADER-NAME: {csrfHeaderName} 
DOCUMENTUM-CSRF-QUERY-NAME: {csrfQueryName} 
DOCUMENTUM-CSRF-TOKEN: {csrfTokenValue}
// Server response 
HTTP/1.1 200 
Set-Cookie: DOCUMENTUM-CLIENT-TOKEN=cblcwodoxcK_MybUbNSejQYeX7U8dgS4F9SZeM4YIjh48…

Configuring HTTP methods for CSRF

As CSRF attack usually harms for requests that change the server data, a secure HTTP method (GET, OPTIONS, etc.) can be excluded from requiring the CSTF token during Client Token authentications. Documentum REST provides another server runtime property to control which HTTP methods are required for CSRF token.

rest.security.csrf.http_methods= POST,PUT,DELETE

Other properties for specifying the token header name, query name and token length are also supported in Documentum REST Services. You can refer to the Documentum REST Services Development Guide or the template file rest-api-runtime.properties.template for more details.

Cross-origin resource sharing (CORS)

Normally JavaScript clients should make requests in the same origin for a website. This restriction prevents JavaScript from making requests across domain boundaries, and has spawned various hacks for making cross-domain requests. Cross-origin resource sharing (CORS) introduces a standard mechanism that can be used by all browsers for implementing cross-domain requests. Here is a simple scenario.

  1. Alice visits a website on domain-a.acme.com
  2. The server returns a main HTML web page that contains resource access to the other
  3. domain domain-b.acme.com
JavaScript
<button onclick="callOtherDomain()">
    ClickMe
</button>
<script>
    var invocation = new XMLHttpRequest();
    var url = 'http://domain-b.acme.com';
    var callOtherDomain = function() {
        invocation.open('GET', url);
        invocation.send();
    }
</script>
  1. Alice gets errors on clicking the button ClickMe

The failure is normal because CORS prevents cross domain access from domain-a.acme.com to domain-b.acme.com. Documentum REST Services provides fine-grained CORS configuration to control REST request access from other domains. By default, cross domain access is denied.

Making cross-origin requests

Most modern web browsers have already supported CORS on the client side. CORS uses HTTP headers to control access to the remote resource. On the client side, the web browser adds a request header Origin: http://other-domain.com with the request. The server returns a CORS-specific header with the response, Access-Control-Allow-Origin: http://some-domains.com, which denotes the origin domains allowed to make requests to the API. A “*” would mean all domains are allowed.

Here is an example. The REST server is configured to accept requests with origin http://opentext.com. If the request doesn't contain a specified origin, the server will return a 403 Forbidden error.

// A cross-origin request 
GET /dctm-rest/repositories 
Host: localhost:8080 
Origin: http://opentext.com
// Server response 
HTTP/1.1 200 
Access-Control-Allow-Origin: http://opentext.com 
Access-Control-Expose-Headers: Location, DOCUMENTUM-CSRF-TOKEN 
Access-Control-Allow-Credentials: true

Many JavaScript clients send CORS preflight requests with HTTP method OPTIONS before performing the actual requests for the safety. The mechanism is similar except for an additional preflight request ahead.

// A preflight request 
OPTIONS /dctm-rest/services 
Host: localhost:8080 
Origin: http://opentext.com 
Access-Control-Request-Method: PUT 
Access-Control-Request-Headers: Location
// Server response 
HTTP/1.1 200 
Access-Control-Allow-Origin: http://opentext.com 
Access-Control-Allow-Methods: PUT 
Access-Control-Allow-Headers: Location 
Access-Control-Expose-Headers: Location, DOCUMENTUM-CSRF-TOKEN 
Access-Control-Allow-Credentials: true

Configuring CORS on server side

As mentioned earlier, cross domain access is denied by default. To enable it, Documentum REST server provides runtime properties to allow CORS access for specific domains or all domains. The value is false by default, meaning CORS is disabled. For the detail usage of these parameters, please refer to Documentum REST Services Development Guide.

rest.cors.enabled=false

rest.cors.allowed.origins=

rest.cors.allowed.methods=

rest.cors.allowed.headers= *

rest.cors.allow.credentials=true

rest.cors.exposed.headers=Location

rest.cors.max.age=3600

Request sanitization

Stored cross-site scripting allows the permanent injection of JavaScript code. This is a security vulnerability because this JavaScript code can result in the theft of user sessions. Request sanitization in Documentum REST Services cleans up user input to secure against this vulnerability. Request sanitization filters two parts of the input:

  • The input object metadata
  • The input HTML content

Here is an example of scripting injection in object metadata. When the stored property value for object_name is rendered into a HTML page, the unexpected alert box will be pop up.

JSON
{
  "name" : "document",
  "type" : "dm_document",
  "properties" : {
    "object_name" : "The<script>alert('****')</script>Document",
  }
}

When creating documents or other objects in Documentum REST Services, the server can sanitize both the metadata and the HTML content and remove any suspicious scripting code from the text. Here is the result of the object metadata sanitization for the above JSON.

JSON
{
  "name" : "document",
  "type" : "dm_document",
  "properties" : {
    "object_name" : "TheDocument",
  }
}

For HTML content sanitization, by default only html and pub_html formats are sanitized. But you can still add other formats into content sanitization by configuring runtime properties.

Configuring sanitization on server side

Sanitization is turned off by default because of its performance impact. To turn it on, Documentum REST server provides runtime properties to configure the sanitization for metadata and content, respectively. For the detail usage of these parameters, please refer to Documentum REST Services Development Guide.

rest.sanitize.type.metadata=false

rest.sanitize.type.content=false

rest.sanitize.content.max.size=500000

rest.sanitize.content.default.charset=UTF-8

rest.sanitize.content.format=html,pub_html

Please note Documentum REST Services uses OWASP AntiSamy library to sanitize the text. The sanitization policies can be configured as well by creating your own policy files. Documentum REST Services Development Guide has all the details.

Customizing sanitization

In a custom REST service development with Documentum REST SDK, you may want to enable the sanitization for your resource models. REST provides an annotation com.emc.documentum.rest.binding.SanitizeConfig which allows to customize sanitization on your own resource models. Here are examples.

Java
// Skip sanitization despite the global configuration
@SerializableType(...)
public class MyModel { 
    @SerializableField
    @SanitizeConfig(skipSanitize=true)
    private String wontBeSanitized;
    ...
}

// Enforce sanitization despite the global configuration
@SerializableType(...)
public class MyModel {
    @SerializableField
    @SanitizeConfig(enforeceSanitize=true)
    private String mustBeSanitized;
    ...
}

HTTP strict transport security (HSTS)

Some websites require HTTPS/SSL protocol on access, but allow HTTP to HTTPS redirect for client requests. This may result into man-in-the-middle attack vulnerability. Here is an example.

  1. Alice visits a website http://mybank.acme.com with her credentials in clear text.
  2. Server sends a redirect (302) response to https://mybank.acme.com.
  3. Alice visits to https://mybank.acme.com with her credentials in encrypted text.

As you can see, if a man is hijacking Alice's socket packages in the middle, he can easily obtain Alice's credentials in clear text. In this case, although host mybank.acme.com has strengthened its communication protocol to HTTPS, it doesn't protect users from leaking confidential information to attackers.

HTTP Strict Transport Security (HSTS)is a web security mechanism which helps to protect websites against protocol downgrade attacks and cookie hijacking. If a server requires HTTPS connections, it sends a header Strict-Transport-Security: max-age= in its response, telling the client that all further requests during that time span should be issued in HTTPS. If a client supports HSTS, it stores this setting in it with an expiration policy. Since the timeout could be long (e.g. one year), web browsers usually save the setting in offline storage.

Documentum REST Services adds server configuration parameters enabling HSTS response headers when the protocol is HTTPS. The Strict-Transport-Security header is enabled by default. For the detailed usage of these parameters, please refer to Documentum REST Services Development Guide.

rest.security.headers.hsts.disabled=false

rest.security.headers.hsts.include_sub_domains=true

rest.security.headers.hsts.max_age_in_seconds=31536000

When HSTS is turned on, the HTTPS response from REST server will include the Strict-Transport-Security header. Here is an example.

GET /dctm-rest/services 
Host: localhost:8443// Server response 
HTTP/1.1 200 
Strict-Transport-Security: max-age=31536000 ; includeSubDomains 
…

Cacheable HTTPS response

Unless directed otherwise, browsers may store a local cached copy of content received from web servers. If content transferred via https is stored in the local cache, it may be retrieved by other users who have access to the same computer in the future. To eliminate the vulnerability, responses should contain directives, through headers Cache-Control, Pragma and Expires, that indicate clients not to store local copies.

Since from release 7.3, Documentum REST Services has added a server runtime parameter to control headers for caching. The value is false by default, meaning cache prevention over HTTPS is enabled.

rest.security.headers.cache_control.disabled=false

When caching is disabled, the REST server response is like this.

GET /dctm-rest/services 
Host: localhost:8080
// Server response 
HTTP/1.1 200 
Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Pragma: no-cache 
Expires: 0

Browser cross-site scripting (XSS)

Cross-site scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.

  1. Alice often visits the search website http:// acme.com/find?q= for web search
  2. If there are no result for the search item, the website returns an error “404 Not Found for
  3. URL /find?q=”
  4. One day Alice receives a mail which provides a hidden link to the search website with
  5. URL http://acme.com/find?q= .
  6. Alice clicks on the link and gets a pop up message box alerting xss.
  7. If this is a malicious script written by an attacker, Alice's confidential information may be
  8. stolen silently.

One approach to prevent XSS attack is to prevent web browsers from running the scripts on the client when receiving a potentially malicious response. XSS Filter is one approach for that. When a dedicated response header X-XSS-Protection is set, the client will normalize the received response message, or even stop rendering the page.

Documentum REST Services has server configuration parameters to enable XSS protection. The value is false by default, meaning XSS protection is enabled. For the detail usage of these parameters, please refer to Documentum REST Services Development Guide.

rest.security.headers.xss_protection.disabled=false

rest.security.headers.xss_protection.explicit_enable=true

rest.security.headers.xss_protection.block=true

When XSS protection is enabled (false), the REST response message adds the HTTP header X-XSS-Protection.

// Server response 
HTTP/1.1 200 
X-XSS-Protection: 1; mode=block 
…

Cross-frame scripting (XFS)

Cross-frame scripting (XFS) is an attack that combines malicious JavaScript with an iframe that loads a legitimate page in an effort to steal data from an unsuspecting user. Here is a simple example.

  1. Alice often visits her bank web site http://mybank.acme.com.
  2. One attacker creates an evil site and sends a mail to Alice to check her account with the
  3. hidden link http://mybank.evil.com, the link points to a page hides an iframe like below.
HTML
<iframe style="position:absolute;top:-9999px" src="http://mybank.acme.com/flawed-page.html"></iframe>
  1. Alice clicks on the link and she see everything the same as mybank.acme.com.
  2. Alice logins and checks her bank account.
  3. Alice's confidential information is stolen.

One approach to eliminate frame scripting vulnerability is to prevent web browsers rendering pages within a <frame>, <iframe> or <object>. Mozilla proposed the response header X-Frame-Options to do that.

Documentum REST Services adds server runtime configuration parameters to disable frame scripting. The value is false by default, meaning frame scripting prevention is enabled.

rest.security.headers.x_frame_options.disabled=false

rest.security.headers.x_frame_options.policy=DENY

When frame scripting prevention is enabled, the REST response message adds the header X-Frame-Options.

// Server response 
HTTP/1.1 200 
X-Frame-Options: DENY 
…

Response content sniffing

Content sniffing is the practice of inspecting the content of a byte stream to attempt to deduce the file format of the data within it. It is useful when there is not a suitable mechanism between the client and server to detect the content MIME. However, it opens up a serious security vulnerability, in which, by confusing the MIME sniffing algorithm, the browser can be manipulated into interpreting data in a way that allows an attacker to carry out operations that are not expected by either the site operator or user, such as cross-site scripting.

In Documentum REST Services, the client and server negotiates the content MIME by Accept and Content-Type headers, so in most cases, there is no need for content sniffing. Further, Documentum REST Services provides a server runtime parameter to stop content sniffing. It's false by default, meaning content sniffing prevention is enabled.

rest.security.headers.content_type_options.disabled=false

When content sniffing is prevented, the response from REST server will include the header X-Content- Type-Options.

// Server response 
HTTP/1.1 200 
X-Content-Type-Options: nosniff 
…

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here