En aquest exercici, implementarem controls de seguretat en una aplicació web per mitigar diverses vulnerabilitats comunes. L'objectiu és aplicar els coneixements adquirits en els mòduls anteriors per assegurar una aplicació web fictícia.

Objectius de l'Exercici

  1. Identificar vulnerabilitats en el codi existent.
  2. Implementar controls de seguretat per mitigar aquestes vulnerabilitats.
  3. Verificar que les vulnerabilitats han estat corregides.

Escenari

Disposem d'una aplicació web fictícia que permet als usuaris registrar-se, iniciar sessió i veure el seu perfil. Aquesta aplicació conté diverses vulnerabilitats que necessiten ser corregides.

Codi Inicial

A continuació, es mostra el codi inicial de l'aplicació web:

# app.py
from flask import Flask, request, render_template_string

app = Flask(__name__)

users = {}

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    users[username] = password
    return "User registered successfully!"

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    if username in users and users[username] == password:
        return f"Welcome, {username}!"
    else:
        return "Invalid credentials!"

@app.route('/profile/<username>')
def profile(username):
    if username in users:
        return render_template_string(f"<h1>Profile of {username}</h1>")
    else:
        return "User not found!"

if __name__ == '__main__':
    app.run(debug=True)

Vulnerabilitats Identificades

  1. Injecció SQL: No hi ha cap vulnerabilitat d'injecció SQL en aquest codi, però és important tenir-ho en compte en aplicacions més complexes.
  2. Pèrdua d'Autenticació: No es fa servir cap mecanisme d'autenticació robust.
  3. Exposició de Dades Sensibles: Les contrasenyes es guarden en text pla.
  4. Cross-Site Scripting (XSS): El perfil de l'usuari es mostra sense cap tipus de sanitització.

Tasques

  1. Implementar Hashing de Contrasenyes

Per evitar l'exposició de dades sensibles, hem de guardar les contrasenyes de manera segura utilitzant hashing.

# app.py (modificat)
from flask import Flask, request, render_template_string
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)

users = {}

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    hashed_password = generate_password_hash(password)
    users[username] = hashed_password
    return "User registered successfully!"

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    if username in users and check_password_hash(users[username], password):
        return f"Welcome, {username}!"
    else:
        return "Invalid credentials!"

@app.route('/profile/<username>')
def profile(username):
    if username in users:
        return render_template_string(f"<h1>Profile of {username}</h1>")
    else:
        return "User not found!"

if __name__ == '__main__':
    app.run(debug=True)

  1. Implementar Autenticació Basada en Sessions

Per millorar la seguretat de l'autenticació, implementarem sessions.

# app.py (modificat)
from flask import Flask, request, render_template_string, session, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'supersecretkey'

users = {}

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    hashed_password = generate_password_hash(password)
    users[username] = hashed_password
    return "User registered successfully!"

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    if username in users and check_password_hash(users[username], password):
        session['username'] = username
        return redirect(url_for('profile', username=username))
    else:
        return "Invalid credentials!"

@app.route('/profile/<username>')
def profile(username):
    if 'username' in session and session['username'] == username:
        return render_template_string(f"<h1>Profile of {username}</h1>")
    else:
        return "User not found or not logged in!"

@app.route('/logout')
def logout():
    session.pop('username', None)
    return "Logged out successfully!"

if __name__ == '__main__':
    app.run(debug=True)

  1. Prevenir Cross-Site Scripting (XSS)

Per prevenir XSS, utilitzarem sanitització de dades.

# app.py (modificat)
from flask import Flask, request, render_template_string, session, redirect, url_for, escape
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'supersecretkey'

users = {}

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    hashed_password = generate_password_hash(password)
    users[username] = hashed_password
    return "User registered successfully!"

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    if username in users and check_password_hash(users[username], password):
        session['username'] = username
        return redirect(url_for('profile', username=username))
    else:
        return "Invalid credentials!"

@app.route('/profile/<username>')
def profile(username):
    if 'username' in session and session['username'] == username:
        return render_template_string(f"<h1>Profile of {escape(username)}</h1>")
    else:
        return "User not found or not logged in!"

@app.route('/logout')
def logout():
    session.pop('username', None)
    return "Logged out successfully!"

if __name__ == '__main__':
    app.run(debug=True)

Verificació

  1. Verificar Hashing de Contrasenyes

  • Registra un nou usuari i comprova que la contrasenya es guarda de manera hashada.

  1. Verificar Autenticació Basada en Sessions

  • Inicia sessió amb un usuari registrat i comprova que pots accedir al perfil.
  • Tanca la sessió i comprova que no pots accedir al perfil sense iniciar sessió.

  1. Verificar Preveniment de XSS

  • Intenta injectar codi maliciós en el nom d'usuari i comprova que es mostra de manera segura.

Conclusió

En aquest exercici, hem implementat controls de seguretat essencials per protegir una aplicació web contra vulnerabilitats comunes. Hem après a utilitzar hashing per a contrasenyes, sessions per a autenticació i sanitització per prevenir XSS. Aquests són passos fonamentals per assegurar qualsevol aplicació web.

Curs d'OWASP: Directrius i Estàndards per a la Seguretat en Aplicacions Web

Mòdul 1: Introducció a OWASP

Mòdul 2: Principals Projectes d'OWASP

Mòdul 3: OWASP Top Ten

Mòdul 4: OWASP ASVS (Application Security Verification Standard)

Mòdul 5: OWASP SAMM (Software Assurance Maturity Model)

Mòdul 6: OWASP ZAP (Zed Attack Proxy)

Mòdul 7: Bones Pràctiques i Recomanacions

Mòdul 8: Exercicis Pràctics i Casos d'Estudi

Mòdul 9: Avaluació i Certificació

© Copyright 2024. Tots els drets reservats