Integrate new CAPTCHA generation code into current webapp #7

Open
opened 2023-06-12 13:57:03 -04:00 by cerealxp · 3 comments
Owner

Currently, app.py can generate old style captchas correctly, but does not work with the new ones. Ie, it doesn't randomize the images, or process the output, or anything like that.

What is remaining to integrate the new captcha generation technique?

  • Select and rotate a random image
  • Serve the recursively generated HTML correctly...
  • Deal with cookies (see JWT issue, add link here...)

All of the above issues should be linked to an issue here on gitlain.

Here is pseudocode for how it should basically work:

@app.route("/captcha3", methods=['GET'])
def captcha3():
    # if request.method == "POST":
        ## Get their guess from POST body
        ## Get JWT cookie
        ## Decrypt payload
        ## Check if guess (from post body) == correct answer (from decrypted JWT payload)
        ## If so: give them a new JWT for winning the CAPTCHA, and forward them to the URL they originally wanted to access precaptcha (just like oauth does)
        ## If not: Redirect them to the GET version of this same URL, with warning enabled to tell them they failed
    # if request.method == "GET":
        # image_path = captcha.random_image()
        # answer, options = captcha.captchafy(image_path)
        # encrypt the answer
        # Set JWT with encrypted answer as HTTP cookie
        # issue: they could compare our encrypted answer with how we encrypt all numbers 1-6, since they will have seem them before.
        # We could solve this with a salt, but then we have to store salts. We could include the salt in plaintext, but then they could build a rainbow table of our guess + salts (since there are only 6 possible guesses)
        # the solution is to use salts big enough that we don't have to fear them repeating / being turned into a rainbow table.
        # We will use UUID's as the salts.
        #
        # Anyway, we pass the data to our Jinja template and render it.
    # else: return 400 error, unsupported HTTP method! (in practice, if this ever happens in real life its almost certainly a pentester. To put it politely.) 


Some notes for the issue about generating the HTML and integrating with Jinja, since we don't have an issue for that (please, someone, do create one based on this note):

What we want (generate the recursive tree in Python)

Ideally, we could pass the recursive tree to Jinja, and Jinja could deal with the HTML.

Why? To separate separate presentation from program logic. If we want to play around with the HTML, we should be able to do that in the template. That's what it's for.

Is this possible with Jinja? Maybe, using recursive macros: https://stackoverflow.com/questions/32771924/macro-recursion-in-jinja2

This will be harder and require a lot more thought. But it would be the "best practice from a software engineering perspective. The usual compromise: Generate the HTML in Python and pass it to Jinja. Then one day when we have free time and want to mess around, figure out this recursive macro nonsense.

Currently, [app.py](https://git.lain.church/jesusvilla/FreeCAPTCHA/src/commit/97c28170c954dfbc85f9524b91d35b050bbed31f/app.py) can generate old style captchas correctly, but does not work with the new ones. Ie, it doesn't randomize the images, or process the output, or anything like that. What is remaining to integrate the new captcha generation technique? - [ ] Select and rotate a random image - [ ] Serve the recursively generated HTML correctly... - [ ] Deal with cookies (see JWT issue, add link here...) All of the above issues should be linked to an issue here on gitlain. Here is pseudocode for how it should basically work: ```python @app.route("/captcha3", methods=['GET']) def captcha3(): # if request.method == "POST": ## Get their guess from POST body ## Get JWT cookie ## Decrypt payload ## Check if guess (from post body) == correct answer (from decrypted JWT payload) ## If so: give them a new JWT for winning the CAPTCHA, and forward them to the URL they originally wanted to access precaptcha (just like oauth does) ## If not: Redirect them to the GET version of this same URL, with warning enabled to tell them they failed # if request.method == "GET": # image_path = captcha.random_image() # answer, options = captcha.captchafy(image_path) # encrypt the answer # Set JWT with encrypted answer as HTTP cookie # issue: they could compare our encrypted answer with how we encrypt all numbers 1-6, since they will have seem them before. # We could solve this with a salt, but then we have to store salts. We could include the salt in plaintext, but then they could build a rainbow table of our guess + salts (since there are only 6 possible guesses) # the solution is to use salts big enough that we don't have to fear them repeating / being turned into a rainbow table. # We will use UUID's as the salts. # # Anyway, we pass the data to our Jinja template and render it. # else: return 400 error, unsupported HTTP method! (in practice, if this ever happens in real life its almost certainly a pentester. To put it politely.) ``` --- Some notes for the issue about generating the HTML and integrating with Jinja, since we don't have an issue for that (please, someone, do create one based on this note): What we want (generate the recursive tree in Python) Ideally, we could pass the recursive tree to Jinja, and Jinja could deal with the HTML. Why? To separate [separate presentation from program logic](https://softwareengineering.stackexchange.com/questions/179626/is-the-separation-of-program-logic-and-presentation-layer-going-too-far). If we want to play around with the HTML, we should be able to do that in the template. That's what it's for. Is this possible with Jinja? Maybe, using recursive macros: https://stackoverflow.com/questions/32771924/macro-recursion-in-jinja2 This will be harder and require a lot more thought. But it would be the "best practice from a software engineering perspective. The usual compromise: Generate the HTML in Python and pass it to Jinja. Then one day when we have free time and want to mess around, figure out this recursive macro nonsense.
Author
Owner

I will be editing these issues to flesh them out, the above is a rough draft still...

I will be editing these issues to flesh them out, the above is a rough draft still...
Author
Owner

This is probably the most important issue because without this, there isn't even a working MVP

This is probably the most important issue because without this, there isn't even a working MVP
cerealxp added the
bug
enhancement
help wanted
Discussion
labels 2023-06-12 14:12:09 -04:00
Author
Owner

I'm going to try to make it work without setting up the JWT stuff or worrying about recursive Jinja complications. I'll just generate the html and serve it and use my current cookie concoction.

I'm going to try to make it work without setting up the JWT stuff or worrying about recursive Jinja complications. I'll just generate the html and serve it and use my current cookie concoction.
Sign in to join this conversation.
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cerealxp/FreeCAPTCHA#7
No description provided.