Django ORM Practice App

This is something that I have in mind for some months now…

I have an ORM App which I practice the ORM with.
(With the shell…)

I want to convert it to something like this

But didnt know how to achieve this kind of behavior with Django.
In the meantime I learned about Tests and understand that TestCase do something very similar…

How would you approach this ?

I thinking about something like have a separate DB for the exercises (which I add for each query ‘using’ to it), and maybe using eval inside a TestCase that will be called from a view…
Not sure about it…

If it’s just something for you, and you have no intent of exposing this to the general public, then yes, you can use eval within your view to execute code entered in a form in your view.

However, if anyone other than yourself has access to this, be prepared to recover and reinitialize your system on a regular and consistent basis, because people will find ways to exploit it. For just an overview of some of the problems, see Eval really is dangerous | Ned Batchelder (and make sure you read all the comments as well.) You can also search the web for “Why Python eval is dangerous” and find much more information and many more examples as to why exposing eval in a web form is a really bad idea.

I read it…
I thinking on create a secondary DB only for that purpose. so the queries will be on a separate DB.

Can I do something like it ?

The issue/problem with doing it isn’t limiting the database being accessed, which you can’t do anyway, but preventing a person from executing any arbitrary python code - putting the entire system at risk.

Can you do it? Sure. But the first malicious user will bring the system down.

using’ doesn’t allow one to query a specific database ?

Also, If you can do it and can access the ORM ‘stream’ within it, one can’t build a custom shell/stream only for one db ?

I know it a complicated task…

You’re missing the point. If you expose an ‘eval’ interface, you are unable to prevent a malicious user from executing any arbitrary code. The previously referenced blog shows how the common mitigation ideas are easily bypassed.

Yeah, I read it, I still want some how to make it work…

Thinking on building a custom shell that only access the wanted db…

Maybe to build some parser that will make sure the commands is safe…

And maintain a blacklist of expressions like “import”…

You can make it “work” - nobody is saying you can’t. What you can’t do is make it work safely. At least not from “inside” the framework. (See notes in last paragraph at bottom.)

You say you’ve read the article, but then you say:

which leads me to believe you’re thinking that the only problem is someone accessing the wrong database - when that’s the least of the issues you’re going to need to deal with.

Then you’ve also said:

which means you didn’t read all the comments talking about all the ways that a “reject” list of expressions can be circumvented.

You can probably make something work reasonably safely by spinning up a new docker container for each user, where that container is very tightly controlled - the worst that the user could do would be to kill their own session. That’s still not going to prevent a DoS attack though, and may possibly make one more practical.

1 Like

I didnt read the comments…

I meant to build some kind of a parser that will check the user didnt enter dangerous keywords, like: “import”, magic methods and more…
And only then will call eval…

Anyway, I get the impression thats is impossible so I will probably drop it…
(The site provided in my first post, make it happen some how… )

I’ll give you one very simple example to show you how difficult (i.e. effectively impossible) it is to build a “reject list” of improper statements. You mention that you would filter out the keyword “import”.

However, getattr(__builtins__, '__tropmi__'[::-1])('os'), will import the os module - and nowhere do you see the string “import” in that command. And it all can get even more obfuscated than that.

Pretty much, whatever you think you can filter can be worked around.

It’s even worse if this is being done in the context of a Django view. By necessity, there’s already a large number of modules that would have already been imported in that context able to be used without additional imports.

My final idea is:

  1. Take the query
  2. Validate for black-list and structure (only <-mode-l>.objects.[filter, values, aggregate, …]
  3. run restricted eval inside a TestCase (if possible)
  4. The query will be added ‘using’, to target the dedicated DB.

Anyway, I mainly consider it as a challenge and its something that could help me when I started to learn the ORM…

I understand the objective - it’s laudable, really. It’s just that Python isn’t designed to protect you against “yourself” - and in this case, “yourself” means “anyone and everyone interested in causing harm to your site”.

2: SomeModel.objects.filter(title=<some nefarious code entered here>)

4: SomeModel.objects.aggregate(new_value=Subquery(OtherModel.objects.using('Wrong_DB").nefarious_operation))

1 Like

Ok, I will (probably) drop it…