Find the RCE Sink: Spotting an eval() Injection in Python

Sécurité Web & API Niveau 2/5 ~3 min 2026-06-27

Le défi

Cette API de 'calcul rapide' exécute tout ce que vous envoyez. Une fonction native de Python transforme ça en exécution de code à distance. Lisez les deux fichiers et tapez le nom de cette fonction.

Ce que tu vas apprendre

  • Recognise eval()/exec() on untrusted input as a remote code execution sink
  • Trace request data from its entry point to a dangerous function across files
  • Tell apart code execution (eval) from safe data parsing (ast.literal_eval)
  • Read a small codebase the way a reviewer does: follow the input, find the sink

Compétences testées

Source code reviewPython injection sinksData-flow tracing

Prérequis

  • Basic Python reading
  • Familiarity with HTTP query parameters

Comment ça marche

Remote code execution (RCE) is the most severe class of web vulnerability: the attacker gets the application to run code of their choosing on the server. In Python, the classic sink is eval() (and its sibling exec()). eval() takes a string and evaluates it as a Python expression - so if any part of that string comes from the user, the user can run Python.

This app exposes a 'quick math' endpoint. It reads expr from the query string and hands it directly to eval(). A normal request like ?expr=2*21 returns 42, which is exactly why this kind of bug ships - it looks like a harmless calculator. But an attacker sends ?expr=__import__('os').system('id') and the server runs a shell command. From there it is a short step to reading files, exfiltrating data, or planting a shell.

The fix is in the second file. ast.literal_eval() parses only Python literals - numbers, strings, lists, dicts - and refuses anything that would execute. That is the right tool when you need to turn text into data. The job in a review like this is to follow the untrusted value (expr) from where it enters to what consumes it, and recognise that the consumer is a code-execution primitive.

Erreurs fréquentes

  • Assuming a 'calculator' is harmless. The friendly feature name hides that eval runs arbitrary code, not just arithmetic.
  • Pointing at request.args instead of the sink. Reading input is fine; the bug is what you do with it. Name the function that executes it.
  • Confusing eval with literal_eval. They look similar but only one executes code - that difference is the whole vulnerability.

Comment s'en protéger

Never pass untrusted input to eval() or exec(). If you need arithmetic, parse it with a real expression parser or a safe library. If you need to turn text into data, use ast.literal_eval() or json.loads().

  • Ban eval/exec on request data in code review and with a linter rule.
  • Treat every query parameter, header, and body field as attacker-controlled.
  • Prefer allow-lists and typed parsing over evaluating strings.

Solution complète

Les membres Pro et Max débloquent la solution complète étape par étape.

Passer Pro

Statistiques de la communauté

45 résolutions
76% taux de réussite
cpkakaping Premier sang

Go deeper

Hacks du jour associés

14 000+ Hackers 100+ Labs & Cours Gratuit
Commencer Gratuitement