Problem/Motivation
Part of #2545972: Remove all code usages SafeMarkup::checkPlain() and rely more on Twig autoescaping. In Drupal 8 we introduced UrlHelper but left usages of check_url()
. With twig auto-escape and the desire to remove SafeMarkup::checkPlain()
to reduce the stored list of safe strings, it is necessary to remove the usages of check_url()
.
Proposed resolution
Use UrlHelper::stripDangerousProtocols()
or UrlHelper::filterBadProtocol()
instead. UrlHelper::stripDangerousProtocols()
can be used in conjunction with SafeMarkup::format()
and an @variable
placeholder which will perform the necessary escaping. UrlHelper::filterBadProtocol()
is an equivalent method apart from the fact the it can be called multiple times on the same url without double escaping.
check_url()
will be changed to no longer mark strings as safe.
Also this highlights the problem with !placeholder
s resulting in unsafe strings - since now that check_url() does not mark strings as safe this unnecessarily breaks things.
Remaining tasks
Agree approach
Review
Commit
User interface changes
None
API changes
- Deprecate
check_url()
check_url()
will be changed to no longer mark strings as safe
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#14 | 2557467.14.patch | 15.76 KB | alexpott |
#11 | 2557467.11.patch | 15.79 KB | alexpott |
#11 | 6-11-interdiff.txt | 1.32 KB | alexpott |
#6 | 2557467.6.patch | 15.86 KB | alexpott |
#6 | 2-6-interdiff.txt | 568 bytes | alexpott |
Comments
Comment #2
alexpottHere's a patch cut from #2545972: Remove all code usages SafeMarkup::checkPlain() and rely more on Twig autoescaping.
Comment #3
mpdonadioThe docblock for this didn't typehint the @return (which was SafeStringInterface). Do we want to explicitly state that is is string now?
Comment #4
joelpittet@mpdonadio probably should, but it wasn't
SafeStringInterface
it was astring
before, just got saved on the SafeMarkup::$safeStrings list.Reviewed the code and big +1 to this issue. I'd RTBC it now but I'd like to see if anybody else has any concerns since it's less than an hour old.
Comment #5
mpdonadioThanks for the correction @joelpittet. Got things confused in my head with all of the different patches I am following and working on.
Comment #6
alexpottHere's the docs improvement.
Comment #7
catchI keep getting turned around by us having Html::filterBadProtocols() and Html::stripDangerousProtocols() and why we need both.
I just skimmed through the original issue that added drupal_strip_dangerous_protocols() - #715142: [beta blocker blocker] Various URLs escaped twice, since check_url() resp. filter_xss_bad_protocol() calls check_plain(). We added that due to a double-escaping bug.
The reason we ended up with both functions as well as check_url() is outlined in
#715142-7: [beta blocker blocker] Various URLs escaped twice, since check_url() resp. filter_xss_bad_protocol() calls check_plain() - then #10, #13. #14 (and several more later). Boils down to wanting to keep a check_url() check in preprocess as definitely safe, vs. requiring an additional check_plain() around it. That issue nearly removed check_url() at the time too as well as the check_plain() from filter_xss_bad_protocol(), with 8.x and autoescaping the arguments against doing that no-longer hold.
Also checked and in 8.x HEAD, we only have one call to filterBadProtocols() outside of tests. This issue adds one more.
Can we:
Convert those couple of cases to stripDangerousProtocols() and add an Html::escape() around them if it's needed?
If that's doable, additionally deprecate UrlHelper::filterBadProtocols()?
At the moment I can't properly understand this comment, and just @see UrlHelper::stripDangerousProtocols() @see Html::escape() would be a lot easier:
Comment #8
mpdonadio#7,
The latest patch on #2544110: XSS attribute filtering is inconsistent and strips valid attributes touches this section in Xss, so I think it may be in scope to remove it as part of that issue. Leave a comment on that issue if you want me to do it there.
Comment #9
catch@mpdonadio thanks for the issue link.
From that issue I also saw #2545056: Attribute class does not sanitize for "javascript:alert('XSS')" which is talking about filtering bad protocols automatically in Attribute. If we did that, a lot of the calls to stripDangerousProtocols() might not be needed either.
Comment #10
alexpottI'm not sure we can deprecate
UrlHelper::filterBadProtocols()
because afaik we still need its double escaping prevention. If I change Xss to useHtml::escape(UrlHelper::stripDangerousProtocols())
I get the following fails in XssTest.Comment #11
alexpottHere is a re-roll. And hopefully a better deprecation notice.
Comment #12
catchLet's open a separate issue for
UrlHelper::filterBadProtocols()
- 2 is better than 3 here. We could mark it @internal for example.Comment #13
star-szr\m/
Comment #14
alexpottRerolled and opened #2559413: UrlHelper::stripDangerousProtocols() and UrlHelper::filterBadProtocol() are confusing
Comment #15
stefan.r CreditAttribution: stefan.r commentedAdded comments look good and the rest looks fairly straightforward.
Added a draft CR at https://www.drupal.org/node/2560027 -- or should we put this in one big CR along with some of the other SafeMarkup-related changes?
80 cols
Comment #16
dawehnerJust wrote some self sanity comments so it looks RTBC for me.
So t() will do the escaping and UrlHelper the stripping of the bad protocol
Also here twig will autoescape
Comment #17
stefan.r CreditAttribution: stefan.r commented+1, updated the CR with those examples
Comment #18
alexpott@stefan.r and @dawehner thanks for the work on the CR - it looks good and I think it deserves its own.
Comment #20
catchThe deprecation message still feels a bit too 'helpful', I probably would've stopped at the first sentence. But can't really push back on it being to helpful so...
Committed/pushed to 8.0.x, thanks!