2026-07-12 20:22:15 +01:00

71 lines
1.9 KiB
Python

#!/usr/bin/env python3
# app.py - minimal vulnerable blog demonstrating stored XSS
from flask import (
Flask,
request,
redirect,
url_for,
render_template,
make_response,
jsonify,
abort
)
import json, os
app = Flask(__name__)
DATA_DIR = 'data'
COMMENTS_FILE = os.path.join(DATA_DIR, 'comments.json')
ADMIN_TOKEN_FILE = os.path.join(DATA_DIR, 'admin_token.txt')
FLAG_FILE = "flag.txt"
def read_comments():
with open(COMMENTS_FILE,'r') as f:
return json.load(f)
def write_comments(comments):
with open(COMMENTS_FILE,'w') as f:
json.dump(comments, f)
def read_file(path):
with open(path, 'r') as f:
return f.read().strip()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/post/<int:post_id>')
def post_view(post_id):
comments = read_comments()
return render_template('post.html', post_id=post_id, comments=comments)
@app.route('/comment', methods=['POST'])
def comment_post():
name = request.form.get('name','Anonymous')
comment = request.form.get('comment','')
comments = read_comments()
next_id = max([c.get('id',0) for c in comments], default=0) + 1
comments.append({'name':name,'comment':comment,'id':next_id})
write_comments(comments)
return redirect(url_for('post_view', post_id=1))
@app.route('/api/comments')
def api_comments():
# returns raw comments as JSON for convenience (admin UI might use this)
return jsonify(read_comments())
@app.route('/admin_login')
def admin_login():
token = request.args.get('token', '')
real_token = read_file(ADMIN_TOKEN_FILE)
if token != real_token:
abort(404)
# Create response that sets a cookie named 'session' containing the flag
resp = make_response(redirect(url_for('post_view', post_id=1)))
flag = read_file(FLAG_FILE)
resp.set_cookie('session', flag, samesite='Lax')
return resp