People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
DownloadFile didn't have any checks on it for directory traversal. By spinning up a malicious SFTP server that exploited the directory traversal, it allowed them to write the file to anywhere on the server.ObjectInputStream is used to create an object from raw bytes. Using user controlled data, this could be used to create arbitrary objects. Although not explicitly stated, this commonly leads to RCE in Java-based products. CVE-2025-8876 was a simple command injection from input provided directly to Runtime.getRuntime().execute(). Both of these were on legacy APIs but required valid sessions.grep for functions that use XML, they found a parser that wasn't configured with secure defaults. So, this led to an XXE issue. They used this vulnerability to retrieve arbitrary files on disk. In all likelihood, this would lead to a complete compromise of the system via extracting configuration, backup and database information with credentials. getComputedStyle function to determine if a link has been visited or not. An easy way to fix this would be to make this API lie. In practice, this approach doesn't work because the CSS styling itself can vary, including colors, spacing, and other elements. X-XSS-Protection: 1 to block XSS attacks. If an XSS attack is found, then Chrome will clear the entire page. The author of this post decided to look at this feature for potential security issues. <script>uid = 1337;</script> in the URL. This is what the page normally looks like, though. Now, you put the data that you want to check into the URL. For instance, <script>uid = 1;</script>. Since this is NOT on the page, nothing happens. You can iterate on the UID over and over again until the XSS auditor finds the string match and blocks. x=123456, the form can be injected as the "fake input" to search through this character by character. XSS auditor ignores 0's for some reason. So, some extra logic that assumes that something is a zero if no matches are found is used instead. Knowledge about the value being used, such as its length and character, can also be helpful.blog.example.com and account.example.com, then the account page would have a JSONP endpoint. This works because of the cookies on the current page that get used. To prevent cross-data leakage, the endpoint verifies that the Referer header is whitelisted.Cache-Control, Expires and Last-Modified. Referer header, it will return the response to this request without doing the check! This becomes an authentication issue as a result. Cache-Control headers. I personally hadn't considered browsing caching as a security issue but it is in this case!
public fun update_v2(
...
) {
// check authority
vector::contains(&update_authority.authority, &tx_context::sender(ctx));
version_check(oracle);
update_(oracle, price, twap_price, clock, ctx);
}
UpdateAuthority contains a list of trusted updater addresses. The intention of vector::contains is to check that the caller is indeed trusted. The problem is that this doesn't revert the execution. It returns a boolean, and that's it. So, the access control check fails.swap(), it utilizes the oracle to determine the price of the asset, rather than the standard constant-product formula. So, an attacker would simply drop the price of the asset and execute a highly discounted trade for the desired asset.assert() not being enabled in production builds, this lets an invalid state get through. Good write-up!react-native-community/cli. This will create a project structure with proper dependencies and configuration files. To start the application, use npx react-native start.@react-native-community/cli from a URL parameter in runServer.js. The added middleware handler /open-url will open a URL via the open() function in NodeJS. The whole reason behind this isn't explained in the article.open() command is very versatile - for good or for bad. On Windows, the command is passed as arguments to cmd and executed using childProcess.spawn(). This also works for URLs, thanks to the default URL scheme handler. By placing a bash command here, it's possible to achieve RCE on the development machine via a single URL parameter.open() expects separate strings for different parameters on the CLI, unlike Windows. So, this doesn't have an easy path to RCE. It can perform remote file loading via smb:// and execute a local file via file://- Wait, isn't this only on localhost? The dev server binds to
0.0.0.0 for some reason. What's hilarious about this is that there's a log message that says "Starting dev server on http://localhost:8081". Overall, a good post on the root cause of a pretty simple issue. to.call(data), where the to had some magic values that shouldn't be controllable. They learned this pattern from reading bridges in the past and noticed that a particular check was missing in this code.