Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
|
5ecde954b7 | 1 week ago |
4 changed files with 722 additions and 228 deletions
@ -0,0 +1,33 @@ |
|||
# Security Audit Checklist for Web Push Service |
|||
|
|||
## Authentication & Authorization |
|||
- [x] Basic auth implemented for admin endpoints |
|||
- [x] VAPID authentication for push notifications |
|||
- [x] Environment variable for admin password |
|||
- [ ] Consider rate limiting for subscription endpoints |
|||
- [ ] Consider adding API key authentication for public endpoints |
|||
|
|||
## Data Validation |
|||
- [x] Input validation for subscription data |
|||
- [x] Message size limits (100 chars) |
|||
- [x] Notification type validation |
|||
- [ ] Consider adding input sanitization for messages |
|||
|
|||
## Database Security |
|||
- [x] SQLite database with configurable path |
|||
- [x] No raw SQL queries (uses SQLAlchemy ORM) |
|||
- [ ] Consider adding database connection pooling |
|||
- [ ] Consider encryption at rest for sensitive data |
|||
|
|||
## Push Notification Security |
|||
- [x] VAPID key rotation capability |
|||
- [x] Secure key generation using cryptography library |
|||
- [x] Proper error handling for expired subscriptions |
|||
- [ ] Consider adding payload encryption |
|||
|
|||
## General Security |
|||
- [x] Type hints for better code safety |
|||
- [x] Error logging implemented |
|||
- [ ] Consider adding request logging |
|||
- [ ] Consider adding CORS protection |
|||
- [ ] Consider adding CSP headers |
File diff suppressed because it is too large
@ -1,25 +1,92 @@ |
|||
""" |
|||
Database Models for Web Push Notification Service |
|||
|
|||
This module defines the SQLAlchemy models for managing web push notifications, |
|||
including VAPID keys, user subscriptions, and application settings. |
|||
|
|||
Author: Matthew Raymer |
|||
Created: 2025 |
|||
""" |
|||
|
|||
from flask_sqlalchemy import SQLAlchemy |
|||
from typing import List, Optional |
|||
|
|||
db = SQLAlchemy() |
|||
|
|||
class VAPIDKey(db.Model): |
|||
""" |
|||
Stores VAPID (Voluntary Application Server Identification) keys for |
|||
web push authentication. |
|||
|
|||
VAPID keys are used to identify the application server to push services |
|||
and establish a trust relationship for sending notifications. |
|||
|
|||
Attributes: |
|||
id (int): Primary key identifier |
|||
public_key (str): Base64-encoded public VAPID key (max 255 chars) |
|||
private_key (str): Base64-encoded private VAPID key (max 255 chars) |
|||
subscriptions (List[Subscription]): Related push notification subscriptions |
|||
""" |
|||
|
|||
id = db.Column(db.Integer, primary_key=True) |
|||
public_key = db.Column(db.String(255), nullable=False) |
|||
private_key = db.Column(db.String(255), nullable=False) |
|||
subscriptions = db.relationship('Subscription', backref='vapid_key', lazy=True) |
|||
|
|||
class Settings(db.Model): |
|||
""" |
|||
Application settings and state management for notification processing. |
|||
|
|||
Tracks the execution state of notification jobs to prevent duplicate |
|||
processing and maintain notification history. |
|||
|
|||
Attributes: |
|||
id (int): Primary key identifier |
|||
prev_notify_end_time (str): ISO 8601 timestamp of last completed notification run |
|||
running_notify_end_time (Optional[str]): ISO 8601 timestamp of currently running |
|||
notification job, or None if no job is running |
|||
""" |
|||
|
|||
id = db.Column(db.Integer, primary_key=True) |
|||
prev_notify_end_time = db.Column(db.String(29), nullable=False) |
|||
running_notify_end_time = db.Column(db.String(29), nullable=True) |
|||
|
|||
class Subscription(db.Model): |
|||
""" |
|||
User subscription details for web push notifications. |
|||
|
|||
Stores the necessary information to send push notifications to a specific |
|||
browser/device, including encryption keys and notification preferences. |
|||
|
|||
Attributes: |
|||
id (int): Primary key identifier |
|||
auth (str): Authentication secret for push encryption (max 255 chars) |
|||
created_date (Optional[str]): ISO 8601 timestamp of subscription creation |
|||
endpoint (str): Push service URL for this subscription (max 500 chars) |
|||
message (Optional[str]): Custom message for direct notifications (max 100 chars) |
|||
notify_time (str): Daily notification time in "HH:MM" format (UTC) |
|||
notify_type (Optional[str]): Type of notification subscription |
|||
Valid values: |
|||
- 'DAILY_CHECK': Regular daily notifications |
|||
- 'DIRECT_NOTIFICATION': One-time direct notifications |
|||
p256dh (str): Client's public key for push encryption (max 255 chars) |
|||
vapid_key_id (int): Foreign key reference to associated VAPID key |
|||
|
|||
Relationships: |
|||
vapid_key: References the VAPID key used for this subscription |
|||
|
|||
Note: |
|||
The endpoint URL is unique per browser/device/user combination and |
|||
serves as the primary identifier for the subscription from the |
|||
push service's perspective. |
|||
""" |
|||
|
|||
id = db.Column(db.Integer, primary_key=True) |
|||
auth = db.Column(db.String(255), nullable=False) |
|||
created_date = db.Column(db.String(29), nullable=True) |
|||
endpoint = db.Column(db.String(500), nullable=False) |
|||
message = db.Column(db.String(100), nullable=True) |
|||
notify_time = db.Column(db.String(5), nullable=False) # HH:MM |
|||
notify_type = db.Column(db.String(32), nullable=True) # 'DAILY_CHECK', 'DIRECT_NOTIFICATION' |
|||
notify_time = db.Column(db.String(5), nullable=False) # HH:MM |
|||
notify_type = db.Column(db.String(32), nullable=True) # 'DAILY_CHECK', 'DIRECT_NOTIFICATION' |
|||
p256dh = db.Column(db.String(255), nullable=False) |
|||
vapid_key_id = db.Column(db.Integer, db.ForeignKey('vapid_key.id'), nullable=False) |
|||
|
Loading…
Reference in new issue