Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+6 votes
560 views
in Plugins by
edited by

To Q2A developers:

I am developing caching plugin for Q2A. I'm facing a big issue of this plugin. It is "code" for CSRF protection is cached. This is a fatal issue of the original plugin.

Example:

<input type="hidden" name="code" value="0-1437352020-1f25a7e49caa37d85df1a50d45949ea62b8aa596">

Do you know a good way to deal with this? It is OK even without a specific program. Please show tips and an process example of other products.

If this plugin is complete, most users of Q2A would use it. Please cooperate.

Thanks.

Q2A version: 1.7
by
I have little clue, but I found this interesting: https://www.fastly.com/blog/Caching-the-Uncacheable-CSRF-security/ Particularly the "Technique 3: Token Over XHR"
by
@Alvaro Thank you for your great hint. Plan to change the part of displayed cache with Ajax (XHR) is likely to be flexible.

3 Answers

+1 vote
by
edited by
How about calling this function, and dynamically replacing the code in the cached content?

function qa_get_form_security_code

Also, if $_POST is present, I would not use cache.  That would take care of posting answers.
by
> How about calling this function, and dynamically replacing the code in the cached content?

Yes. I'm already thinking this way. Please tell me detailed processing methods of this method. And I hope different ideas.

> Also, if $_POST is present, I would not use cache.  That would take care of posting answers.

This feature is already equipped.
by
I think this issue applies if you allow users to post without requiring registration/login (which I don't).  But in that case, there are multiple calls to this function (please search for that function name).

For example in question-view.php, here are the calls:
        $a_view['buttons_form_hidden']=array('code' => qa_get_form_security_code('buttons-'.$answerid), 'qa_click' => '');

'code' => qa_get_form_security_code('answer-'.$question['postid']),

$prefix.'code' => qa_get_form_security_code('comment-'.$parent['postid']),

So regex has to be written to make those calls, and replace those values.

It is a lot work doing this for every page.  I would limit caching to question page, which is probably the most important/heaviest load.

This can be done, but is a lot of work.
by
Yes. You are right. But, I want to challenge to the limit. If it is impossible absolutely, I might remove the question page from the cache.

By the way, I'm thinking also the way below.
1. Serialize and save content array at the cache timing
2. Read and unserialize content array when displaying cache
3. Generate only forms (codes) and replace it with inner HTML on cache
Note: Programming would be possible. However, performance may be a problem.
by
I think questions pages get 90% of the traffic, so actually I would only focus on them.

If you agree, then I would focus on getting the full content of the question/answer, and cache that.  I would not cache anything else.  I would also not cache the presentation, i.e. which is theme-dependent, only the text representing the thread.

This is a lot work.  I am not sure it is worth it.  The problem is really simple if users cannot post without logging in.

I think cpu is cheap these days.  One can optimize mysql and for php, use php caching (e.g. APC).
by
When we give up this problem, this plugin will die. If many restrictions exist, no one will not use it. In addition, benefit of PHP accelerator is small. They are not effective as the optimization of the application logic. Professional developers know it.

By the way, I might override process related to CSRF with client-side method.
by
You can generate form's random id, set it into cookie, and then check it after post'ing.  Should not be that hard.
by
Thanks steven.
by
No problem. This is a tough issue.  I was reading up, and even cookie tokens can be spoofed.  Suggest reading up on cookie /session CSRF measures before proceeding.  And thanks for keeping this plugin alive, although a hard one to do.
by
I have again studied functions below. Fortunately, we can override these functions. Hint for solution would be here.
File: qa-include/app/users.php
1. qa_set_form_security_key()
2. qa_calc_form_security_hash()
3. qa_get_form_security_code()
4. qa_check_form_security_code()
by
Yes, those are the main functions.  I don't think you need to over-ride, simply call qa_get_form_security_code() and update the static content with the new code (multiple places for questions/answers/comments).  That's it, I think?
+1 vote
by

After all, I was fixed with client-side Javascript and overriding qa_check_form_security_code() function that checks CSRF protection code in V0.3.

by
Congrats for this... now can we use this plugin on main websites??
by
No. Many problems still exist. In some cases, the official release might be next year. If there is a cooperation of many developers, there is a possibility that release is accelerated. However, it would be probably not.
by
Wow! I hadn't even thought that this plugin will take that much for its first official release. But its even good that you are developing it, so I am sure that final product will be awesome... :)
by
Thanks Gurjyot for your understanding. This plugin is so simple. However, since many processing of Q2A are bypassed, many problems occur. Development may not require so much time. However, because the impact on the core is very large, must be a lot of test is carried out.
0 votes
by
removing security is never a good idea.

You have many solutions for this caching problem.

One requires a pluging to override the active theme class and a good knowledge of QA software to distinguish the user specific datas from the general container and the real time questions datas.

Half of the work is ready but I have too many things to do this summer. Please wait for 2 ou 3 weeks and you will merge the 2 works. Or , if you are impatient, contact me in private to get my methods and some pieces of code
by
You may have been a little misunderstanding. Security code has not been removed.
...