Search code examples
phpsecuritylaravel-5.1csrf-protection

Acunetix scan of Laravel login page


I have an application written using Laravel 5.1 framework. Recently, one of my clients ran an Acunetix security scan on the application and found HTML form with no apparent CSRF protection on my login page.

However, the login form DOES have CSRF protection. The name of the element with the CSRF token is "_token". The scan result says "Discovered by: Crawler".

So my questions are:

  • Why is acunetix showing this result?
  • Is "_token" not a recognized name for a CSRF token element? Should I add another hidden element into the form with the same value using a more recognizable name?
  • What does it mean "Discovered by: Crawler"? Does this mean the scan only checks the form HTML and nothing else?

Below is the snippet of the HTML form blade template:

@section('content')
        <form id="loginForm" class="form-signin" role="form" method="POST" action="{{ url('/auth/login') }}">
            <h2 class="form-signin-heading"><img src="/images/J10_Logo_330x194.jpg" alt="{{ trans('content.image_alt.j10_logo') }}"></h2>
            <input type="hidden" name="_token" value="">
            <label for="username" class="">{{ trans('auth.login.username') }}</label>
            <input type="username" class="form-control" name="username" value="{{ old('username') }}">
            <label for="inputPassword" class="">{{ trans('auth.login.password') }}</label>
            <input type="password" class="form-control" name="password" autocomplete="off">
            <div class="forgot-password"><input type="checkbox" name="remember"> {{ trans('auth.login.remember_me') }}</div>
            <div class="forgot-password"><a href="#">{{ trans('auth.login.forgot_password') }}</a></div>
            <button type="submit" class="btn btn-lg btn-primary btn-block">{{ trans('auth.login.login') }}</button>
@if (count($errors) > 0)
            <p class="text-danger">
@foreach($errors->all() as $error)
                {{ $error }}<br />
@endforeach
            </p>
@endif
        </form>
@endsection

You may notice that in the above snippet, the "_token" element value is blank. This is intentional since I am basically trying to "circumvent" acunetix's detection by only setting its value using javascript since everything I have tried so far does not seem to work.


Solution

  • The alert provided most probably indicates that this may be a false positive. CSRF alerts more often than not require human intervention to verify whether:

    1. There actually is an anti-CSRF token
    2. If the form (or rather, input) requires any anti-CSRF

    If you are already making use of the anti-CSRF token, then you can go ahead and mark that alert as a false positive. That will omit it from any future scans on the affected item (e.g. userinfo.php, being considered an item).

    Certain alerts such as the one you specified, are discovered by the crawler module. Since Acunetix Vulnerability Scanner adopts a black-box methodology, it has no prior knowledge of the application it is scanning.

    Thus, it first starts by dynamicaly mapping out the application's site structure using the crawler module and at the same time discovering particular alerts (Medium or Low alerts generally). Once the crawl is complete, the actual scanner module starts which proceeds to run every security test (script) on all the items discovered by the crawler.


    Regarding one of you comments - "I am assuming that the acunetix crawler does not run javascript and would not populate the _token element."

    The crawler perse does not execute and analyze Javascript, however the DeepScan (read more here) technology does, which occurs during the crawling stage. Thus the scanner is still able to understand client-side heavy application such as SPAs making use of frameworks like AngularJS, ReactJS etc.