Intrinsic Drivers (Curiosity, Passions and Purpose [Massively Transformative Purposes])
Autonomy (Freedom to do)
Mastery (Challenge-Skills improvement)
Curiosity
List down 25 items that you are curious about. For example, you will spend your free time on researching a topic or problem, read a book on a subject, attending a lecture, watching a youtube video and keeping track of the topic in news or social media like Twitter.
Make sure that the listed items are specific enough so that your brain can look for patterns. If the topic is too broad (e.g. Application Security), then it will be hard to discover what exactly you want to explore.
Hunt for the curiosities intersections. Discover the overlapping areas between the different items that you have listed.
Curiosity by itself is not enough to trigger any motivation. You need to stack one curiosity on top on another. The more you stack, the more powerful the list of stacked curiosities will be to motivate you to research and learn more.
Whenever you recognize a new pattern between what you are curious about, your brain reward you with Dopamine.
Helps you to focus on the task
Detect more patterns by improving signal-to-noise ratio
Makes us feel good about doing an activity.
Enhance our memory on a specific subject.
Spend time on these intersections. Allocate 20 to 30 minutes daily on listening to podcasts, watching videos, reading articles, books, lectures, doing practical projects related to any aspects of the intersections.
For example, if you are interested in how solving Leetcode problems can help to improve your programming skills. You might try to read a few pages on a Data Structure and Algorithm (DSA) topics. Then try to solve 1 related question to the topic that you are reading. Or you might read a specific book on the programming language such as Fluent Python and see how you can write better code.
Engage in these curiosities everyday. This will allow your brain to adapt and process the new information in the new subject slowly. This method is similar to “incubation” stage where your brain is joining the old information with the new information to form more patterns. Let our brain naturally make these connections without forcing our brain to make any discoveries.
Pay attention to these two things while you are engaging in your curiosities:
History of the subject. If you note down the historical details of the subject, your brain will create a narrative that help you to snitch the details into a coherent story that you can remember easily without effortful memorization.
Technical Language. There are precise definitions for jargons in the field that you need to understand in order to make better connections between what you are exploring. To communicate and understand the subject better, you need to note down the jargons definitions. The experts in the field use the jargons to explain something precisely.
Go Public. Before going public, make sure you spend time playing around the intersections of your curiosities. At least have some unique perspectives and ideas before going to public (online forum, book clubs, meetups etc.)
Purposes
Write down your massively transformative purpose (MTPs). The purpose (reason why the work is done) that is large and audacious, and bring significant change to an industry, community or to the planet.
Look for areas where your core passions intersect with the MTPs. You want to look for the overlap between passion and purpose.
Personal Notes:
Although the book presented like an algorithmic process for triggering flow that help to accomplish the daily tasks, the process is not so linear. You might not know what are your MTP (massively transformative purposes) while reading the book. This discovery of your MTP might take time and explorations of your curiosity.
How do you even have 25 list of items that you are curious about? It can be things that you learn from books, online courses, youtube videos, internet forums, social media or from friends etc. Everytime you consume the information, take note of what you are curious about and the questions that you want to ask further on a specific area.
In order to read the Git Blob objects, we need to understand that git uses zlib to compress the stored objects. We can use the Java zip utils to decompress the Git blob.
Code Snippets
Below are some methods of decompressing the Blob file. If you did some research online, you will find many examples showing Method 1.
But I recommend using Method 2 as it is does not assume the size of the decompressed file. This method is also used in Apache Commons library.
Make sure the binary file is not corrupted or you might encounter java.util.zip.ZipException
Method 1
The byte array size of result can be arbitrarily set with a specific size. But you will have problems if the decompressed file size is uncertain.
String file = "<PATH to Git blob>";
byte[] fileBytes = Files.readAllBytes(Paths.get(file));
Inflater decompresser = new Inflater();
decompresser.setInput(fileBytes, 0, fileBytes.length);
byte[] result = new byte[1024]; // Size need to be set
int resultLength = 0;
resultLength = decompresser.inflate(result);
decompresser.end();
Method 2: Checks if end of compressed data is reached
This method reads the content of the file and output to ByteArrayOutputStream object.
String file = "<PATH to Git blob>";
byte[] fileBytes = Files.readAllBytes(Paths.get(file));
Inflater inflater = new Inflater();
inflater.setInput(fileBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(fileBytes.length);
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] result = outputStream.toByteArray();
Highly recommend security researchers to watch this. The talk focuses more toward improving your methodology and mindset:
Don’t look for defences; Start with the attacks first.
Look for unfashionable flaws.
Your understanding of a vulnerability concept may be corrupted. Don’t reply on internet searches to learn. Learn from the original sources.
Recognise the fear from the new or unknown (Technique sounds cool but…)
Recognise that you might think that something is an implausible idea. Don’t just try something and then give out if it does not work. Instead do this: Explain why the idea will not work unless condition X exists. Try the obvious to make sure that it is obviously secured.
Invisible Chainlinks give you advantages. They can be related to a particular context, application specific knowledge, inconvenient. For example, param miner works well if you have the application specific knowledge.
Automation
Use automation to scan for clues about the application.
Scan to learn
Test Hypothesis
Ask question and iterate
When enumerating, focus on specific things rather than broad information to reduce noise.
If you encountered below error, this is because snapd.service is not started yet.
snap install hello-world
error: cannot communicate with server: Post "http://localhost/v2/snaps/hello-world": dial unix /run/snapd.socket: connect: no such file or directory
Run the following command and you should be able to see the version
$ systemctl enable --now snapd apparmor
$ snap version 127 ⨯
snap 2.55.5
snapd 2.55.5
series 16
kali 2021.1
kernel 5.10.0-kali3-amd64
The purpose of this walkthrough is to explain each part of the Smart Contract code with more context so that we can gain better understanding.
Lottery.sol
Think about the different processes for a lottery.
Participants have to enter the lottery. We need to track down who are the participants for this lottery.
We need to know how much to charge the participants for entering the lottery.
Owner will need to start the lottery.
Owner will end the lottery and we need a random way to calculate the winner of the lottery. And we need a robust way of generating the random winner that minimise the probability of participants cheating.
We need to track the state of the lottery: whether it is opened, closed or the winner is being calculated.
Tracking Participants
We need to create an address array to track down the participants. Before we add the new player to the participant list, they have to pay an entry fee. This entry fee is calculated based on current Ether price.
address payable[] public players;
function enter() public payable {
require(msg.value > getEntranceFee());
players.push(msg.sender);
}
We can use ChainLink price feed to get the latest Ether data. To do so, we need to specify the dependencies and remappings in brownie-config.yaml file.
We can make a function call without changing any state in the smart contract. In this example, we are trying to retrieve the stored value in the smart contract.
print(f"Initial Stored Value = {simple_storage.functions.retrieve().call()}")
Now, we call the store function in the smart contract to update favoriteNumber variable.
We will sign this transaction with the private key, send the transaction to the Ganache server and then wait for the transaction receipt.
Notice if you execute the transaction in local blockchain VM, the transaction speed will be very fast. But in actual Testnet or Mainnet, the transaction is likely to be slower.
Usual steps of creating a Dockerfile of your application:
Specify Base Image
Specify any environment variables
Specify commands to run on the top of OS layer such as:
downloading or updating dependencies
add groups or users to run process instead of root
Copy the application files into the image.
Specify which port(s) for container to listen
Specify the command to start the application
Dockerfile Instructions
Arguments
FROM
Base Image or other Container Image
RUN
1. Passing commands (runs in shell) 2. Passing exec form: [“executable”, “p1”, “p2”] Execute command in a new layer.
Examples: – Updating dependencies
COPY
COPY is preferred to ADD as we know clearly that COPY will just copy files from local directory. ADD is useful if you wanna copy the content in a tar file.
ENTRYPOINT
Define the command that will always be executed when the container starts.
By default, Docker is using /bin/sh -c as the entrypoint.
CMD
Define the arguments that will be appended to the ENTRYPOINT
WORKDIR
Define where your commands should run. Saves the trouble of running to many cd .....
EXPOSE
Define the ports that a container listens.
ENV
Setting environment variables that can be used in other instructions such as RUN
FROM node:12-alpine
RUN apk add --no-cache python2 g++ make
EXPOSE 9091
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
“…make sure that the constraint is not allowed to waste any time. Ever. It should never be waiting on other resource for anything, and it should always be working on the highest priority commitment the IT Operations organization has made to the rest of the enterprise. Always.”
The Phoenix project
The NUMBER ONE constraint in Security department is people.
It is unlikely we can hire enough people to match the number of developers and operations engineers.
The way to free up our constraint (people) is to try to automate as many tasks as possible so that the people can do the things that are unique and contextual.
Another way is to take a preventative approach by educating developers and ops engineers on best security practices that they need to follow (this means secure by defaults configurations, having documentation and guides). The famous Netflix’s paved roads….
any improvement not made at the constraint is just an illusion, yes?
Performing source code review is one of the important skills that you should pickup as an Application Security engineer. Being polygot in programming is helpful because you might be reviewing source code that are written in different languages. Right now, I seldom see anyone mentioning a systematic approach to read source code if you are a novice with the codebase or languages.
Reading source code is a underrated skill in today’s programming education. Often when we want to learn programming, we are given advice to build projects and write more code to learn programming. However, another aspects of learning programming is to read the code of other programmers.
This is why I think “The Programmer’s Brain” is one of the insightful programming books to read because it discusses about different aspects of being a programmer: – How to get better at reading code? – How to get better at thinking about code? – How to get better at writing code?
Get better at reading code!
Cognitive Processes in relations to programming
We can model our cognitive processes with the below diagram:
Hermans, F. (2021). Programmer’s brain: What every programmer needs to know about cognition. Manning.
At a high level, when we start reading the code, information relating to the code enters to our Short-term memory. Think of the time when you remember some information for a short period of time to memorize a phone number or a quick task to complete. This is the use of short-term memory.
Then when we are thinking and interpreting the code, we are using the information from our Short-term memory to our Working memory. The information is processed in our Working memory to generate new understanding / meaning.
Our Working memory retrieves and connect information from our Long-term memory to process the information. Think of our Working memory like a melting pot. For example, we can recall certain syntax pattern from our Long-term memory. Like when we are reading the Javascript code, we know console.log(...) will print out information based on our Long-term memory.
console.log(message)
In short, when we are reading a code, different cognitive processes are engaged to comprehend the code and perform certain actions later such as changing the code or adding new code etc.
Why we get confused when reading code?
1) Lack of knowledge
Sometimes you get confused when reading a source code if you are unfamiliar with the language syntax or concepts. Or you might be unfamiliar with the specific industry / domain knowledge that the code is written for. In this context, we say that you lack knowledge to understand the code.
For example, below is a snippet of a Racket code. If you do not understand LISP-like code or concept of Lambda, then you will not know how to evaluate ((double inc) 5)
To understand what is going on: – You need to know the syntax of a function in LISP – You understand that you can pass function into another function – In this case, the function inc is passed to the function double. In this function double, the inc function will be applied twice. – Hence ((double inc) 5) will evaluate to 7.
To understand in terms of cognitive processes, we are unable to retrieve any information from our Long-term memory that can be used by the working memory to evaluate the code.
2) Lack of information
Unfamiliar with how a particular method works or purpose of a class etc because the information cannot be retrieved directly from the code itself.
For example, we can see a python function that seems to filter a group of members by name. But we do not know how exactly the name is gonna be filtered. Hence we might guess or search for additional information from the code base.
We are temporarily confused because we cannot understand the function immediately from the code itself.
While coding a program, we might forget about how a particular concept works or their syntax. Often, we will just quickly google to retrieve for an answer (either from the documentation or stackoverflow).
The author argues it is better to know some of these syntax by heart rather than googling for answers all the time. First of all, it is distracting to google for the answers as you might be tempted to do something else (once you are in your browser especially with the multi-tabs). Second, you need to be able to recall the language syntax from your long-term memory in order to clunk the code (that you are reading) effectively.
Our long-term memories will decay in a pattern similar to a forgetting curve. If we don’t recall the things that we learned in a specific period of time, we will forget things. But if we try to recall the memories at a specific time, the decay will be slowed down.
We know this very well when we tried to cram for an exam, then we might forget everything a few things after the exam is over. Because of the failure of having future reminders, we will struggle a retrieve a concept or syntax from our long-term memory.
It is not efficient to recall every concepts every single day. Instead, we can use a spaced repetition system (SRS) software to automate the reminders for us based on how well we think we can recall a particular concept.
Note: I have tried spaced repetition system and struggles to integrate to my everyday workflow. It’s not because SRS methodology does not work. Rather it takes a commitment to adopt SRS well and make it a habit go through your deck everyday. I will keep trying and see what are the ways we can integrate SRS better into our lives.
Adopt a spaced repetition system (SRS) and add new knowledge that you have to your deck. This can be a situation where you are learning a new programming language, a new concept or framework. You will need to use judgments to know what concepts or syntax need to be included as you can’t add everything you learned into the deck.
Adding a new card on Javascript’s array prototype filter method
Also when you find yourself googling for an answer, then add a new card to your deck. This shows that you have not understand the concepts or syntax by heart. For example, most programmers would know how to write a for-loop in their language. If they do not know, it means that they have not learned the language deeply yet.
Another way to recall the syntax better is to actively think about the concepts that you are studying. It is easier for us to recall something if they are related to something that we know. When we relate a new concept / syntax to our existing knowledge, then we have a better chance of recalling the new concept / syntax in the future. Some questions to think about can be:
Think and write down the concepts that you think is related to this new concept or syntax.
In what ways are they similar and different?
Think of variants of code that can achieve the same goals as this new concept or syntax.
How important is this concept or syntax to the language, framework or codebase etc.?
Reducing cognitive loads when reading complex code
Refactoring code temporarily
Replacing unfamiliar language constructs
Adding the concepts that you are confused to SRS.
Working memory aids
Create Dependency graph
Using a state table
Think about code better!
Reaching deeper understanding of the codebase
Get better at solving programming problems
Avoiding bugs (misconceptions in thinking)
Write better code!
Naming things better
Name moulds
Feitelson’s three-step model
Avoiding code smells and cognitive loads
22 code smells from Martin Fowler’s Refactoring
Arnaoudova’s six linguistic antipatterns
Get better at solving complex programming problem
Automatization
Learn from code and its explanation
Germane Load
Practices that you can do
A) Reading different code base and attempt to understand what each code is doing.
1. Choose a code base to read
Choose a codebase where you have at least some knowledge of the programming language. You should have a high level understanding of what the code does.
2. Select a code snippet and study it for two minutes.
Choose a method, function or coherent code that is about half a page or maximum 50 lines of code.
3. Reproduce the code in paper or in an IDE (new file).
4. Reflect on what you have produced.
Which lines do you find easy and which lines are difficult?
Does the lines of code that are unfamiliar to you because of the programming concepts or domain knowledge?