Compare commits
3
Commits
7de8e4782b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bac3cfeb4b | ||
|
|
6bf96beaed | ||
|
|
e2aaa5dcd4 |
No files matched your search
@@ -71,6 +71,18 @@ php database/migrate.php
|
|||||||
bash tests/curl.sh
|
bash tests/curl.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Sécurité
|
||||||
|
|
||||||
|
Éléments de sécurité implémentés dans l'API :
|
||||||
|
|
||||||
|
- **Injection SQL** : toutes les requêtes avec paramètres utilisent des requêtes préparées PDO (`prepare()` + `execute()`) dans `src/LinkRepository.php`, jamais de concaténation de variables dans le SQL.
|
||||||
|
- **Validation des entrées** : champs obligatoires vérifiés, `trim()` systématique, et validation de `link_url` via `FILTER_VALIDATE_URL` (`src/LinkController.php`).
|
||||||
|
- **Pas de fuite d'informations** : toute erreur (base, rendu) renvoie une réponse 500 générique `Erreur interne du serveur.` sans stack trace ni détail (`public/index.php`). `display_errors` n'est pas activé.
|
||||||
|
- **Exposition minimale au web** : le DocumentRoot Apache (Docker) pointe vers `public/` uniquement ; `src/`, `database/` et la base SQLite ne sont pas servis publiquement. Le `.htaccess` réécrit toute requête vers `index.php`.
|
||||||
|
- **CORS restreint** : méthodes limitées à `GET, POST, PUT, DELETE, OPTIONS` et en-têtes à `Content-Type` (`public/index.php`).
|
||||||
|
- **Base hors de l'image Docker** : `*.sqlite` est exclu via `.dockerignore` et stocké dans le volume `db-data`, pas dans les layers de l'image.
|
||||||
|
- **Typage strict** : `declare(strict_types=1)` dans tous les fichiers PHP, paramètres et retours typés.
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
### Lancement
|
### Lancement
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
require dirname(__DIR__) . '/src/Database.php';
|
|
||||||
|
|
||||||
$applied = Database::runMigrations();
|
|
||||||
|
|
||||||
if ($applied === []) {
|
|
||||||
echo "Nothing to migrate.\n";
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($applied as $version) {
|
|
||||||
echo "Applied {$version}\n";
|
|
||||||
}
|
|
||||||
File renamed without changes.
+2
-50
@@ -10,61 +10,13 @@ final class Database
|
|||||||
{
|
{
|
||||||
if (self::$pdo === null) {
|
if (self::$pdo === null) {
|
||||||
self::init();
|
self::init();
|
||||||
self::runMigrations();
|
assert(self::$pdo instanceof PDO);
|
||||||
|
self::$pdo->exec((string) file_get_contents(dirname(__DIR__) . '/database/schema.sql'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$pdo;
|
return self::$pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function runMigrations(): array
|
|
||||||
{
|
|
||||||
if (self::$pdo === null) {
|
|
||||||
self::init();
|
|
||||||
}
|
|
||||||
|
|
||||||
$root = dirname(__DIR__);
|
|
||||||
|
|
||||||
self::$pdo->exec(
|
|
||||||
"CREATE TABLE IF NOT EXISTS migrations (
|
|
||||||
version TEXT PRIMARY KEY,
|
|
||||||
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
||||||
)"
|
|
||||||
);
|
|
||||||
|
|
||||||
$applied = array_column(self::$pdo->query('SELECT version FROM migrations')->fetchAll(), 'version');
|
|
||||||
|
|
||||||
$files = glob($root . '/database/migrations/*.sql') ?: [];
|
|
||||||
sort($files);
|
|
||||||
|
|
||||||
$newlyApplied = [];
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$version = basename($file);
|
|
||||||
|
|
||||||
if (in_array($version, $applied, true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
self::$pdo->beginTransaction();
|
|
||||||
|
|
||||||
try {
|
|
||||||
self::$pdo->exec((string) file_get_contents($file));
|
|
||||||
|
|
||||||
$stmt = self::$pdo->prepare('INSERT INTO migrations (version) VALUES (:version)');
|
|
||||||
$stmt->execute(['version' => $version]);
|
|
||||||
|
|
||||||
self::$pdo->commit();
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
self::$pdo->rollBack();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
$newlyApplied[] = $version;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $newlyApplied;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function init(): void
|
private static function init(): void
|
||||||
{
|
{
|
||||||
$root = dirname(__DIR__);
|
$root = dirname(__DIR__);
|
||||||
|
|||||||
Reference in new issue
Block a user