Estoy creando mi propia API y me preguntaba: ¿Cómo proteger los parámetros recibidos?
Ejemplo:
brand y color .Mi punto final recibe esos parámetros en la carga útil. Con este payload recibido busco en mi base de datos:
car = Car.where(color: params[:color]) # or car = Car.find_by(brand: params[:brand]) # or writing Car.first.update!(brand: params[:brand])Pero estoy tan preocupado por lo que sucede si alguien intenta explotar con SQL o XSS. ¿Cómo trabajas con esto?
Muchas gracias :)
Los ejemplos de su pregunta están todos protegidos contra la inyección de SQL automáticamente.
Citas relevantes de las guías oficiales de Rails :
7.2.1 Introducción
Los ataques de inyección SQL tienen como objetivo influir en las consultas de la base de datos mediante la manipulación de los parámetros de la aplicación web. Un objetivo popular de los ataques de inyección SQL es eludir la autorización. Otro objetivo es llevar a cabo la manipulación de datos o la lectura de datos arbitrarios. Aquí hay un ejemplo de cómo no usar los datos de entrada del usuario en una consulta:
Project.where("name = '#{params[:name]}'")
Luego, más adelante en el mismo documento :
7.2.4 Contramedidas
Ruby on Rails tiene un filtro incorporado para caracteres SQL especiales, que escaparán
',", carácter NULL y saltos de línea. El usoModel.find(id)oModel.find_by_some thing(something)aplica automáticamente esta contramedida. Pero en Los fragmentos de SQL, especialmente en los fragmentos de condiciones (where("...")), los métodosconnection.execute()oModel.find_by_sql(), deben aplicarse manualmente.En lugar de pasar una cadena, puede usar controladores posicionales para desinfectar cadenas contaminadas como esta:
Model.where("zip_code = ? AND quantity >= ?", entered_zip_code, entered_quantity).firstEl primer parámetro es un fragmento de SQL con signos de interrogación. El segundo y tercer parámetro reemplazarán los signos de interrogación con el valor de las variables.
También puede usar controladores con nombre, los valores se tomarán del hash utilizado:
values = { zip: entered_zip_code, qty: entered_quantity } Model.where("zip_code = :zip AND quantity >= :qty", values).firstAdemás, puede dividir y encadenar condicionales válidos para su caso de uso:
Model.where(zip_code: entered_zip_code).where("quantity >= ?", entered_quantity).first
En la mayoría de los casos, Rails se encarga de la inyección de SQL. Pero debe evitar pasar cadenas como parámetros a los métodos de Active Records. Evita esto:
Car.where(“color = '#{params[:color]'”)
No es agradable de ver ;)
Y use matrices o hashes en su lugar:
car = Car.where(color: params[:color])
car = Car.where(["color = ?", params[:color])
Al hacerlo, Active Records escapará automáticamente los caracteres no deseados, protegiendo contra la inyección de SQL.
Para obtener más información, consulte el documento de Rails: https://guides.rubyonrails.org/security.html#sql-injection-countermeasures
Actualicé esta respuesta después de que @spickermann informara un error significativo.