Jump to content

BitPoet

Members
  • Posts

    1,275
  • Joined

  • Last visited

  • Days Won

    56

Posts posted by BitPoet

  1. I wonder if @ryan was ever contacted about this.

    I've tried to come up with a scenario where the URL injection mentioned in the CVE can become exploitable, but I'm having a hard time. When you can intercept a communication to that level and modify the message body, you could just forge the necessary requests, supply them with the intercepted session information and use the built-in module upload functionality. That's why we have DANE, so the communication stays confidential even if you're routed through untrustworthy networks.

    I've sent a rejection request to MITRE with the following rationale:

    Quote

    The reported vulnerability describes how a malicious extension module might be imported and executed in an installation of the ProcessWire content management system. The exploitation mechanism described in the verbose article on medium.com (linked below) is based on two assumptions:
    1. the user logged into the ProcessWire installation has admin permissions;
    2. the attacker is able to intercept and modify requests between the client (browser) and the webserver hosting the ProcessWire installation.

    Such an admin user, however, already has the means to upload zip files which contain arbitrary module code from the local system through a HTTP POST request. If an attacker can intercept and modify the communication to the level required for the described scenario, they could also use the intercepted session information and simply forge a request that contains the code for a malicious module.

    It is my understanding that with the combination of a) being able to execute a MITM attack as needed here and b) being able to abuse the session credentials for an admin user that way, any modern, browser based CMS could be modified in a way that it either performs unwanted actions or stops working, so the numbers of CVE entries one could generate would be astronomical, when, on the other hand, it is essential knowledge that the safe administration of a web application requires state of the art means of ensuring confidentiality (e.g. by using strong TLS and securing the integrity of the certificate through DANE). In summary: since the scenario in question already requires a far further reaching breach as a prerequisite, it should not be considered an independent vulnerability.

     

    • Like 9
    • Thanks 1
  2. Comments.php isn't loaded automatically. It's only included when FieldtypeComments is loaded.

    The quickest way to access all the auxiliary classes for this fieldtype is to load the module by calling

    $modules->get('FieldtypeComments');

     

    • Like 4
    • Thanks 1
  3. 22 hours ago, lenoir said:

    You think there's better way to get the SVG without the http GET? 

    When you use file_get_contents with the filename property, there won't be an extra http GET, as it will recognize the local path and use regular file system IO. It's only when the argument to file_get_contents starts with a protocol schema indicator (http(s):// etc.) that it uses the network wrapper.

    • Like 1
  4. On 1/2/2024 at 12:36 PM, ceberlin said:

    There is a warning with your composer version when running PHP 8.1

    Thanks for letting me know. I've created an issue and will take a look as soon as I find a quiet minute.

  5. I really don't think the problem is within the module code. Are there any messages when you do a Modules -> Refresh? Do you have another module active that accesses simpleSearch?

    Additional idea: a debug_backtrace from within the constructor might be able to shed some light on it if it's really a case of the module being blocked from uninstall because it's in use.

  6. 22 hours ago, fruid said:

    Is that issue to be found in the module?

    After a quick glance, I don't think so. Have you tried writing into the PW log from ___install and ___uninstall? This should at least tell you whether uninstall+install happen. In the later case, you should also see the page request that triggers the re-installation. Just to make sure: you have $config->debug enabled so you don't miss any warnings, right?

    • Like 1
  7. You'll probably find either the full code or at least an include directive or module invocation in the page's PHP template file in site/templates. It's usually home.php for the start page, but if this differs from a default installation, you can look the name up in the template's configuration in the backend on the Files tab. If that is empty, the template file is named the same as the backend template.

  8. To me it looks like renderRepeaterLabel is also called for a dummy repeater item (see the call with a NullPage here). That one doesn't have a page associated yet, as it hasn't been saved. It's just used to render the form for adding a new one. So the calls for the existing items succeed, but that last one fails and throws the error.

    This can be cured easily by adding a check for $page in the hook:

      // Get values of arguments sent to hook (if needed)
      $label = $event->arguments(0);
      $cnt = $event->arguments(1);
      $page = $event->arguments(2);
    
      // Only execute the hook for actual repeater items,
      // not for blank placeholders
      if($page instanceof NullPage)
        return;
    
      // Your code here, perhaps modifying the return value
      // just a simple test:
      $return = "LABEL " . $page->getForPage()->template();

    In a short test, this worked like expected.

    • Like 1
  9. To create a new field, you need to select a Fieldtype, not an Inputfield. Fieldtypes often have a matching Inputfield, but some support different Inputfields to faciliate the input. The Fieldtype is the part that takes care of storing and loading the data for the field, while the Inputfield provides the UI for entering that data.

    In the case of InputfieldTextTags, it doesn't have a matching FieldtypeTextTags, but rather complements the existing Fieldtypes FieldtypeText, FieldtypePage and FieldtypeOptions. So you need to create one of those and then, when you configure the field, choose "Text Tags" as the Inputfield of choice. Once you save it, you will see the configuration options specific to InputfieldTextTags.

    • Like 3
  10. Sometimes, you want to search a text field by the length of its content. FieldtypeText doesn't provide this functionality (yet). It's possible to add the necessary SQL to a query by hooking into PageFinder::getQuery like @bernhard pointed out here, but that's of course not really straight forward. There's also an open feature request for FieldtypeText in processwire-requests.

    FieldtypeTextWithLength is an extension of FieldtypeText, so you can switch your field's type between the two without loosing any information.

    After switching your field to "Text with .length Selector", you can search by the (character, not bytes!) length of the content:

    $pagesWithShortHeadlines = $pages->find('headline.length<10');

    You will also find a new "Length" subfield when using Pages -> Find in the PW backend:

    fttwl.thumb.png.bdfa461eedc704cb971ac8eb71e4fb5c.png

    • Like 6
  11. On 11/22/2023 at 1:30 PM, bernhard said:

    @BitPoet that's real bit poetry

    Thanks! Appreciated!

    🧠 about it, in times of utf8(mb4) one might want to use CHAR_LENGTH instead of LENGTH. The first one counts the code points, i.e. visible characters, while the latter returns the bytes. LENGTH('😱') is 4.

    • Like 1
  12. A short&quick&dirty module that adds .length (switching back and forth between regular Text fields and "Text with .length Selector" should not cause any troubles):

    <?php namespace ProcessWire;
    
    class FieldtypeTextWithLength extends FieldtypeText {
    
    	public static function getModuleInfo() {
    		return [
    			'title'			=>	__('Text with .length Selector', __FILE__),
    			'summary'		=>	__('Like FieldtypeText, but with a subfield selector .length for string length comparison', __FILE__),
    			'version'		=>	'0.0.1'
    		];
    	}
    	
    	public function getMatchQuery($query, $table, $subfield, $operator, $value) {
    		
    		$database = $this->wire("database");
    		
    		if($subfield === 'length') {
    			
    			$table = $database->escapeTable($table);
    			$value = $database->escapeStr($value);
    			
    			$query->where("LENGTH({$table}.data){$operator}$value");
    		} else {
    			parent::getMatchQuery($query, $table, $subfield, $operator, $value);
    		}
    		
    		return $query;
    	}
    	
    }

     

    • Like 3
    • Thanks 2
  13. 5 hours ago, Robin S said:

    One way is to set the option when the datepicker field is focused

    The problem I have is that the focus event isn't triggered for inline datepickers, which are especially handy if one wants to avoid invalid manual input.

    I've nevertheless thrown together a small POC module I've called DatePickerExclusions that works with focus and button click options. It still needs an option for time windows.

    • Like 1
  14. 4 hours ago, darrenc said:
    $image->removeVariations("width=201"); // nope
    

    PageImage::removeVariations takes an associative array of options as its argument, which in turn is passed on to PageImageVariations::remove and PageImageVariations::find. The docs for the latter say (irrelevant parts snipped):

    	/**
    	 * @param array $options Optional, one or more options in an associative array of the following:
    	 * 	- `width` (int): only variations with given width will be returned
    	 * 	- `height` (int): only variations with given height will be returned
    	 * 	- `width>=` (int): only variations with width greater than or equal to given will be returned
    	 * 	- `height>=` (int): only variations with height greater than or equal to given will be returned
    	 * 	- `width<=` (int): only variations with width less than or equal to given will be returned
    	 * 	- `height<=` (int): only variations with height less than or equal to given will be returned
    	 * 	- `suffix` (string): only variations having the given suffix will be returned
    	 *  - `suffixes` (array): only variations having one of the given suffixes will be returned
    	 *  - `noSuffix` (string): exclude variations having this suffix
    	 *  - `noSuffixes` (array): exclude variations having any of these suffixes
    	 *  - `name` (string): only variations containing this text in filename will be returned (case insensitive)
    	 *  - `noName` (string): only variations NOT containing this text in filename will be returned (case insensitive)
    	 *  - `regexName` (string): only variations that match this PCRE regex will be returned
         */

    So ["width" => "201"] should work (untested though).

    • Like 1
  15. This is great! Just a tiny nitpick: I'd swap around the logic for "Don't allow selection in both directions" and get rid of the "Don't", or maybe change it to "Disallow". It's a very cultural and regional thing whether questions with a negation get answered with a yes or no to confirm then, and it's bitten me in the backside myself when I rolled out an app with such a toggle to our international employees.

    • Like 3
×
×
  • Create New...