-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Rails/OutputSafety to disallow wrapping safe_join #4320
Update Rails/OutputSafety to disallow wrapping safe_join #4320
Conversation
f145254
to
7762339
Compare
Yikes, good catch @klesse413! |
I'm similarly convinced by @klesse413's great write-up that this pull request is a good idea. However, the error message hasn't been updated in this PR (which explicitly states it allows safe_join), which would be confusing. Either the line about safe_join should be removed or, even better, detect safe_join and output a different error message declaring that safe_join is, in fact, not safe. |
That would be better IMO. |
I don't really understand what you mean by " |
@josh My apologies, sloppy wording on my part (this is what I get for making a comment before finishing my morning coffee :) ). I was referring to the last sentence in @klesse413's PR, namely the line "since safe_join does not provide any additional safety" |
Ah, gotcha. Maybe we should just change the copy to not include any "quick fix" suggestions as its a complicated issue. We can just leave it as "Tagging a string as html safe may be a security risk" (or similar). Then improve the styleguide reference for this cop as we can include much more context and examples there about how best to resolve issues where other safer helpers could be used in place of An example with # bad
( person.login + " " + content_tag(:span, person.email) ).html_safe
# good
safe_join([person.login, " ", content_tag(:span, person.email)]) |
I agree with that idea @josh - I'll update this PR 👍 |
7762339
to
29413c1
Compare
updated! |
You'll also have to update the cop documentation and examples. The rationale for the cop can certainly be expanded a bit. |
29413c1
to
4f7041f
Compare
Ah sorry about that - updated the documentation with a bit of an explanation and added the new example |
@@ -25,16 +27,18 @@ module Rails | |||
# out << content_tag(:li, "two") | |||
# safe_join(out) | |||
# | |||
# # bad | |||
# ( person.login + " " + content_tag(:span, person.email) ).html_safe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the spaces inside the outer parens.
This needs a changelog entry and it's good to go. :-) |
…n, as this is not safe
4f7041f
to
e2c98ee
Compare
Awesome, thanks! Should be good now 👍 |
👍 |
@bbatsov thanks for pinging me on this PR. I found @klesse413's argument convincing as well, and I give a 👍 to this PR. |
At Betterment, we built custom cops to prevent usage of
raw
andhtml_safe
without review, but we'd love to get on the mainline version now that there is a built-inRails/OutputSafety
cop. However, we can't switch unless this cop can provide the guarantees that we need. Hopefully our learnings are valuable to the community.Proposed Change
I would like to propose changing the behavior of the
Rails/OutputSafety
cop. The change is to no longer allow usage ofraw
andhtml_safe
when they are wrapped insafe_join
. Instead,raw
andhtml_safe
should only be used when the cop is explicitly disabled. This change essentially reverts theRails/OutputSafety
cop back to its original functionality.Background
When it was first introduced, the
Rails/OutputSafety
cop only allowed the usage ofraw
orhtml_safe
if the cop was explicitly disabled.For reference, here is a link to that original PR: #3135 In that PR, @josh explained:
A few months after the introduction of this cop, an issue was opened here: #3676 which was addressed by this PR: #3682. The change is to allow usage of
raw
orhtml_safe
when the usages are wrapped insafe_join
.Why
In summary,
safe_join
is not a declaration about the safety of the buffers it joins, and it shouldn't be used by rubocop to impute that.I'm proposing this change because usage of
safe_join
to combine buffers that have already been declared "safe" by usingraw
orhtml_safe
to return aSafeBuffer
does not add any additional "safety" to the buffer. Callingraw
orhtml_safe
essentially blesses a buffer as safe by returning aSafeBuffer
containing the content, like so:Rather than bless content as already "safe",
safe_join
actually escapes the content, like so:However, when passed content that has already been blessed as safe (because it's a
SafeBuffer
),safe_join
does not escape the content, like so:Therefore, if the
Rails/OutputSafety
cop tells us that we should not useraw
orhtml_safe
without explicitly disabling it, we should still hold to the standard of needing to explicitly disable it when usages are wrapped insafe_join
, sincesafe_join
does not provide any additional safety.Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).and description in grammatically correct, complete sentences.
rake generate_cops_documentation
(required only when you've added a new cop or changed the configuration/documentation of an existing cop).