Häufige Sicherheitsfehler in Laravel-Anwendungen

Einführung

In den meisten Fällen entstehen Sicherheitslücken nur durch mangelndes Bewusstsein und nicht durch Nachlässigkeit. Während wir festgestellt haben, dass die meisten Entwickler sich um Sicherheit kümmern, verstehen sie manchmal nicht, wie ein bestimmtes Codemuster zu Sicherheitslücken führen kann. Daher haben wir uns im E-Book entschlossen, die häufigsten Sicherheitsprobleme zu teilen, die wir gesehen haben, während wir verschiedenen Startups beim Schutz ihrer Anwendungen geholfen haben. Laravel. In jedem Angriffsbeispiel zeigen wir Ihnen auch die Best Practices zum Schutz Ihrer Anwendung vor Angriffen. Wir hoffen, dass diese Informationen für Sie und Ihr Entwicklungsteam nützlich sind.

CyberPanda-Team

SQL-Injektion

Laravel bietet einen robusten Query Builder und Eloquent ORM. Und dank ihnen sind die meisten Anfragen standardmäßig in Anwendungen geschützt, daher beispielsweise eine Anfrage wie

Product::where('category_id', $request->get('categoryId'))->get();

wird automatisch geschützt, da Laravel den Code in eine vorbereitete Anweisung übersetzt und ausführt.

Entwickler machen jedoch normalerweise den Fehler zu glauben, dass Laravel vor allen SQL-Injections schützt, obwohl es einige Angriffsmethoden gibt, die Laravel nicht schützen kann.

Dies sind die häufigsten Gründe für die SQL-Injektion, die wir bei unseren Sicherheitsüberprüfungen in modernen Laravel-Anwendungen gesehen haben.

1. SQL-Injektion über den Spaltennamen

, , , Laravel , Query Builder Eloquent. , , , , .

Laravel:

PDO does not support binding column names. Therefore, you should never allow user input to dictate the column names referenced by your queries, including "order by" columns, etc. If you must allow the user to select certain columns to query against, always validate the column names against a white-list of allowed columns.

, SQL-:

$categoryId = $request->get('categoryId');
$orderBy    = $request->get('orderBy');

Product::query()
  ->where('category_id', $categoryId)
  ->orderBy($orderBy)
  ->get();

- orderBy

http://example.com/users?orderBy=id->test"' ASC, IF((SELECT count(*)
FROM users ) < 10, SLEEP(20), SLEEP(0)) DESC -- "'

SQL-:

select
  *
from `users`
order by `id`->'$."test"' ASC,
  IF((SELECT count(*) FROM users ) < 10, SLEEP(20), SLEEP(0))
DESC -- "'"' asc limit 26 offset 0

, Laravel*, , , Laravel , Query Builder .

, SQL-, - , , .

, «users» - "secretAnswer", SQL-.

2. SQL-

$id = $request->route('id');
$rules = [
    'username' => 'required|unique:users,name,' . $id,
];
$validator = Validator::make($request->post(), $rules);

Laravel $id , SQL-. " " > "SQL-".

3. SQL-

, , , , DB::raw . , , - . DB::raw - , , DB::getPdo()->quote.

:

public function update(Request $request) {
    $id = $request->route('id');

    $rules = [
        'username' => 'required|unique:users,username,' . $id,
    ];

    $validator = Validator::make($request->post(), $rules);

    if ($validator->fails()) {
        return response()->json($validator->errors(), 422);
    }

    $user = User::findOrFail($id);
    $user->fill($validator->validated());
    $user->save();

    return response()->json(['user' => $user]);
}

required|unique:users,username,'. $id? ! ()

, unique , . , $id , , . , , , .

1.

, - ID = 10|sometimes, required|unique:users,username,10|sometimes , - , .

2. DDOS REGEX

Regex ReDoS DDOS . , , , :

PUT /api/users/1,id,name,444|regex:%23(.*a){100}%23
{
    "username": "aaaaa.....ALOT_OF_REPETED_As_aaaaaaaaaa"
}

3. SQL-

SQL- . :

PUT /api/users/1,id,name,444|unique:users,secret_col_name_here
{
    "username": "secret_value_to_check"
}

, unique ( PDO) SQL- . Laravel .

:

  1. - , , ;

  2. (ID ), , .

XSS ( ) Laravel Blade

XSS 1990- , , - , , . , , XSS- :

Some text
<input onfocus='$.post("/admin/users", {name:"MaliciousUser", email:
"MaliciousUser@example.com", password: "test123", });' autofocus />
test

- . IP- , , /.

, XSS- Laravel.

Laravel Blade, XSS-, , :

// $name = 'John Doe <script>alert("xss");</script>';
<div class="user-card">
 <div> ... </div>
 <div>{{ $name }}</div>
 <div> ... </div>
</div>

Blade {{ }} . , :

<div class="user-card">
 <div> ... </div>
 <div>John Doe
&lt;script&gt;alert(&quot;xss&quot;);&lt;/script&gt;</div>
 <div> ... </div>
</div>

XSS. Laravel ( ) , XSS-, :

1. XSS {!! $userBio !!}

, HTML, {!! !!}:

// $userBio = 'Hi, I am John Doe <script>alert("xss");</script>';
<div class="user-card">
 <div> ... </div>
 <div>{!! $userBio !!}</div>
 <div> ... </div>
</div>

Laravel , $userBio JavaScript , XSS-.

:

  1. html , .

  2. , HTML, , htmlpurifier.org, HTML JS .

2. XSS a.href

, , , , XSS-:

1: javascript:code

// $userWebsite = "javascript:alert('Hacked!');";

<a href="{!! $userWebsite !!}" >My Website</a>

2: base64:

, .

// $userWebsite =
"data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGFja2VkISIpOzwvc2NyaXB0Pg
==";

<a href="{!! $userWebsite !!}" >My Website</a>

(«Hacked!») , « -» ...

:

  1. , . http/https ;

  2. , http/https «#broken-link».

3. XSS

Blade , , HTML. , , , Laravel :

// Registering the directive code
Blade::directive('hello', function ($name) {
    return "<?php echo 'Hello ' . $name; ?>";
});

// user.blade.php file
// $name = 'John Doe <script>alert("xss");</script>';

@hello($name);

:

Laravel e(), , . 3 , Laravel . , XSS- Laravel, XSS-, , , React.js, Vue.js, javascript jQuery, XSS-.

Laravel

Eloquent, ORM, , . , , .

, , :

// app/Models/User.php file
class User extends Authenticatable
{
    use SoftDeletes;

    const ROLE_USER = 'user';
    const ROLE_ADMINISTRATOR = 'administrator';

    protected $fillable = ['name', 'email', 'password', 'role'];

    // ... rest of the code ...
}

// app/Http/Requests/StoreUserRequest.php file
class StoreUserRequest extends Request
{
    public function rules()
    {
        return [
            'name'             => 'string|required',
            'email'            => 'email|required',
            'password'         => 'string|required|min:6',
            'confirm_password' => 'same:password',
        ];
    }
}
// app/Controllers/UserController.php file
class UserController extends Controller
{
    public function store(StoreUserRequest $request)
    {
        $user = new User();
        $user->role = User::ROLE_USER;
        $user->fill($request->all());
        $user->save();

        return response()->json([
            'success' => true,
        ],201);
    }

    // ... rest of the code ...
}

, , - , , .

{
    "name" : "Hacker",
    "email" : "hacker@example.com",
    "role" : "administrator",
    "password" : "some_random_password",
    "confirm_password" : "some_random_password"
}

"role" $fillable. "role" , . , , , API, - , Laravel, . $fillable , , , API, ACL.

, Laravel.

:

1.

, , . , . "name", "email" "password". Laravel $request->validated(), .

, $request->all() $request->validated() :

public function store(StoreUserRequest $request)
{
    $user = new User();
    $user->role = User::ROLE_USER;
    $user->fill($request->validated());
    $user->save();
    
    return response()->json([
        'success' => true,
    ],201);
}

Laravel, $request->validate() $validator->validated(), .

, , , .

2.

$fillable ( , ) $guarded ( , ), $guarded, .

3. . $model->forceFill($data)

$model->forceFill , $forceFill $fillable . forceFill, , .

, , ? , , . , , / . , , , 0,1-0,2% . , - 1 , 10 , 10'000-20'000 . , .

- , .

- Laravel Auth , , IP- , . , :

1.

, . Symantec , 80% 2FA.

2. IP-

, IP, .

3.

IP, 100% , .

4. , /

FaceBook, - , :

5.

, , .

, Laravel, SQL- XSS, , ACL . ACL - , .

Laravel , .

HTTP

- HTTP (HTTP Strict Transport Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, , . .), . HTTP . , HTTP Strict Transport Security HTTPS ( , HTTP HTTPS ). X-Frame-Options .

Laravel, . , , ? , , , , , .

Laravel , . , :

. , , 700 Equifax. , Equifax Apache Struts, 2 . Equifax 147,9 .

Laravel , , , , .

Laravel - , - - . , Laravel, API (, Eloquent), , Laravel , .

, , , , :

  1. Race Condition

  2. Server Side Request Forgery

  3. PHP Type Juggling

  4. Unrestricted File Upload

  5. Path Traversal

  6. Sensitive Data Exposure

  7. Server Side Template Injection

  8. Insecure Deserialization

  9. Session Fixation

  10. XML External Entity (XXE) Processing

  11. JWT Security

. , {{$userBio}} {!!$userBio!!}.

* "Der Angriffsvektor wurde in der neuesten Version von Laravel behoben" - laut Originalartikel ist das Datum seiner Veröffentlichung sowie auf der Website nicht klar, weshalb nicht festgestellt werden konnte, welche Version von Laravel zu diesem Zeitpunkt die neueste war. Trotzdem gelangte der Artikel am Tag der Übersetzung in die Hände, und in diesem Moment existierte Laravel 8 einige Tage lang.




All Articles