-
Notifications
You must be signed in to change notification settings - Fork 308
review site for html injections #722
Comments
In investigating the issue 8506070 caused, I've audited participant statement usage throughout the site. User Statementstored non-escaped statement.json: wrapped! |
Fixed in b4bdc32: index.html: meta og:description: SERIOUSLY BAD: not-escaped (I confirmed in a development environment that I can indeed close the tag and inject a Fixed in 959e72a: index.html: displaying the statement: escaped twice! see #723 This doesn't seem to be a place where escape is needed, oddly. Fixed in cca632d: about/goals.html: BAD: not escaped Good to close? |
well, the issue suggests looking for html injections throughout the site. I only focused on statement fields, so technically the issue is not yet fulfilled. |
Good point. :) |
@buttscicles caught a few more of these (thanks!). I'm beginning to realize now why Tornado moved to HTML-escaping by default in 2.x. This feels like whack-a-mole. Gittip uses Aspen's default templating language, Tornado 1.x. We have a ticket over on Aspen to upgrade to 2.x (AspenWeb/pando.py#158). Picking up over there ... |
Let's take this up now that we've migrated to Jinja2 (#1783). |
@clone1018 Are we good to close now that we're on Jinja2? |
I wouldn't say we're good but we're good for now. |
@clone1018 Would you be willing to conduct a review so we can close this ticket? |
@whit537 I wouldn't feel completely safe until we change Jinja2 to being autoescape by default http://jinja.pocoo.org/docs/extensions/#autoescape-extension |
I'm in favor of closing this specific ticket for now, we can reticket any other issues and if escaping becomes a problem we can ticket the autoescape extension. |
I'm leery of autoescape, because the rules for escaping differ with the syntax you're templating into. If we're inserting into an href attribute like Even with autoescape we still need this audit. |
Could you go into detail @whit537 about the sorts of escaping rules that could cause trouble? In general, automatically escaping everything is a boon to security because it gives you a much smaller surface area to check for holes. |
So you're saying... it might not use the right type of escaping for the given context? |
Yup. We got bit by this once already, iirc. |
Basically, we need an audit based on that cheat sheet. Whether or not we use autoescaping is orthogonal. |
Really, it would be great to have some tooling that presented a list of all the places in templates where we insert stuff, so we can review and check them off one by one. |
Now that we have i18n we should consider including that in a review. IRC |
I'll start taking a look at this. Thanks. |
Retort:
|
It just seems increasingly stupid to rely on "a human knows" for the 544 places where we are potentially vulnerable to injection. Performance will have to be really bad to justify not switching to autoescaping. No? |
http://jinja.pocoo.org/docs/dev/extensions/#newstyle-gettext |
So it looks like implementing autoescaping will take some work. It's not a trivial quick answer to this ticket. |
Not true, we also use it for plain text in email simplates. |
P.S. The place to implement autoescaping would be in aspen_jinja2, by adding
http://jinja.pocoo.org/docs/dev/templates/#autoescape-extension |
Okay, so if we go with autoescaping I guess we'd use the |
@Changaco Can you speak to whether we're using newstyle gettext calls? |
Sort of, we use custom functions. |
Figured this would be worth having for now until we switch to autoescape (#3152).
Figured this would be worth having for now until we switch to autoescape (#3152).
Here's a slightly differently-formatted list: https://gist.github.com/whit537/03b1e5f88fcf38c3dd87 Looks like we have 527 replacements on master right now. |
I separated out the places where we are just doing i18n ( |
|
Alright, I still don't want to go through 336 of these. :-) |
The next step down the autoescaping path is to benchmark performance. If performance isn't "really a lot" worse with autoescaping then we should just use that. It'll take a chunk of work to switch over though due to i18n so benchmarking probably makes sense to make sure it'll be worth it. |
If performance is really as atrocious as promised then we should review the 336 places and make it part of our PR review habit. |
Here's a script I wrote to help with benchmarking: https://gist.github.com/whit537/352a6b02d5f644720007 Gonna do some benchmarks now. |
#!/usr/bin/env python
"""This is a helper script for benchmarking page performance re: #722.
Set this in local.env to avoid a canonicalizing redirect:
CANONICAL_HOST=
Then run this script like so:
[gratipay] $ honcho run -e defaults.env,local.env ./env/bin/python benchmark-autoescaping.py
"""
import time
import aspen_jinja2_renderer
from gratipay.testing import Harness
def autoescaping_compile_meta(self, configuration):
loader = None
if configuration.project_root is not None:
# Instantiate a loader that will be used to resolve template bases.
loader = aspen_jinja2_renderer.FileSystemLoader(configuration.project_root)
return aspen_jinja2_renderer.Environment( loader=loader
, autoescape=True
, extensions=['jinja2.ext.autoescape']
)
start = time.time()
for i in range(100):
Harness.client.GET('/')
print("{} seconds without autoescaping".format(time.time() - start))
aspen_jinja2_renderer.Factory.compile_meta = autoescaping_compile_meta
start = time.time()
for i in range(100):
Harness.client.GET('/')
print("{} seconds *with* autoescaping".format(time.time() - start)) |
10x
|
#!/usr/bin/env python
"""This is a helper script for benchmarking page performance re: #722.
Set this in local.env to avoid a canonicalizing redirect:
CANONICAL_HOST=
Then run this script like so:
[gratipay] $ honcho run -e defaults.env,local.env ./env/bin/python benchmark-autoescaping.py
"""
import sys
import time
import aspen_jinja2_renderer
from gratipay.testing import Harness
def autoescaping_compile_meta(self, configuration):
loader = None
if configuration.project_root is not None:
# Instantiate a loader that will be used to resolve template bases.
loader = aspen_jinja2_renderer.FileSystemLoader(configuration.project_root)
return aspen_jinja2_renderer.Environment( loader=loader
, autoescape=True
, extensions=['jinja2.ext.autoescape']
)
try:
n = int(sys.argv[1])
except IndexError:
n = 10
start = time.time()
for i in range(n):
Harness.client.GET('/')
print("{} seconds without autoescaping".format(time.time() - start))
aspen_jinja2_renderer.Factory.compile_meta = autoescaping_compile_meta
start = time.time()
for i in range(n):
Harness.client.GET('/')
print("{} seconds *with* autoescaping".format(time.time() - start)) |
Alright, performance concerns look like FUD to me. |
I just discovered that I wasn't escaping statements. :-(
I'm not sure how that happened, but it did. We need to review the whole site for html injections.
Want to back this issue? Place a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: