-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from functionofpwnosec/enhancements
Laravel@secure_dev
- Loading branch information
Showing
16 changed files
with
508 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,105 @@ | ||
# laravel-security-enhancements | ||
This project is a simple Laravel application that comes with various security features to protect against common attacks such as SQL Injection, XSS, CSRF, and others. The project also comes with secure authentication features and user access rights management. | ||
# Laravel Security Enhancements Project | ||
|
||
## Deskripsi | ||
|
||
Proyek ini merupakan aplikasi web yang dibangun menggunakan framework Laravel, yang dirancang untuk mendemonstrasikan berbagai fitur keamanan dan pengelolaan konten. Dalam dunia yang semakin terhubung, penting bagi pengembang untuk memahami dan menerapkan praktik keamanan terbaik untuk melindungi data pengguna dan mencegah serangan. | ||
|
||
Aplikasi ini menawarkan fitur-fitur seperti pengelolaan artikel, komentar, pengaturan profil pengguna, dan notifikasi keamanan. Melalui aplikasi ini, pengguna dapat membuat, mengedit, dan menghapus artikel, serta menambahkan komentar pada artikel yang ada. Proyek ini juga dilengkapi dengan sistem autentikasi pengguna, yang memungkinkan pengguna untuk mendaftar, login, dan mengelola profil mereka. | ||
|
||
Salah satu fitur unggulan dari aplikasi ini adalah pengiriman notifikasi kepada pengguna ketika ada login dari perangkat atau alamat IP baru, menambah lapisan keamanan tambahan untuk melindungi akun pengguna. | ||
|
||
### Fitur Utama | ||
|
||
- **Pengelolaan Pengguna:** | ||
- Registrasi pengguna baru | ||
- Login dan logout pengguna | ||
- Pengaturan profil pengguna yang dapat diperbarui | ||
|
||
- **Pengelolaan Artikel:** | ||
- Membuat, mengedit, dan menghapus artikel | ||
- Menampilkan daftar artikel dengan detail penulis | ||
|
||
- **Komentar:** | ||
- Menambahkan komentar pada artikel | ||
- Menghapus komentar yang telah ditambahkan | ||
|
||
- **Notifikasi Keamanan:** | ||
- Mengirim notifikasi melalui email kepada pengguna saat login dari perangkat baru | ||
- Mencatat alamat IP terakhir yang digunakan untuk login | ||
|
||
### Teknologi yang Digunakan | ||
|
||
- **Laravel**: Framework PHP untuk membangun aplikasi web. | ||
- **MySQL**: Database untuk menyimpan data pengguna, artikel, dan komentar. | ||
- **Bootstrap**: Framework CSS untuk mempercepat pengembangan antarmuka pengguna. | ||
- **Composer**: Manajer paket untuk PHP yang digunakan untuk mengelola ketergantungan proyek. | ||
|
||
### Instalasi | ||
|
||
Untuk menginstal dan menjalankan proyek ini, ikuti langkah-langkah berikut: | ||
|
||
1. **Klon Repository** | ||
|
||
```bash | ||
git clone https://github.com/username/repo-name.git | ||
cd repo-name | ||
``` | ||
2. Instal Ketergantungan | ||
Pastikan Anda telah menginstal Composer, kemudian jalankan: | ||
``` | ||
composer install | ||
``` | ||
3. Konfigurasi Environment | ||
Salin file `.env.example` ke `.env`: | ||
``` | ||
cp .env.example .env | ||
``` | ||
Kemudian, atur koneksi database Anda di file `.env`. | ||
|
||
4. Migrasi Database | ||
Jalankan migrasi untuk membuat tabel di database: | ||
``` | ||
php artisan migrate | ||
``` | ||
5. Menjalankan Aplikasi | ||
Setelah semua konfigurasi selesai, Anda dapat menjalankan server lokal menggunakan perintah berikut: | ||
``` | ||
php artisan serve | ||
``` | ||
Akses aplikasi di `http://localhost:8000`. | ||
|
||
## Kesimpulan | ||
Proyek ini merupakan contoh penerapan prinsip keamanan dalam pengembangan aplikasi web menggunakan Laravel. Dengan menambahkan berbagai fitur seperti pengelolaan pengguna, artikel, komentar, dan notifikasi keamanan, proyek ini bertujuan untuk memberikan pemahaman yang lebih baik tentang bagaimana mengamankan aplikasi web dan melindungi data pengguna. | ||
|
||
## Hak Cipta | ||
Hak cipta sepenuhnya dimiliki oleh **PT. PwnOsec Technologies Ltd.** dengan semua hak yang terkait. Tidak ada bagian dari perangkat lunak ini, baik dalam bentuk kode sumber, dokumentasi, maupun komponen lainnya, yang boleh didistribusikan, dimodifikasi, atau digunakan untuk tujuan komersial tanpa persetujuan tertulis dari pemilik hak cipta. | ||
|
||
### Tanggal Penerbitan | ||
Hak cipta ini berlaku mulai dari tanggal penerbitan proyek ini, dan akan diperbarui secara berkala oleh **PT. PwnOsec Technologies Ltd.** untuk memastikan perlindungan hukum yang sesuai. | ||
|
||
## Lisensi Penggunaan | ||
Proyek ini dilisensikan di bawah model lisensi berikut: | ||
|
||
1. **Penggunaan Komersial:** | ||
Penggunaan komersial perangkat lunak ini hanya diizinkan bagi pihak-pihak yang telah mendapatkan lisensi resmi dari PT. PwnOsec Technologies Ltd. | ||
|
||
2. **Penggunaan Pribadi:** | ||
Anda diizinkan untuk mempelajari dan mengkloning proyek ini hanya untuk penggunaan pribadi dan edukasi. Penggunaan dalam skala komersial, redistribusi, atau penjualan kembali perangkat lunak ini memerlukan izin resmi. | ||
|
||
3. **Modifikasi:** | ||
Modifikasi diperbolehkan hanya untuk penggunaan internal dan pribadi. Setiap modifikasi yang dilakukan tidak boleh didistribusikan atau dijual tanpa persetujuan dari PT. PwnOsec Technologies Ltd. | ||
|
||
## Kontak | ||
Jika Anda memiliki pertanyaan terkait penggunaan, lisensi, atau memerlukan izin penggunaan komersial, silakan hubungi kami di: | ||
|
||
- **Email:** [email protected] | ||
- **Situs Web:** [www.pwnosec.com](http://www.pwnosec.com) | ||
- **Alamat Kantor:** | ||
PT. PwnOsec Technologies Ltd. | ||
Jl. Keamanan Siber No. 123, Jakarta, Indonesia | ||
|
||
--- | ||
Hak cipta © 2024 **PT. PwnOsec Technologies Ltd.**. Semua hak dilindungi undang-undang. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use App\Models\Article; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\Auth; | ||
|
||
class ArticleController extends Controller | ||
{ | ||
public function index() | ||
{ | ||
$articles = Article::with('user')->get(); | ||
return view('articles.index', compact('articles')); | ||
} | ||
|
||
public function create() | ||
{ | ||
return view('articles.create'); | ||
} | ||
|
||
public function store(Request $request) | ||
{ | ||
$request->validate([ | ||
'title' => 'required|string|max:255', | ||
'content' => 'required|string', | ||
]); | ||
|
||
Article::create([ | ||
'title' => $request->title, | ||
'content' => $request->content, | ||
'user_id' => Auth::id(), | ||
]); | ||
|
||
return redirect()->route('articles.index'); | ||
} | ||
|
||
public function edit(Article $article) | ||
{ | ||
return view('articles.edit', compact('article')); | ||
} | ||
|
||
public function update(Request $request, Article $article) | ||
{ | ||
$request->validate([ | ||
'title' => 'required|string|max:255', | ||
'content' => 'required|string', | ||
]); | ||
|
||
$article->update($request->only('title', 'content')); | ||
|
||
return redirect()->route('articles.index'); | ||
} | ||
|
||
public function show(Article $article) | ||
{ | ||
return view('articles.show', compact('article')); | ||
} | ||
|
||
public function destroy(Article $article) | ||
{ | ||
$article->delete(); | ||
return redirect()->route('articles.index'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use App\Notifications\NewDeviceLogin; | ||
|
||
public function login(Request $request) | ||
{ | ||
$credentials = $request->only('email', 'password'); | ||
|
||
if (Auth::attempt($credentials)) { | ||
// Kirim notifikasi jika login dari IP baru | ||
if (session()->get('last_ip_address') !== $request->ip()) { | ||
auth()->user()->notify(new NewDeviceLogin($request->ip())); | ||
} | ||
|
||
session(['last_ip_address' => $request->ip()]); // Simpan IP terakhir | ||
return redirect()->route('welcome'); | ||
} | ||
|
||
return back()->withErrors([ | ||
'email' => 'The provided credentials do not match our records.', | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use App\Models\Comment; | ||
use App\Models\Article; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\Auth; | ||
|
||
class CommentController extends Controller | ||
{ | ||
public function store(Request $request, Article $article) | ||
{ | ||
$request->validate([ | ||
'content' => 'required|string', | ||
]); | ||
|
||
Comment::create([ | ||
'content' => $request->content, | ||
'article_id' => $article->id, | ||
'user_id' => Auth::id(), | ||
]); | ||
|
||
return redirect()->route('articles.show', $article); | ||
} | ||
|
||
public function destroy(Comment $comment) | ||
{ | ||
$comment->delete(); | ||
return back(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
public function edit() | ||
{ | ||
return view('user.edit', ['user' => auth()->user()]); | ||
} | ||
|
||
public function update(Request $request) | ||
{ | ||
$request->validate([ | ||
'name' => 'required|string|max:255', | ||
'email' => 'required|string|email|max:255', | ||
]); | ||
|
||
$user = auth()->user(); | ||
$user->update($request->only('name', 'email')); | ||
|
||
return redirect()->route('profile')->with('success', 'Profile updated successfully.'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use Illuminate\Database\Eloquent\Factories\HasFactory; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
class Article extends Model | ||
{ | ||
use HasFactory; | ||
|
||
protected $fillable = ['title', 'content', 'user_id']; | ||
|
||
public function user() | ||
{ | ||
return $this->belongsTo(User::class); | ||
} | ||
|
||
public function comments() | ||
{ | ||
return $this->hasMany(Comment::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use Illuminate\Database\Eloquent\Factories\HasFactory; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
class Comment extends Model | ||
{ | ||
use HasFactory; | ||
|
||
protected $fillable = ['content', 'article_id', 'user_id']; | ||
|
||
public function article() | ||
{ | ||
return $this->belongsTo(Article::class); | ||
} | ||
|
||
public function user() | ||
{ | ||
return $this->belongsTo(User::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace App\Notifications; | ||
|
||
use Illuminate\Bus\Queueable; | ||
use Illuminate\Notifications\Messages\MailMessage; | ||
use Illuminate\Notifications\Notification; | ||
|
||
class NewDeviceLogin extends Notification | ||
{ | ||
use Queueable; | ||
|
||
protected $ipAddress; | ||
|
||
public function __construct($ipAddress) | ||
{ | ||
$this->ipAddress = $ipAddress; | ||
} | ||
|
||
public function via($notifiable) | ||
{ | ||
return ['mail']; | ||
} | ||
|
||
public function toMail($notifiable) | ||
{ | ||
return (new MailMessage) | ||
->greeting('Hello!') | ||
->line('A login was detected from a new device.') | ||
->line('IP Address: ' . $this->ipAddress) | ||
->line('If this was you, you can ignore this message. If not, please secure your account.'); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
database/migrations/2024_10_11_000001_create_articles_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
class CreateArticlesTable extends Migration | ||
{ | ||
public function up() | ||
{ | ||
Schema::create('articles', function (Blueprint $table) { | ||
$table->id(); | ||
$table->string('title'); | ||
$table->text('content'); | ||
$table->foreignId('user_id')->constrained()->onDelete('cascade'); | ||
$table->timestamps(); | ||
}); | ||
} | ||
|
||
public function down() | ||
{ | ||
Schema::dropIfExists('articles'); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
database/migrations/2024_10_11_000002_create_comments_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
class CreateCommentsTable extends Migration | ||
{ | ||
public function up() | ||
{ | ||
Schema::create('comments', function (Blueprint $table) { | ||
$table->id(); | ||
$table->text('content'); | ||
$table->foreignId('article_id')->constrained()->onDelete('cascade'); | ||
$table->foreignId('user_id')->constrained()->onDelete('cascade'); | ||
$table->timestamps(); | ||
}); | ||
} | ||
|
||
public function down() | ||
{ | ||
Schema::dropIfExists('comments'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Create Article</title> | ||
</head> | ||
<body> | ||
<h1>Create Article</h1> | ||
<form method="POST" action="{{ route('articles.store') }}"> | ||
@csrf | ||
<input type="text" name="title" required placeholder="Title"> | ||
<textarea name="content" required placeholder="Content"></textarea> | ||
<button type="submit">Submit</button> | ||
</form> | ||
</body> | ||
</html> |
Oops, something went wrong.