Charles Robertson
01/06/2023, 9:54 AMCacheRegionNew()
ACF does not enforce this.
The consequences are enormous for migration projects.
I am now facing this exact issue.
We are migrating from ACF to Lucee, and from what I can see, unless we expose the plain text:
this.webAdminPassword
In the:
Application.cfc
We would need to build a form, before the main application loads and ask the user to submit the Administrator password, before proceeding.
As I understand, the Administrator password is an encrypted hash, which means it cannot be reversed. So, I would need expose the clear text version of the password?
I mean I understand that it is a security issue, but why does ACF feel that it is unnecessary to enforce this methodology? 🤔Charles Robertson
01/06/2023, 10:32 AMthis.webAdminPassword
At least, we could read this out of a file or just expose it directly. But, if a malicious user got hold of the hash, it still wouldn’t allow them to get into the Administrator UI.zackster
01/06/2023, 10:38 AMCharles Robertson
01/06/2023, 10:54 AMApplication.cfc?
I mean maybe, it is OK? But, it doesn't feel OK?Charles Robertson
01/06/2023, 11:01 AMApplication.cfc, I read sensitive directly from the database. Normally, a password in the DB, would either be an encrypted Hash or just encrypted? Clearly, the latter would be reversible and so would be a good candidate to resolve this problem. But, it may not be possible to store the Administrator password in the DB, due to company security policies.
By the way, I am working, as a contractor, for another company, so I don't know yet, whether they would allow this approach.
But, my main question, is why do the guys at Lucee feel that certain cache functions, like:
CacheRegionNew()
Require an Administrator password to work? When ACF doesn't require an Administrator password?cfsimplicity
01/06/2023, 12:15 PMserver.system.environment.MYWEBCONTEXTPASSWORD (or however you want to name it)Charles Robertson
01/06/2023, 12:31 PMserver.system.environment
Awesome advice. 🙌
Currently, I have added the password like this:
webroot/settings.json
{
"adminSalt":"294AFCA2-7E60-4721-8636FA62CB4F1705",
"hspw":"b37158b3b23fc83851d9f3a3ba6d9241b7490b4ffc468d8d7c8ce01ff987cf76",
}
And then decrypt in Application.cfc
I cannot use the CommandBox .cfconfig.json values as the password here is an encrypted hash, which cannot be reversed.
However, I like your idea, so I might add it, into an environmental variable as an encrypted value, along with its salt.zackster
01/06/2023, 12:48 PMzackster
01/06/2023, 12:49 PMCharles Robertson
01/06/2023, 1:00 PMCacheRegionNew()
The only cache method that requires a password in Lucee?Charles Robertson
01/06/2023, 1:32 PMapplication.cfc, for many reasons.
It seems the the cache is created dynamically based on a chain of different actions.
When you say:
for security reasons any context wide changes require a password, but you can just defined the cache for your applicationHow do I define the cache in a Lucee application without a password? I would be extremely grateful for a description of how to carry this out. 🙏
zackster
01/06/2023, 1:37 PMCharles Robertson
01/16/2023, 4:00 PMApplication.cfc initialisation methodology
When I use:
Application.cfc
variables.szCacheName = "CONFIGSETTINGS";
variables.szApplicationName = "LA-EPORTFOLIO";
variables.szPropertiesCachename = ucase(variables.szApplicationName) & "_" & ucase(variables.szCacheName);
variables.stuCacheProps = {
CLEARONFLUSH = "true",
DISKPERSISTENT = "true",
ETERNAL = "true",
MAXELEMENTSINMEMORY = "1000000",
MAXELEMENTSONDISK = "0",
OBJECTTYPE = "OBJECT",
OVERFLOWTODISK = "true",
STATISTICS = "true",
TIMETOLIVESECONDS = 0,
TIMETOIDLESECONDS = 0
};
this.cache.connections[variables.szPropertiesCachename] = {
class: 'lucee.runtime.cache.ram.RamCache',
custom: variables.stuCacheProps,
default: 'object'
};
And I do:
Application.cfc
<cffunction name="cacheNames" access="public" output="false" returnType="array">
<cfreturn getPageContext().getConfig().getCacheConnections().keySet().toArray() />
</cffunction>
<cffunction name="onRequestStart" access="public" output="false" returnType="boolean">
<cfargument name="targetPage" type="string" required="true" />
<cfscript>
variables.cacheNamesJava = this.cacheNames();
variables.cacheNames = [].append(variables.cacheNamesJava, true)
WriteDump(var={
cacheNamesProperties = CacheGetProperties(type=variables.cacheNames[1]),
cacheNames = variables.cacheNames
},output="C:\domains\acf-lucee- shared\logs\la_code_application_onRequestStart_160122.htm",format="html");
</cfscript>
...
I get the following output [please see screenshot]
I just don't fee that the cache has initialise properly. Where are all the custom props and the name?
Do I have to install ramCache?zackster
01/16/2023, 4:02 PMzackster
01/16/2023, 4:03 PMCharles Robertson
01/16/2023, 4:05 PMCharles Robertson
01/16/2023, 4:06 PMCharles Robertson
01/16/2023, 4:07 PMCharles Robertson
01/16/2023, 4:11 PMname: la-eportfolio_configsettingszackster
01/16/2023, 4:12 PMCharles Robertson
01/16/2023, 4:13 PMCharles Robertson
01/16/2023, 4:13 PMCharles Robertson
01/16/2023, 4:23 PMvariables.cacheNamesJava = this.cacheNames();
variables.cacheNames = [].append(variables.cacheNamesJava, true)
WriteDump(var={
cacheNamesProperties = CacheGetProperties(type=variables.cacheNames[1]),
cacheNames = variables.cacheNames
},output="C:\domains\acf-lucee-shared\logs\la_code_application_onRequestStart_160122.htm",format="html");
variables.cacheput_obj = now();
cachePut('cacheput_obj',variables.cacheput_obj,createTimespan(0,0,0,30),createTimespan(0,0,0,30),variables.cacheNames[1]);
if(cacheIdExists('cacheput_obj',variables.cacheNames[1])){
WriteDump(var={
cacheExist = true
},output="C:\domains\acf-lucee-shared\logs\la_code_application_onRequestStart_160122.htm",format="html");
}
Gives me:Charles Robertson
01/16/2023, 4:50 PMvariables.szCacheName = "CONFIGSETTINGS";
variables.szApplicationName = "LA-EPORTFOLIO";
variables.szPropertiesCachename = ucase(variables.szApplicationName) & "_" & ucase(variables.szCacheName);
variables.stuCacheProps = {
CLEARONFLUSH = true,
DISKPERSISTENT = true,
ETERNAL = true,
MAXELEMENTSINMEMORY = 1000000,
MAXELEMENTSONDISK = 0,
OBJECTTYPE = "OBJECT",
OVERFLOWTODISK = true,
STATISTICS = true,
TIMETOLIVESECONDS = 0,
TIMETOIDLESECONDS = 0
};
this.cache.connections[variables.szPropertiesCachename] = {
class: 'org.lucee.extension.cache.eh.EHCache',
custom: variables.stuCacheProps,
default: 'object'
};
this.cache.object = 'default';Charles Robertson
01/18/2023, 3:23 PMthis.SessionTimeout="#CreateTimeSpan( 0, 1, 0, 0 )#";
this.applicationtimeout="#CreateTimeSpan( 30, 0, 0, 0 )#";
this.clientmanagement="Yes";
this.clientstorage="cookie";
this.LoginStorage="session";
// CACHE INIT
variables.szCacheName = "CONFIGSETTINGS";
variables.szApplicationName = "LA-EPORTFOLIO";
variables.szPropertiesCachename = ucase(variables.szApplicationName) & "_" & ucase(variables.szCacheName);
variables.stuCacheProps = {
CLEARONFLUSH = true,
DISKPERSISTENT = true,
ETERNAL = true,
MAXELEMENTSINMEMORY = 1000000,
MAXELEMENTSONDISK = 0,
OBJECTTYPE = "OBJECT",
OVERFLOWTODISK = true,
STATISTICS = true,
TIMETOLIVESECONDS = 0,
TIMETOIDLESECONDS = 0
};
variables.cacheExists = StructKeyExists(this,"cache") AND StructKeyExists(this.cache,"connections") AND StructKeyExists(this.cache.connections,variables.szPropertiesCachename) ? true : false;
if(NOT variables.cacheExists){
this.cache.connections[variables.szPropertiesCachename] = {
class: 'org.lucee.extension.cache.eh.EHCache',
custom: variables.stuCacheProps,
default: 'object'
};
this.cache.object = 'default';
}
I cannot use cacheRegionExists(), because it requires a web admin password? I want to avoid exposing the web admin password.
Does the cache last for a certain amount time and then it expires like the application scope?zackster
01/18/2023, 3:25 PMCharles Robertson
01/18/2023, 3:26 PMzackster
01/18/2023, 3:26 PMCharles Robertson
01/18/2023, 3:27 PMzackster
01/18/2023, 3:28 PMCharles Robertson
01/18/2023, 3:33 PMzackster
01/18/2023, 3:57 PMzackster
01/18/2023, 3:58 PMCharles Robertson
01/18/2023, 4:07 PMthis.cache.connections[variables.szPropertiesCachename] = {
class: 'org.lucee.extension.cache.eh.EHCache',
custom: variables.stuCacheProps,
default: 'object'
};
this.cache.object = 'default';
Rather than:
if(NOT variables.cacheExists){
this.cache.connections[variables.szPropertiesCachename] = {
class: 'org.lucee.extension.cache.eh.EHCache',
custom: variables.stuCacheProps,
default: 'object'
};
this.cache.object = 'default';
}
Will the cache be overwritten on every page request?
Or will the cache structure last forever?
Basically, can I get rid of this conditional:
if(NOT variables.cacheExists){
...
I understand that each cache object has an expiry, but what about the cache itself? 🙂