@havoc-security/scanner 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +22 -0
- package/dist/analyzers/AuthorizationCoverageAnalyzer.d.ts +7 -0
- package/dist/analyzers/AuthorizationCoverageAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/AuthorizationCoverageAnalyzer.js +100 -0
- package/dist/analyzers/AuthorizationCoverageAnalyzer.js.map +1 -0
- package/dist/analyzers/CredentialExposureAnalyzer.d.ts +11 -0
- package/dist/analyzers/CredentialExposureAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/CredentialExposureAnalyzer.js +262 -0
- package/dist/analyzers/CredentialExposureAnalyzer.js.map +1 -0
- package/dist/analyzers/DependencyAuditAnalyzer.d.ts +28 -0
- package/dist/analyzers/DependencyAuditAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/DependencyAuditAnalyzer.js +107 -0
- package/dist/analyzers/DependencyAuditAnalyzer.js.map +1 -0
- package/dist/analyzers/EncryptionAnalyzer.d.ts +7 -0
- package/dist/analyzers/EncryptionAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/EncryptionAnalyzer.js +170 -0
- package/dist/analyzers/EncryptionAnalyzer.js.map +1 -0
- package/dist/analyzers/FileUploadAnalyzer.d.ts +8 -0
- package/dist/analyzers/FileUploadAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/FileUploadAnalyzer.js +193 -0
- package/dist/analyzers/FileUploadAnalyzer.js.map +1 -0
- package/dist/analyzers/IdorAnalyzer.d.ts +7 -0
- package/dist/analyzers/IdorAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/IdorAnalyzer.js +91 -0
- package/dist/analyzers/IdorAnalyzer.js.map +1 -0
- package/dist/analyzers/MassAssignmentAnalyzer.d.ts +7 -0
- package/dist/analyzers/MassAssignmentAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/MassAssignmentAnalyzer.js +90 -0
- package/dist/analyzers/MassAssignmentAnalyzer.js.map +1 -0
- package/dist/analyzers/PrivilegeEscalationAnalyzer.d.ts +7 -0
- package/dist/analyzers/PrivilegeEscalationAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/PrivilegeEscalationAnalyzer.js +217 -0
- package/dist/analyzers/PrivilegeEscalationAnalyzer.js.map +1 -0
- package/dist/analyzers/RateLimitAnalyzer.d.ts +7 -0
- package/dist/analyzers/RateLimitAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/RateLimitAnalyzer.js +151 -0
- package/dist/analyzers/RateLimitAnalyzer.js.map +1 -0
- package/dist/analyzers/SessionSecurityAnalyzer.d.ts +10 -0
- package/dist/analyzers/SessionSecurityAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/SessionSecurityAnalyzer.js +295 -0
- package/dist/analyzers/SessionSecurityAnalyzer.js.map +1 -0
- package/dist/analyzers/SqlInjectionAnalyzer.d.ts +7 -0
- package/dist/analyzers/SqlInjectionAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/SqlInjectionAnalyzer.js +77 -0
- package/dist/analyzers/SqlInjectionAnalyzer.js.map +1 -0
- package/dist/analyzers/XssSurfaceAnalyzer.d.ts +7 -0
- package/dist/analyzers/XssSurfaceAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/XssSurfaceAnalyzer.js +100 -0
- package/dist/analyzers/XssSurfaceAnalyzer.js.map +1 -0
- package/dist/analyzers/index.d.ts +13 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +13 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +139 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/PhpParser.d.ts +56 -0
- package/dist/parsers/PhpParser.d.ts.map +1 -0
- package/dist/parsers/PhpParser.js +193 -0
- package/dist/parsers/PhpParser.js.map +1 -0
- package/dist/parsers/RouteParser.d.ts +87 -0
- package/dist/parsers/RouteParser.d.ts.map +1 -0
- package/dist/parsers/RouteParser.js +327 -0
- package/dist/parsers/RouteParser.js.map +1 -0
- package/dist/rules/index.d.ts +14 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +9 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/types/index.d.ts +137 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +30 -0
- package/package.json.bak +27 -0
- package/src/analyzers/AuthorizationCoverageAnalyzer.ts +213 -0
- package/src/analyzers/CredentialExposureAnalyzer.ts +312 -0
- package/src/analyzers/DependencyAuditAnalyzer.ts +135 -0
- package/src/analyzers/EncryptionAnalyzer.ts +195 -0
- package/src/analyzers/FileUploadAnalyzer.ts +239 -0
- package/src/analyzers/IdorAnalyzer.ts +118 -0
- package/src/analyzers/InsecureDeserializationAnalyzer.ts +212 -0
- package/src/analyzers/MassAssignmentAnalyzer.ts +105 -0
- package/src/analyzers/OpenRedirectAnalyzer.ts +149 -0
- package/src/analyzers/PrivilegeEscalationAnalyzer.ts +258 -0
- package/src/analyzers/RateLimitAnalyzer.ts +195 -0
- package/src/analyzers/SecurityHeaderAnalyzer.ts +263 -0
- package/src/analyzers/SessionSecurityAnalyzer.ts +342 -0
- package/src/analyzers/SqlInjectionAnalyzer.ts +99 -0
- package/src/analyzers/XssSurfaceAnalyzer.ts +112 -0
- package/src/analyzers/exclusions.ts +87 -0
- package/src/analyzers/index.ts +15 -0
- package/src/index.ts +226 -0
- package/src/parsers/PhpParser.ts +259 -0
- package/src/parsers/RouteParser.ts +384 -0
- package/src/rules/index.ts +16 -0
- package/src/types/index.ts +164 -0
- package/tests/EncryptionAnalyzer.test.ts +137 -0
- package/tests/PrivilegeEscalationAnalyzer.test.ts +141 -0
- package/tests/RateLimitAnalyzer.test.ts +112 -0
- package/tests/analyzers.test.ts +678 -0
- package/tests/auth-coverage-route-aware.test.ts +294 -0
- package/tests/credential-exposure.test.ts +142 -0
- package/tests/file-upload.test.ts +141 -0
- package/tests/fixtures/app/Http/Controllers/AdminController.php +19 -0
- package/tests/fixtures/app/Http/Controllers/PostController.php +49 -0
- package/tests/fixtures/app/Http/Controllers/PublicController.php +17 -0
- package/tests/fixtures/app/Models/Comment.php +11 -0
- package/tests/fixtures/app/Models/OpenModel.php +11 -0
- package/tests/fixtures/app/Models/Post.php +14 -0
- package/tests/fixtures/app/Models/SafeModel.php +10 -0
- package/tests/fixtures/app/Models/User.php +15 -0
- package/tests/fixtures/blade/mail.blade.php +8 -0
- package/tests/fixtures/blade/safe.blade.php +12 -0
- package/tests/fixtures/blade/vulnerable.blade.php +12 -0
- package/tests/fixtures/controllers/AdminController.php +19 -0
- package/tests/fixtures/controllers/PostController.php +49 -0
- package/tests/fixtures/controllers/PublicController.php +17 -0
- package/tests/fixtures/deserialization/safe.php +32 -0
- package/tests/fixtures/deserialization/unsafe.php +60 -0
- package/tests/fixtures/models/Comment.php +11 -0
- package/tests/fixtures/models/OpenModel.php +11 -0
- package/tests/fixtures/models/Post.php +14 -0
- package/tests/fixtures/models/SafeModel.php +10 -0
- package/tests/fixtures/models/User.php +15 -0
- package/tests/fixtures/redirect/safe.php +38 -0
- package/tests/fixtures/redirect/unsafe.php +39 -0
- package/tests/fixtures/routes/api.php +9 -0
- package/tests/fixtures/routes/web.php +18 -0
- package/tests/fixtures/security-headers/app/Http/Middleware/SecurityHeaders.php +24 -0
- package/tests/fixtures/security-headers/app/Providers/AppServiceProvider.php +16 -0
- package/tests/fixtures/sql/safe_queries.php +7 -0
- package/tests/fixtures/sql/vulnerable_queries.php +7 -0
- package/tests/new-analyzers.test.ts +373 -0
- package/tests/route-parser.test.ts +257 -0
- package/tests/scanner.test.ts +82 -0
- package/tests/session-security.test.ts +161 -0
- package/tests/types.test.ts +29 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head><title>{{ $title }}</title></head>
|
|
4
|
+
<body>
|
|
5
|
+
<p>{{ $user->name }}</p>
|
|
6
|
+
<p>{{ $content }}</p>
|
|
7
|
+
<!-- Safe: using e() -->
|
|
8
|
+
<div>{!! e($userContent) !!}</div>
|
|
9
|
+
<!-- Safe: config value -->
|
|
10
|
+
<div>{!! config('app.footer_html') !!}</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<body>
|
|
4
|
+
<!-- Dangerous: user-controlled content without escaping -->
|
|
5
|
+
<div>{!! $comment->body !!}</div>
|
|
6
|
+
<div>{!! $message !!}</div>
|
|
7
|
+
<!-- Unknown context -->
|
|
8
|
+
<div>{!! $someVariable !!}</div>
|
|
9
|
+
<!-- Safe usage -->
|
|
10
|
+
<div>{{ $safeVariable }}</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
class AdminController extends Controller
|
|
6
|
+
{
|
|
7
|
+
public function dashboard()
|
|
8
|
+
{
|
|
9
|
+
Gate::authorize('admin');
|
|
10
|
+
return view('admin.dashboard');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public function settings()
|
|
14
|
+
{
|
|
15
|
+
// Fully covered with Gate
|
|
16
|
+
Gate::allows('manage-settings');
|
|
17
|
+
return view('admin.settings');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use App\Models\Post;
|
|
6
|
+
use Illuminate\Http\Request;
|
|
7
|
+
|
|
8
|
+
class PostController extends Controller
|
|
9
|
+
{
|
|
10
|
+
public function __construct()
|
|
11
|
+
{
|
|
12
|
+
// constructors are excluded
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public function index()
|
|
16
|
+
{
|
|
17
|
+
$this->authorize('viewAny', Post::class);
|
|
18
|
+
return Post::all();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public function show(Post $post)
|
|
22
|
+
{
|
|
23
|
+
Gate::allows('view', $post);
|
|
24
|
+
return $post;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public function store(Request $request)
|
|
28
|
+
{
|
|
29
|
+
// Missing authorization — should be flagged
|
|
30
|
+
return Post::create($request->all());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public function update(Request $request, Post $post)
|
|
34
|
+
{
|
|
35
|
+
// Missing authorization — should be flagged
|
|
36
|
+
$post->update($request->all());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public function destroy(Post $post)
|
|
40
|
+
{
|
|
41
|
+
$this->authorize('delete', $post);
|
|
42
|
+
$post->delete();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected function someProtectedMethod()
|
|
46
|
+
{
|
|
47
|
+
// protected — not flagged
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
class PublicController extends Controller
|
|
6
|
+
{
|
|
7
|
+
public function home()
|
|
8
|
+
{
|
|
9
|
+
// Public page — no auth needed, but analyzer will flag it
|
|
10
|
+
return view('home');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public function about()
|
|
14
|
+
{
|
|
15
|
+
return view('about');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
class SafeDeserializationController extends Controller
|
|
6
|
+
{
|
|
7
|
+
// SAFE: unserialize with allowed_classes => false
|
|
8
|
+
public function loadSafe($data)
|
|
9
|
+
{
|
|
10
|
+
return unserialize($data, ['allowed_classes' => false]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// SAFE: json_decode instead of unserialize
|
|
14
|
+
public function loadJson($data)
|
|
15
|
+
{
|
|
16
|
+
return json_decode($data, true);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// SAFE: assert with boolean expression
|
|
20
|
+
public function checkBool($value)
|
|
21
|
+
{
|
|
22
|
+
assert($value > 0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// SAFE: preg_replace_callback
|
|
26
|
+
public function transform($content)
|
|
27
|
+
{
|
|
28
|
+
return preg_replace_callback('/\{(\w+)\}/', function($matches) {
|
|
29
|
+
return strtoupper($matches[1]);
|
|
30
|
+
}, $content);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Http\Request;
|
|
6
|
+
|
|
7
|
+
class DeserializationController extends Controller
|
|
8
|
+
{
|
|
9
|
+
// CRITICAL: unserialize with user input
|
|
10
|
+
public function loadSession(Request $request)
|
|
11
|
+
{
|
|
12
|
+
$data = unserialize($request->input('session_data'));
|
|
13
|
+
return response()->json($data);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// CRITICAL: unserialize with $_GET
|
|
17
|
+
public function legacyLoad()
|
|
18
|
+
{
|
|
19
|
+
$obj = unserialize($_GET['data']);
|
|
20
|
+
return $obj;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// MEDIUM: unserialize without allowed_classes
|
|
24
|
+
public function loadFromCache($cacheValue)
|
|
25
|
+
{
|
|
26
|
+
$data = unserialize($cacheValue);
|
|
27
|
+
return $data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// HIGH: eval usage
|
|
31
|
+
public function executeTemplate($template)
|
|
32
|
+
{
|
|
33
|
+
eval($template);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// HIGH: create_function
|
|
37
|
+
public function legacyCallback()
|
|
38
|
+
{
|
|
39
|
+
$fn = create_function('$x', 'return $x * 2;');
|
|
40
|
+
return $fn(5);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// HIGH: preg_replace with /e
|
|
44
|
+
public function transformContent($content)
|
|
45
|
+
{
|
|
46
|
+
return preg_replace('/\{(\w+)\}/e', 'strtoupper("$1")', $content);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// HIGH: assert with string
|
|
50
|
+
public function checkValue()
|
|
51
|
+
{
|
|
52
|
+
assert('strlen($str) > 0');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// HIGH: extract with user input
|
|
56
|
+
public function processRequest(Request $request)
|
|
57
|
+
{
|
|
58
|
+
extract($request->all());
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Http\Request;
|
|
6
|
+
|
|
7
|
+
class SafeRedirectController extends Controller
|
|
8
|
+
{
|
|
9
|
+
// SAFE: redirect()->intended()
|
|
10
|
+
public function loginSafe(Request $request)
|
|
11
|
+
{
|
|
12
|
+
return redirect()->intended('/dashboard');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// SAFE: back()
|
|
16
|
+
public function goBack()
|
|
17
|
+
{
|
|
18
|
+
return back();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// SAFE: Redirect::back()
|
|
22
|
+
public function redirectBack()
|
|
23
|
+
{
|
|
24
|
+
return \Redirect::back();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// SAFE: redirect to explicit path
|
|
28
|
+
public function goHome()
|
|
29
|
+
{
|
|
30
|
+
return redirect('/home');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// SAFE: redirect to named route
|
|
34
|
+
public function goRoute()
|
|
35
|
+
{
|
|
36
|
+
return redirect(route('dashboard'));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Http\Request;
|
|
6
|
+
|
|
7
|
+
class RedirectController extends Controller
|
|
8
|
+
{
|
|
9
|
+
// HIGH: direct user input redirect
|
|
10
|
+
public function loginRedirect(Request $request)
|
|
11
|
+
{
|
|
12
|
+
return redirect($request->input('url'));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// HIGH: Redirect::to with user input
|
|
16
|
+
public function oauthCallback(Request $request)
|
|
17
|
+
{
|
|
18
|
+
return \Redirect::to($request->get('redirect'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// HIGH: $_GET in redirect
|
|
22
|
+
public function legacyRedirect()
|
|
23
|
+
{
|
|
24
|
+
return redirect($_GET['next']);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// MEDIUM: redirect via named variable
|
|
28
|
+
public function afterLogin(Request $request)
|
|
29
|
+
{
|
|
30
|
+
$url = $request->input('redirect');
|
|
31
|
+
return redirect($url);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// MEDIUM: Redirect::to with variable
|
|
35
|
+
public function goTo($redirect)
|
|
36
|
+
{
|
|
37
|
+
return \Redirect::to($redirect);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use App\Http\Controllers\PostController;
|
|
4
|
+
|
|
5
|
+
Route::middleware('auth:sanctum')->group(function () {
|
|
6
|
+
Route::apiResource('posts', PostController::class);
|
|
7
|
+
// Nested
|
|
8
|
+
Route::get('/users/{user}/comments/{comment}', [PostController::class, 'userComment']);
|
|
9
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use App\Http\Controllers\PostController;
|
|
4
|
+
use App\Http\Controllers\AdminController;
|
|
5
|
+
|
|
6
|
+
Route::middleware(['auth'])->group(function () {
|
|
7
|
+
Route::resource('posts', PostController::class);
|
|
8
|
+
Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Nested resource — potential IDOR
|
|
12
|
+
Route::get('/users/{userId}/posts/{postId}', [PostController::class, 'showUserPost']);
|
|
13
|
+
Route::resource('users.posts', PostController::class);
|
|
14
|
+
|
|
15
|
+
// Public routes
|
|
16
|
+
Route::get('/', function () {
|
|
17
|
+
return view('welcome');
|
|
18
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Middleware;
|
|
4
|
+
|
|
5
|
+
use Closure;
|
|
6
|
+
use Illuminate\Http\Request;
|
|
7
|
+
|
|
8
|
+
class SecurityHeaders
|
|
9
|
+
{
|
|
10
|
+
public function handle(Request $request, Closure $next)
|
|
11
|
+
{
|
|
12
|
+
$response = $next($request);
|
|
13
|
+
|
|
14
|
+
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
|
|
15
|
+
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
|
16
|
+
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
17
|
+
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
|
18
|
+
$response->headers->set('Content-Security-Policy', "default-src 'self'");
|
|
19
|
+
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
20
|
+
$response->headers->set('Permissions-Policy', 'camera=(), microphone=()');
|
|
21
|
+
|
|
22
|
+
return $response;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Providers;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Support\ServiceProvider;
|
|
6
|
+
use Illuminate\Support\Facades\URL;
|
|
7
|
+
|
|
8
|
+
class AppServiceProvider extends ServiceProvider
|
|
9
|
+
{
|
|
10
|
+
public function boot(): void
|
|
11
|
+
{
|
|
12
|
+
if (app()->environment('production')) {
|
|
13
|
+
URL::forceScheme('https');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
// Safe: using parameter bindings
|
|
4
|
+
$results = DB::select('SELECT * FROM users WHERE id = ?', [$id]);
|
|
5
|
+
$users = User::whereRaw('age > ?', [$minAge])->get();
|
|
6
|
+
$posts = Post::orderByRaw('created_at DESC')->get();
|
|
7
|
+
$stats = DB::select('SELECT count(*) FROM orders WHERE status = :status', ['status' => $status]);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
// Dangerous: string interpolation
|
|
4
|
+
$results = DB::select("SELECT * FROM users WHERE name = '$name'");
|
|
5
|
+
$users = User::whereRaw("age > $minAge")->get();
|
|
6
|
+
$posts = Post::whereRaw('status = ' . $status)->get();
|
|
7
|
+
$raw = DB::statement("DELETE FROM logs WHERE user = " . $userId);
|