A basic newbie question

What built-in Python function can you use to create new config items that persist between requests?

There’s a number of ways you could create a “config” item that persists through the lifespan of multiple requests. It depends though on the total lifespan of this item. Should it remain across the lifespan of the server session (from when it last started up) or remain indefinitely with a timestamp that eventually expires?

For the former, you can simply create a dict that’s accessible throughout the application lifespan.

# set defaults as initial key/value pairs
config = {}

# assuming usage of flask here, but also applies to any other framework
@app.route('/', methods=['POST'])
def home():
    global config
    payload = request.get_json()
    try:
        # if request passed a json payload with a config key, value is not false or empty
        if payload['config']:
            config = payload['config']
    except KeyError:
        pass
    # ...

You could also go with another approach like storing config in a singleton object instead of a global, using cookies to associate a config with a specific user session (the above example sets the config for everyone while the server persists instead of being specific to that user), etc. The above example is just meant to get you started and provide a general idea.

1 Like

Frank asked:

“What built-in Python function can you use to create new config items
that persist between requests?”

None. Why does it have to be a built-in function?

If you want your config to persist between interpreter sessions, then
you need to save your config to permant storage (hard drive). You can
just open a file and write some ad hoc data to it, but it might be
better to use a more standard, less ad hoc solution:

especially configparser:

Other options may include JSON or YAML, but the important thing is that
you physically write the data out to disk otherwise it will be lost when
the interpreter shuts down.

If the config doesn’t have to persist between sessions, then just use
your normal variables, possibly including a dict. How are you storing
your config now? If you show us a simplified snippet of your existing
code, we may be able to suggest an alternative.

2 Likes

It’s for a question on exploiting Jinja2 for SSTI.

Isn’t this from immersive labs Jinja2 exploitation challenge?

Question 4 of 7
What built-in Python function can you use to create new config items that persist between requests?

As one of only eight level 9 labs that immersive labs have and as one of the hardest labs on their platform, I wouldn’t categorise this as “a basic newbie question”.

If you are doing the lab I would strongly discourage you from just asking for the answer since the majority of the value of the lab comes from exploring the problem yourself.

1 Like

I actually emailed a Python dev who actually works on python, and he said theres no inbuilt function to do what they say in the question.
Of course im going to ask

I’m sorry but the Python dev who you emailed is wrong. As someone who has completed these labs, let me assure you that there is a solution and that there is a function built into the Python language for creating new config items that persist between requests.

You should try to use the knowledge you gained from completing questions 1 - 3 to understand how flask manages its configuration and what tools you have available through this interface to manipulate that.

I hate underspecified questions like this. The correct answer is, “any
built-in function you like”. Proof:

# app.py
from flask import Flask
app = Flask(__name__)

with open('config.py', 'w') as f:
    f.write(chr(84) + 'ESTING = ' + str(bool(ord('A') < 255)) + '\n')

app.config.from_pyfile('config.py')

And there you have it, a way to use open, chr, str, bool and
ord to create a Flask config that persists between requests.

Since config.py is Python code, it can contain any Python built-ins you
like. If the question is referring to something more specific, it should
be more specific.

“What built-in Python function can you use to create new config items
in the way we are thinking off, not any other way that persist
between requests? No, not that way, guess again.”

So tell me then?

@MarkCBell, it’s happy to hear someone’s actually completed this one! It’s been putting me through the ringer. I don’t want it ruined, but are you able to drop any links to help figure out how to exec a python function without the use of parentheses? Without parentheses, you can’t call a function, just reference it. I can’t seem to get past that. Am I looking in the wrong direction? I think I have a solid understanding of Flask’s config and ways to interact with it and ideas for how to get banned chars into a config item, I just can’t figure out how you’d CREATE that config item without calling a function?

This is rather vague.

It may be that your tutorial question is poorly worded. The term “built
in” in Python usually means things which are part of the language itself
(like the “sorted()” or “print()” functions) rather than modules which
come shipped with it as standard.

People have mentioned that there are several presupplied modules which
can support a persistent configuration storage. The “configparser”
module is a likely choice, which reads and writes config files in the
style of Windows .ini files. I’d start with that, myself.

Cheers,
Cameron Simpson cs@cskk.id.au

Does not work. :confused:

So tell me then?

I’m sorry but unfortunately I cannot just tell you the answer to this question since that would violate of clause 9.4 of the terms and conditions of immersive labs - “You agree not to publish or share any techniques, answers on how to complete labs, information, intellectual property contained in the platform”

Good. Because I got them to remove the question. There is NO inbuilt function.

Excellent, good luck with the other questions in the challenge.

Mark has stated that there is a built-in function that can be used;
Frank has stated that there is not, and that he has convinced the
website owners to remove the question from the challenge.

The state of the Python language is not like quantum mechanics, this
built-in function cannot be in a superposition of existing and not
existing at the same time. Either it does exist (Mark’s position, but he
refuses to tell us what it is) or it doesn’t (Frank’s position, which he
says the challenge owners now agree with).

I’m not a requests expert, but from my reading of requests tutorials and
documentation, I cannot see how this function could exist except in the
trivial sense that you could use dict to make a key:value mapping that
you then pass to requests.

Assuming good faith and that nobody is intentionally being dishonest,
I’m curious how to reconcile this contradiction. Misunderstanding?
Flexible definition of “built-in function”? Trick question?

Maybe Mark would be willing to adhere to the challenge terms and
conditions by giving a hint as to what he believed the answer to be
rather than the full answer.

(“rhymes with Ben”)

So I’ve checked and yes this question has been removed from the challenge.

I imagine the most likely reason for the discrepancy between my and Frank’s positions is misunderstanding, so perhaps I can provide an alternate phrasing of the question which avoids python keywords:

What is the name of a function that is currently present within (one of the namespaces of) the flask process that is running on the target server which can be used to create new config items?

Regarding the removal of this question

Either it does exist (Mark’s position, but he refuses to tell us what it is) or it doesn’t (Frank’s position, which he says the challenge owners now agree with).

I would offer an alternative interpretation for why the challenge owners removed this question: that it was not particularly relevant to the main point of the challenge - understanding and applying a Jinja2 SSTI vulnerability to gain control of and exfiltrate data from a server.

Personally I am in favor of removing this question for this reason as in my opinion these Level 9 challenges should be as open-ended as possible to broadly test of the culmination of all of your knowledge and understanding on a topic. This challenge could event be distilled down to just “The server at XX.XX.XX.XX has a jinja2 SSTI vulnerability. What is the contents of /data/token.txt on the server?” Ultimately, I think obtaining the contents of this token though any means should count as a success.

What is wrong with this if statement?

fname = input("What is your first name? ")
lname = input("What is your last name? “)
print(“Hi there, " + fname + " " + lname + " , nice to meet you \n” )
age = input(“How old are you”)
print(age + " is a good age”)

if age >= 16:
print(“You’re old enough to drive”)
elif age < 16:
print(“You’re not old enough to drive, but that’s okay”)

nvm, 10 characters long

Please commence a new topic for unrelated questions, do not reply to
an existing topic. The latter attaches your reply to an existing
discussion, to the confusion of all.

To your question:

What is wrong with this if statement?

I should imagine you got an error message when you ran it. Have you
read that error message closely?

fname = input("What is your first name? ")
lname = input("What is your last name? “)
print(“Hi there, " + fname + " " + lname + " , nice to meet you \n” )
age = input(“How old are you”)
print(age + " is a good age”)

if age >= 16:
print(“You’re old enough to drive”)
elif age < 16:
print(“You’re not old enough to drive, but that’s okay”)

Well, for the if-statement itself, it is a bit redundant. You only need
an “else” for the second part. Otherwise it is fine.

Your real problem is that age is the wrong type, which I suspect
Python’s error message hinted at.

What is its type? What type does input() return?

Cheers,
Cameron Simpson cs@cskk.id.au