|
|
Manuel Jacob
|
a8b407f29405
|
4 years ago
|
|
controllers: don’t pass start=0 to BaseRepository.get_changesets() MercurialRepository.get_changesets() can fail if passing start=0 if the revision 0 is not in self.revisions. That can happen if revision 0 is not in the visible subset of the revisions in the repository. Before Kallithea changeset 7c43e15fb8bc7a73f17f577e59a4698589b6809d, it was working by chance because start=0 was treated like start=None in the relevant places (GitRepository.get_changesets still does that). The intention of passing start=0 was seemingly to not limit the start. Therefore passing start=None (or nothing, as it’s the default value) should be correct. I got the following traceback before this change: Traceback (most recent call last): File "~/vcs/kallithea/kallithea/controllers/changelog.py", line 117, in index collection = c.db_repo_scm_instance.get_changesets(start=0, end=revision, File "~/vcs/kallithea/kallithea/lib/vcs/backends/hg/repository.py", line 529, in get_changesets start_pos = None if start is None else self.revisions.index(start_raw_id) ValueError: ' 4257f758b3eaacaebb6956d1aefc019afab956b8' is not in list
|
|
|
Mads Kiilerich
|
4f0de9468da3
|
5 years ago
|
|
controllers: move controllers base class from lib/base to controllers
TG quickstart put it in lib/base.py , but it fits better on the controllers layer as a base there.
The contributing docs were a bit ahead of time ... but with a typo.
|
|
|
Mads Kiilerich
|
67e5b90801aa
|
5 years ago
|
|
lib: move webhelpers2 and friends to webutils
Gives less of the unfortunate use of helpers - especially in low level libs.
|
|
|
Mads Kiilerich
|
f8b092f9e6a3
|
5 years ago
|
|
lib: consistently use webutils.url instead of h.url
Templates are still the valid use case for accessing through h.
Simplify mocking of url() function.
|
|
|
Mads Kiilerich
|
0be48652ca48
|
5 years ago
|
|
routing: separate url handling from routing - move it to webutils
This is a helper method relying on the thread local tg.request. We didn't have a good place to put it. Now we do.
This (re)moves unfortunate dependencies to the routing module (which almost is a controller).
|
|
|
Mads Kiilerich
|
bdb79ef2c879
|
6 years ago
|
|
py3: drop .keys when we don't need them
In python 3 they will be iterators and mostly useless ... but they are already mostly redundant in py2.
|
|
|
Mads Kiilerich
|
4f03bd5ac2f2
|
6 years ago
|
|
lib: handle both HTML, unsafe strings, and exceptions passed to helpers.flash()
Before, h.flash would trust any input to contain html ... and callers would convert exceptions to string, often with a simple str() or unicode() ... which really didn't deserve to be trusted.
Instead, only trust messages that have a __html__ and escape anything else ... but also apply str/unicode on the parameter so the caller doesn't have to but *can* pass an exception directly.
|
|
|
Mads Kiilerich
|
ed78b4fbe2a3
|
6 years ago
|
|
|
|
|
Mads Kiilerich
|
287b5f1cb40a
|
6 years ago
|
|
py3: only use safe_str for string conversion - not for arbitrary __str__ invocation
Usually, we actually just want unicode string, and it is better to just unicode().
|
|
|
Mads Kiilerich
|
3936f5cc4c58
|
6 years ago
|
|
page: replace RepoPage with Page given the reverse collection
That seems to be all RepoPage did ...
We must still take care to make sure the collection works correctly, even when filtered so indices might be higher than repo length. vcs module takes care of that by internally creating a list of hashes (which it can reverse), while the Changeset instances are only created on demand. We can save some resources by not retrieving the whole list of Changesets just to reverse it so we can use a few entries.
|
|
|
Mads Kiilerich
|
fcfc62767107
|
6 years ago
|
|
|
|
|
Mads Kiilerich
|
0a277465fddf
|
6 years ago
|
|
|
|
|
Thomas De Schampheleire
|
9f41dc6f328a
|
7 years ago
|
|
|
|
|
Thomas De Schampheleire
|
c9159e6fda04
|
7 years ago
|
|
cleanup: remove unnecessary (and potentially problematic) use of 'literal'
webhelpers.html.literal (kallithea.lib.helpers.literal) is only needed when the passed string may contain HTML that needs to be interpreted literally. It is unnecessary for plain strings.
Incorrect usage of literal can lead to XSS issues, via a malicious user controlling data which will be rendered in other users' browsers. The data could either be stored previously in the system or be part of a forged URL the victim clicks on.
For example, when a user browses to a forged URL where a repository changeset or branch name contains a javascript snippet, the snippet was executed when printed on the page using 'literal'.
Remaining uses of 'literal' have been reviewed with no apparent problems found.
Reported by Bob Hogg <wombat@rwhogg.site> (thanks!).
|
|
|
Thomas De Schampheleire
|
81db5704b285
|
7 years ago
|
|
cleanup: remove unnecessary (and potentially problematic) use of 'literal'
webhelpers.html.literal (kallithea.lib.helpers.literal) is only needed when the passed string may contain HTML that needs to be interpreted literally. It is unnecessary for plain strings.
Incorrect usage of literal can lead to XSS issues, via a malicious user controlling data which will be rendered in other users' browsers. The data could either be stored previously in the system or be part of a forged URL the victim clicks on.
For example, when a user browses to a forged URL where a repository changeset or branch name contains a javascript snippet, the snippet was executed when printed on the page using 'literal'.
Remaining uses of 'literal' have been reviewed with no apparent problems found.
Reported by Bob Hogg <wombat@rwhogg.site> (thanks!).
|
|
|
Mads Kiilerich
|
9f976d75b04c
|
8 years ago
|
|
auth: restore anonymous repository access Dominik Ruf found that aa25ef34ebab introduced a regression in anonymous access to repositories ... if that is enabled. The refactoring was too strict when it missed that not all repo permission checks require a logged in user. Read access can be granted to the default user ... but not write or admin. Instead of the commands used in aa25ef34ebab, the following commands are used to consistently also allow the default user in all decorators where we only need repo read access: # Introduce explicit allow_default_user=True - that was the default before aa25ef34ebab sed -i 's/ @LoginRequired()/ @LoginRequired(allow_default_user=True)/g' `hg mani` sed -i 's/ @LoginRequired(\(..*\))/ @LoginRequired(\1, allow_default_user=True)/g' `hg mani` # The primary case: Replace @NotAnonymous with removal of allow_default_user=True perl -0pi -e 's/\ @LoginRequired\((?:(.*), )?allow_default_user=True\)\n\s*\ @NotAnonymous\(\)/\ @LoginRequired(\1)/g' `hg mani` # If there is a global permission check, no anonymous is ever allowed perl -0pi -e 's/\ @LoginRequired\(allow_default_user=True\)(\n\s*\ @HasPermission)/\ @LoginRequired()\1/g' `hg mani` # Repo access for write or admin also assume no default user perl -0pi -e 's/\ @LoginRequired\(allow_default_user=True\)(\n\s*\ @HasRepoPermissionLevelDecorator\('"'(write|admin)'"'\))/\ @LoginRequired()\1/g' `hg mani`
|
|
|
domruf
|
1174b9f0afc4
|
8 years ago
|
|
changelog: cleanup url hack Instead of using a hack, that removes the 'set' parameter from the request, don't give the submit button a name and therefore don't submit the parameter in the first place. Related to 97c12433267a
|
|
|
Lars Kruse
|
7691290837d2
|
8 years ago
|
|
codingstyle: trivial whitespace fixes
Reported by flake8.
|
|
|
Mads Kiilerich
|
e6e69ed2c89e
|
8 years ago
|
|
summary: inline _load_changelog_summary
It makes more sense to have this summary specific code in the summary controller.
|
|
|
Mads Kiilerich
|
dbc009ab5af3
|
8 years ago
|
|
summary: drop the in-page paging and replace it with simpler page reload
This makes code and future refactorings simpler, and it only losses a little bit of nice-ness.
|
|
|
domruf
|
651e37ed51c6
|
9 years ago
|
|
controllers: consistently use c.cs_pagination for changeset paginators
More consistency makes it easier and less confusion to introduce a shared changelog_table implementation. Just rename context variables.
|
|
|
Mads Kiilerich
|
f0ec7be78077
|
8 years ago
|
|
controllers: consistently use c.cs_comments and cs_statuses
c.comments and c.statuses were also used for lists of comments and statuses. To get more consistency and avoid confusion and conflicts, use different for names for mappings from changeset hashes.
|
|
|
Thomas De Schampheleire
|
4517e212f09a
|
9 years ago
|
|
controllers: rename __before__ to _before in preparation of TurboGears2
__before__ in Pylons is called _before in TurboGears2. We can prepare this rename already in Pylons-based Kallithea, so that the real TG2 migration commit just changes the BaseController.
Since TurboGears2 _before can pass extra arguments, we add *args and **kwargs parameters as well.
|
|
|
Mads Kiilerich
|
e9ac5698281d
|
9 years ago
|
|
tg: minimize future diff by some mocking and replacing some pylons imports with tg
No actual tg dependency yet, just a temporary hack faking tg as an alias for pylons.
Based on work by Alessandro Molina.
|
|
|
Søren Løvborg
|
33b71a130b16
|
9 years ago
|
|
templates: properly escape inline JavaScript values
TLDR: Kallithea has issues with escaping values for use in inline JS. Despite judicious poking of the code, no actual security vulnerabilities have been found, just lots of corner-case bugs. This patch fixes those, and hardens the code against actual security issues.
The long version:
To embed a Python value (typically a 'unicode' plain-text value) in a larger file, it must be escaped in a context specific manner. Example:
>>> s = u'<script>alert("It\'s a trap!");</script>'
1) Escaped for insertion into HTML element context
>>> print cgi.escape(s) <script>alert("It's a trap!");</script>
2) Escaped for insertion into HTML element or attribute context
>>> print h.escape(s) <script>alert("It's a trap!");</script>
This is the default Mako escaping, as usually used by Kallithea.
3) Encoded as JSON
>>> print json.dumps(s) "<script>alert(\"It's a trap!\");</script>"
4) Escaped for insertion into a JavaScript file
>>> print '(' + json.dumps(s) + ')' ("<script>alert(\"It's a trap!\");</script>")
The parentheses are not actually required for strings, but may be needed to avoid syntax errors if the value is a number or dict (object).
5) Escaped for insertion into a HTML inline <script> element
>>> print h.js(s) ("\x3cscript\x3ealert(\"It's a trap!\");\x3c/script\x3e")
Here, we need to combine JS and HTML escaping, further complicated by the fact that "<script>" tag contents can either be parsed in XHTML mode (in which case '<', '>' and '&' must additionally be XML escaped) or HTML mode (in which case '</script>' must be escaped, but not using HTML escaping, which is not available in HTML "<script>" tags). Therefore, the XML special characters (which can only occur in string literals) are escaped using JavaScript string literal escape sequences.
(This, incidentally, is why modern web security best practices ban all use of inline JavaScript...)
Unsurprisingly, Kallithea does not do (5) correctly. In most cases, Kallithea might slap a pair of single quotes around the HTML escaped Python value. A typical benign example:
$('#child_link').html('${_('No revisions')}');
This works in English, but if a localized version of the string contains an apostrophe, the result will be broken JavaScript. In the more severe cases, where the text is user controllable, it leaves the door open to injections. In this example, the script inserts the string as HTML, so Mako's implicit HTML escaping makes sense; but in many other cases, HTML escaping is actually an error, because the value is not used by the script in an HTML context.
The good news is that the HTML escaping thwarts attempts at XSS, since it's impossible to inject syntactically valid JavaScript of any useful complexity. It does allow JavaScript errors and gibberish to appear on the page, though.
In these cases, the escaping has been fixed to use either the new 'h.js' helper, which does JavaScript escaping (but not HTML escaping), OR the new 'h.jshtml' helper (which does both), in those cases where it was unclear if the value might be used (by the script) in an HTML context. Some of these can probably be "relaxed" from h.jshtml to h.js later, but for now, using h.jshtml fixes escaping and doesn't introduce new errors.
In a few places, Kallithea JSON encodes values in the controller, then inserts the JSON (without any further escaping) into <script> tags. This is also wrong, and carries actual risk of XSS vulnerabilities. However, in all cases, security vulnerabilities were narrowly avoided due to other filtering in Kallithea. (E.g. many special characters are banned from appearing in usernames.) In these cases, the escaping has been fixed and moved to the template, making it immediately visible that proper escaping has been performed.
Mini-FAQ (frequently anticipated questions):
Q: Why do everything in one big, hard to review patch? Q: Why add escaping in specific case FOO, it doesn't seem needed?
Because the goal here is to have "escape everywhere" as the default policy, rather than identifying individual bugs and fixing them one by one by adding escaping where needed. As such, this patch surely introduces a lot of needless escaping. This is no different from how Mako/Pylons HTML escape everything by default, even when not needed: it's errs on the side of needless work, to prevent erring on the side of skipping required (and security critical) work.
As for reviewability, the most important thing to notice is not where escaping has been introduced, but any places where it might have been missed (or where h.jshtml is needed, but h.js is used).
Q: The added escaping is kinda verbose/ugly.
That is not a question, but yes, I agree. Hopefully it'll encourage us to move away from inline JavaScript altogether. That's a significantly larger job, though; with luck this patch will keep us safe and secure until such a time as we can implement the real fix.
Q: Why not use Mako filter syntax ("${val|h.js}")?
Because of long-standing Mako bug #140, preventing use of 'h' in filters.
Q: Why not work around bug #140, or even use straight "${val|js}"?
Because Mako still applies the default h.escape filter before the explicitly specified filters.
Q: Where do we go from here?
Longer term, we should stop doing variable expansions in script blocks, and instead pass data to JS via e.g. data attributes, or asynchronously using AJAX calls. Once we've done that, we can remove inline JavaScript altogether in favor of separate script files, and set a strict Content Security Policy explicitly blocking inline scripting, and thus also the most common kind of cross-site scripting attack.
|
|
|
Søren Løvborg
|
a17c8e5f6712
|
9 years ago
|
|
auth: simplify repository permission checks
In practice, Kallithea has the 'repository.admin' permission imply the 'repository.write' permission, which again implies 'repository.read'.
This codifies/enforces this practice by replacing HasRepoPermissionAny "perm function" with the new HasRepositoryLevel function, reducing the risk of errors and saving quite a lot of typing.
|
|
|
Mads Kiilerich
|
a6af26b5ffc1
|
9 years ago
|
|
|
|
|
Thomas De Schampheleire
|
e33b17db388d
|
9 years ago
|
|
helpers: move Page/RepoPage to a separate file page.py
The Page and RepoPage classes are not used from templates and thus do not belong in helpers. They could have been put in utils.py, but because they are completely standalone we can easily split them to a separate file.
|
|
|
Thomas De Schampheleire
|
af3539a458f6
|
9 years ago
|
|
Turbogears2 migration: replace pylons.url by kallithea.config.routing.url
In preparation for the migration to Turbogears2, introduce a kallithea.config.routing.url to replace pylons.url. The implementation is basically the same: wrap around routes.url().
This change involves: - a number of import statement changes - fixing some tests in test_libs.py; to avoid duplication, the different implementations of fake_url were grouped in one place.
This change was first proposed by Alessandro Molina in his initial port. Following changes were made afterwards: - move UrlGenerator from kallithea.lib.utils to kallithea.config.routing - add documentation to UrlGenerator - kallithea/lib/auth.py used url_for instead of url, for no apparent reason so this was changed. - fix libs tests - rebase onto Pylons-based Kallithea first
|
|
|
Mads Kiilerich
|
fb64046d02c2
|
9 years ago
|
|
controllers: simplify request.GET.get for safe_int
Don't specify the default value twice - the one for safe_int is enough.
|
|
|
Mads Kiilerich
|
edb24bc0f71a
|
10 years ago
|
|
|
|
|
Søren Løvborg
|
d9b78d8f1db3
|
10 years ago
|
|
cleanup: replace redirect with WebOb exceptions
All redirect does is to log "Generating 302 redirect" with logging the actual location and raise a WebOb HTTPFound exception, and the logging is redundant, as WebOb exceptions and their status codes are already logged.
Instead, just raise the exception directly, which is both explicit and simpler (and finally, gets rid of "return redirect" which never really returns).
|
|
|
Mads Kiilerich
|
1346754f1852
|
10 years ago
|
|
forms: don't use secure forms with authentication token for GET requests The token is secret and should never be used in forms posted with GET which are URL encoded. aef21d16a262 was too aggresive in using secure forms everywhere and did thus also incorrectly use them for forms posted with GET. Some token leakage was reported by Gjoko Krstic <gjoko@zeroscience.mk> of Zero Science Lab.
|
|
|
Mads Kiilerich
|
0210d0b769d4
|
10 years ago
|
|
|
|
|
Mads Kiilerich
|
d69aa464f373
|
10 years ago
|
|
cleanup: consistently use 'except ... as ...:'
Use the Python 2.6+ syntax instead of the old confusing 'except ..., ...' syntax.
|
|
|
Mads Kiilerich
|
97c12433267a
|
10 years ago
|
|
changelog: fix URL after submitting new page size via GET form
The URL ended up getting lots of crap. Workaround this by redirecting to a clean URL.
|
|
|
Mads Kiilerich
|
7e78fff64709
|
11 years ago
|
|
|
|
|
Mads Kiilerich
|
0111c18298a0
|
11 years ago
|
|
|
|
|
Mads Kiilerich
|
7ad20e8f16bd
|
11 years ago
|
|
|
|
|
Mads Kiilerich
|
42bc65838fd1
|
12 years ago
|
|
|
|
|
Mads Kiilerich
|
432e86d1e555
|
12 years ago
|
|
|
|
|
Bradley M. Kuhn
|
24c0d584ba86
|
11 years ago
|
|
|
|
|
Bradley M. Kuhn
|
1948ede028ef
|
11 years ago
|
|
|
|
|
Bradley M. Kuhn
|
ad38f9f93b3b
|
11 years ago
|
|
Correct licensing information in individual files.
The top-level license file is now LICENSE.md.
Also, in various places where there should have been joint copyright holders listed, a single copyright holder was listed. It does not appear easy to add a link to a large list of copyright holders in these places, so it simply refers to the fact that various authors hold copyright.
In future, if an easy method is discovered to link to a list from those places, we should do so.
Finally, text is added to LICENSE.md to point to where the full list of copyright holders is, and that Kallithea as a whole is GPLv3'd.
|
|
|
Bradley M. Kuhn
|
06e49be38d78
|
11 years ago
|
|
|
|
|
Bradley M. Kuhn
|
9581233e9275
|
11 years ago
|
|
|
|
|
Bradley M. Kuhn
|
d1addaf7a91e
|
11 years ago
|
|
Second step in two-part process to rename directories. This is the actual directory rename.
|