aurweb/web/html/addvote.php
canyonknight 2c93f0a98f Implement token system to fix CSRF vulnerabilities
Specially crafted pages can force authenticated users to unknowingly perform
actions on the AUR website despite being on an attacker's website. This
cross-site request forgery (CSRF) vulnerability applies to all POST data on
the AUR.

Implement a token system using a double submit cookie. Have a hidden form
value on every page containing POST forms. Use the newly added check_token() to
verify the token sent via POST matches the "AURSID" cookie value. Random
nature of the token limits potential for CSRF.

Signed-off-by: canyonknight <canyonknight@gmail.com>
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de>
2012-06-24 10:59:23 +02:00

119 lines
3.3 KiB
PHP

<?php
set_include_path(get_include_path() . PATH_SEPARATOR . '../lib');
include_once("aur.inc.php");
set_lang();
check_sid();
html_header();
if (isset($_COOKIE["AURSID"])) {
$atype = account_from_sid($_COOKIE["AURSID"]);
} else {
$atype = "";
}
if ($atype == "Trusted User" OR $atype == "Developer") {
$dbh = db_connect();
if (!empty($_POST['addVote']) && !check_token()) {
$error = __("Invalid token for user action.");
}
if (!empty($_POST['addVote']) && check_token()) {
$error = "";
if (!empty($_POST['user'])) {
$qcheck = "SELECT * FROM Users WHERE Username = '" . db_escape_string($_POST['user']) . "'";
$result = db_query($qcheck, $dbh);
if ($result) {
$check = mysql_num_rows($result);
}
else {
$check = 0;
}
if ($check == 0) {
$error.= __("Username does not exist.");
} else {
$qcheck = "SELECT * FROM TU_VoteInfo WHERE User = '" . db_escape_string($_POST['user']) . "'";
$qcheck.= " AND End > UNIX_TIMESTAMP()";
$result = db_query($qcheck, $dbh);
if ($result) {
$check = mysql_num_rows($result);
}
else {
$check = 0;
}
if ($check != 0) {
$error.= __("%s already has proposal running for them.", htmlentities($_POST['user']));
}
}
}
if (!empty($_POST['length'])) {
if (!is_numeric($_POST['length'])) {
$error.= __("Length must be a number.") ;
} else if ($_POST['length'] < 1) {
$error.= __("Length must be at least 1.");
} else {
$len = (60*60*24)*$_POST['length'];
}
} else {
$len = 60*60*24*7;
}
if (empty($_POST['agenda'])) {
$error.= __("Proposal cannot be empty.");
}
}
if (!empty($_POST['addVote']) && empty($error)) {
$q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, SubmitterID) VALUES ";
$q.= "('" . db_escape_string($_POST['agenda']) . "', ";
$q.= "'" . db_escape_string($_POST['user']) . "', ";
$q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . db_escape_string($len);
$q.= ", " . uid_from_sid($_COOKIE["AURSID"]) . ")";
db_query($q, $dbh);
print "<p class=\"pkgoutput\">" . __("New proposal submitted.") . "</p>\n";
} else {
?>
<?php if (!empty($error)): ?>
<p style="color: red;" class="pkgoutput"><?php print $error ?></p>
<?php endif; ?>
<div class="pgbox">
<div class="pgboxtitle"><?php print __("Submit a proposal to vote on.") ?></div>
<div class="pgboxbody">
<form action='addvote.php' method='post'>
<p>
<b><?php print __('Applicant/TU') ?></b>
<input type='text' name='user' value='<?php if (!empty($_POST['user'])) { print htmlentities($_POST['user'], ENT_QUOTES); } ?>' />
<?php print __("(empty if not applicable)") ?>
</p>
<p>
<b><?php print __('Length in days') ?></b>
<input type='text' name='length' value='<?php if (!empty($_POST['length'])) { print htmlentities($_POST['length'], ENT_QUOTES); } ?>' />
<?php print __("(defaults to 7 if empty)") ?>
</p>
<p>
<b><?php print __('Proposal') ?></b><br />
<textarea name='agenda' rows='25' cols='80'><?php if (!empty($_POST['agenda'])) { print htmlentities($_POST['agenda']); } ?></textarea><br />
<input type='hidden' name='addVote' value='1' />
<input type='hidden' name='token' value='<?php print htmlspecialchars($_COOKIE['AURSID']) ?>' />
<input type='submit' class='button' value='<?php print __('Submit'); ?>' />
</p>
</form>
</div>
</div>
<?php
}
} else {
print __("You are not allowed to access this area.");
}
html_footer(AUR_VERSION);