feat: Implement SystemRoleProtection validator to prevent modification of system roles
This commit is contained in:
parent
0181f72208
commit
9e95a83325
95
SECURITY.md
Normal file
95
SECURITY.md
Normal file
@ -0,0 +1,95 @@
|
||||
# Security Recommendations for myCRM
|
||||
|
||||
## Implemented Security Measures
|
||||
|
||||
### 1. Authentication & Authorization
|
||||
- ✅ Session-based authentication (stateless: false)
|
||||
- ✅ Role-based access control (RBAC)
|
||||
- ✅ API endpoints protected with `is_granted()` checks
|
||||
- ✅ User can only edit own profile or requires ROLE_ADMIN
|
||||
- ✅ System roles protected via SystemRoleProtection validator
|
||||
|
||||
### 2. Password Security
|
||||
- ✅ Passwords hashed via Symfony PasswordHasher
|
||||
- ✅ Plain passwords erased after hashing
|
||||
- ✅ No passwords in serialization groups
|
||||
|
||||
### 3. XSS Prevention
|
||||
- ✅ Vue.js automatic escaping
|
||||
- ✅ No v-html or innerHTML usage
|
||||
- ✅ All user input properly escaped
|
||||
|
||||
### 4. CSRF Protection
|
||||
- ✅ Session-based API (SameSite cookies)
|
||||
- ✅ credentials: 'same-origin' in fetch calls
|
||||
|
||||
## Recommended Additional Measures
|
||||
|
||||
### 1. Rate Limiting
|
||||
Consider implementing rate limiting for API endpoints:
|
||||
```bash
|
||||
composer require symfony/rate-limiter
|
||||
```
|
||||
|
||||
Configuration example in `config/packages/rate_limiter.yaml`:
|
||||
```yaml
|
||||
framework:
|
||||
rate_limiter:
|
||||
api_login:
|
||||
policy: 'sliding_window'
|
||||
limit: 5
|
||||
interval: '1 minute'
|
||||
api_general:
|
||||
policy: 'fixed_window'
|
||||
limit: 100
|
||||
interval: '1 hour'
|
||||
```
|
||||
|
||||
### 2. HTTPS Only (Production)
|
||||
Ensure HTTPS is enforced in production:
|
||||
```yaml
|
||||
# config/packages/framework.yaml (when@prod)
|
||||
framework:
|
||||
session:
|
||||
cookie_secure: true
|
||||
cookie_samesite: 'strict'
|
||||
```
|
||||
|
||||
### 3. Content Security Policy
|
||||
Add CSP headers via `nelmio/security-bundle`:
|
||||
```bash
|
||||
composer require nelmio/security-bundle
|
||||
```
|
||||
|
||||
### 4. Input Validation
|
||||
- ✅ Email validation (Symfony built-in)
|
||||
- ✅ Required field validation
|
||||
- Consider adding: max length validation, sanitization
|
||||
|
||||
### 5. Audit Logging
|
||||
Consider logging sensitive operations:
|
||||
- User creation/deletion
|
||||
- Role assignment changes
|
||||
- Permission modifications
|
||||
|
||||
### 6. Database Security
|
||||
- ✅ Prepared statements via Doctrine (SQL injection protected)
|
||||
- ✅ Unique constraints on email/role+module combinations
|
||||
- Consider: Database encryption for sensitive fields
|
||||
|
||||
### 7. Error Handling
|
||||
Current: Errors exposed in dev mode
|
||||
Production: Ensure debug mode is disabled and errors are logged securely
|
||||
|
||||
## Security Checklist for Deployment
|
||||
|
||||
- [ ] Set `APP_ENV=prod` and `APP_DEBUG=0`
|
||||
- [ ] Enable HTTPS with valid SSL certificate
|
||||
- [ ] Set secure session cookie settings
|
||||
- [ ] Implement rate limiting
|
||||
- [ ] Set up security headers (CSP, X-Frame-Options, etc.)
|
||||
- [ ] Regular dependency updates (`composer update`)
|
||||
- [ ] Database backups configured
|
||||
- [ ] Error logging to secure location
|
||||
- [ ] Monitor authentication failures
|
||||
- [ ] Review and rotate secrets in `.env`
|
||||
@ -9,6 +9,7 @@ use ApiPlatform\Metadata\Post;
|
||||
use ApiPlatform\Metadata\Put;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use App\Repository\RoleRepository;
|
||||
use App\Validator\SystemRoleProtection;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
@ -16,6 +17,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
#[ORM\Entity(repositoryClass: RoleRepository::class)]
|
||||
#[ORM\Table(name: 'roles')]
|
||||
#[SystemRoleProtection(groups: ['role:write'])]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(stateless: false),
|
||||
|
||||
16
src/Validator/SystemRoleProtection.php
Normal file
16
src/Validator/SystemRoleProtection.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
#[\Attribute]
|
||||
class SystemRoleProtection extends Constraint
|
||||
{
|
||||
public string $message = 'System-Rollen können nicht bearbeitet oder gelöscht werden.';
|
||||
|
||||
public function getTargets(): string
|
||||
{
|
||||
return self::CLASS_CONSTRAINT;
|
||||
}
|
||||
}
|
||||
29
src/Validator/SystemRoleProtectionValidator.php
Normal file
29
src/Validator/SystemRoleProtectionValidator.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Validator;
|
||||
|
||||
use App\Entity\Role;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedValueException;
|
||||
|
||||
class SystemRoleProtectionValidator extends ConstraintValidator
|
||||
{
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!$constraint instanceof SystemRoleProtection) {
|
||||
throw new UnexpectedTypeException($constraint, SystemRoleProtection::class);
|
||||
}
|
||||
|
||||
if (!$value instanceof Role) {
|
||||
throw new UnexpectedValueException($value, Role::class);
|
||||
}
|
||||
|
||||
// Check if this is an existing system role being modified
|
||||
if ($value->getId() !== null && $value->isSystem()) {
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user