Access to api 'getDecryptedValue(password)' from scope has been refused

abelal
Tera Contributor

Hello all!

 

We have a password stored in basic_auth_credentials table that is effectively shared by several apps. In the past, we would normally work exclusively in global scope but have since turned to using scoped apps, reason being it's easier to manage a scoped app by opening up in ServiceNow studio and you're presented with the relevant files. Makes it far easier for other developers in the team to make changes - everything is scoped!

 

Now, there obvious problem with this is some APIs are restricted from app scope. The one I'm having difficulties with is getDecryptedValue.

Essentially, in my scoped app I have a flow script that runs

const credential = new GlideRecord('basic_auth_credentials');
credential.get('name', 'ADO - Pipeline');
const pat = credential.password.getDecryptedValue();

'ADO - Pipeline' is stored in basic_auth_credentials which I presume is globally scoped, and as mentioned it's used by many different apps which currently sit inside global scope. When script is run in app scope, I get this error:

Security restricted: Access to api 'getDecryptedValue(password)' from scope 'x_clpl_ab_csv_ad_g' has been refused due to the api's cross-scope access policy. 

I understand what it means but no idea how to make it work.

 

As an alternative I've used this script which does work

const credential = new GlideRecord('basic_auth_credentials');
credential.get('name', 'ADO - Pipeline');
const pat = new global.ScopedEncrypter().decrypt(credential.password);

 

However, it's not recommended to do this as it'll allow app to get any credential whilst all I really need is access to 'ADO - Pipeline'.

 

Any options available?

9 REPLIES 9

In Application Cross-Scope there is no record for my scoped application with requested, but many with allowed. I believe that's because runtime access tracking is set to tracking, which automatically grants access? If set to enforced, it requests.

 

I suspect, and as you said, getDecryptedValue is an API in global scope that simply can't be accessed from scoped apps leaving something like below running from global scope the only option to use.

 

const pat = new global.ScopedEncrypter().decrypt(credential.password);

 

Matt Hernandez
Tera Guru

Good morning Abelal,

Can you help me understand the risk here? You mentioned ScopedEncrypter().decrypt() is "..not recommended to do this as it'll allow app to get any credential".

Is the concern that maybe a delegated developer is given privileges to make enhancements on an app which is set to "Tracking" and thus he's able to add code to query some forbidden credential record of another app, and uses debugging to steal that?

And maybe if it was set to "Enforced" someone else who is a platform admin would have to intervene?

Hi @Matt Hernandez,

 

That is indeed the concern. If application has access to call ScopedEncrypter().decrypt() it can in theory then get access to any credential. I'm by no means an expert in SN so I could very well be wrong here, but based on my limited understand that is a serious security risk.

JUNXIANW
Tera Contributor

Hi @abelal
Have you solved it?
I am facing the same problem. I added Cross-Scope Access and filled the [Target Name] field with [ScopedGlideElement], but it still didn't work.

abelal
Tera Contributor

@JUNXIANW , yes. After raising a ticket with SN support we were advised to use to a different method.

 

 

    // get record containing credential
    var record = new GlideRecord('basic_auth_credentials');
    record.get('name', inputs.pattokenname);

    // old way
    //const pat = credential.password.getDecryptedValue();
    //const pat = new global.ScopedEncrypter().decrypt(credential.password);

    var provider = new sn_cc.StandardCredentialsProvider();            
    var credential = provider.getCredentialByID(record.sys_id);
    const pat = credential.getAttribute('password');  

 

Hope this helps.