Security API – Dale a tus empleados lo que necesitan (de forma segura)
Hace poco vimos en SecurityInside consejos a tener en cuenta para revisar la seguridad de tu API. Como comentamos, ofrecer servicios de información en el mundo de hoy si no tienes API, te da una desventaja considerable que podría terminar por arruinar tu negocio.
Es por eso que tu departamento de desarrollo debe tener en mente trabajar en una buena api (sencilla y segura) que de servicio tanto a clientes como a las plataformas y herramientas internas.
Hay muchas formas de desarrollar APIs, pero en mi caso me he decantado últimamente por Flask para Python sobre Elastic Beanstalk de Amazon Web Services.
Security API, ¿por qué?
Cada vez que arranco un proyecto de seguridad con una nueva empresa, me presento desde el punto de vista de vida laboral. Cuento mis años como becario, desarrollador, jefe de proyecto, consultor y luego el paso al mundo de la seguridad. Me miran como diciendo «¿para qué todo este rollo?». Sencillo, es la forma de introducir que soy un apasionado de la seguridad y que mi objetivo principal es asegurar los activos de la empresa, pero siempre tratando de hacer la vida sencilla a los compañeros que tienen que lidiar con todas las medidas y controles de seguridad que se implanten.
Conozco profesionales de la seguridad que nunca se han manchado las manos picando código y que aplican medidas maravillosas que fortifican los activos mientras complican el trabajo diario. Lo importante es la seguridad, pero mi perfil de desarrollador me hace pensar siempre en hacerlo de forma que ellos tengan todas las facilidades para trabajar. Seguros, pero trabajando.
Por todo esto, hace no mucho empecé a dar vueltas a la idea de crear una «security api» que diera servicio a determinadas necesidades de los compañeros de los diferentes departamentos. De esta forma, aplico medidas de seguridad generales y les doy la posibilidad de solicitar ciertos permisos, accesos, … de forma automática en base a roles.
¿Cómo funciona?
Básicamente todo funciona en base a usuarios que se autentican con login, password y 2fa (Google Authenticator, Android, iOS). Cada usuario tiene un rol y subrol con el que se indica qué cosas tienen permitidas y todo se gestiona mediante JSON Web Tokens.
Flask api template
Os he dejado en Github un nuevo repositorio que contiene el esqueleto de una api desarrollado en Python utilizando la biblioteca Flask.
Podéis lanzarlo en local para desarrollo y hacer pruebas de forma sencilla utilizando Postman, ya que os he dejado también un fichero con ejemplos de uso. Tendréis queja… 😀
Vamos viéndo cosillas
En el fichero principal (flask_api.py) veréis unas cuantas cosas que os voy a ir explicando.
Al principio, tenéis una función que se lanza tras arrancar el server, ahí se pueden configurar diferentes cosas (dar de alta la ip del server en determinados grupos de seguridad, enviar notificaciones, …):
########################################################################################## # This function makes initial tasks. ########################################################################################## @application.before_first_request def _run_on_start(): if not DEBUG: print "Flask started!" # Here you can do some initial tasks ##########################################################################################
Después se incluyen dos apartados para la gestión de códigos 404 y 405:
########################################################################################## # This function returns happy 404. ########################################################################################## @application.errorhandler(404) def page_not_found(e): return redirect("https://goo.gl/LuKygx", code=302) ########################################################################################## ########################################################################################## # This function returns happy 405. ########################################################################################## @application.errorhandler(405) def method_not_allowed(e): ret_html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>' ret_html = ret_html + '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">' ret_html = ret_html + '<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' ret_html = ret_html + '<title>Flask API SecurityInside.info Template</title>' ret_html = ret_html + '<style type="text/css" media="screen">' ret_html = ret_html + 'h1 {text-align:left; color: #444;}' ret_html = ret_html + '</style></head><body>' ret_html = ret_html + '<h1>Flask API <a href="http://www.securityinside.info" target="blank">SecurityInside.info</a> Template</h1>' ret_html = ret_html + 'Method not allowed or missing params, check API doc to solve the problem.' ret_html = ret_html + '</body></html>' return flask_api_functions.ret_content_type(ret_html, 'html', 405) ##########################################################################################
Una siempre interesante función ping para comprobar rápidamente si el server está vivo:
########################################################################################## # This function shows API alive info. ########################################################################################## @application.route('/' + API_VERSION + '/ping', methods=['GET']) def ping(): response = {'code': 200, 'message': 'pong'} return flask_api_functions.ret_content_type(response, 'json', 200) ##########################################################################################
La parte más interesante del ejemplo, la gestión del login y creación del token:
########################################################################################## # This function checks auth user and return JWT. ########################################################################################## @application.route('/' + API_VERSION + '/login', methods=['POST']) def login(): # Check preconditions ################################################################################## response = flask_api_functions.check_preconditions(request, False) if (response['code'] != 200): return flask_api_functions.ret_content_type(response, 'json', response['code']) ################################################################################## # Check for user credentials ################################################################################## response = flask_api_functions.check_auth(request) return flask_api_functions.ret_content_type(response, 'json', response['code']) ################################################################################## ##########################################################################################
Y la implementación concreta dentro del fichero flask_api_functions.py:
########################################################################################## # This function checks user authorization header request. # # @param request - User request data. # # @return Formatted response. # ########################################################################################## def check_auth(request): try: auth = base64.b64decode(request.headers['Authorization'].split()[1]) except: response = {'code': 401, 'message': 'Invalid basic authorization header.'} return response if len(auth.split(':')) != 2: response = {'code': 401, 'message': 'Invalid basic authorization header.'} return response else: """ Here you have to check user credentials and optional totp value. """ # If user credentials is ok, then generate jwt if(True): # User with valid credentials token = jwt.encode({ 'user_id': '<insert_here_user_id>', 'user_name': '<insert_here_user_name>', 'user_roles': '<insert_here_user_roles>', 'other_fields': '<insert_here_other_fields>', 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=1)}, SECRET) response = {'code': 200, 'message': None, 'token': token} return response # If user credentials is not ok, then return error message else: response = {'code': 401, 'message': '(d\'oh!) Wrong user, password, totp value or maybe user is not active.'} return response ##########################################################################################
Para entender ciertas cosas como la forma de enviar el header «Authentication», pásate por el README.md del repositorio y ejecuta las pruebas con postman, verás que es la mar de sencillo.
Importante antes de terminar
Flask no está preparado para funcionar directamente en un entorno de producción, para hacerlo tienes que tener en cuenta un par de cosas (está todo en la documentación del repositorio).
En mi caso particular, ya os he dicho que lo tengo montado en Elastic Beanstalk de Amazon Web Services, si queréis os puedo contar cómo lo he hecho en otra entrada.
Por supuesto, si tenéis alguna duda sobre esta entrada, preguntad que estaré encantado de echar una mano.
Saludos!
- GuardDuty: Un viaje a través del tiempo en AWS Security - 21 noviembre, 2023
- Webinar – Seguridad para familias - 11 enero, 2021
- SecurityInside Live: CISO Day 2020 - 17 septiembre, 2020
mexican mail order pharmacies: mexico pharmacy – mexican border pharmacies shipping to usa
buying prescription drugs in mexico online
http://cmqpharma.com/# mexican mail order pharmacies
best online pharmacies in mexico
п»їbest mexican online pharmacies: cmq pharma mexican pharmacy – buying prescription drugs in mexico online
mexican drugstore online: п»їbest mexican online pharmacies – buying prescription drugs in mexico
indianpharmacy com pharmacy website india reputable indian pharmacies
https://foruspharma.com/# pharmacies in mexico that ship to usa
purple pharmacy mexico price list: medicine in mexico pharmacies – mexico pharmacies prescription drugs
pharmacy website india: top 10 pharmacies in india – cheapest online pharmacy india
canadapharmacyonline: best canadian pharmacy – pharmacies in canada that ship to the us
https://foruspharma.com/# buying prescription drugs in mexico
canadian drug pharmacy: canadian pharmacy review – canada drugs
canadian pharmacy 24: canadian valley pharmacy – canada drug pharmacy
indianpharmacy com indian pharmacy indian pharmacy online
pharmacies in mexico that ship to usa: buying from online mexican pharmacy – purple pharmacy mexico price list
Online medicine order: world pharmacy india – best india pharmacy
buy medicines online in india: indian pharmacy paypal – top 10 online pharmacy in india
top 10 pharmacies in india: top 10 online pharmacy in india – indianpharmacy com
https://canadapharmast.com/# best canadian online pharmacy reviews
buy prescription drugs from india: online shopping pharmacy india – buy medicines online in india
canadian pharmacy online reviews: canadian pharmacy online – canadian pharmacy world
https://foruspharma.com/# mexican online pharmacies prescription drugs
п»їbest mexican online pharmacies reputable mexican pharmacies online reputable mexican pharmacies online
canada drugs online: safe online pharmacies in canada – canada drugs online review
canadian online pharmacy: canadian drugs – canadian discount pharmacy
buying prescription drugs in mexico online: mexican rx online – mexican drugstore online
canadian world pharmacy vipps approved canadian online pharmacy canadian pharmacy prices
pharmacy com canada: canadian pharmacy meds reviews – canadian pharmacy world reviews
online canadian drugstore: the canadian pharmacy – real canadian pharmacy
http://canadapharmast.com/# northern pharmacy canada
medicine in mexico pharmacies: mexico pharmacies prescription drugs – buying prescription drugs in mexico
canadian pharmacy online ship to usa ed meds online canada canada drugs online review
buy medicines online in india: buy prescription drugs from india – pharmacy website india
http://foruspharma.com/# mexican online pharmacies prescription drugs
pharmacy wholesalers canada: best canadian online pharmacy – cheap canadian pharmacy
mexican mail order pharmacies: best online pharmacies in mexico – buying from online mexican pharmacy
vipps canadian pharmacy: trusted canadian pharmacy – canada pharmacy 24h
http://ciprodelivery.pro/# antibiotics cipro
can i purchase clomid now: buying cheap clomid without insurance – get generic clomid pills
http://amoxildelivery.pro/# amoxicillin online purchase
doxcyclene: doxycycline rx – doxycycline 100mg price in india
https://amoxildelivery.pro/# amoxicillin script
http://doxycyclinedelivery.pro/# doxycycline 50 mg price uk
cipro pharmacy: buy cipro cheap – ciprofloxacin 500mg buy online
http://ciprodelivery.pro/# ciprofloxacin 500mg buy online
http://doxycyclinedelivery.pro/# where can i buy doxycycline online
ciprofloxacin 500 mg tablet price: ciprofloxacin mail online – buy cipro without rx
https://clomiddelivery.pro/# clomid online
http://paxloviddelivery.pro/# paxlovid buy
paxlovid pill: п»їpaxlovid – paxlovid buy
amoxicillin 800 mg price: where can you get amoxicillin – cost of amoxicillin 875 mg
https://paxloviddelivery.pro/# Paxlovid buy online
https://clomiddelivery.pro/# can you get clomid without dr prescription
http://doxycyclinedelivery.pro/# doxycycline 100mg pills
doxycycline india buy: doxycycline online usa – buy cheap doxycycline uk
http://clomiddelivery.pro/# can you get clomid for sale
buy generic clomid without insurance: how can i get cheap clomid without a prescription – cost of clomid
http://paxloviddelivery.pro/# paxlovid pharmacy
https://paxloviddelivery.pro/# paxlovid covid
order amoxicillin online no prescription: amoxicillin 500mg capsules antibiotic – buy amoxicillin 500mg online
http://clomiddelivery.pro/# clomid price
Paxlovid over the counter: paxlovid covid – п»їpaxlovid
http://doxycyclinedelivery.pro/# buy vibramycin
https://paxloviddelivery.pro/# paxlovid buy
п»їpaxlovid: paxlovid pill – paxlovid cost without insurance
https://amoxildelivery.pro/# over the counter amoxicillin
paxlovid pharmacy: paxlovid price – paxlovid for sale
paxlovid cost without insurance: paxlovid generic – paxlovid pharmacy
price for amoxicillin 875 mg: canadian pharmacy amoxicillin – amoxicillin in india
buy amoxicillin online cheap: amoxicillin buy online canada – can you buy amoxicillin over the counter