Security
For Versions 7 and above platform, security is governed by following rules:
* Standard web browsers and 'https' protocol are used. The web technology provides a first level insulation between the web server and the workstation.
* Passwords are not transferred on the network. The authentication system is based on standards. The following options are available:
1. The Windows login that is controlled in an LDAP directory,
2. An Oauth2 authentication (a redirection is done to the authentication server).
* The connection between the Sage X3 Web Server and the Sage X3 server is based on certificates that are created at installation time by a private certificate authority.
* Rights managements are done at service level and are based on function profiles associated with the user.
* The access of the Sage X3 processes to the server is restricted by a white list of authorized directories.
* On the Sage X3 Web Server, the processes and/or the services that 'node.js' and 'mongodb' do not require to be root or have administrator privileges.
One of the consequences of this is that the management of passwords that was handled by Sage X3 is now obsolete and no more used; the security rules for passwords are now managed by the security providers (google, LDAP rules) you choose.
Note: For simplicity reasons or for autonomous demo servers), a fallback solution based on users and encrypted passwords stored in the Sage X3 Web Server is available, but is not to be used for production environments.
The syracuse web server has different parameters to tune the security. The configuration is based on a dedicated security
section in the nodelocale.js
file.
The server is protected against clickjacking by adding the x-frame-options: DENY
http header.
CODECODE CODEjsexports.config = {security: {http: {headers: {// set 'x-frame-options' to enable embedding into another site via iframe// 'x-frame-options': 'allow-from http://other-site','x-frame-options': 'SAMEORIGIN', // default value is 'DENY'},},},};
Before U9.0.3
The header was directly under the
http
as follows:CODECODE CODEjsexports.config = {security: {http: {// set 'x-frame-options' to enable embedding into another site via iframe// 'x-frame-options': 'allow-from http://other-site',// 'x-frame-options': 'SAMEORIGIN','x-frame-options': 'DENY' // default value},},};
Any headers in the headers
property will be added in the response. By default, the following are added:
x-content-type-options: nosniff
: Prevents Internet Explorer and Google Chrome from MIME-sniffingx-xss-protection: 1; mode=block
: Enables the Cross-site scripting (XSS) filter built into most recent web browserscontent-security-policy: frame-ancestors 'self'
: New standard to prevent clickjacking, will allow your site only.The content-security-policy
has many directives you can use to control what the browser can render. Among all directives we can mention:
default-src
: This directive is used as default for the following more fine grained directives should they not be specified.script-src
: Trust only script sources in the listchild-src
: Deprecated: Trust only embedded content in the list. This directive will control what can be loaded in an iframe or web-workers.frame-src
: Trust only embedded content in the list. This directive will control what can be loaded in an iframe. If frame-src
is not specified it defaults to child-src
which defaults to default-src
if not present.worker-src
: Trust only web workers in the list. If worker-src
is not specified it defaults to script-src
which defaults to default-src
if not present.frame-ancestors
: Similar to the x-frame-options
header but if both exists the w3c spec mention that the frame-ancestors
must be used.Note on child-src, frame-src and worker-src
The directive frame-src
was deprecated by CSP version 2 but has recently been undeprecated in favour to child-src
.
The web standard defines frame-src
and worker-src
to be used in the future. In conclusion, it's best so specify frame-src
and worker-src
since these allow more fine grained control when using up to date browsers. Still setting child-src
to be there as a fallback for old browsers
These directives can be modified as sub-properties of content-security-policy
as follows:
CODECODE CODEjsexports.config = {security: {http: {headers: {"content-security-policy": {"frame-src": ["'self'", "www.w3schools.com"]},},},},};
Debugging content-security-policy
issues. While hardening the security configuration it may happen to many resources get blocked and make the system unusable. To avoid this, it is possible to only report potential violations but not block them effectively.
To report violations, set the property content-security-policy-report-only
instead of content-security-policy
.
The above configuration would look like:
CODECODE CODEjsexports.config = {security: {http: {headers: {"content-security-policy-report-only": {"frame-src": ["'self'", "www.w3schools.com"]},},},},};
content-security-policy
and content-security-policy-report-only
. This will block access to resources as defined in content-security-policy
while only reporting additional violations caused by directives put in content-security-policy-report-only
without blocking them.content-security-policy-report-only
will only report access violations but not block them in any way so it's very important to replace it with content-security-policy
once the configuration was successfully tested
The user interface can include some external contents by using iframe. Including such contents may corrupt the security of the site, but by adding the sandbox
attribute to the iframe HTML tags we can reduce the risk.
HTML vignettes support 3 levels (low
, medium
, high
) of security.
Per default, these levels define the sandbox attribute as follows:
low
: "allow-same-origin allow-forms allow-popups allow-scripts"
medium
: "allow-forms allow-scripts"
high
: ""
As of today, the medium level is selected per default to compute the sandbox attribute.
You can change the default authorization of the 3 levels by editing the security
section in nodelocal.js
.
Each of the 3 levels can consist of one or more of the supported elements of the sandbox attribute:
* allow-formsEnables form submission
* allow-pointer-lockEnables pointer APIs (for example pointer position)
* allow-popupsEnables popups
* allow-same-originAllows the iframe content to be treated as being from the same origin
* allow-scriptsEnables scripts
* allow-top-navigationAllows the iframe content to navigate its top-level browsing context
Examples
CODECODE CODEjsexports.config = {security: {client: {iframe: {sandbox: {// low: null, // if null no sandbox attribute will be added (not recommended)// medium: null, // if null no sandbox attribute will be added (not recommended)low: "allow-same-origin allow-forms allow-popups allow-scripts",medium: "allow-same-origin allow-forms allow-scripts",high: ""}}},},};
It's highly recommended to not set any of the security levels to null. In case of doing so please make sure to at least restrict access to resources by setting the content-security-policy
accordingly.
In general, combining the sandbox
attribute and the frame-src
and child-src
directive of the content-security-policy
provide a better control of what can be rendered in the browser.
Setup
Create 2 external links with the following url:
Create a new landing page
Add a web gadgets for both external links above
Test
By default your 2 gadgets are displayed and you can submit the form data.
For web gadgets, the medium
level is used, so in the nodelocale.js
file, change the security.client.iframe.sandbox.medium
property as follows:
CODECODE CODEjsmedium: "allow-same-origin allow-scripts",
Do the same by removing allow-same-origin
, now the demo_iframe_sandbox_origin
page cannot load the book list with the ajax request.
Finally, edit the security.http.headers
property to add a content-security-policy
header as follows:
CODECODE CODEjsexports.config = {security: {http: {headers: {"content-security-policy": {"frame-src": ["'self'"]},},},},};
Edit the security.http.headers
property to add a content-security-policy
header as follows:
CODECODE CODEjsexports.config = {security: {http: {headers: {"content-security-policy": {"default-src": ["'self'", "'unsafe-inline'"],"connect-src": ["'self'", "ws:", "wss:"],"script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'", "cdn.pendo.io", "app.pendo.io"],"img-src": ["'self'", "data:", "app.pendo.io"],"child-src": ["self"], // Compatibility for older browsers"frame-src": ["'self'"]}},},},};
As an administrator and for security purposes, it is important to be able to set allowed or forbidden protocols and encryption algorithms.
The configuration of the options used to create a TLS server can be managed by editing the security
section in the nodelocal.js
file. This configuration ensures that the TLS V1.2 protocol is used and forbids RC4 and CBC encryption.
Edit the security.tls
property to add renegotiation
and context
parameters as follows:
CODECODE CODEjsconst constants = require('constants');exports.config = {security: {tls: {// For up to date recommendations on TLS security// see https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Server_Protocol_and_Cipher_Configurationrenegotiation: {limit: 3, // default 3window: 600 // default 600 (10 minutes)},context: {// Cipher suite acceptedciphers: 'EDH+aRSA+AESGCM:EDH+aRSA+AES:EECDH+aRSA+AESGCM:EECDH+aRSA+AES:-SHA' +':ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:RSA+AESGCM:RSA+AES+SHA256:RSA+AES+SHA' +':DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA' +':!aNULL:!eNULL:!LOW:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:!ADH:!IDEA',// Use the server's cipher suite preferences instead of the client's one (recommended)honorCipherOrder: true,// Rejected protocols known as unsecured (SSL V2, V3, TLS V1.0, V1.1)secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1}}},};
Here are several tests you can run to ensure that the TLS security level meets the requirements.
These tests consider that an HTTPS server is running on port 8126. The standard port of an HTTPS server is 443.
CODECODE CODEsh$ openssl s_client -tls1 -connect localhost:8126CONNECTED(00000204)no peer certificate availableNo client certificate CA names sentSSL handshake has read 0 bytes and written 0 bytesNew, (NONE), Cipher is (NONE)Secure Renegotiation IS NOT supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:Protocol : TLSv1Cipher: 0000Session-ID:Session-ID-ctx:Master-Key:Key-Arg : NonePSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1529961360Timeout : 7200 (sec)Verify return code: 0 (ok)20556:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:
CODECODE CODEsh$ openssl s_client -cipher ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA -connect localhost:8126CONNECTED(00000220)no peer certificate availableNo client certificate CA names sentSSL handshake has read 7 bytes and written 150 bytesNew, (NONE), Cipher is (NONE)Secure Renegotiation IS NOT supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:Protocol : TLSv1.2Cipher: 0000Session-ID:Session-ID-ctx:Master-Key:Key-Arg : NonePSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1529961371Timeout : 300 (sec)Verify return code: 0 (ok)10480:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:802:
CODECODE CODEsh$ openssl s_client -cipher SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:PSK-AES256-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:IDEA-CBC-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA -connect localhost:8126CONNECTED(00000218)no peer certificate availableNo client certificate CA names sentSSL handshake has read 7 bytes and written 158 bytesNew, (NONE), Cipher is (NONE)Secure Renegotiation IS NOT supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:Protocol : TLSv1.2Cipher: 0000Session-ID:Session-ID-ctx:Master-Key:Key-Arg : NonePSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1529961383Timeout : 300 (sec)Verify return code: 0 (ok)16904:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:802:
CODECODE CODEsh$ openssl s_client -cipher RC4-SHA:RC4-MD5:DES-CBC3-SHA:ECDHE-RSA-AES256-GCM-SHA384 -connect localhost:8126CONNECTED(00000208)Certificate chain0 s:/CN=....i:/C=....1 s:/C=....i:/C=...Server certificate-----BEGIN CERTIFICATE----------END CERTIFICATE-----subject=/CN=....issuer=/C=....No client certificate CA names sentPeer signing digest: SHA512Server Temp Key: ECDH, P-256, 256 bitsSSL handshake has read 2368 bytes and written 272 bytesNew, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384Server public key is 2048 bitSecure Renegotiation IS supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:Protocol : TLSv1.2Cipher: ECDHE-RSA-AES256-GCM-SHA384Session-ID: ....Session-ID-ctx:Master-Key: .....Key-Arg : NonePSK identity: NonePSK identity hint: NoneSRP username: NoneTLS session ticket lifetime hint: 300 (seconds)TLS session ticket:....Start Time: 1529961397Timeout : 300 (sec)Verify return code: 19 (self signed certificate in certificate chain)depth=1 C = ....verify error:num=19:self signed certificate in certificate chainread:errno=10093
CODECODE CODEsh$ openssl s_client -connect localhost:8126CONNECTED(00000134)Certificate chain0 s:/CN=....i:/C=....1 s:/C=....i:/C=...Server certificate-----BEGIN CERTIFICATE----------END CERTIFICATE-----subject=/CN=....issuer=/C=....No client certificate CA names sentPeer signing digest: SHA512Server Temp Key: ECDH, P-256, 256 bitsSSL handshake has read 2368 bytes and written 434 bytesNew, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384Server public key is 2048 bitSecure Renegotiation IS supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:Protocol : TLSv1.2Cipher: ECDHE-RSA-AES256-GCM-SHA384Session-ID: ....Session-ID-ctx:Master-Key: .....Key-Arg : NonePSK identity: NonePSK identity hint: NoneSRP username: NoneTLS session ticket lifetime hint: 300 (seconds)TLS session ticket:....Start Time: 1529961553Timeout : 300 (sec)Verify return code: 19 (self signed certificate in certificate chain)depth=1 C = ....verify error:num=19:self signed certificate in certificate chainread:errno=10093