incredible security hole with scheduler
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-03-2016 05:07 AM
When running script actions launched by alfresco scheduler, I got the following behaviour (5.0.d or 5.1.e):
- scheduler run as 'System' or 'admin' (same results), executes js script stored in repo folder 'Scheduled Actions'
- this script create/move/delete documents
- documents created or moved have arbitrary 'owner' or 'modifiedBy' properties
- documents deleted appear in arbitrary user's trash ( -> user gains access to content he had no permission on initially)
Consequences:
- any users may become owner-deletors of any content created/moved/deleted by this script, executed by admin/system.
- Users ask me: why this document is owned by 'john', he has no access to this site…….
It seems that this 'arbitrary user' is the last logged in user…..
This is very easy to reproduce, you just have write a js script that:
- create log file in any site
- update it each times it runs
you'll see that the cm:modifier becomes any arbitrary user……
one question : How is it possible ??? did somebody face the same kind of issue ?
Scheduled-action-service-context.xml:
- scheduler run as 'System' or 'admin' (same results), executes js script stored in repo folder 'Scheduled Actions'
- this script create/move/delete documents
- documents created or moved have arbitrary 'owner' or 'modifiedBy' properties
- documents deleted appear in arbitrary user's trash ( -> user gains access to content he had no permission on initially)
Consequences:
- any users may become owner-deletors of any content created/moved/deleted by this script, executed by admin/system.
- Users ask me: why this document is owned by 'john', he has no access to this site…….
It seems that this 'arbitrary user' is the last logged in user…..
This is very easy to reproduce, you just have write a js script that:
- create log file in any site
- update it each times it runs
you'll see that the cm:modifier becomes any arbitrary user……
one question : How is it possible ??? did somebody face the same kind of issue ?
Scheduled-action-service-context.xml:
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'><beans> <!– Define the model factory used to generate object models suitable for use with freemarker templates. –> <bean id="templateActionModelFactory" class="org.alfresco.repo.action.scheduled.FreeMarkerWithLuceneExtensionsModelFactory"> <property name="serviceRegistry"> <ref bean="ServiceRegistry"/> </property> </bean> <bean id="runScriptActionTestJScript" class="org.alfresco.repo.action.scheduled.SimpleTemplateActionDefinition"> <property name="actionName"> <value>script</value> </property> <property name="parameterTemplates"> <map> <entry> <key> <value>script-ref</value> </key> <value>\$\{selectSingleNode('workspace://SpacesStore', 'fts-alfresco', 'PATH:"/app:company_home/app:dictionary/cm:Scheduled_x0020_Actions/cm:myTestScript.js"' )\}</value> </entry> </map> </property> <property name="templateActionModelFactory"> <ref bean="templateActionModelFactory"/> </property> <property name="dictionaryService"> <ref bean="DictionaryService"/> </property> <property name="actionService"> <ref bean="ActionService"/> </property> <property name="templateService"> <ref bean="TemplateService"/> </property> </bean> <bean id="runtestScheduleEveryOneMinutes" class="org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinition"> <property name="transactionMode"> <value>UNTIL_FIRST_FAILURE</value> <!–value>ISOLATED_TRANSACTIONS</value–> </property> <property name="compensatingActionMode"> <value>IGNORE</value> </property> <property name="searchService"> <ref bean="SearchService"/> </property> <property name="templateService"> <ref bean="TemplateService"/> </property> <property name="queryLanguage"> <value>fts-alfresco</value> </property> <property name="stores"> <list> <value>workspace://SpacesStore</value> </list> </property> <!– Find all nodes that do not have the aspect –> <property name="queryTemplate"> <value>PATH:"/app:company_home/st:sites/cm:mySite/cm:documentLibrary/cm:_Inbox"</value> </property> <property name="cronExpression"> <value>0 0/15 * * * ?</value> </property> <property name="jobName"> <value>TestJScriptJobName</value> </property> <property name="jobGroup"> <value>TestJScriptJobGroup</value> </property> <property name="triggerName"> <value>TestJScriptTriggerName</value> </property> <property name="triggerGroup"> <value>TestJScriptTriggerGroup</value> </property> <property name="scheduler"> <ref bean="schedulerFactory"/> </property> <property name="actionService"> <ref bean="ActionService"/> </property> <property name="templateActionModelFactory"> <ref bean="templateActionModelFactory"/> </property> <property name="templateActionDefinition"> <ref bean="runScriptActionTestJScript"/> </property> <property name="transactionService"> <ref bean="TransactionService"/> </property> <property name="runAsUser"> <value>System</value> <!–value>admin</value–> </property> </bean> </beans>
Labels:
- Labels:
-
Archive
4 REPLIES 4
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2016 07:48 PM
Hi,
Out of interest, can you include the content of the script you're running (/app:company_home/app:dictionary/cmcheduled_x0020_Actions/cm:myTestScript.js) ?
Can you also outline how many files exist beneath /app:company_home/st:sites/cm:mySite/cm:documentLibrary/cm:_Inbox and whether the arbitrary cm:modifier property values you're seeing correspond to the modifiers/owners of these files? The queryTemplate you've specified will run your script for each of the nodes that exist underneath the cm:_Inbox path, so it would be good to see if this has a bearing here
Thanks
Steven
Out of interest, can you include the content of the script you're running (/app:company_home/app:dictionary/cmcheduled_x0020_Actions/cm:myTestScript.js) ?
Can you also outline how many files exist beneath /app:company_home/st:sites/cm:mySite/cm:documentLibrary/cm:_Inbox and whether the arbitrary cm:modifier property values you're seeing correspond to the modifiers/owners of these files? The queryTemplate you've specified will run your script for each of the nodes that exist underneath the cm:_Inbox path, so it would be good to see if this has a bearing here
Thanks
Steven
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-05-2016 04:13 PM
Hi steven,
The whole process is aimed to publish invoices to a Customer portal.
All Customer invoices from ERP are pushed into 'Inbox'. The scheduler run the script which is parsing the folder content, and takes actions for each child document (transform, classify, extract content, add aspect, manage permissions, move files….). I can't put all the script here (very big script), but below is the main logic.
Script is run as either System or admin user by the scheduler, and I get the following:
- for moved invoices: cm:modifier is replaced by an arbitrary user (any user currently authenticated against alfresco, I didn't understand any rule, could be the last logged in user). cm:creator is preserved, and no cmwner defined (ownable aspect no set).
- for deleted temporary files (mainly transformed document), following properties are set to an arbitrary user :
cmwner, cm:modifier, cm:creator
The arbitrary users ARE NOT MEMBERS of the site.
- for script log file: cm:modifier altered
I think it's possible to reproduce this just by running a simple script that create/open a log file, and write into it each time the scheduler execute the jobs.
The cm:modifier will be altered to any authenticated user. (environment 5.x community, with some users working on the platform)
structure of my script:
The whole process is aimed to publish invoices to a Customer portal.
All Customer invoices from ERP are pushed into 'Inbox'. The scheduler run the script which is parsing the folder content, and takes actions for each child document (transform, classify, extract content, add aspect, manage permissions, move files….). I can't put all the script here (very big script), but below is the main logic.
Script is run as either System or admin user by the scheduler, and I get the following:
- for moved invoices: cm:modifier is replaced by an arbitrary user (any user currently authenticated against alfresco, I didn't understand any rule, could be the last logged in user). cm:creator is preserved, and no cmwner defined (ownable aspect no set).
- for deleted temporary files (mainly transformed document), following properties are set to an arbitrary user :
cmwner, cm:modifier, cm:creator
The arbitrary users ARE NOT MEMBERS of the site.
- for script log file: cm:modifier altered
I think it's possible to reproduce this just by running a simple script that create/open a log file, and write into it each time the scheduler execute the jobs.
The cm:modifier will be altered to any authenticated user. (environment 5.x community, with some users working on the platform)
structure of my script:
logger.system.out(" -> running script, " + new Date().toString());try{ if ((debug) || (log)) { // get or create log file var configFolder = companyhome.childByNamePath(configRootPath); var logFile = configFolder.childByNamePath(logFileName); // if no log file, create a new one if ( logFile == null) { logFile = configFolder.createFile(logFileName); } // else rotate log file if necessary else if (parseInt(logFile.size/1024) > logMaxSize){ var logFileBackup = configFolder.childByNamePath(logFileNameBackup); // remove previous log backup if (logFileBackup != null){ configFolder.removeNode(logFileBackup); } // rename existing log logFile.name = logFileNameBackup; logFile.save(); // create new log file logFile = configFolder.createFile(logFileName); } if ( logFile == null) throw "Unable to open/create log file"; logFile.content += "\n\n________________________________________________________________\n"; logFile.content += new Date().toString() + "Run execution \n"; } // manage locks (one process at a time). var configFolder = companyhome.childByNamePath(configRootPath); var lockFile = companyhome.childByNamePath(configRootPath + "/" + lockFileName); if (!lockFile){ // lock file does not exists // create lock file if not exists if (!lockFile) lockFile = configFolder.createFile(lockFileName); if (!lockFile) throw "Unable to create lock file"; // get document array to process var childsFiles = new Array(); if (document.type == "{http://www.alfresco.org/model/content/1.0}folder"){ if (log) logFile.content += "\nCurrent node is a folder, processing childs\n"; childsFiles = document.childFileFolders(true, false); } else if (document.type == "{http://www.alfresco.org/model/content/1.0}content"){ if (log) logFile.content += "\nCurrent node is a document, processing current node only\n"; childsFiles[0] = document; } else { throw "Unknow document type"; } // process documents for (ii_main in childsFiles){ if (log) logFile.content += " -> Processing file: " + childsFiles[ii_main].properties.name + "\n"; if (debug) logger.system.out(" -> Processing file: " + childsFiles[ii_main].properties.name); // // put all business logic here () // } // release lock (hide) var lockFile = companyhome.childByNamePath(configRootPath + "/" + lockFileName); if (lockFile){ configFolder.removeNode(lockFile); } } else{ // Process already running if (log) logFile.content += "Process already running\n"; if (debug) logger.system.out("Process already running"); }}catch (err){ logger.system.out("! Aborting, error message: " + err); if (log) logFile.content += "\n ! Aborting, error message: " + err + "\n"; // release lock var configFolder = companyhome.childByNamePath(configRootPath); var lockFile = companyhome.childByNamePath(configRootPath + "/" + lockFileName); if (lockFile){ configFolder.removeNode(lockFile); }}
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-09-2016 05:04 AM
I reproduce this behaviour with any 5.x version (tested on 5.0.d, 5.1.e, 5.1.g).
To summarize:
- Scheduler execute script action as 'admin' user
- Script is just openning a log file and writing current user name into it
- Users are accessing alfresco using CIFS protocol (Kerberso authentication)
- User context of the script becomes any authenticated user, log files properties cm:modifier is altered with any arbitrary user (breaking security model, this user has no access to current site…).
This is a major security breach.
I'll open a case in jira.
Does anybody already faced this ? Any suggestion ?
To summarize:
- Scheduler execute script action as 'admin' user
- Script is just openning a log file and writing current user name into it
- Users are accessing alfresco using CIFS protocol (Kerberso authentication)
- User context of the script becomes any authenticated user, log files properties cm:modifier is altered with any arbitrary user (breaking security model, this user has no access to current site…).
This is a major security breach.
I'll open a case in jira.
Does anybody already faced this ? Any suggestion ?
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-09-2016 08:38 AM