I reviewed character escaping everywhere with the following ideas:

  * use a single common function to escape user data: `escape` using `htmlspecialchars`.
  * sanitize fields in `index.php` after reading them from datastore and before sending them to templates.
  	It means no escaping function in Twig templates.
    2 reasons:
    * it reduces risks of security issue for future user made templates
    * more readable templates
  * sanitize user configuration fields after loading them.
This commit is contained in:
ArthurHoaro 2015-06-11 13:53:27 +02:00
parent 0923a2bc1b
commit 5f85fcd863
12 changed files with 113 additions and 95 deletions

View file

@ -36,12 +36,12 @@
{if="$link.tags"}
<div class="dailyEntryTags">
{loop="link.taglist"}
{$value|htmlspecialchars} -
{$value} -
{/loop}
</div>
{/if}
<div class="dailyEntryTitle">
<a href="{$link.url}">{$link.title|htmlspecialchars}</a>
<a href="{$link.url}">{$link.title}</a>
</div>
{if="$link.thumbnail"}
<div class="dailyEntryThumbnail">{$link.thumbnail}</div>

View file

@ -1,7 +1,7 @@
{loop="links"}
<h3><a href="{$value.url}">{$value.title|htmlspecialchars}</a></h3>
<small>{if="!$GLOBALS['config']['HIDE_TIMESTAMPS']"}{function="strftime('%c', $value.timestamp)"} - {/if}{if="$value.tags"}{$value.tags|htmlspecialchars}{/if}<br>
{$value.url|htmlspecialchars}</small><br>
<h3><a href="{$value.url}">{$value.title}</a></h3>
<small>{if="!$GLOBALS['config']['HIDE_TIMESTAMPS']"}{function="strftime('%c', $value.timestamp)"} - {/if}{if="$value.tags"}{$value.tags}{/if}<br>
{$value.url}</small><br>
{if="$value.thumbnail"}{$value.thumbnail}{/if}<br>
{if="$value.description"}{$value.formatedDescription}{/if}
<br><br><hr>

View file

@ -15,11 +15,11 @@
<div id="editlinkform">
<form method="post" name="linkform">
<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">
<label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url|htmlspecialchars}" class="lf_input"><br>
<label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title|htmlspecialchars}" class="lf_input"><br>
<label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description|htmlspecialchars}</textarea><br>
<label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"><br>
<label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"><br>
<label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description}</textarea><br>
<label for="lf_tags"><i>Tags</i></label><br>
<input type="text" id="lf_tags" name="lf_tags" id="lf_tags" value="{$link.tags|htmlspecialchars}" class="lf_input"
<input type="text" id="lf_tags" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input"
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" ><br>
{if="($link_is_new && $GLOBALS['privateLinkByDefault']==true) || $link.private == true"}
<input type="checkbox" checked="checked" name="lf_private" id="lf_private">
@ -32,7 +32,7 @@
<input type="submit" value="Cancel" name="cancel_edit" class="bigbutton">
{if="!$link_is_new"}<input type="submit" value="Delete" name="delete_link" class="bigbutton delete" onClick="return confirmDeleteLink();">{/if}
<input type="hidden" name="token" value="{$token}">
{if="$http_referer"}<input type="hidden" name="returnurl" value="{$http_referer|htmlspecialchars}">{/if}
{if="$http_referer"}<input type="hidden" name="returnurl" value="{$http_referer}">{/if}
</form>
</div>
</div>

View file

@ -5,11 +5,11 @@
<div id="pageheader">
{include="page.header"}
<div id="uploaddiv">
Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...) (Max: {$maxfilesize|htmlspecialchars} bytes).
Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...) (Max: {$maxfilesize} bytes).
<form method="POST" action="?do=upload" enctype="multipart/form-data" name="uploadform" id="uploadform">
<input type="hidden" name="token" value="{$token}">
<input type="file" name="filetoupload">
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize|htmlspecialchars}">
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
<input type="submit" name="import_file" value="Import" class="bigbutton"><br>
<input type="checkbox" name="private" id="private"><label for="private">&nbsp;Import all links as private</label><br>
<input type="checkbox" name="overwrite" id="overwrite"><label for="overwrite">&nbsp;Overwrite existing links</label>

View file

@ -33,7 +33,7 @@
{if="$search_type=='tags'"}
<div id="searchcriteria">{$result_count} results for tags <i>
{loop="search_crits"}
<span class="linktag" title="Remove tag"><a href="?removetag={$value|htmlspecialchars}">{$value|htmlspecialchars} <span class="remove">x</span></a></span>
<span class="linktag" title="Remove tag"><a href="?removetag={$value}">{$value} <span class="remove">x</span></a></span>
{/loop}</i></div>
{/if}
{/if}
@ -50,7 +50,7 @@
<input type="hidden" name="token" value="{$token}"><input type="hidden" name="delete_link"><input type="image" alt="Delete" src="images/delete_icon.png#" title="Delete" class="button_delete" onClick="return confirmDeleteLink();"></form>
</div>
{/if}
<span class="linktitle"><a href="{$redirector}{$value.url|htmlspecialchars}">{$value.title|htmlspecialchars}</a></span>
<span class="linktitle"><a href="{$redirector}{$value.url}">{$value.title}</a></span>
<br>
{if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if}
{if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"}
@ -59,15 +59,15 @@
<span class="linkdate" title="Short link here"><a href="?{$value.linkdate|smallHash}">permalink</a> - </span>
{/if}
{if="$GLOBALS['config']['ARCHIVE_ORG']"}
<span class="linkarchive"><a href="https://web.archive.org/web/{$value.url|htmlspecialchars}">archive</a> - </span>
<span class="linkarchive"><a href="https://web.archive.org/web/{$value.url}">archive</a> - </span>
{/if}
<div class="linkqrcode"><a href="http://qrfree.kaywa.com/?l=1&amp;s=8&amp;d={$scripturl|urlencode}%3F{$value.linkdate|smallHash}"
onclick="return showQrCode(this);" class="qrcode" data-permalink="{$scripturl}?{$value.linkdate|smallHash}">
<img src="images/qrcode.png#" alt="QR-Code" title="{function="strftime('%c', $value.timestamp)"}"></a></div> -
<a href="{$value.url|htmlspecialchars}"><span class="linkurl" title="Short link">{$value.url|htmlspecialchars}</span></a><br>
<a href="{$value.url}"><span class="linkurl" title="Short link">{$value.url}</span></a><br>
{if="$value.tags"}
<div class="linktaglist">
{loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value|htmlspecialchars}</a></span> {/loop}
{loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value}</a></span> {/loop}
</div>
{/if}
</div>

View file

@ -17,7 +17,7 @@
<input type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3">
Stay signed in (Do not check on public computers)</label>
<input type="hidden" name="token" value="{$token}">
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl|htmlspecialchars}">{/if}
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
</form>
{/if}
</div>

View file

@ -2,7 +2,7 @@
<b><a href="https://github.com/shaarli/Shaarli">Shaarli</a></b> - The personal, minimalist, super-fast, no-database delicious clone by the <a href="https://github.com/shaarli/Shaarli">Shaarli</a> community - <a href="doc/Home.html">Help/documentation</a>
</div>
{if="$newversion"}
<div id="newversion"><span id="version_id">&#x25CF;</span> Shaarli {$newversion|htmlspecialchars} is <a href="https://github.com/shaarli/Shaarli/releases">available</a>.</div>
<div id="newversion"><span id="version_id">&#x25CF;</span> Shaarli {$newversion} is <a href="https://github.com/shaarli/Shaarli/releases">available</a>.</div>
{/if}
{if="isLoggedIn()"}
<script>function confirmDeleteLink() { var agree=confirm("Are you sure you want to delete this link ?"); if (agree) return true ; else return false ; }</script>

View file

@ -8,7 +8,7 @@
<div id="menu">
<ul>
<li><span id="shaarli_title">
<a href="{$titleLink}">{$shaarlititle|htmlspecialchars}</a>
<a href="{$titleLink}">{$shaarlititle}</a>
</span>
</li>

View file

@ -9,7 +9,7 @@
<div id="picwall_container">
{loop="linksToDisplay"}
<div class="picwall_pictureframe">
{$value.thumbnail}<a href="{$value.url}"><span class="info">{$value.title|htmlspecialchars}</span></a>
{$value.thumbnail}<a href="{$value.url}"><span class="info">{$value.title}</span></a>
</div>
{/loop}
</div>

View file

@ -6,7 +6,7 @@
<div class="center">
<div id="cloudtag">
{loop="tags"}
<span class="count">{$value.count}</span><a href="?searchtags={$key|urlencode}" style="font-size:{$value.size}pt;">{$key|htmlspecialchars}</a>
<span class="count">{$value.count}</span><a href="?searchtags={$key|urlencode}" style="font-size:{$value.size}pt;">{$key}</a>
{/loop}
</div>
</div>