2017-10-22 4 views
0

Dies ist der Code von Ruby on Rails-Tutorial von MH:SQL Interpolation von Ruby on Rails Tutorial

def feed 
    following_ids = "SELECT followed_id FROM relationships 
        WHERE follower_id = :user_id" 
    Micropost.where("user_id IN (#{following_ids}) 
        OR user_id = :user_id", user_id: id) 
end 

Ist das SQL sicher? Weil viele Leute mir gesagt haben, benutze niemals Interpolation, sondern benutze immer einen Escape-Code (mit? In diesem Fall). Ist dieser Code also sicher?

Antwort

1

Ja, das ist sicher.

Es gibt keine Interpolation in der Tat: die ganze Abfrage als

geschrieben werden konnte
Micropost.where("user_id IN (
    SELECT followed_id FROM relationships 
     WHERE follower_id = :user_id) 
    OR user_id = :user_id", user_id: id) 

aber aus Gründen der Übersichtlichkeit wurde die erste Abfrage in seine eigene Variable extrahiert.

Die Interpolation muss vermieden werden, wenn die interpolierte Zeichenfolge von außen kommt. Diese Zeichenfolge wird von Ihnen direkt hier erstellt, daher besteht keine Gefahr einer SQL-Injektion oder dergleichen.


Beispiele

sicher, id bestimmt:

id = 42 
"SELECT * FROM users WHERE users.id = #{id}" 

unsicher, kommt params[:id] von außen und kann gefährlich sein:

"SELECT * FROM users WHERE users.id = #{params[:id]}" 
1

Dies ist sicher, da die Stringinterpolation nicht das Problem ist. Es führt nur zu einer Sicherheitsanfälligkeit, wenn Sie den Text, der in die Abfrage interpoliert wird, nicht steuern.

In Ihrem Beispiel ist die Zeichenfolge following_ids, die eingefügt wird, keine unbekannte Benutzereingabe, sondern eine feste SQL-Unterabfrage. Dies kann nicht zu einem Sicherheitsproblem führen.

Aber ich stimme zu, dass dies immer noch nicht ein gutes Beispiel ist und wahrscheinlich um Scopes und Rails Abfragesyntax umgestaltet werden sollte.