mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-02-15 03:23:17 +00:00
[P0 Security] Mass Assignment Protection – $fillable für alle 18 Models (vibe-kanban 4a764a11)
## Security Audit: Mass Assignment Protection ### Problem Alle 18 Eloquent Models verwenden `protected $guarded = [];` – das bedeutet **kein Schutz** gegen Mass Assignment. Ein Angreifer könnte über manipulierte Requests sensible Felder wie `accepted`, `sats_paid`, `association_status`, `paid` oder `created_by` direkt setzen. ### Betroffene Dateien und empfohlene Änderungen Ersetze in **jedem** der folgenden Models `protected $guarded = [];` durch ein explizites `protected $fillable = [...]` Array. Hier die Analyse pro Model: **Höchstes Risiko (Finanzen & Identity):** 1. **`app/Models/PaymentEvent.php`** – Finanz-kritisch! - Sensible Felder (NICHT fillable): `einundzwanzig_pleb_id`, `year`, `amount`, `event_id`, `paid`, `btc_pay_invoice` - `$fillable` sollte leer oder minimal sein – alle Felder werden programmatisch gesetzt 2. **`app/Models/EinundzwanzigPleb.php`** - Sensible Felder: `association_status`, `application_for`, `nip05_handle` - `$fillable = ['npub', 'pubkey', 'email', 'no_email', 'application_text', 'archived_application_text']` 3. **`app/Models/Vote.php`** - Sensible Felder: `einundzwanzig_pleb_id`, `project_proposal_id`, `value` - `$fillable = ['reason']` – alle anderen Felder müssen programmatisch gesetzt werden 4. **`app/Models/ProjectProposal.php`** - Sensible Felder: `einundzwanzig_pleb_id`, `accepted`, `sats_paid`, `slug` - `$fillable = ['name', 'support_in_sats', 'description', 'website']` 5. **`app/Models/Election.php`** - Sensible Felder: `year`, `candidates`, `end_time` - `$fillable` sollte leer sein – nur Admin-gesteuert **Mittleres Risiko (mit `created_by` auto-fill in boot):** 6. **`app/Models/Venue.php`** – `$fillable = ['name']` (slug & created_by auto-generiert) 7. **`app/Models/MeetupEvent.php`** – `$fillable = ['start']` (meetup_id, created_by, attendees guarded) 8. **`app/Models/CourseEvent.php`** – `$fillable = ['from', 'to']` (course_id, venue_id, created_by guarded) 9. **`app/Models/Course.php`** – `$fillable = ['name', 'description']` (lecturer_id, created_by guarded) 10. **`app/Models/Meetup.php`** – `$fillable = ['name']` (city_id, created_by, slug, github_data, simplified_geojson guarded) 11. **`app/Models/Lecturer.php`** – `$fillable = ['name']` (active, created_by, slug guarded) 12. **`app/Models/City.php`** – `$fillable = ['name']` (country_id, created_by, slug, osm_relation, simplified_geojson guarded) **Niedrigeres Risiko (Lookup/Reference-Daten):** 13. **`app/Models/Event.php`** – `$fillable = []` (alle Felder: event_id, parent_event_id, pubkey, json, type sind extern gesteuert) 14. **`app/Models/RenderedEvent.php`** – `$fillable = []` (event_id, html, profile_image, profile_name alle system-generiert) 15. **`app/Models/Profile.php`** – `$fillable = ['name', 'display_name', 'picture', 'banner', 'website', 'about']` (pubkey, deleted, nip05, lud16, lud06 guarded) 16. **`app/Models/Category.php`** – `$fillable = ['name']` 17. **`app/Models/Country.php`** – `$fillable = ['name']` (code, language_codes guarded) 18. **`app/Models/Notification.php`** – `$fillable = ['name', 'description']` (einundzwanzig_pleb_id, category guarded) ### Vorgehen 1. Jedes Model öffnen und `$guarded = []` durch das oben definierte `$fillable` Array ersetzen 2. Prüfen, ob bestehende `::create()` oder `::update()` Aufrufe noch funktionieren – ggf. müssen explizite Feld-Zuweisungen ergänzt werden 3. Für jedes geänderte Model einen Pest-Test schreiben, der verifiziert, dass Mass Assignment von sensiblen Feldern blockiert wird 4. `vendor/bin/pint --dirty` ausführen 5. Bestehende Tests laufen lassen: `php artisan test --compact` ### Akzeptanzkriterien - Kein Model hat mehr `$guarded = []` - Alle sensiblen Felder (status, paid, accepted, created_by, slug, IDs) sind NICHT in `$fillable` - Bestehende Features funktionieren weiterhin (Tests grün) - Neue Tests verifizieren Mass Assignment Protection
This commit is contained in:
@@ -9,12 +9,10 @@ class Category extends Model
|
||||
{
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -17,12 +17,10 @@ class City extends Model
|
||||
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -9,12 +9,10 @@ class Country extends Model
|
||||
{
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -19,12 +19,11 @@ class Course extends Model implements HasMedia
|
||||
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -9,12 +9,11 @@ class CourseEvent extends Model
|
||||
{
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'from',
|
||||
'to',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -15,7 +15,17 @@ class EinundzwanzigPleb extends Authenticatable implements CipherSweetEncrypted
|
||||
use HasFactory;
|
||||
use UsesCipherSweet;
|
||||
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'npub',
|
||||
'pubkey',
|
||||
'email',
|
||||
'no_email',
|
||||
'nip05_handle',
|
||||
'association_status',
|
||||
'application_text',
|
||||
'archived_application_text',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
|
||||
@@ -9,7 +9,8 @@ class Election extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
|
||||
@@ -6,7 +6,14 @@ use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Event extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'event_id',
|
||||
'pubkey',
|
||||
'parent_event_id',
|
||||
'json',
|
||||
'type',
|
||||
];
|
||||
|
||||
public function renderedEvent()
|
||||
{
|
||||
|
||||
@@ -21,12 +21,10 @@ class Lecturer extends Model implements HasMedia
|
||||
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -21,12 +21,10 @@ class Meetup extends Model implements HasMedia
|
||||
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -9,12 +9,10 @@ class MeetupEvent extends Model
|
||||
{
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'start',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -12,7 +12,11 @@ class Notification extends Model implements HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
|
||||
@@ -9,7 +9,14 @@ class PaymentEvent extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'year',
|
||||
'event_id',
|
||||
'amount',
|
||||
'paid',
|
||||
'btc_pay_invoice',
|
||||
];
|
||||
|
||||
public function pleb()
|
||||
{
|
||||
|
||||
@@ -6,5 +6,18 @@ use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Profile extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'pubkey',
|
||||
'name',
|
||||
'display_name',
|
||||
'picture',
|
||||
'banner',
|
||||
'website',
|
||||
'about',
|
||||
'nip05',
|
||||
'lud16',
|
||||
'lud06',
|
||||
'deleted',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -20,12 +20,13 @@ class ProjectProposal extends Model implements HasMedia
|
||||
use HasSlug;
|
||||
use InteractsWithMedia;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'support_in_sats',
|
||||
'website',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -6,7 +6,13 @@ use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class RenderedEvent extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'event_id',
|
||||
'html',
|
||||
'profile_image',
|
||||
'profile_name',
|
||||
];
|
||||
|
||||
public function event()
|
||||
{
|
||||
|
||||
@@ -22,12 +22,10 @@ class Venue extends Model implements HasMedia
|
||||
|
||||
protected $connection = 'einundzwanzig';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
@@ -7,12 +7,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Vote extends Model
|
||||
{
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'einundzwanzig_pleb_id',
|
||||
'project_proposal_id',
|
||||
'value',
|
||||
'reason',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
||||
Reference in New Issue
Block a user