We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 30023
    • 172 Posts
    require_once($modx->config['base_path'].'assets/libs/docmanager/document.class.inc.php');
    $doc = new Document($id);
    *** [[Do something to some of the fields, but not all]]
    $doc->Save();


    Because docmanager does not escape strings (you need to it yourself if the data you are putting in requires it) you cannot do the above without escaping all the text/char fields in modx_site_content again i.e. even ones that are unchanged.

    i.e. Say I inserted on the line *** some code that altered the pagetitle. If I then proceed but the content field contains text with single quotes, the $doc->Save() will fail as the single quotes are taken to delimit the ’new’ value.

    This also gives rise to an SQL injection vulnerability - if a user has an alternative way of inserting into the site content, they can then use the above to run some SQL. First they input the SQL into a field - and presumably you’ll be escaping the input, so it won’t run, but it will be stored as that SQL statement. Second they do an action that runs something akin to the above code where you have ignored that particular field as you are not changing it. Unbeknown to you docmanager has read in that SQL, and on running Save() will hence run the SQL.

    To avoid this you need to ensure you run something like

    foreach ($unchanged_text_tv_fields as $field)
    	{
    	$doc->Set($field, $modx->db->escape($doc->Get($field)));
    	}
    


    on all of pagetitle, longtitle, menutitle, introtext, type, contentType, description, alias, content, unless they have already set with new escaped values anyway.

    You don’t need to do this if the user has absolutely no other way of influencing these fields AND the above fields will never contain single quotes.

    -- Tim.
      • 31471
      • 206 Posts
      Alternatively you can load only those fields you will change:
      $doc = new Document($id,'pagetitle,content');