From 2a20e2365182d308c9116da16bc2f8a5742ce6bd Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Tue, 3 Sep 2024 13:04:07 -0700 Subject: [PATCH] Sign the _redirect_to= parameter, refs #10 --- datasette_write/__init__.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/datasette_write/__init__.py b/datasette_write/__init__.py index bac40b1..011cd86 100644 --- a/datasette_write/__init__.py +++ b/datasette_write/__init__.py @@ -28,8 +28,7 @@ async def write(request, datasette): "database_name": database_name, "tables": tables, "views": views, - "redirect_to": request.args.get("_redirect_to") - or "", # TODO: Sign this + "redirect_to": request.args.get("_redirect_to"), "sql_textarea_height": max(10, int(1.4 * len(sql.split("\n")))), }, request=request, @@ -74,16 +73,18 @@ async def write(request, datasette): message, type=datasette.INFO if result else datasette.ERROR, ) - - redirect_to = formdata.get("_redirect_to") or datasette.urls.path( - "/-/write?" - ) + urlencode( + # Default redirect back to this page + redirect_to = datasette.urls.path("/-/write?") + urlencode( { "database": database.name, "sql": sql, } ) - + try: + # Unless value and valid signature for _redirect_to= + redirect_to = datasette.unsign(formdata["_redirect_to"], "redirect_to") + except (KeyError, ValueError): + pass return Response.redirect(redirect_to) else: return Response.html("Bad method", status_code=405) @@ -215,7 +216,7 @@ async def inner(): table, set_clauses, where_clauses ) args["sql"] = sql - args["_redirect_to"] = request.path + args["_redirect_to"] = datasette.sign(request.path, "redirect_to") return [ { "href": datasette.urls.path("/-/write") + "?" + urlencode(args),