Closed (won't fix)
Project:
Drupal core
Version:
8.0.x-dev
Component:
javascript
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
23 Sep 2009 at 20:56 UTC
Updated:
14 May 2015 at 12:39 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
dave reidAdding tags..
Comment #2
litwol commentedIncluding myself in this initiative.
Setting this to 8x-dev as i really doubt this has a chance at 7.
Comment #3
dave reidInitial patch for review. Reinforces the fact that I suck at jQuery because I can get the result in the success callback but can't get it to return a proper value.
Comment #4
dave reidAlthough I didn't mean to cross post, I want to make a case for this to be accepted into Drupal 7's API slush. I'd like our Drupal 7 modules to be able to use this function and not keep coding their own, insecure versions.
Comment #5
dave reidwoot! Working version now with async: false.
Comment #6
dave reidNamed the JS function wrong.
Comment #7
dave reidThis could really use a look-over by a jQuery ninja.
Comment #8
ufku commentedThe Ajax Markup API was created for this purpose.
I use it with BUEditor. I know there is the live module doing a similar thing but it is limited to node and comment preview and it previews the whole node.
Ajax markup, OTH, is just an ajaxified version of check_markup.
@Dave, instead of returning the output you should consider taking the success or complete callback as a parameter of Drupal.checkFormat
Comment #9
dave reidAdding a callback to Drupal.checkFormat didn't seem consistent with the way core handles these types of methods. Also fixing cross-post.
Comment #10
ufku commentedI've just seen #586180.
Comment #11
ufku commentedSorry, I'm not able to post patches right now.
"async: false" is not a good choice as it freezes the browser. A loading notice is always better than a locked browser interface.
Comment #12
dave reidYeah that's why I need a jQuery ninja to help me out. I couldn't get it to return the value unless I specified async: false.
Comment #13
john morahan commentedSee also: #304873: Add filter_xss() functionality to drupal.js
Comment #14
ufku commentedurl = Drupal.settings.basePath + 'js/filter/check-markup';This will not produce the right url when the site is multilingual and uses an url prefix.
Current implementation is vulnerable to CSRF as it does not set a token and check it in $_POST
To solve these we should include an url and a token in each page.
Comment #15
markus_petrux commentedsubscribing
Comment #16
kkaefer commentedUsing SYNCHRONOUS XMLHttpRequests completely blocks the browser when performing those requests. That means the user can’t scroll, click, type or in fact do anything with the website. Add a suboptimal internet connection and a badly tuned server to the mix and you end up with a user experience that is below zero.
Comment #17
dave reidI'm completely aware that I should be avoiding the async: false option, but like I said before, I need a jQuery ninja to help figure out how to properly get the return value without async: false. I couldn't get it to work unless I did that.
Comment #18
dave reid@ufku: Did you actually test it? Yes the request will work just fine. That's how we format URLs for our Drupal AJAX requests. Please also explain how it would be vulnerable to an CSRF attack since we don't include any kind of token-type valiation to auto-completion or Drupal.checkPlain()?
Comment #19
john morahan commentedwell, checkPlain and autocomplete do not have any side effects. check_markup could for example invoke the php filter.
Comment #20
markus_petrux commentedTo work asynchronously, this needs a callback that can be invoked when the AJAX request succeeds. This pattern can be found in ajax.js (D7) or ahah.js (D6).
Comment #21
markus_petrux commentedIn fact, it would be nice if this feature could reuse ajax.js stuff, I think. I haven't been following D7 updates on this, but looking at the code, it seems it could be possible.
Comment #22
kkaefer commentedWe should probably use something like this:
This approach uses the
jQuery.load()function to change the markup of a DOM element. The way you use it is as follows:$('#foo').checkMarkup($('textarea').val()). This doesn’t return the checked value but instead replaces#foo’s contents with the return value. That’s how asynchronous callbacks work. In case you really need the return value, you can create an empty DOM node, call this function and pass a callback function that will be called when the DOM node contains the result:(the code is untested)
Comment #23
pwolanin commentedSeems like there needs to be some kind of additional access checking here? - imagine that anonymous users cannot post any content. An attacker could still post content to this URL and possibly exploit filter system bugs or cause high load.
The access callback could invoke a hook to see if the current user has permission to use JS-based filtering?
Comment #24
pwolanin commentedcross-post
Comment #25
dave reidThat's tough because it should be available to anyone who has a change to make any kind of input that uses the filter system. That would be nodes, blocks, comments, fields, etc. Not sure what the best way to check such a broad access would be.
Comment #26
pwolanin commented@Dave Reid - no only to users who have access to a JS front-end to make those changes. I..e. if you can access tinyMCE, then the module providing it should arrange for the access callback to trturn true (e.g. via hook invocation)
Comment #27
ufku commentedThat's not the case for multilingual paths. The output of /somepath is not always the same as /LANG_CODE/somepath.
Drupal.settings.basePath should be used for producing file paths but not for producing URLs. Instead an URL produced by the url() function can be added to Drupal.settings.
Besides, the current implementation assumes clean-urls is on.
As Morahan said, it could be possible to execute PHP with POST data sent remotely by(in behalf of) an admin.
Comment #28
dave reidPeople who have access to the PHP filter are the only ones that would be able to execute PHP code, so there's not really too much risk there. The main thing is if this were available to anonymous users and used to try and bot-hack sites in mass.
Comment #29
ufku commentedWhat I meant was, an admin may enter a malicious site which silently posts a form containing the PHP code to the admin's site where he is still logged in. The admin wouldn't even know that he/she has posted and executed the code. It's definitely high risk.
Against high load, +1 for a 'use ajax filtering' kind of permission.
Comment #30
kkaefer commentedufku, you’re right. This kind of attack is called CSRF and it can be mitigated/solved by using the form tokens.
Comment #31
pwolanin commentedInteresting point - so given the potential that this would include the PHP filter, the POST needs to reference a form ID and token or ... ?
How does the current live module handle this?
Comment #32
ufku commentedActually the Ajax Markup API covers nearly all of the above issues.
But, I'm not sure a similar implementation may have a chance to go into D7.
Comment #33
dave reidMoving to 8.x
Comment #34
David_Rothstein commentedI think as a security hardening patch and a relatively small change, this still would have a decent shot at being accepted for D7.
However, it's not something that I personally have time or skill to work on anytime soon... so mostly just subscribing :)
Comment #35
sunNo longer possible to do for D7.
Comment #36
mgifford#6: 586098-jquery-checkmarkup-D7.patch queued for re-testing.
Comment #38
nod_if there is an ajax call involved Drupal.checkMarkup has to have a callback parameter that will be fired once the data comes back.
Also since nothing special is going on with the parameters, it should accept an object directly passed to the $.ajax call.
Drupal.checkMarkup(data, callback);Comment #39
nod_Comment #40
sunThe idea here is to use a synchronous/blocking request.
AFAICS, it is likely that code, which does or will actually use this functionality will have a full stack of preceding and/or subsequent/following logic that depends on the outcome of the filtered user input.
For now, I'd recommend to continue with the synchronous/blocking request approach. A later version could possibly allow to extend/override the default Ajax options for special use-cases.
Comment #41
nod_This is bad bad bad. On mobile? deadly.
The function is not used anywhere since it doesn't exists. It should be in it's documentation that the way to use it is explained, properly, with a callback.
Please don't introduce bad practices.
And just for example: http://bugs.jquery.com/ticket/8819
Comment #42
mgifford@nod_ so you want to mark this as Closed, Won't fix?
Comment #43
nod_yup.