Introduction

Intigriti is a foreign bug bounty platform that releases an XSS challenge every month. Participants have about one to two weeks to think about it, and the goal is to execute alert(document.domain) on a specific website. After solving the challenge, the results are reported through the Intigriti platform, and three randomly selected winners will receive coupons for their own store.

Last month’s challenge had few winners, so I was lucky enough to win a €50 coupon. It was actually a good deal because the items in the store were quite cheap. I bought a t-shirt, two hats, and international shipping for about €45.

However, this kind of prize is based on luck, and solving the problem is more important than winning.

The challenge URL is here: https://challenge-0521.intigriti.io/

Read More

Introduction

One day, while browsing the internet, I came across an XSS challenge: Intigriti’s 0421 XSS challenge - by @terjanq. Apart from the challenge itself being very attractive, what attracted me more was the author who created it.

Many of the security-related resources I found online that were more focused on front-end were maintained or contributed to by this author, such as Tiny XSS Payloads or the eye-opening XS-Leaks Wiki.

Intigriti seems to hold this kind of XSS challenge every month, and this was the hardest one they have ever held. The challenge lasted from 4/19 to 4/25, with a week to try, and only 15 people successfully solved it. In March, 45 people solved the challenge, and in February, 33 people did, so the number of people who solved it this time was indeed much less, indicating the difficulty of the challenge.

I spent about five days on it, and every time I got stuck, I thought, “I should give up and wait for the answer.” But then, from time to time, new ideas would come up, and I would try again. Finally, on the last day before the deadline, I solved it before the time limit, and when I did, I clenched my fists and shouted, “Too awesome!”

This article is about my experience in solving the challenge. I previously wrote an English version, but it was probably worse than an elementary school composition, so I decided to write a Chinese version to better express my thoughts. The title will have a “Part 1” because this article is about my solution, and the next article will be about the author’s solution, and the one after that will analyze other people’s solutions.

But it seems that my blog is cursed to break the series of articles that haven’t been written yet, so I hope I can make it through this time.

Read More

Preface

If you don’t know what XSS (Cross-site Scripting) is, in simple terms, it is when a hacker can execute JavaScript code on your website. Since it can be executed, it is possible to steal the user’s token, impersonate the user’s identity to log in, even if the token cannot be stolen, it can still modify the page content, or redirect the user to a phishing website, and so on.

To prevent XSS, it is necessary to prevent hackers from executing code on the website, and there are many ways to defend against it. For example, CSP (Content-Security-Policy) can be used as an HTTP response header to prevent the execution of inline scripts or restrict the domains from which scripts can be loaded. Trusted Types can also be used to prevent some potential attacks and specify rules, or use some libraries that filter XSS, such as DOMPurify and js-xss.

But is it enough to use these? Yes and no.

If used correctly, of course, there is no problem, but if there are incorrect settings, there may still be XSS vulnerabilities.

Recently, I just transferred from a company to a cybersecurity team, Cymetrics, and when I was researching some websites, I found a ready-made case. Therefore, this article uses this ready-made case to illustrate what is called incorrect settings and what impact this setting will have.

Read More

Introduction

After writing CSS for a while, we should all be familiar with common properties such as display, position, padding, margin, border, background, etc. We can write them smoothly without having to look up anything.

These properties are common because they are used in many places. However, some CSS properties can only be used in specific places or under specific circumstances. I often forget these less commonly used properties, but they are actually very important in some cases.

Therefore, in this article, I want to introduce some CSS properties that I think are not easy to remember but are very useful. This is also a note for myself.

Read More

Introduction

Whenever I start a JavaScript-related project, my go-to setup is usually ESLint + Prettier. If you haven’t heard of them, let me briefly explain. Prettier is used to format your code, so you don’t have to argue with others about whether to add semicolons, whether to break { for if blocks, or how many characters per line. With Prettier, you let it decide (although there are configuration files you can adjust).

This is actually quite helpful for teams because it unifies the code format, and the basic coding style will be consistent. Although ESLint also has some formatting-related parts, it focuses more on best practices when writing code, such as declaring variables before using them and using const for variables that won’t change. This is beyond the scope of formatting.

Therefore, using ESLint with Prettier can ensure the minimum quality of the entire codebase, at least avoiding terrible formatting. The most common rule people use with ESLint is probably the Airbnb JavaScript Style Guide, which explains each rule in detail.

When I was writing code before, I suddenly thought of a place where ESLint might be suitable, so I tried it out and found that making a “usable” plugin was easier than I thought. This article records the process and experience.

Read More

Preface

This article has a little less technical content, and I would like to share with you the process of writing this series of articles and some thoughts after finishing it.

If you haven’t read this series of articles yet, the links are as follows:

Read More

Introduction

In the previous articles, we learned that the CORS protocol is essentially a security protocol. In addition to CORS, there are actually a series of things related to cross-origin, such as:

  1. CORB (Cross-Origin Read Blocking)
  2. CORP (Cross-Origin Resource Policy)
  3. COEP (Cross-Origin-Embedder-Policy)
  4. COOP (Cross-Origin-Opener-Policy)

Doesn’t just seeing this series of similar terms make you dizzy? Yes, me too. In the process of organizing this information, I found that the security issues related to cross-origin are more complicated than I thought, but after spending some time organizing them, I found that there is still a logical sequence to follow. Therefore, this article will explain why these things appear in a context that I think should be easier to understand.

In addition to the various COXX things mentioned above, there are other cross-origin related security issues that I want to mention in this article.

Before we continue, I would like to remind everyone that this article is about “security issues of cross-origin”, not just “security issues of CORS”. The things protected by the CORS protocol and their content have been introduced before. What this article is going to talk about is actually somewhat deviating from the main title “CORS” complete guide, because this is not very related to the CORS protocol, but rather raises the level again and talks about “cross-origin” itself.

So when you read the following things, don’t confuse them with CORS. Except for the first thing to be discussed later, the others are not very related to CORS.

Read More

Introduction

After acquiring knowledge, how can you determine whether it is correct or not? In the field of programming, this is actually a relatively simple question. You just need to check how the specification is written (if there is one).

For example, various language features of JavaScript can be found in the ECMAScript Specification. Why [] === [] is false, why 'b' + 'a' + + 'a' + 'a' is baNaNa, all of these are explained in detail in the specification, using what rules to perform the conversion.

In addition to JS, almost all HTML or other related specifications in the Web field can be found on w3.org or whatwg.org, and the resources are quite rich.

Although the implementation of browsers may be different from what is written in the specification (such as this article), the spec is the most complete and authoritative place, so it is correct to come here to find information.

If you search for the CORS spec, you may find RFC6454 - The Web Origin Concept and W3C’s Cross-Origin Resource Sharing, but these two have been replaced by a document called Fetch.

At first, I was puzzled and thought I had read it wrong. What is the relationship between fetch and CORS? Later, I learned that the fetch here is different from the fetch in the Web API. This specification defines everything related to “fetching data”, as written in its outline:

The Fetch standard defines requests, responses, and the process that binds them: fetching.

In this article, let’s take a look at the CORS-related specifications together, proving that what I said in the previous articles is not nonsense, but based on facts. Since the specification is quite long, I will only pick some key points that I think are important. If you want to understand all the content of the specification, you still need to read it yourself.

Read More

Introduction

In the previous article, we mentioned the common solutions to CORS errors and the solution that should be chosen in most cases: “Ask the backend to add response headers.”

However, “cross-origin requests” can actually be further divided into two types: simple requests and non-simple requests. Simple requests can be solved using the solution in the previous article, but non-simple requests are more complicated.

In addition, cross-origin requests do not send cookies by default, and an additional setting is required when using xhr or fetch, and the backend also needs to add an additional header.

There are actually many headers related to CORS, some of which you may not have heard of. Originally, I wanted to list these things one by one and explain them, but after careful consideration, I felt that this would be a bit boring, and everyone would probably forget after reading it.

So what would be a better way? Everyone likes to hear stories, so in this article, let’s start from the perspective of a story and tell you a story about love and CORS.

The protagonist’s name is well known, yes, it’s the unoriginal Xiaoming.

Read More

Introduction

In the previous article CORS Complete Guide (Part 1): Why CORS Error Occurs?, we understood why the browser has a same-origin policy and that the blocked cross-origin request is actually the response, not the request. After clarifying some misconceptions and having a basic understanding of CORS, we can now talk about how to solve CORS issues.

First of all, I want to let you know that the methods mentioned in this article are not complete solutions. In fact, cross-origin requests are divided into two types: simple requests and non-simple requests. The fact that “the blocked cross-origin request is actually the response, not the request” basically only applies to simple requests, and this article will only focus on “simple requests”. As for how to distinguish between simple and non-simple requests, and how to handle non-simple requests, these will be discussed in the next article.

There are actually many ways to solve basic CORS errors. Let’s first introduce a few “palliative” methods:

  1. Turn off the browser’s security settings.
  2. Set the fetch mode to no-cors.
  3. Do not use AJAX to fetch data.

After discussing these three methods, we will talk about the last and most correct method: “Add CORS header to the backend”.

Read More