Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #1

Merged
merged 6 commits into from Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 59 additions & 0 deletions README.md
Expand Up @@ -93,6 +93,59 @@ You may also define `routes` for each middleware in `config/security.php` and ap

Firewall will send a notification as soon as an attack has been detected. Emails entered in `notifications.email.to` config must be valid Laravel users in order to send notifications. Check out the Notifications documentation of Laravel for further information.

## .env Variables

```sh
FIREWALL_ENABLED=true
FIREWALL_WHITELIST="127.0.0.0/24"

FIREWALL_DB_CONNECTION="${DB_CONNECTION}"
FIREWALL_DB_PREFIX=security_

FIREWALL_CRON_ENABLED=false
FIREWALL_CRON_EXPRESSION="* * * * *"

FIREWALL_BLOCK_VIEW=null
FIREWALL_BLOCK_REDIRECT=null
FIREWALL_BLOCK_ABORT=false
FIREWALL_BLOCK_CODE=403

FIREWALL_EMAIL_ENABLED=false
FIREWALL_EMAIL_NAME="${MAIL_FROM_NAME}"
FIREWALL_EMAIL_FROM="${MAIL_FROM_ADDRESS}"
FIREWALL_EMAIL_TO="webmaster@example.com"
FIREWALL_EMAIL_QUEUE=default

FIREWALL_SLACK_ENABLED=false
FIREWALL_SLACK_EMOJI=":fire:"
FIREWALL_SLACK_FROM="Laravel Security"
FIREWALL_SLACK_TO= # webhook url
FIREWALL_SLACK_CHANNEL=null
FIREWALL_SLACK_QUEUE=default

FIREWALL_DISCORD_ENABLED=false
FIREWALL_DISCORD_TO= # webhook url
FIREWALL_DISCORD_CHANNEL=null
FIREWALL_DISCORD_QUEUE=default

FIREWALL_MIDDLEWARE_IP_ENABLED=true
FIREWALL_MIDDLEWARE_AGENT_ENABLED=true
FIREWALL_MIDDLEWARE_BOT_ENABLED=true
FIREWALL_MIDDLEWARE_GEO_ENABLED=true
FIREWALL_MIDDLEWARE_LFI_ENABLED=true
FIREWALL_MIDDLEWARE_LOGIN_ENABLED=true
FIREWALL_MIDDLEWARE_PHP_ENABLED=true
FIREWALL_MIDDLEWARE_REFERRER_ENABLED=true
FIREWALL_MIDDLEWARE_RFI_ENABLED=true
FIREWALL_MIDDLEWARE_SESSION_ENABLED=true
FIREWALL_MIDDLEWARE_SQLI_ENABLED=true
FIREWALL_MIDDLEWARE_SWEAR_ENABLED=true
FIREWALL_MIDDLEWARE_URL_ENABLED=true
FIREWALL_MIDDLEWARE_WHITELIST_ENABLED=true
FIREWALL_MIDDLEWARE_XSS_ENABLED=true
FIREWALL_MIDDLEWARE_KEYWORD_ENABLED=true
```

## Changelog

Please see [Releases](../../releases) for more information on what has changed recently.
Expand All @@ -110,6 +163,12 @@ Please review [our security policy](https://github.com/ozankurt/laravel-security
- [ozankurt/laravel-security](https://github.com/ozankurt/laravel-security)
- [All Contributors](../../contributors)

## Todo

- [ ] logs/ips datatable
- [ ] ip by country breakdown -> datatable + chart
- [ ] type of attack breakdown -> datatable + chart

## License

The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.
114 changes: 58 additions & 56 deletions composer.json
@@ -1,59 +1,61 @@
{
"name": "ozankurt/laravel-security",
"description": "Web Application Firewall (WAF) package for Laravel",
"keywords": [
"laravel",
"firewall",
"security",
"waf",
"blacklist",
"xss",
"sqli",
"rfi",
"lfi"
],
"license": "MIT",
"authors": [
{
"name": "Ozan Kurt",
"email": "me@ozankurt.com",
"homepage": "https://ozankurt.com",
"role": "Developer"
}
],
"require": {
"php": "^8.0",
"laravel/framework": "^9.0|^10.0|^11.0",
"guzzlehttp/guzzle": "^7.4",
"jenssegers/agent": "2.6.*"
},
"require-dev": {
"phpunit/phpunit": "^9.5|^10.0",
"orchestra/testbench": "^7.4|^8.0"
},
"autoload": {
"psr-4": {
"OzanKurt\\Security\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"OzanKurt\\Security\\Tests\\": "tests"
}
},
"extra": {
"laravel": {
"providers": [
"OzanKurt\\Security\\SecurityServiceProvider"
]
}
},
"scripts": {
"test": "vendor/bin/phpunit"
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true
}
"name": "ozankurt/laravel-security",
"description": "Web Application Firewall (WAF) package for Laravel",
"keywords": [
"laravel",
"firewall",
"security",
"waf",
"blacklist",
"xss",
"sqli",
"rfi",
"lfi"
],
"license": "MIT",
"authors": [
{
"name": "Ozan Kurt",
"email": "me@ozankurt.com",
"homepage": "https://ozankurt.com",
"role": "Developer"
}
],
"require": {
"php": "^8.0",
"laravel/framework": "^9.0|^10.0|^11.0",
"guzzlehttp/guzzle": "^7.4",
"jenssegers/agent": "2.6.*",
"voku/anti-xss": "~4.1.42",
"voku/portable-utf8": "^6.0.13"
},
"require-dev": {
"phpunit/phpunit": "^9.5|^10.0",
"orchestra/testbench": "^7.4|^8.0"
},
"autoload": {
"psr-4": {
"OzanKurt\\Security\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"OzanKurt\\Security\\Tests\\": "tests"
}
},
"extra": {
"laravel": {
"providers": [
"OzanKurt\\Security\\SecurityServiceProvider"
]
}
},
"scripts": {
"test": "vendor/bin/phpunit"
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true
}
}
}
37 changes: 32 additions & 5 deletions config/security.php
Expand Up @@ -4,7 +4,18 @@

'enabled' => env('FIREWALL_ENABLED', true),

'whitelist' => explode(',', env('FIREWALL_WHITELIST', '')),
'whitelist' => explode(',', env('FIREWALL_WHITELIST', '127.0.0.0/24')),

'dashboard' => [
'enabled' => env('FIREWALL_DASHBOARD_ENABLED', true),
'route_prefix' => 'security',
'route_name' => 'security.',
'date_format' => 'd/m/Y H:i:s',
'middleware' => [
'auth',
OzanKurt\Security\Http\Middleware\SecurityDashboardMiddleware::class,
],
],

'database' => [
'connection' => env('FIREWALL_DB_CONNECTION', env('DB_CONNECTION', 'mysql')),
Expand Down Expand Up @@ -35,10 +46,10 @@
'responses' => [

'block' => [
'view' => env('FIREWALL_BLOCK_VIEW', null),
'redirect' => env('FIREWALL_BLOCK_REDIRECT', null),
'abort' => env('FIREWALL_BLOCK_ABORT', false),
'code' => env('FIREWALL_BLOCK_CODE', 403),
'view' => null,
'redirect' => null,
'abort' => false,
'code' => 403,
//'exception' => \OzanKurt\Security\Exceptions\AccessDenied::class,
],

Expand All @@ -63,6 +74,12 @@
'queue' => env('FIREWALL_SLACK_QUEUE', 'default'),
],

'discord' => [
'enabled' => env('FIREWALL_DISCORD_ENABLED', false),
'webhook_url' => env('FIREWALL_DISCORD_WEBHOOK_URL'),
'queue' => env('FIREWALL_DISCORD_QUEUE', 'default'),
],

],

'all_middleware' => [
Expand Down Expand Up @@ -424,6 +441,16 @@
'xss' => [
'enabled' => env('FIREWALL_MIDDLEWARE_XSS_ENABLED', env('FIREWALL_ENABLED', true)),

'mode' => 'block', // 'block', 'clean'

'allow_blade_echoes' => false,

'blade_echo_tags' => [
['{!!', '!!}'],
['{{', '}}'],
['{{{', '}}}'],
],

'methods' => ['post', 'put', 'patch'],

'routes' => [
Expand Down
16 changes: 13 additions & 3 deletions database/migrations/create_ips_table.php
Expand Up @@ -6,20 +6,30 @@

return new class extends Migration
{
protected string $tableName;

public function __construct()
{
$this->connection = config('security.database.connection');
$this->tableName = config('security.database.table_prefix') . config('security.database.ip.table');
}

public function up(): void
{
Schema::connection(config('security.database.connection'))->create(config('security.database.ip.table'), function (Blueprint $table) {
Schema::create($this->tableName, function (Blueprint $table) {
$table->id();
$table->string('ip')->index('ip');
$table->string('ip')->index();
$table->foreignId('log_id')->nullable()->index();
$table->string('entry_type')->nullable();
$table->boolean('is_blocked')->default(1);
$table->unsignedInteger('request_count')->default(0);
$table->timestamps();
$table->softDeletes();
});
}

public function down(): void
{
Schema::connection(config('security.database.connection'))->drop(config('security.database.ip.table'));
Schema::drop($this->tableName);
}
};
14 changes: 11 additions & 3 deletions database/migrations/create_logs_table.php
Expand Up @@ -7,12 +7,20 @@

return new class extends Migration
{
protected string $tableName;

public function __construct()
{
$this->connection = config('security.database.connection');
$this->tableName = config('security.database.table_prefix') . config('security.database.log.table');
}

public function up(): void
{
Schema::connection(config('security.database.connection'))->create(config('security.database.log.table'), function (Blueprint $table) {
Schema::create($this->tableName, function (Blueprint $table) {
$table->increments('id');
$table->foreignId('user_id')->nullable()->index();
$table->string('middleware')->index();
$table->string('middleware')->nullable()->index();
$table->string('level')->default(LogLevel::MEDIUM)->index();
$table->string('ip')->index();
$table->text('url')->nullable();
Expand All @@ -26,6 +34,6 @@ public function up(): void

public function down(): void
{
Schema::connection(config('security.database.connection'))->drop(config('security.database.log.table'));
Schema::drop($this->tableName);
}
};
6 changes: 6 additions & 0 deletions public/css/bootstrap.min.css

Large diffs are not rendered by default.

Binary file added public/images/cloud-bg-dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/cloud-bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/laravel-security.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/js/bootstrap.bundle.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions public/manifest.json
@@ -0,0 +1 @@
{"version": "1.0.0"}