Web Application Penetration Testing: Objective, Methodology, Black Box, Grey Box and White Box Tests

Faced with an ever-increasing number of sophisticated attacks, web application security is a major challenge. Indeed, security is now crucial to reassure customers, build loyalty and convert prospects.

There are several ways of assessing the security of a web application. In this article, we present the “offensive” approach, which we believe to be the most effective: web application penetration testing. We detail the principles and objectives, as well as use cases for black box, grey box and white box penetration tests on various targets.

What is a web application penetration test?

A web application penetration test consists of assessing the security of a web platform (showcase site, SaaS application, e-commerce site) by reproducing the conditions of a real attack.

The aim is to identify all the vulnerabilities on the server side and in all the functionalities and components of the web application (front and backend, APIs, third-party services, etc.), measure their impact and propose corrective measures to strengthen the security of the target system.

Web penetration testing and vulnerability testing: what are the differences and specificities?

Penetration testing and vulnerability testing are two different approaches, even if they share some similarities.

On the one hand, vulnerability tests are based on automatic scanners that identify only the most well-known vulnerabilities, listed in a database, without exploiting them. On the other hand, a web penetration test is not limited to technical flaws and automated searches, but involves one or more pentesters to identify more complex flaws, including logical vulnerabilities, using scenarios tailored to the tested application.

A penetration test involves putting yourself in the shoes of an internal or external attacker (with or without information about the target system) to assess the security of an application by exploiting vulnerabilities (technical and logical) to varying degrees of complexity, using manual scripts. This not only eliminates false positives, but also enables the security of a web application to be better tested by assessing the real impact of identified vulnerabilities.

Furthermore, once a vulnerability has been identified, it is important to dig into it to see if it can be used as a pivot point for the discovery of another flaw, because very often several vulnerabilities are exploited in order to gain access, which is impossible with an automatic scanner.

Penetration testing report and results presentation

The results of the tests are documented in a full report that details the methodology, the technical and logical vulnerabilities identified, their impact, the exploitation scenarios and recommendations for correction.

This report is presented by the pentesters in order to discuss the results of the penetration test. Finally, a counter-audit phase can be carried out to validate the correct implementation of the fixes and the absence of side-effects.

Scope of a web application penetration test

A penetration test is a tailor-made operation. It is possible to test all the functionalities of a web application or to focus on the areas most at risk, depending on the need identified.

During a web penetration test, the pentesters’ objective will be to find the most critical vulnerabilities as listed by the OWASP and other security standards.

The tests cover (but are not limited to):

  • Servers: identification of poorly secured services, out-of-date software, configuration errors, etc.
  • The search for logical flaws in the application’s workflows
  • The most common web application vulnerabilities: injections (SQL, XSS, SSTI, etc.), access control flaws (IDORs, possible privilege escalation, etc.), problems with authentication and session management, use of vulnerable third-party components, etc.
  • Vulnerabilities inherent in REST APIs, GraphQL, etc.

For more information, take a look at our articles exploring the most common vulnerabilities and attacks on web applications and the flaws inherent in APIs.

Perform a penetration test with Vaadata

Black box penetration testing of an e-commerce website

A black box penetration test is the approach where a pentester has the least information about the target application. In fact, no account or technical information is provided in order to get as close as possible to the conditions of an external attack.

In a black box project, there are 2 possible scenarios:

  • There is only a connection interface to the website. The objective for a pentester will be to gain access to the targeted platform. This can be achieved by exploiting SQLi-type vulnerabilities, a lack of access control, a trivial password, etc.
  • The target of the tests is an e-commerce website. It’s a rather special case of a black box project where we’re getting closer to the grey box. In fact, any user can create an account and thus gain access to additional functionalities.

Let’s take the example of a black box penetration test of an online clothing sales site to present our methodology. First and foremost, given the limited amount of information available, we are going to try to gain a better understanding of the platform.

Open source research (OSINT)

Open source research (OSINT) consists of retrieving information exposed on the web within the scope of the audit. This phase is important because it can guide the search for vulnerabilities and facilitate their discovery.

Some of these exposed resources may contain sensitive information that should not be disclosed publicly.

The perfect illustration is the discovery during an audit of a publicly accessible GitHub directory containing the application’s source code. This source code did not comply with best security practices, as it contained a hard-coded administrator password. Therefore, a quick search enabled an administrator account to be compromised.

These searches can go even further, for example to recover databases containing credentials that may have been leaked in recent years. The aim is to find potential valid identifiers in relation to the audited scope.

Technology research

Knowledge of the frameworks used can be useful in guiding tests and finding vulnerabilities. One tool for obtaining this type of information is Wappalyzer.

The tool will analyse requests passing through our browser in search of technical elements. It has a large database for identifying plugins, monitoring or content management tools, etc. It is based, for example, on the headers in the server response.

We can also obtain the versions of the tools in question, so we will be looking for known vulnerabilities in a specific version.

A common case during an audit is when Wappalyzer reports the use of Magento. This is a well-known framework for e-commerce sites. With this knowledge, we can have the source code, as Magento has an open-source version, and also retrieve the GraphQL schema.

File search

With this new knowledge of the technologies used, we can carry out a more precise file search.

Tools such as feroxbuster can be used to discover the files on the server. Dictionaries of relevant file names and directories are needed to avoid missing sensitive data. Sometimes files that are not used for the application’s operation are still accessible. These might include log files containing user passwords, or source code backups. Technology-related dictionaries are also used for greater efficiency.

Vulnerability research

The e-commerce websites we audit often use well-known and mature frameworks in terms of security, such as Magento, mentioned above.

During a penetration test of an e-commerce site, we will create an account to access more functions such as modifying personal information. In a second phase, we will create another account to test access control issues between users.

Access Control Testing

The creation of accounts is a point of attention for us, because if this functionality is not correctly implemented it can lead to account theft or a leak of technical information.

We can use a real case to illustrate this. When an account was created on the platform, using an existing email, the server revealed the unique identifier of the account linked to this email.

On the web interface, only a message saying “Email address already used” was displayed, but the server response contained the unique identifier linked to the email address.

This information may seem insignificant, but it was decisive in exploiting a second vulnerability.

The application used an endpoint that gave a token to the user making the request and then accessed all the requests in the GraphQL schema. This endpoint was vulnerable to IDORs. By putting our account identifier in the request, the server returned a token enabling authentication on GraphQL. By changing this identifier to the one we had leaked earlier, we could steal the token of the targeted user and make requests using his account.

In this case, we could recover his/her personal information.

Testing the payment module

E-commerce sites have a critical functionality: payment. Secure solutions are often used. In general, we do not test these directly.

The tests will focus on the way in which the payment solution has been integrated into the application. We are therefore looking for logical vulnerabilities linked to the poor implementation of payment solutions.

To do this, we need to manipulate the request parameters. The most obvious vulnerability to test is modifying the price of an item. The value of the item may be passed as a parameter to the request. A pentester could then change the price and pay less or not pay at all and still receive the product.

Other logical flaws

Another logical problem concerns the quantity of a product ordered. This is a case that we have already encountered during a project.

The parameter managing the quantity the user wanted to put in his basket accepted a decimal value. By setting a quantity equal to 0.5, the price was halved even though the invoice indicated that the product had been ordered with a quantity of 1.

Another simple test is to make a payment using a test card. Developers can use test cards supplied (i.e. made public) by software publishers. These cards are generally used in development environments, but it is possible that they are activated in production.

Furthermore, the best configuration for testing the implementation of the payment system is to have access to the platform’s back office, but this corresponds to a grey box test.

Grey box penetration testing of a SaaS application

The special feature of a grey box security audit is that testers are provided with accounts on the platform. This is far more exhaustive than a black box audit, because all the functions are accessible to the pentester.

Let’s take the example of a grey box pentest of a SaaS application that manages the schedules of a company’s employees.

It is very common for a SaaS application to offer different types of account. A very basic application would have just 3 distinct roles: “employee”, “administrator” and “super_administrator”. The vast majority of an organisation’s employees would have a “collaborator” account with which they could modify their calendar individually, while managers could view and modify their team’s calendars.

Finally, “super administrator” accounts would only be available to employees of the software publisher, and the account would have access to all the organisations on the platform.

Access control

Access control is a very important task to carry out, as the impact of a lack of access control is often high, allowing an attacker to recover sensitive data or to escalate his/her privileges. A good understanding of the application is needed to determine the errors made by the developers regarding the rights for each request. A vulnerability scanner cannot determine the incorrect implementation of permissions.

For more information on access control testing, you can consult our article on IDOR (Insecure Direct Object Reference) vulnerabilities.

To take the real case of an penetration test, we were able to escalate our privileges from ’employee’ to ‘super administrator’, which is a critical vulnerability. This means that any employee of a company that is a client of the SaaS application could have an impact on all the other client organisations.

We identified this problem during access control tests. We had been provided with an “administrator” account and a “collaborator” account. We first made the legitimate request to change roles with an ‘administrator’ account, then we repeated the request with a ‘collaborator’ account. The response from the application was identical, meaning that an account with the lowest level of privilege could raise its level of access rights.

PATCH /auth/organization /06fa370/ HTTP/2
Host: backend.target.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
Accept: application/json, text/plain, */*
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authorization: JWT tokenCollaborator
Referer: https://app.target.com/
Content-Length: 68
Origin: https://app.target.com
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Te: trailers

{"id":"06fa3703-8640-4559-9256-3464bb1e67ab","organization_role":"administrator"}

Response:

HTTP/2 200 OK
Date: Thu, 13 Apr 2023 09:34:26 GMT
Content-Type: application/json
Content-Length: 330
Server: nginx
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Vary: Origin
Access-Control-Allow-Origin: *
{"id":"06fa370","user":"85b17b88-6008 ","organization":"69a9fcf8-490d","is_test":true,"is_principal":true,"organization_role":"administrator”}

The criticality of the vulnerability could be increased by becoming super administrator of the platform. It is possible to try several values for the “organization_role” parameter. In the case of this pentest, the value we were looking for was “root”, which is a fairly common value for this type of parameter.

The easiest way is to have the source code to find out the expected value directly, but we’ll look at that later.

Cross-site scripting (XSS) vulnerabilities

Another type of vulnerability is XSS (JavaScript code injection). Sometimes we are granted access to an administration platform as part of a grey box project. This is an advantage when it comes to detecting XSS, which would otherwise be blind.

These are XSS that are triggered on a platform other than the one we are auditing. They may not be triggered when browsing the main application. Access to the back office means that we can’t miss this type of vulnerability. If we don’t have this access, we will use specific payloads to detect blind XSS. A tool like XSSHunter is very useful in this case. It’s a web service that will be exposed so that the XSS payload can make a request to this server.

In this way, we can find out when the JavaScript code was executed, where the request came from and so on. Pre-made payloads can be found on XSSHunter to take a screenshot of the victim’s browser, for example.

If we don’t have access to the back office, the call to the injected code may be triggered several days after the tests. A tool like XSSHunter will enable us to detect such a vulnerability and identify its origin.

White box penetration test

A white box security audit involves the pentesters having access to the source code. This has several advantages:

  • The possibility of concentrating on the development done specifically for the application. In the case of a site built with Magento, we’ll be going over its native features more quickly, as there’s less chance of finding vulnerabilities given that it’s open-source and is likely to be regularly studied by security researchers.
  • A better understanding of the application. We have access to all the operations performed by the server, and the processing carried out on the application’s user inputs.
  • Greater efficiency and completeness. We can see all the endpoints in the application. Some routes may not be accessible from the interface, because they are no longer in use or are only available to developers. It is still possible to find them without the source code using tools such as Feroxbsuter (mentioned above). With a white box, we’re sure not to miss any.

These are the best conditions for finding the most vulnerabilities and ensuring that the platform is secure.

Searching for vulnerabilities in the code

The source code can be used to quickly identify vulnerabilities such as XSS. Depending on the framework used, certain functions can lead to JavaScript code injections provided that user input is used by the vulnerable function.

We will illustrate this. Sometimes a developer may want an element to be rendered directly in HTML format, but this poses a security problem if the user can control the content of this element.

In Angular (a TypeScript framework), a potentially problematic function is “byPassSecurityTrustHtml()”.

A search using the grep tool will allow us to quickly find all occurrences of the dangerous function, or simply use a text editor such as VSCode.

The search will return a piece of code like the following:

ngAfterViewInit(): void {
    this.elem = this.sanitizer.bypassSecurityTrustHtml(this.elem);
  }

An overall understanding of the code will tell us whether the “elem” variable is controllable by an attacker or not. If it is, we need to find out where in the application this component is used to confirm the vulnerability.

Rights issues can also be detected by analysing the code. It is not easy to find them just by looking at the source code. It is simpler to find a right problem with a right matrix in the classic way and then to find the line responsible for this problem. Once the pattern has been identified, all you have to do is search for it to be sure of determining all the places where the problem could appear. Exhaustiveness is then quicker to achieve with this method.

Semgrep

Semgrep is a tool based on regular expression searches, just like grep. Where the tool is more powerful than a simple grep is that there is already a regular expression database that can detect dangerous patterns depending on the programming language used. The tool can go even further, as in some cases it can detect whether variables are controllable by a user by searching through other files in the directory.

Here’s an example of an element reported by Semgrep:

python.django.security.audit.xss.direct-use-of-httpresponse.direct-use-of httpresponse

Detected data rendered directly to the end user via 'HttpResponse' or a similar object. This bypasses Django's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Django's template engine to safely render HTML.  
      Details: https://sg.run/EknN

         24┆ return HttpResponse(json.dumps({ 'status': 'ERROR', 'error': str(e) }), content_type='text/html')

A potential XSS is detected due to the use of HttpResponse with a “text/html” content_type. Each security element is classified with a criticality and a detection confidence level.

However, tools such as Semgrep detect many false positives. During the audit, the results of these tools should be checked manually to identify vulnerabilities that could be exploited by an attacker.

Author : Julien BRACON – Pentester @Vaadata