Skip to content

Commit 3247ce2

Browse files
authored
feat: enforce CSRF protection and POST-only policy across endpoints (#940)
1 parent 8c46d2e commit 3247ce2

File tree

86 files changed

+3844
-4369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+3844
-4369
lines changed

api/subscriptions/get_subscriptions.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,4 @@ function getPriceConverted($price, $currency, $database)
352352
];
353353
echo json_encode($response);
354354
exit;
355-
}
356-
357-
358-
?>
359-
355+
}

endpoints/admin/adduser.php

Lines changed: 116 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
11
<?php
22
require_once '../../includes/connect_endpoint.php';
3-
4-
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
5-
die(json_encode([
6-
"success" => false,
7-
"message" => translate('session_expired', $i18n)
8-
]));
9-
}
10-
11-
// Check that user is an admin
12-
if ($userId !== 1) {
13-
die(json_encode([
14-
"success" => false,
15-
"message" => translate('error', $i18n)
16-
]));
17-
}
3+
require_once '../../includes/validate_endpoint_admin.php';
184

195
$currencies = [
206
['id' => 1, 'name' => 'Euro', 'symbol' => '', 'code' => 'EUR'],
@@ -116,155 +102,142 @@ function validate($value)
116102
return $value;
117103
}
118104

119-
if ($_SERVER["REQUEST_METHOD"] === "POST") {
120-
121-
$postData = file_get_contents("php://input");
122-
$data = json_decode($postData, true);
105+
$postData = file_get_contents("php://input");
106+
$data = json_decode($postData, true);
123107

124-
$loggedInUserId = $userId;
108+
$loggedInUserId = $userId;
125109

126-
$email = validate($data['email']);
127-
$username = validate($data['username']);
128-
$password = $data['password'];
110+
$email = validate($data['email']);
111+
$username = validate($data['username']);
112+
$password = $data['password'];
129113

130-
if (empty($username) || empty($password) || empty($email)) {
131-
die(json_encode([
132-
"success" => false,
133-
"message" => translate('error', $i18n)
134-
]));
135-
}
136-
137-
$stmt = $db->prepare('SELECT COUNT(*) FROM user WHERE username = :username OR email = :email');
138-
$stmt->bindValue(':username', $username, SQLITE3_INTEGER);
139-
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
140-
$result = $stmt->execute();
141-
$row = $result->fetchArray();
142-
// Error if user exist
143-
if ($row[0] > 0) {
144-
die(json_encode([
145-
"success" => false,
146-
"message" => translate('error', $i18n)
147-
]));
148-
}
149-
150-
// Get main currency and language from admin user
151-
$stmt = $db->prepare('SELECT main_currency, language FROM user WHERE id = :id');
152-
$stmt->bindValue(':id', $loggedInUserId, SQLITE3_TEXT);
153-
$result = $stmt->execute();
154-
$row = $result->fetchArray();
155-
$currency = $row['main_currency'] ?? 1;
156-
$language = $row['language'] ?? 'en';
157-
$avatar = "images/avatars/0.svg";
114+
if (empty($username) || empty($password) || empty($email)) {
115+
die(json_encode([
116+
"success" => false,
117+
"message" => translate('error', $i18n)
118+
]));
119+
}
158120

159-
// Get code for main currency
160-
$stmt = $db->prepare('SELECT code FROM currencies WHERE id = :id');
161-
$stmt->bindValue(':id', $currency, SQLITE3_TEXT);
162-
$row = $stmt->execute();
163-
$main_currency = $row->fetchArray()['code'];
121+
$stmt = $db->prepare('SELECT COUNT(*) FROM user WHERE username = :username OR email = :email');
122+
$stmt->bindValue(':username', $username, SQLITE3_INTEGER);
123+
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
124+
$result = $stmt->execute();
125+
$row = $result->fetchArray();
126+
// Error if user exist
127+
if ($row[0] > 0) {
128+
die(json_encode([
129+
"success" => false,
130+
"message" => translate('error', $i18n)
131+
]));
132+
}
164133

165-
$query = "INSERT INTO user (username, email, password, main_currency, avatar, language, budget) VALUES (:username, :email, :password, :main_currency, :avatar, :language, :budget)";
134+
// Get main currency and language from admin user
135+
$stmt = $db->prepare('SELECT main_currency, language FROM user WHERE id = :id');
136+
$stmt->bindValue(':id', $loggedInUserId, SQLITE3_TEXT);
137+
$result = $stmt->execute();
138+
$row = $result->fetchArray();
139+
$currency = $row['main_currency'] ?? 1;
140+
$language = $row['language'] ?? 'en';
141+
$avatar = "images/avatars/0.svg";
142+
143+
// Get code for main currency
144+
$stmt = $db->prepare('SELECT code FROM currencies WHERE id = :id');
145+
$stmt->bindValue(':id', $currency, SQLITE3_TEXT);
146+
$row = $stmt->execute();
147+
$main_currency = $row->fetchArray()['code'];
148+
149+
$query = "INSERT INTO user (username, email, password, main_currency, avatar, language, budget) VALUES (:username, :email, :password, :main_currency, :avatar, :language, :budget)";
150+
$stmt = $db->prepare($query);
151+
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
152+
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
153+
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
154+
$stmt->bindValue(':password', $hashedPassword, SQLITE3_TEXT);
155+
$stmt->bindValue(':main_currency', 1, SQLITE3_TEXT);
156+
$stmt->bindValue(':avatar', $avatar, SQLITE3_TEXT);
157+
$stmt->bindValue(':language', $language, SQLITE3_TEXT);
158+
$stmt->bindValue(':budget', 0, SQLITE3_INTEGER);
159+
$result = $stmt->execute();
160+
161+
if ($result) {
162+
163+
// Get id of the newly created user
164+
$newUserId = $db->lastInsertRowID();
165+
166+
// Add username as household member for that user
167+
$query = "INSERT INTO household (name, user_id) VALUES (:name, :user_id)";
166168
$stmt = $db->prepare($query);
167-
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
168-
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
169-
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
170-
$stmt->bindValue(':password', $hashedPassword, SQLITE3_TEXT);
171-
$stmt->bindValue(':main_currency', 1, SQLITE3_TEXT);
172-
$stmt->bindValue(':avatar', $avatar, SQLITE3_TEXT);
173-
$stmt->bindValue(':language', $language, SQLITE3_TEXT);
174-
$stmt->bindValue(':budget', 0, SQLITE3_INTEGER);
175-
$result = $stmt->execute();
169+
$stmt->bindValue(':name', $username, SQLITE3_TEXT);
170+
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
171+
$stmt->execute();
176172

177-
if ($result) {
173+
if ($newUserId > 1) {
178174

179-
// Get id of the newly created user
180-
$newUserId = $db->lastInsertRowID();
181-
182-
// Add username as household member for that user
183-
$query = "INSERT INTO household (name, user_id) VALUES (:name, :user_id)";
175+
// Add categories for that user
176+
$query = 'INSERT INTO categories (name, "order", user_id) VALUES (:name, :order, :user_id)';
184177
$stmt = $db->prepare($query);
185-
$stmt->bindValue(':name', $username, SQLITE3_TEXT);
186-
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
187-
$stmt->execute();
188-
189-
if ($newUserId > 1) {
190-
191-
// Add categories for that user
192-
$query = 'INSERT INTO categories (name, "order", user_id) VALUES (:name, :order, :user_id)';
193-
$stmt = $db->prepare($query);
194-
foreach ($categories as $index => $category) {
195-
$stmt->bindValue(':name', $category['name'], SQLITE3_TEXT);
196-
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
197-
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
198-
$stmt->execute();
199-
}
200-
201-
// Add payment methods for that user
202-
$query = 'INSERT INTO payment_methods (name, icon, "order", user_id) VALUES (:name, :icon, :order, :user_id)';
203-
$stmt = $db->prepare($query);
204-
foreach ($payment_methods as $index => $payment_method) {
205-
$stmt->bindValue(':name', $payment_method['name'], SQLITE3_TEXT);
206-
$stmt->bindValue(':icon', $payment_method['icon'], SQLITE3_TEXT);
207-
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
208-
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
209-
$stmt->execute();
210-
}
211-
212-
// Add currencies for that user
213-
$query = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :user_id)";
214-
$stmt = $db->prepare($query);
215-
foreach ($currencies as $currency) {
216-
$stmt->bindValue(':name', $currency['name'], SQLITE3_TEXT);
217-
$stmt->bindValue(':symbol', $currency['symbol'], SQLITE3_TEXT);
218-
$stmt->bindValue(':code', $currency['code'], SQLITE3_TEXT);
219-
$stmt->bindValue(':rate', 1, SQLITE3_FLOAT);
220-
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
221-
$stmt->execute();
222-
}
223-
224-
// Retrieve main currency id
225-
$query = "SELECT id FROM currencies WHERE code = :code AND user_id = :user_id";
226-
$stmt = $db->prepare($query);
227-
$stmt->bindValue(':code', $main_currency, SQLITE3_TEXT);
178+
foreach ($categories as $index => $category) {
179+
$stmt->bindValue(':name', $category['name'], SQLITE3_TEXT);
180+
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
228181
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
229-
$result = $stmt->execute();
230-
$currency = $result->fetchArray(SQLITE3_ASSOC);
182+
$stmt->execute();
183+
}
231184

232-
// Update user main currency
233-
$query = "UPDATE user SET main_currency = :main_currency WHERE id = :user_id";
234-
$stmt = $db->prepare($query);
235-
$stmt->bindValue(':main_currency', $currency['id'], SQLITE3_INTEGER);
185+
// Add payment methods for that user
186+
$query = 'INSERT INTO payment_methods (name, icon, "order", user_id) VALUES (:name, :icon, :order, :user_id)';
187+
$stmt = $db->prepare($query);
188+
foreach ($payment_methods as $index => $payment_method) {
189+
$stmt->bindValue(':name', $payment_method['name'], SQLITE3_TEXT);
190+
$stmt->bindValue(':icon', $payment_method['icon'], SQLITE3_TEXT);
191+
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
236192
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
237193
$stmt->execute();
194+
}
238195

239-
// Add settings for that user
240-
$query = "INSERT INTO settings (dark_theme, monthly_price, convert_currency, remove_background, color_theme, hide_disabled, user_id, disabled_to_bottom, show_original_price, mobile_nav)
241-
VALUES (2, 0, 0, 0, 'blue', 0, :user_id, 0, 0, 0)";
242-
$stmt = $db->prepare($query);
196+
// Add currencies for that user
197+
$query = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :user_id)";
198+
$stmt = $db->prepare($query);
199+
foreach ($currencies as $currency) {
200+
$stmt->bindValue(':name', $currency['name'], SQLITE3_TEXT);
201+
$stmt->bindValue(':symbol', $currency['symbol'], SQLITE3_TEXT);
202+
$stmt->bindValue(':code', $currency['code'], SQLITE3_TEXT);
203+
$stmt->bindValue(':rate', 1, SQLITE3_FLOAT);
243204
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
244205
$stmt->execute();
245-
246-
// If email verification is required add the user to the email_verification table
247-
$query = "SELECT * FROM admin";
248-
$stmt = $db->prepare($query);
249-
$result = $stmt->execute();
250-
$settings = $result->fetchArray(SQLITE3_ASSOC);
251206
}
252207

253-
$db->close();
208+
// Retrieve main currency id
209+
$query = "SELECT id FROM currencies WHERE code = :code AND user_id = :user_id";
210+
$stmt = $db->prepare($query);
211+
$stmt->bindValue(':code', $main_currency, SQLITE3_TEXT);
212+
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
213+
$result = $stmt->execute();
214+
$currency = $result->fetchArray(SQLITE3_ASSOC);
254215

255-
die(json_encode([
256-
"success" => true,
257-
"message" => translate('success', $i18n)
258-
]));
259-
}
216+
// Update user main currency
217+
$query = "UPDATE user SET main_currency = :main_currency WHERE id = :user_id";
218+
$stmt = $db->prepare($query);
219+
$stmt->bindValue(':main_currency', $currency['id'], SQLITE3_INTEGER);
220+
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
221+
$stmt->execute();
222+
223+
// Add settings for that user
224+
$query = "INSERT INTO settings (dark_theme, monthly_price, convert_currency, remove_background, color_theme, hide_disabled, user_id, disabled_to_bottom, show_original_price, mobile_nav)
225+
VALUES (2, 0, 0, 0, 'blue', 0, :user_id, 0, 0, 0)";
226+
$stmt = $db->prepare($query);
227+
$stmt->bindValue(':user_id', $newUserId, SQLITE3_INTEGER);
228+
$stmt->execute();
260229

230+
// If email verification is required add the user to the email_verification table
231+
$query = "SELECT * FROM admin";
232+
$stmt = $db->prepare($query);
233+
$result = $stmt->execute();
234+
$settings = $result->fetchArray(SQLITE3_ASSOC);
235+
}
261236

237+
$db->close();
262238

263-
} else {
264239
die(json_encode([
265-
"success" => false,
266-
"message" => translate('error', $i18n)
240+
"success" => true,
241+
"message" => translate('success', $i18n)
267242
]));
268-
}
269-
270-
?>
243+
}

endpoints/admin/deleteunusedlogos.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,7 @@
11
<?php
22

33
require_once '../../includes/connect_endpoint.php';
4-
5-
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
6-
die(json_encode([
7-
"success" => false,
8-
"message" => translate('session_expired', $i18n)
9-
]));
10-
}
11-
12-
// Check that user is an admin
13-
if ($userId !== 1) {
14-
die(json_encode([
15-
"success" => false,
16-
"message" => translate('error', $i18n)
17-
]));
18-
}
4+
require_once '../../includes/validate_endpoint_admin.php';
195

206
$query = 'SELECT logo FROM subscriptions';
217
$stmt = $db->prepare($query);

0 commit comments

Comments
 (0)