fix(monavisvalidator): restrict to known domains
This commit is contained in:
parent
ba3fda1928
commit
497146081d
1 changed files with 26 additions and 4 deletions
|
@ -1,9 +1,31 @@
|
||||||
|
# We need to ensure the embed code is not any random string in order to avoid injections
|
||||||
class MonAvisEmbedValidator < ActiveModel::Validator
|
class MonAvisEmbedValidator < ActiveModel::Validator
|
||||||
|
class MonAvisEmbedError < StandardError; end
|
||||||
|
# from time to time, they decide to change domain just for fun. if it breaks, check the new subdomain
|
||||||
|
KNOWN_SUBDOMAIN = ['jedonnemonavis', 'monavis', 'voxusagers']
|
||||||
|
HREF_CHECKER = /https:\/\/#{KNOWN_SUBDOMAIN.join('|')}.numerique.gouv.fr\/Demarches\/\d+.*key=[[:alnum:]]+.*/
|
||||||
|
IMG_CHECKER = /https:\/\/#{KNOWN_SUBDOMAIN.join('|')}.numerique.gouv.fr\/(monavis-)?static\/bouton-blanc|bleu.png|svg/
|
||||||
|
|
||||||
def validate(record)
|
def validate(record)
|
||||||
# We need to ensure the embed code is not any random string in order to avoid injections
|
if record.monavis_embed.present?
|
||||||
r = Regexp.new('<a href="https://monavis|voxusagers.numerique.gouv.fr/Demarches/\d+.*key=[[:alnum:]]+.*">\s*<img src="https://monavis|voxusagers.numerique.gouv.fr/(monavis-)?static/bouton-blanc|bleu.png|svg" alt="Je donne mon avis" (title="Je donne mon avis sur cette démarche" )?/>\s*</a>', Regexp::MULTILINE)
|
embed = Nokogiri::HTML(record.monavis_embed)
|
||||||
if record.monavis_embed.present? && !r.match?(record.monavis_embed)
|
check_link(embed.css('a'))
|
||||||
record.errors.add :base, :invalid, message: "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
|
check_img(embed.css('img'))
|
||||||
end
|
end
|
||||||
|
rescue MonAvisEmbedError => e
|
||||||
|
record.errors.add :base, :invalid, message: "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme. #{e.message}"
|
||||||
|
rescue # nokogiri
|
||||||
|
record.errors.add :base, :invalid, message: "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_link(links)
|
||||||
|
raise MonAvisEmbedError.new("le code monavis doit comporter un seul lien") if links.size != 1
|
||||||
|
raise MonAvisEmbedError.new("le lien du bouton mon avis doit pointer vers le bon domaine") if !HREF_CHECKER.match?(links.first['href'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_img(imgs)
|
||||||
|
raise MonAvisEmbedError.new("le code monavis doit comporter une seule image") if imgs.size != 1
|
||||||
|
raise MonAvisEmbedError.new("l'image du bouton mon avis ne pointe pas vers le bon domaine") if !IMG_CHECKER.match?(imgs.first['src'])
|
||||||
|
raise MonAvisEmbedError.new("l'image du bouton mon avis n'a pas d'attribut alt") if imgs.first['alt'].blank?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue