Welcome!
Please sit down.
We are starting with the recording now.
I hope you had a wonderful meal.
Today I will be talking about
how to write less insecure JavaScript.
My name is André Jaenisch.
This presentation will go live on the 6th of February 2022.
You can find video and subtitles linked in the presentation
which you can reach via the QR code.
Please don't use Google Lens.
I prepared something for you
so I would encourage you
to come and follow along with the slides.
Who am I? I'm André Jaenisch.
I'm a software engineer.
I'm giving this presentation on my own.
You can find me on Matrix @Ryuno-Ki on Matrix itself
or on Twitter or on other places I linked for you.
I will be talking about fifty minutes now
and if you have questions please write them down
because it's pre-recorded
and we will have a Q-and-A at the end
or you can reach out to me and ask me anytime.
What will you learn today?
We are talking about
how to write less insecure JavaScript
that means: main focus on what you can do as a developer
but it's also having a social component
so we're looking shortly at
what you can do as a team,
as a company or as a community.
Company because I think most of you will having a paid job writing code
but it is also valid for NGOs
and community is the Open Source community around.
My motivation?
I'm a self-taught developer and my expectation is
that i have interest in adjacent fields.
I picked up books, for example by Bruce Schneier,
I'm listening to podcasts, for example Troy Hunt
Darknet Diaries or Tanya Jenca,
and I am following Snyk.
Let me quote an podcast:
„Focus on the people because everything else is an implementation detail.”
So software coding is mainly about people.
Before we go into any code deep snippets:
Don't try these on other people's machines.
You might risk legal liabilities that means you could come in jail.
and second thing:
it's not about 100 percent security because that's impossible
but that does not mean that it's not worth trying
because it's about making it more expensive for attackers.
If you followed along you will end up here
and can pick an avatar,
either Alice or Bob,
both are figures in the literature about cryptography.
If you coose one you will get a small avatar
in the upper corner.
If you don't want an avatar just click elsewhere.
And I got inspiration by a book cover I recently found
about Alice and Bob learning Application Security.
So let's get started! What can you do as a developer?
It's a lot what you can do and there are many pitfalls.
As I mentioned I'm following Snyk and they're blogging about it.
But they're also maintaining an open vulnerability database
which I used for studying
commits in December last year and January this year
and draw some lessons from it.
Now it might be that you are a senior developer who don't want to see code
in this case you can hit the right arrow and skip forwards to the tooling
or you can follow along with me for this talk
and looking at code so we're going downwards.
I'm making some assumptions.
So this presentation will be about JavaScript.
You might get some slightly different results with TypeScript,
Im not a big fan of TypeScript because I think it gives you a false sense of safety
and what we learn here can mostly be transferred to other programming languages
The second assumption I'm taking is
that you already familiar with JavaScript
so that I don't have to explain
what is a prototype chain and other things.
OWASP stands for Open Web Application Security Project.
They're publishing a report regularly
about the top ten.
I linked it here, so if you are following the slides
you can hit the link
Personally I think it's a bit dry
but it's important and worth studying
so look at the report and
you find more explanations there.
The Top Ten for the last edition were these:
Broken access controls, cryptographic failures, injection, insecure design
security misconfiguration, vulnerable and outdated components,
identification and authentication failures,
software and data integrity failures,
security logging and monitoring failures,
and server-side request forgery.
Those items change from one report to the other,
and you will find more explanation about what's in about it in the OWASP link.
I'm looking at some of them
but I've focused more on the vulnerability database
and we will look more into attack vectors.
This presentation has a lot of lingo.
The idea is that I try to explain it in short words
but when you use the terms it's easier to research more.
The list here is by no means exhaustive.
There are so many other things you can do
but we will have some real code examples
and I picked some recent vulnerabilities.
So first thing I want to start with
is one of the hard things in tech.
It's not invalidating cache but naming things.
You can do already a lot by
picking a good name.
So if you are using a framework like for example React or Angular
or a template language, for example Nunjucks,
you will see that some patterns are
with dangerously, raw, unsafe. So you have to do something more
to escape them.
to mark them „Hey I know they're safe.”
And they're defaulting to a safe state of data
and they're nudging developers to think about before
they are using unsafe data.
By writing longer you have more time to think
„Hey, do I want to really use that one or
do I want to make sure it's safe to use?”
You find a link here „back to attack vectors”
that will bring you back to the overview we saw before
so if you are following with the slides
it's more or less a choose-your-own-adventure
so you can pick those items that interests you and
skip others.
The next thing is something you will run into time and again:
It's called cross-site scripting or XSS.
I'm quoting Snyk here
because I find they have a really good definition of it
and I will explain a bit afterwards.
So Snyk says:
A cross-site scripting attacks occurs
when the attacker tricks a legitimate web-based
application or site to accept a request
as originating from a trusted source.
This is done by escpaing the context of the web application;
the web application then delivers
that data to its users along with other
trusted dynamic content, without validating it.
The browser unknowingly executes malicious script on
the client side in order to perform actions
that are otherwise typically
blocked by the browser's Same Origin Policy.
Wow! That was a mouthful!
So what does it mean?
First off: the browser has different layers of security.
For example the Same Origin Policy.
That is, if a source is loaded from the same protocol,
host and port it's considered from the same origin.
So it is to be trusted.
If there is from some other subdomain for example
it will have to be validated.
Or you will have to do some more legwork.
And what that attack now tries to is like
„Okay I try to mimic the developer
and put something into it”, so for the browser
it looks like it comes from the web author, so the developer,
and is trusted blindly, that is without validating.
When you're looking into security measures
best practice is to imagine an evil user.
In the cryptographic literature that's called Eve.
The main important thing is to validate input and to sanitize output.
If you are validating a ReST API, for example,
you can use a JSON schema with the additionalProperties flag
so now other things are coming from the JSON response
than what you expected.
You can then validate it for example with a library called ajv.
There are other solutions.
If you are validating input, keep in mind
that it also extends to like forms or URL parameters.
The other main important thing is to
sanitize the output, so everything which comes
from your database for example.
One library could be DOMPurify,
another might be sanitize-html
I'm preferring DOMPurify because
they have a section about what you can do
when you find some security there.
What I want to stress is
Do. Not. Use. Regular. Expressions.
There are so many crazy things you can do with HTML
that's valid HTML but will likely escape your regular expression.
Please, use a library!
Okay, cool. What else?
You can, for example, enforce a Content Security Policy.
That means that you are having an allowlist.
Okay, I expect images to be loaded from these domains,
I expected JavaScript coming from that domain,
and everything else will be blocked by the browser.
There is a web extension called laboratory
which might help. So you just clicking through
your application and it will generate the HTTP headers.
Then you can put them into NginX or Apache or whatever you use.
If you are seeing invalid requests
that likely means that you're under attack right now
and the best thing is to redirect to a safe origin,
for example the root path.
If you are detecting simultaneous logins
especially those from two different IP adresses
please invalidate those sessions.
The idea is that you are
likely under attack again
from a bot net, so different machines
from all over the world and the passwords are
for example fetched from a recent break
and it's called password spraying.
The worst case is that you are logging out
an legitimate user but that's still better than
being attacked and loosing data.
Next thing! Malicious package or typosquatting.
The problem here is that someone else tries
to register a package, for example on npm
which contains malicious code but is only
a small typo to the legitimate package.
For example: moment.js and somebody
tries to register monent.js with an n instead of the m
and that is especially common with popular packages.
You can then download the malicious code by
for example copy-pasting a typo from the web.
What you can do is you register a package with alternate spelling
so with typos. It can be empty or it can
have a README which says
„Hey you tried to download this package. I think
you meant this other package. Please, use that one.”
If you are in a company it's most likely
that you have a private npm registry to
protect intellectual property.
There are software like Verdaccio
bit, Nexus, Artifactory or Gemfury
you can use for that.
Artifactory, for example, is based on Java
so if you have a Java backend that might be a good choice.
During the research of this presentation
I learned about npq.
npq checks for known vulnerabilities
or popularity before you install with npm
or yarn which is helpful to find
„Okay, hey this is a new package
and it has some known vulnerabilities.
Are you sure you want to install that one?”
The other thing you can use is snync
which stands for „so now you're not confused”.
The idea here is if you have a private
npm registry it is still possible to register that same name
on the public npm registry
which might be not what to want
because that on the public registry could
be a malicious package. So snync
checks that before installation.
Next subject: prototype pollution
That's JavaScript specific one.
Again, I'm quoting Snyk here.
„Prototype pollution is a vulnerability affecting JavaScript.
Prototype pollution refers to the ability
to inject properties into existing JavaScript language construct prototypes such as objects
JavaScript allows all Object attributes to be altered,
including their magical attributes,
such as __proto__,
constructor and prototype.
An attacker manipulates these attributes to overwrite,
or pollute, a JavaScript application object prototype
of the base object by injection other values.
Properties on the Object.prototype are then
inherited by all the JavaScript objects
through the prototype chain.
When that happens this leads to either
denial of service by triggering JavaScript exceptions,
or it tampers with the application source code
to force the code path that the attacker injects,
thereby leading to remote code execution.
Again, a lot. What does it mean?
Take for example toString() or valueOf().
Those are used for string or numeric representation of
an object during type coercion.
So, let's say we're using toString()
and now we're returning a number instead.
That would trigger some JavaScript exceptions
which blocks all other execution so
you have a denial of service.
Or, you are returning a string but you are
executing some other code before.
That would be a remote code execution
which is one of the worst things you can have
in software.
Here we have some example code. Something I could
have written myself.
I slightly edited it to fit in the slides. So you
normally would have function isObject
typeof object = function or = object
but that would'nt have fit in those code boxes.
What does it do?
Mainly we are exporting the function clone at the end
that goes over an object,
checks wheter it has to recurse into that
or it just copies over. Looks innocent, doesn't it?
So we have a code path that checks for the isAdmin flag
and I have an object created somewhere else.
For the sake of brevity here created as plain JavaScript object.
You would have undefined as a value
because the property is not set.
So now we have some input which is not validated
for example, that argument of clone().
And the attacker now sets an object with
a property of "constructor" which
has an object as value with a key of "prototype"
and now isAdmin is true.
For example because he read your source code.
If you're now logging
"console.log(o.isAdmin)" you get "true". Why?
Because we overwrote the prototype chain
and now we have a value that is controlled by the attacker.
That works. This code snippet here is
taken from an book called
Hack Tricks. A git book from
Carlos Prolop which is also released under the Creative Commons license.
You can find other code snippets under this link.
What you can do?
Be careful with recursive merge or deep clone functions.
For example, lodash was affected
by the same prototype pollution we saw here.
You should freeze your Object.prototype.
For example, JavaScript, ECMAScript 6 has an Object.freeze
If you're looking into freezing
you might also want to look into ice factory
pattern which I linked here.
Or you could use immutable data structures which has
a lot of advantages.
I looked into two libraries here:
Immutable.js or Immer.
Object.create(null) would get rid of the
prototype chain so you don't have that vulnerability.
You can also use Map instead of a plain Object
Map is not affected by this attacks but
it might be slower than a plain object.
The original prototype pollution was reported
by Oliver Arteau in a paper called
„JavaScript prototype pollution attack in NodeJS application”.
It's also valid in other cases, for example
jQuery or other browser things.
Next is one of my favourites:
Reverse Tabnapping. So it's like kidnapping but with a browser tab.
Problem is: You're using external links
and normally you put a target="_blank".
That will expose your original website
in a window.opener property.
This allows the site you link to
to manipulate the source from where
you're coming so your page.
Browsers fixed it recently,
so a couple years back,
so you don't have to use it, but I
recommend to use that rel property with a value of noopener
and noreferrer.
noopener is required
by a bit older browsers and
noreferrer by even older browsers.
What it does is set that window.opener to null
thereby protecting your page from manipulation from outside.
It doesn't hurt to have these attributes
and you're securing more browsers or more visitors.
Next thing is called Directory Traversal.
You might also find it in literature as Path Traversal.
The idea here is that you're exploiting HTTP
to gain unauthorised access to restricted files or directories.
So. Most servers are running on Linux
and the ../ is moving up one directory on the file system.
And the other thing you'd need to know
is that the file system directory structure
is often mapped to URL path structure.
So if I try to get above the root path
on a web URL I might get access to the file system.
You could, for example, try this with cURL.
You don't have to try that on my website
where this presentation is hosted because
you would get a Bad Request. I tried it
so you don't have to.
And with --path-as-is flag you are telling
cURL to not resolve that ../
but pass it as-is to the server and
then try to make an attempt there.
This is an attempt to read without authorization
A popular aim is the /etc/passwords where
the encrypted hashes of all passwords on that
machine are stored.
There is a write variant called Zip Slip Vulnerability
where you have that directory traversal attack
as path of a file inside the archive.
I won't show it here because
I'm not sure whether it is working or how to craft one.
That would be used, for example, to overwrite
the private key on SSH so you can log into that machine.
What you can do as a counter measure?
Don't rely on user input. Again
when accessing the file system.
instead you could use, for example, a mapping.
Normalise the path information, that is
the URL encoding or zero bytes in path
and if you have a path string
check the prefix, so the first part
for the directory and then check
whether the user has access right
on that directory.
So this is unauthorised access.
If possible try to avoid requests to
file system via URL
That also means the index pages
you see, for example, on download pages sometimes.
And don't store sensitive files on web server storage.
That can be secrets, that can be private keys.
Most services have a vault where you can
store them safely in.
You find more information, for example,
on the cURL blog page
where they explain what --path-as-is is.
Okay, cool. Exploiting postMessage.
That can be relevant to Web Extensions or iFrames.
Here the problem is lack of validation of origin
for incoming messages which then
allows for arbitrary code execution.
What does it mean?
I tried to compile a code snippet again.
I haven't written many Web Extensions myself
so it can be a bit different than what we see here.
So what do we have?
We have first listening to message events from anywhere.
Or sending messages to everybody who is listening:
The asterisk.
And then we're listening to events.
Here we have one where is „page-ready”
which is not relevant for us right now
but we are targeting for the chrome.runtime.message API
which is everything else that is not „page-ready” message.
We then have a payload
so on my vulnerable website I
would have this code in.
And I have to open a new window, so
a pop up, because content scripts for this example
is not executed on hidden
iFrame, so I have to open a pop-up.
When that pop-up opens
I'm sending a postMessage
to the web extension
because it is not checking the origin.
I looked into the manifest of the web extension
to learn „Okay, what do I have to use as a payload?”
and the data name is, for example, something it expects
and then I can have the
cross-site scripting payload after it because,
for example, it's using
a path as innerHTML, so I can
run JavaScript on the web extension.
Afterwards the pop-up is closing
and the user doesn't know
that she got attacked.
What you can do?
The API itself specifies that it's
the developer's responsibility to check
the origin of attribute of any messages
received to ensure that they only accept messages
from origins they expect.
Again, be careful with regular expressions. Why?
For example, I'm checking the origin
with this first line.
And the wildcard is not considered, so the dot is a wildcard
and I could register as an hacker a website
wwwXecample.com
which would pass the regular expression
and I would be allowed to run code.
or the anchoring is not expected
so I just check for the second example
but I can as attacker have that as
a subdomain for my vulnerable website.
Or I'm using event.origin, so that is
what we need to check and just check for a substring and
again I can have a longer string, for example
www.example.com.attacker.com
which is then also
considered valid.
and I can execute arbitrary code.
The requirement for validating origin holds true
for iFrames and Web Extensions like we saw.
I think also for Web Sockets because
they are not checking the origin as well
but accepting all incoming requests
as far as I know.
If you are reading the exploiting
xdLocalStorage article I linked
above you will see some of the code snippets
are also attacking the localStorage
where you normally put more code snippets in
and just submit a post message with a key that
then looks up in the localStorage.
If you can manipulate that you
might also sneak in code.
I'm following the blog article from
Wladimir Palant, who is, for example,
the author of AdBlock,
who regularly posts some ideas
on how he discovered vulnerabilities in web extensions.
OWASP which we learned about in the beginning
is also providing cheat sheets, for example
on HTML5 Security which is
really helpful if you are, for example, authoring a web extension.
Next one: ReDOS attacks
ReDOS stands for Regular Expression Denial of Service.
I linked a YouTube video which explains what is meant.
I discovered that one on Twitter
and added some remarks which i consider
that helpful that I've brought with me here.
So what I would use from my own experiences is
Don't use a regular expression if you can.
Instead use, for example, string methods
startsWith() or endsWith() or
use some functional programming and if you
don't have regular expression you are just not
vulnerable to ReDOS attacks.
Second thing i would recommend is to limit the input size.
The length attribute is comparably
easy to check and
if you error out you don't fall
prey to such attacks so I can't
send you, for example, Hamlet
as a string and have your regular expression work.
If you are using regular expression
perhaps you want to first have a quick check
on it. For example, if you checking
an email string and it does not contain an @
symbol, your regular expression will fail
anyway but you have a quick check before.
If you're using regular expressions
anchoring it, so that is ^, $ for start and end
or \b for word boundary.
That can help you a lot.
Like we saw before with the origin checks.
If you really have to use a regular expression
try to break it up into smaller parts that checks
part of it instead of having one giant
regular expression to rule them all.
Because regular expressions are hard to understand
and if you are having a complex regular expression
nobody will dare touch it
and that can't help.
One thing I've learned from an article of CloudFlare
in 2019 they had a CPU exhaustion so a
regular expression denial of service
because they used Lua instead of
what they're using now: Rust.
So there are some different engines
for regular expressions.
If you can pick your one wisely.
With that I finished with the
examples for the code.
If you have questions, again, at the end of the talk.
Next thing is tooling.
Again, I'm making some assumptions.
For example, I assume you're using ESLint.
You're using VS Code.
It might be possible to
have it on other editors as well
but it's more legwork and VS Code is
popular so I am assuming you are using that one.
You're installing your dependencies using npm yarn.
And you have contact to the backend team,
for generating the HTML
or configuring the server or using
Express.js or Fastify yourself.
What tools are we looking into shortly?
First is ESLint.
Then I'll suggest VS Code extensions you can use.
I'll give some recommendations what you can do
if you're installing packages.
I suggest some things you can do
to test at least test some data to get
idea of „Okay, those are
known bad strings”.
and I suggest to define a
Content Security Policy.
Again, you can jump straight
to a specific subject on the slides
and skip others.
So, first thing: ESLint
I can recommend those two extensions.
One is for Node.js security rules
which check for patterns
that a known to become vulnerable.
The other thing is about trojan source
which we learned about last year
which uses the bidirectional feature of Unicode.
And you can see some
which looks like a code comment but
is then executed as code.
And the plugin checks for those Unicode things.
Next things are Visual Studio Code extensions.
Again, ESLint. So I assume
you're using ESLint so you can have a plugin
which allows you to lint while you're writing
so you don't make mistakes in the first place.
The second is about Gremlins
which, for example, checks for invisible
Unicode characters which might be helpful as well.
And the third is Snyk Vulnerability Scanner
I formerly had the Vuln Cost extension here
but that get folded into this extension and
it checks for known vulnerabilities in your dependencies
which is also helpful that you know
„Okay, hey maybe I should use a
newer version”. Which leads us to
Package installation.
I often use npm
and I only recently switched to yarn, so I start with npm here.
When I install packages I would normally use
„npm install” which is bad.
Why? Because I can have a
different version than my colleagues.
Or I can run
post-install scripts which are bad because
they can have arbitrary code execution.
So i better use the lock-files
via „npm ci”
because those allow for deterministic builds.
--ignore-scripts will mentioned stop the post-install scripts.
It might not work with all dependencies
but those lifecycle scripts are
possible attack vector where you can have malicious code
and you should avoid it if it is possible.
For yarn it looks similar.
Normally you would use „yarn”
which then again not checks the lock-files.
So better is is to use yarn with a „--frozen-lockfile” flag.
Or even better to
stop the post-install scripts with
the „--ignore-scripts” flag.
Test data.
If you have quality assurance
colleagues in your team, this is
now a good chance to hug them from me.
Because those things are
something you could have in
the quality assurance department.
The first thing is the Big List of Naughty Strings
which is a JSON or
list of text strings which
have strings are known to cause problems
and you can then have a script which
fires them to your forms,
to your URL search parameters,
to your API endpoints and things like that
to see whether something breaks.
There is, for example, in the repo
a GIF which shows
how they broke, for example,
Twitter compose message
form. The other thing is for interactive
testing called Bug Magnet which
is a web extension for all popular web browsers.
Where you can then right-click into an input,
for example, on the form
and pick different values, for example,
payloads, which causes cross-site scripting or
SQL injection or what else.
Or even large inputs so you can
see whether something breaks there as well.
Next thing is Content Security Policy.
Like mentioned before
you would say
„Okay, these are the origins
where I expect scripts
or images or iFrames
or what else to be loaded from.
There is a way to get reports on
violations of this policy
and it's sometimes a bit
hard to generate it
to know „Okay what… how is the
syntax for it?”
There, laboratory might help you.
Word of warning here:
In my experiences you might have to
communicate more.
Because you might have an
Tag Management Plugin
for marketing which then loads code
from other sources and that would be
blocked as well, so you learn more
about where you're loading code from.
The Content Security Policy here is a
link to Snyk article which explains
why you should have one in the first place.
Okay, cool. With this
I conclude the section
for what you can do as a developer.
But normally you are not only working
as a developer but in a team.
So we're looking:
„Okay, what can you do within a team?”
which is mostly about the project.
This section's a bit shorter
that what we had before because I'm running
a bit out of time.
Again, I listed some efforts you can use.
For example, on a project,
with a culture or what you can do with
regards to the software architecture,
to Auth - so authentication and authorisation -
what you can do when it comes to testing
and some paperwork which might be helpful.
The culture.
First thing I would recommend is to
implement a no-blame culture.
That means if something goes wrong
it's *not* the *fault* of a *single person*
but treated as a process failure.
So look into what can be done to
prevent that from happening again.
That's also known, for example, as post mortem.
You can publish it or not.
I would recommend to publish it because
we are learning here as an industry together.
And it's best practice in the industry
to publish them.
If you're not publishing it, please make it
available internally, so other teams can learn from it.
Second thing is
Software architecture which is
something I learned to love
the more code I write.
The 12-Factor App is meant for microservices
but is has some useful ideas which
you might want to copy into your project, so I
recommend to take a look at it.
As we mentioned before
Input validation and output sanitation is important.
Hexagonal architecture and
Domain-driven design are meant for object oriented programming
but they give you some
framework where you could put
code into, so you have only to check it in
one place instead of all over
your codebase.
Immutable datastructures has
a lot of positive aspects.
So again, I brought
Immutable.js and immer here for you.
And what you also
should looked into is AuthN and AuthZ which stand
for authentication and authorization
which is too long to write.
Next thing I would recommend
is to separate the customer data or user data from
the app ones because the user data
is more valuable and
it should be protected stricter.
So you don't want to loose customer
data if you get breached
if you can avoid it. And with separating I
mean a different database not a table on the same database.
What is also helpful is to
track the flow of data.
So if you are using a microservice you most
likely having some HTTP headers
that tracks you and allows for monitoring.
If not, at least have some architecture diagram
like „Okay, this data comes in here and it flows there and
it gets transformed there and so on.
So it allows you to have an
bird's perspective on your code
and try to decide: „okay we need
to add more protections on this place or not.”
Next thing is Auth.
Auth is mostly authorisation or authentication.
It gets a bit blurry here, so I'm
sloppy a bit myself.
What you could do is to look into
magic links or other passwordless login
methods. Magic link is
you get an one time link per mail.
You click it and you're logged in.
If you don't like that one
at least look into One-Time Passwords
so allow someone to protect
not only the password
for login but also you use a Yubikey
Yubikey, an authorisation app or
a SMS to have a second
measure of login, so
even if the password gets cracked
by someone it's not lost
because it needs a second input.
You might use already JSON web tokens.
I would encourage you to
learn more about the best practices
- that is this article -
Because there are things you
can do wrong there as well.
Apply consistent auth strategies.
I recall an article where npm
had two microservices which
used different strategies so if you
carefully crafted package.json you could
back then inject
malicious packages which got
authorised on both things, so it was fine.
If you're using
token based authentication
better have a long time limit for
the refresh token because that
one is revocable. So if
you find „Okay, here was an attack”
you can revoke that token but the session
tokens are not revocable
so they should have a short limit
and get refreshed with the other token.
And if you
finding a session token and
it's past the time to live
it should be considered as expired
and a new one should be requested.
I mentioned it before: don't store secrets
on the file system. Instead
use a Vault. That also applies
to environment variables
which might have API keys as well.
Please, use a vault.
Most cloud providers
offer you a service for that one.
You have different grades of security for
different privileges. For example, if you
have a developer or operator
which has the „keys to the kingdom”
they should be
complying to higher
levels of security.
Otherwise you just bothering your
users and they won't use your service
which is also not helpful.
I have some ideas what you
can do to testing for security.
The first thing is about
a SAST, a Static Application Security Testing.
which scans your code
without executing it
and flags known vulnerabilities or patterns that
can be exploited.
The second thing I can think of is
fuzzing your code. I'm not sure
how much you can do that with JavaScript
so if you know about it, please let me know!
Which is like „Okay, I'm trying
to mutate inputs and see whether
something crashes.
If you're running Express or
Fastify there is extensions or
middlewares you can use. For example Helmet
for Express which sets HTTP security headers
which protects you
which protects you, for example, from clickjacking
or from cross-site scripting, so
so you're activating some security measures
in the browser. Fastify
has similar middlewares
so go look for it.
Snyk wrote up some
security best practice
which I can recommend.
We saw already some of them before.
And there is an
CLI tool which you can
use for scanning for vulnerable websites.
So the idea is if you're
hotlinking, for example, from unpkg
or other CDNs
and they're pointing to
a vulnerable version
this tool would tell you about it.
Yeah, paperwork!
Something we all love, doesn't we?
Something I don't see often is
maintaining a Software Bill of Materials.
That is a list of dependencies and
dependencies of dependencies that
you're using. Which can
be helpful, for example, for license compliance
but also to know„ Okay, we have
some vulnerable third party
dependencies. What can we do about it?
Something I learned about
to love is
ADRs, architectural decision records.
If you're making some decisions
on your software architecture write down:
What you decided?
What was the problem you tried to solve?
What alternatives you have considered?
And what implications your decisions have?
because if you are in the future
looking back: „Okay, why did we did it
that way you have an record about
it and can say: „Okay, now the
context has changed and now the
alternative might be more preferable
and you have listed alternatives.
If you get attacked, there is
a high chance that you will panic.
The best is to thinking about
the emergency before it happens.
Which can happen, for example, with runbooks.
I listened to an episode
of the We Hack Purple podcast and
found out about the
Magento Incident Response Plan
which lists „Okay, who should be informed?
Who should come together? And what things to do.
If you create such a runbook, please print it out.
because if your machine gets encrypted
by a ransomware your runbook won't help you
so please use some dead wood here.
If you get attacked which
it's also helpful to think about
how do we want to inform
our customers or users. That
could be, for example, via status page
or via Social Media channels.
So, next session: What can you do as a company?
Again if you're using an
or a part of a NGO
that might be helpful for you as well.
There's a chance that within
your employees there is some which are
interested in security. Make them
Security Champions, so
Let them share their interest with
other teams and educate them.
We had that two-factor authentification
with a One-Time Password before.
Again, it might be good idea to
have it for developers or operators.
Or other peoples with high privileges.
You're likely using a
password based authentication.
and if you are a company I would
recommend you to check those passwords against the
Have I Been Pwned database
which costs some API fee
but is worth it.
Do backups. Do backups regularly. And
check whether your backups are still working
because if you have a corrupt backup it
won't help you either.
Something you most likely doing already
monitor your data network
traffic and look into a
intrusion detection system so you are learning
about when you get attacked.
And the last thing here is
Chaos Engineering, that is
turning off certain systems and check what
happens. So you're more resilient
in case of something goes down.
There are security professionals
that can write an audit for you.
They're sometimes called
penetration tester or consultants or something.
I would love to see those security audits to be
published because for me
it means to earn some trust from
the developer community.
You're most likely having
different service providers.
Create or make some subscribe a
Service Level Agreement, so that
also means the marketing service providers, so
they make some promises
what they want to do if their service go down.
There's the possibility to have
a bug bounty program so you are
rewarding people for
notifying you about security vulnerabilities
they found, but you can also
outline: „Okay, we want you to
only look into these services but not the others.”
So, if you can't do that
please at least provide an e-mail address
for reporting security issues or
some contact form and also: process them!
You can have those, for example, in
a security.txt file which is
under a .well-known directory.
Security is a process.
and it's not a single thing
and you're done, but it's also an
security in depth or defense in depth
so you have different layers of security.
If one protection
falls, you might have still
others that will guard you.
You're running an office and
I recommend you to segment your network.
That is
if there is some
rooms where visitors can enter
segments those from other things
from your internal network.
Please, also scan for open ports
which indicates: „Okay,
here we have services running”, which
listen to anybody who's talking to them.
Close them if you don't need them
because those can be
attack vectors to your network
and an attacker can
go into other places from there.
If you get an
security notification
by a researcher handle those
disclosures responsibly.
I linked you to some
ideas where you can look into.
Security is also often
something you can look into:
„Okay, how much damage would
be caused and how likely is it to happen?”
That's also called Threat Modelling.
I link you to that so you
have different attack vectors
or types of attacks, for example script kiddies
which just scan
„Okay, is something happening here?”
Or you have Advanced Penetration Threat
which is more likely to attack especially you and not just
anybody on the Internet.
If you're allowing
to work from home look
into VPNs, so
virtual private networks
for your distributed teams because there
were instances where someone attacked
someone via SSH on the -
from home into the office because the network at
home is most likely not as secure as your office.
If you have security certificates
check them for expiration dates.
Or check whether they're
revoked because
that can lead to errors as well and
expired certificate is not trustworthy.
Especially as
a company you're most likely
following some ISO norms,
for example the 27001.
For security, that's more focussed on processes
but worth to look into as well.
As mentioned before
with the typo squatting,
that can also happen to domains.
If you register
domains with
small typos in them and redirect
them to the legitimate domain
you're preventing
your visitors from getting attacked via domain squatting.
There's something called boss fraud mail where you
receive an e-mail
which seems to come from your superior
but isn't and most likely
like transfer some money
or click this link and your employees
get attacked so raise some awareness
about them.
It happens all the time that
API keys or environments are checked in
into your codebase so scan
your codebases for some
security secrets.
There are tools for it that you can use.
If you want to get
hands-on experience OWASP
is also offering an service
which is called Juice Shop which
you can use for training and they have other
additional services you can use for
training so check some them out.
Last thing is a bit short because
it mostly subsumize all we had seen before.
So don't be discouraged.
I only have one item here which is:
Encourage the use of SECURITY.md.
Which outlines: „Okay,
I have an open source package. How do
I want to be informed in case of
something's vulnerable here?”
If you have additional ideas
please, let me know.
What you learned here
is also worth to report against open source
maintainers. Again, via a
secure channel.
So we can all stay together safely.
That was a lot!
So you might be wondering what
where to go now?
Let's define some next best actions!
I would recommend to set up Snyk
which becomes an industry standard. You can see it,
for example, in Docker.
Or as an audit tool.
I learned a lot about the We Hack Purple podcast, so
I can highly recommend that one as well.
Troy Hunt is the
developer behind Have I Been Pwned.
So he's having a podcast and reporting about it
again as well.
Subscribe to that podcast as well!
Or/and study
the OWASP cheat sheet series
which goes into different subjects.
My presentation wouldn't be possible
without other creative folks, so I
want to shout out and link to where
I found the images.
And today
we learned about a lot of stuff.
So I tried to summarize it here.
If you're using the slides yourself this list
might be a bit different, so
try to figure out how that works.
and with that I want to thank you and shout out to
reveal because HTML5 presentations rulez!
My presentation is licensed
under a Creative Commons Attribution license and I link
you to the code repository in case you
want to tweak it yourself.
Thank you.