Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sap/xssec

Package Overview
Dependencies
Maintainers
3
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sap/xssec - npm Package Compare versions

Comparing version 2.1.16 to 2.2.3

22

CHANGELOG.md
# Change Log
All notable changes to this project will be documented in this file.
## 2.2.3 - 2019-08-07
- Add retry for recieving keys
## 2.2.2 - 2019-06-24
- Use verification key from binding as backup if online key retrieval fails
## 2.2.1 - 2019-06-17
- Fix uaaDomain comparison in key cache
## 2.2.0 - 2019-06-17
- Align key cache implementation with other container security libraries
## 2.1.17 - 2019-05-17
- Introduce http timeout of two seconds
- Update version of module debug, lru-cache and @sap/xsenv
- Fix token verification for broker master instance subscriptions
## 2.1.16 - 2019-01-28

@@ -5,0 +27,0 @@

56

lib/keycache.js
'use strict';
var constants = require('./constants');
var request = require('request');
var request = require('requestretry');
var LRU = require('lru-cache');

@@ -82,8 +82,8 @@ var validUrl = require('valid-url');

KeyCache.prototype.getKey = function getKey(keyId, uaaUrl, cb) {
KeyCache.prototype.getKey = function getKey(tokenKeyUrl, keyId, cb) {
var self = this;
if ((keyId === null) || (keyId === undefined)) {
if ((tokenKeyUrl === null) || (tokenKeyUrl === undefined)) {
var error = new Error(
'Parameter keyId null or undefined. To read a key from the KeyCache with function KeyCache.getKey, you need to specify parameter keyId.');
'Parameter tokenKeyUrl null or undefined. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.');
return process.nextTick(function() {

@@ -93,5 +93,5 @@ cb(error, null);

}
if ((uaaUrl === null) || (uaaUrl === undefined)) {
if (validUrl.isHttpsUri(tokenKeyUrl) === undefined) {
var error = new Error(
'Parameter uaaUrl null or undefined. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter uaaUrl as a valid https URL.');
'Parameter tokenKeyUrl is not a valid https URL. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter tokenKeyUrl as a valid https URL.');
return process.nextTick(function() {

@@ -101,5 +101,5 @@ cb(error, null);

}
if (validUrl.isHttpsUri(uaaUrl) === undefined) {
if ((keyId === null) || (keyId === undefined)) {
var error = new Error(
'Parameter uaaUrl is not a valid https URL. To enable the KeyCache reading keys from the UAA which are yet unavailable in the cache, you need to specify parameter uaaUrl as a valid https URL.');
'Parameter keyId null or undefined. To read a key from the KeyCache with function KeyCache.getKey, you need to specify parameter keyId.');
return process.nextTick(function() {

@@ -110,8 +110,8 @@ cb(error, null);

debugTrace('Looking for key with keyID: "' + keyId + '" in cache.');
var cacheKey = tokenKeyUrl + keyId;
debugTrace('Looking for key "' + cacheKey + '" in cache.');
// Check whether keyid is in cache
var tmpResult = this.lruCache.get(keyId);
var tmpResult = this.lruCache.get(cacheKey);
if (tmpResult !== undefined) {
debugTrace('Key with keyID: "' + keyId
+ '" found in cache. Returning key "' + tmpResult + '".');
debugTrace('Key with keyID: "' + keyId + '" found in cache. Returning key "' + tmpResult + '".');
return process.nextTick(function() {

@@ -123,4 +123,3 @@ cb(null, tmpResult);

// UAA
var error = new Error('Key with keyID: "' + keyId
+ '" not found in cache. Configuration says not to query UAA.');
var error = new Error('Key "' + cacheKey + '" not found in cache. Configuration says not to query UAA.');
return process.nextTick(function() {

@@ -132,7 +131,9 @@ cb(error, null);

var options = {
url : uaaUrl + this.tokenKeyPath
url : tokenKeyUrl,
timeout: 2000,
maxAttempts: 3,
retryDelay: 500,
retrySrategy: request.RetryStrategies.HTTPOrNetworkError
};
debugTrace('Key with keyID: "' + keyId
+ '" not found in cache. Querying keys from UAA via URL "'
+ options.url + '".');
debugTrace('Key "' + cacheKey + '" not found in cache. Querying keys from UAA via URL "' + options.url + '".');
request

@@ -142,3 +143,9 @@ .get(

function(err, response, body) {
if (response) {
debugTrace('Finished after number of requests attempts: ' + response.attempts);
}
if (err) {
if (err.code === 'ETIMEDOUT' && err.connect === true) {
debugError('getKey: HTTP connection timeout.');
}
debugError('An error occurred when reading the token keys from '

@@ -173,3 +180,3 @@ + options.url

// breaks before adding the key to the cache
self.addKey(json.keys[i].kid,
self.addKey(tokenKeyUrl + json.keys[i].kid,
json.keys[i].value.replace(

@@ -187,7 +194,5 @@ /(\r\n|\n|\r)/gm, ''));

}
var tmpResult = self.lruCache.get(keyId);
var tmpResult = self.lruCache.get(cacheKey);
if (tmpResult !== undefined) {
debugTrace('Key with keyID: "' + keyId
+ '" found in cache. Returning key "'
+ tmpResult + '".');
debugTrace('Key "' + cacheKey + '" found in cache. Returning key "' + tmpResult + '".');
return process.nextTick(function() {

@@ -198,5 +203,4 @@ cb(null, tmpResult);

var error = new Error(
'Obtained token keys from UAA, but key with requested keyID "'
+ keyId
+ '" still not found in cache.');
'Obtained token keys from UAA, but key with requested keyID "' +
cacheKey + '" still not found in cache.');
return process.nextTick(function() {

@@ -203,0 +207,0 @@ cb(error, null);

@@ -182,15 +182,15 @@ 'use strict';

var applicationPlan = false;
if (result.cid.indexOf('!t') !== -1) {
applicationPlan = true;
var subscriptionsAllowed = false;
if (result.cid.indexOf('!t') !== -1 || result.cid.indexOf('!b') !== -1) {
subscriptionsAllowed = true;
}
if ((result.cid === self.config.clientid)
&& (result.zid === self.config.identityzoneid || applicationPlan === true)) {
&& (result.zid === self.config.identityzoneid || subscriptionsAllowed === true)) {
// clientid and identity zone of the token must match with the values of the application
// (if the token was issued for the xsuaa application plan it is sufficient that the clientid matches)
if (applicationPlan === false) {
// (if the token was issued for the xsuaa application or broker plan it is sufficient that the clientid matches)
if (subscriptionsAllowed === false) {
debugTrace('\nClient Id and Identity Zone of the access token match\n'
+ 'with the current application\'s Client Id and Zone.');
} else {
debugTrace('\nClient Id of the access token (XSUAA application plan) matches\n'
debugTrace('\nClient Id of the access token (XSUAA application or broker plan) matches\n'
+ 'with the current application\'s Client Id.');

@@ -572,3 +572,2 @@ }

}
var uaaURLString = config.url;
var invalidatedTokenHeaderJSON = null;

@@ -585,38 +584,17 @@ try {

invalidatedTokenHeaderJSON = JSON.parse(invalidatedTokenHeaderString);
if (!invalidatedTokenHeaderJSON.kid || invalidatedTokenHeaderJSON.kid == 'legacy-token-key') {
if (!invalidatedTokenHeaderJSON.kid || invalidatedTokenHeaderJSON.kid == 'legacy-token-key' || !invalidatedTokenHeaderJSON.jku) {
return cb(null, config.verificationkey);
}
var invalidatedTokenContentBuffer = new Buffer(invalidatedTokenParts[1], 'base64');
var invalidatedTokenContentString = invalidatedTokenContentBuffer.toString('utf8');
var invalidatedTokenContentJSON = JSON.parse(invalidatedTokenContentString);
if (!invalidatedTokenContentJSON.iss) {
var error = new Error('JWT token contains no iss field. Giving up.', null);
error.statuscode = 400;
return cb(error);
}
var tokenIssuer = invalidatedTokenContentJSON.iss;
var tokenIssuerURL = url.parse(tokenIssuer);
var tokenIssuerURLHostname = tokenIssuerURL.hostname;
var tokenIssuerURLIDZIndex = tokenIssuerURLHostname.indexOf('.');
if (tokenIssuerURLIDZIndex < 0) {
debugTrace('\nUnexpected Issuer Format in JWT. Use legacy-token-key.');
return cb(null, config.verificationkey);
}
var tokenIssuerIDZ = tokenIssuerURLHostname.substring(0, tokenIssuerURLIDZIndex);
debugTrace('\nIdentity zone of token issuer: '+tokenIssuerIDZ+'\n');
var uaaURL = url.parse(uaaURLString);
var uaaURLHostname = uaaURL.hostname;
var uaaURLIDZIndex = uaaURLHostname.indexOf('.');
if (uaaURLIDZIndex < 0) {
var error = new Error('Unexpected format of UAA URL in configuration. Giving up.', null);
error.statuscode = 500;
return cb(error);
}
var uaaURLHostnameWithoutIDZ = uaaURLHostname.substring(uaaURLIDZIndex, uaaURLHostname.length);
var newHostname = tokenIssuerIDZ + uaaURLHostnameWithoutIDZ;
uaaURL.hostname = newHostname;
uaaURL.host = null;
uaaURLString = url.format(uaaURL);
return keyCache.getKey(invalidatedTokenHeaderJSON.kid, uaaURLString, cb);
validateJku(invalidatedTokenHeaderJSON.jku, config.uaadomain, function(err) {
if (err) {
return cb(null, config.verificationkey);
}
keyCache.getKey(invalidatedTokenHeaderJSON.jku, invalidatedTokenHeaderJSON.kid, function(err, key) {
if (err) {
return cb(null, config.verificationkey);
} else {
return cb(null, key);
}
});
});
} catch (e) {

@@ -628,2 +606,17 @@ e.statuscode = 403;

function validateJku(jkuUrl, uaaDomain, cb) {
if (uaaDomain === null || uaaDomain === undefined) {
var errorString = 'Service is not properly configured in \'VCAP_SERVICES\', attribute \'uaadomain\' is missing. Use legacy-token-key.';
debugTrace('\n' + errorString);
return cb(new Error(errorString));
}
var tokenKeyUrl = url.parse(jkuUrl);
if (tokenKeyUrl.hostname.substring(tokenKeyUrl.hostname.indexOf(uaaDomain), tokenKeyUrl.hostname.length) !== uaaDomain) {
var errorString = 'JKU of the JWT token (' + jkuUrl + ') does not match with the uaa domain (' + uaaDomain + '). Use legacy-token-key.';
debugTrace('\n' + errorString);
return cb(new Error(errorString));
}
cb(null);
}
function checkTokenLocal(accessToken, verificationkey, ssojwt, cb) {

@@ -737,3 +730,4 @@

bearer: securityContext.token
}
},
timeout: 2000
};

@@ -751,2 +745,5 @@ if (scopes !== null) {

if (error) {
if (error.code === 'ETIMEDOUT' && error.connect === true) {
debugError('requestToken: HTTP connection timeout.');
}
debugError(error.message);

@@ -777,3 +774,4 @@ debugError(error.stack);

pass: serviceCredentials.clientsecret
}
},
timeout: 2000
};

@@ -784,2 +782,5 @@ request.post(

if (error) {
if (error.code === 'ETIMEDOUT' && error.connect === true) {
debugError('requestToken: HTTP connection timeout.');
}
debugError(error.message);

@@ -844,3 +845,4 @@ debugError(error.stack);

pass: serviceCredentials.clientsecret
}
},
timeout: 2000
};

@@ -855,2 +857,5 @@ if (additionalAttributes !== null) {

if (error) {
if (error.code === 'ETIMEDOUT' && error.connect === true) {
debugError('requestToken: HTTP connection timeout.');
}
debugError(error.message);

@@ -857,0 +862,0 @@ debugError(error.stack);

@@ -1,1 +0,1 @@

{"bundleDependencies":false,"dependencies":{"@sap/node-jwt":"^1.4.13","@sap/xsenv":"^1.2.9","debug":"3.1.0","lru-cache":"4.1.1","request":"2.88.0","valid-url":"1.0.9"},"deprecated":false,"description":"XS Advanced Container Security API for node.js","devDependencies":{"filter-node-package":"2.0.0","istanbul":"^0.4.5","jwt-decode":"^2.2.0","mocha":"^5.1.0","should":"^13.2.1"},"keywords":["xs"],"main":"./lib","name":"@sap/xssec","repository":{"type":"git"},"scripts":{"prepareRelease":"clean-packages && npm prune --production","test":"make test"},"version":"2.1.16","license":"SEE LICENSE IN developer-license-3.1.txt"}
{"bundleDependencies":false,"dependencies":{"@sap/node-jwt":"^1.5.2","@sap/xsenv":"^2.0.0","debug":"4.1.1","lru-cache":"5.1.1","request":"2.88.0","requestretry":"4.0.0","valid-url":"1.0.9"},"deprecated":false,"description":"XS Advanced Container Security API for node.js","devDependencies":{"filter-node-package":"2.0.0","istanbul":"^0.4.5","jwt-decode":"^2.2.0","mocha":"^5.1.0","should":"^13.2.1"},"keywords":["xs"],"main":"./lib","name":"@sap/xssec","repository":{"type":"git"},"scripts":{"prepareRelease":"clean-packages && npm prune --production","test":"make test"},"version":"2.2.3","license":"SEE LICENSE IN developer-license-3.1.txt"}

@@ -181,2 +181,6 @@ @sap/xssec: XS Advanced Container Security API for node.js

### Usage in Docker
If you intend to use XS Advanced Container Security inside a Docker image make sure to use a base image other than **alpine**. The alpine base system is lacking needed symbols for system calls.
## API Description

@@ -183,0 +187,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc