initial commit
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/nkode-landing-page.iml" filepath="$PROJECT_DIR$/.idea/nkode-landing-page.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/nkode-landing-page.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
BIN
assets/advanced_settings.png
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
assets/baseball.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
assets/confirm_nkode.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
assets/ladybug.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
40
assets/lightmodenkode.svg
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="79.858757mm"
|
||||
height="19.359062mm"
|
||||
viewBox="0 0 79.858757 19.359062"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="g31"
|
||||
transform="translate(-15.907308,-105.79601)"><path
|
||||
id="path27"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
d="m 53.401267,110.12347 a 7.5,7.5 0 0 0 -7.499801,7.4998 7.5,7.5 0 0 0 7.499801,7.50031 7.5,7.5 0 0 0 7.500317,-7.50031 7.5,7.5 0 0 0 -7.500317,-7.4998 z m -0.04444,3.36982 a 3.8236849,4.1434846 0 0 1 3.824056,4.14393 3.8236849,4.1434846 0 0 1 -3.824056,4.14342 3.8236849,4.1434846 0 0 1 -3.823539,-4.14342 3.8236849,4.1434846 0 0 1 3.823539,-4.14393 z" /><path
|
||||
id="path28"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
d="m 74.580952,105.79603 c -0.0065,0 -0.01188,0.005 -0.01188,0.0119 v 5.35988 a 7.5,7.5 0 0 0 -3.730005,-1.01285 7.5,7.5 0 0 0 -7.499801,7.4998 7.5,7.5 0 0 0 7.499801,7.50031 7.5,7.5 0 0 0 7.500317,-7.50031 7.5,7.5 0 0 0 -0.04393,-0.61444 c 0.0059,-6.1e-4 0.01085,-0.005 0.01085,-0.0114 v -11.22101 c 0,-0.006 -0.0054,-0.0119 -0.01189,-0.0119 z m -3.786332,7.72873 a 3.8236849,4.1434846 0 0 1 3.774447,3.49126 v 0.0129 c 0,0.003 0.0014,0.005 0.0031,0.007 a 3.8236849,4.1434846 0 0 1 0.04651,0.63252 3.8236849,4.1434846 0 0 1 -3.824056,4.14342 3.8236849,4.1434846 0 0 1 -3.823539,-4.14342 3.8236849,4.1434846 0 0 1 3.823539,-4.14393 z" /><path
|
||||
id="path29"
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
d="m 88.26568,110.14103 a 7.5,7.5 0 0 0 -7.499799,7.4998 7.5,7.5 0 0 0 7.499799,7.50031 7.5,7.5 0 0 0 6.30711,-3.44526 l -3.30884,-1.56167 a 3.8236849,4.1434846 0 0 1 -3.04271,1.66399 3.8236849,4.1434846 0 0 1 -3.68091,-3.08974 h 7.36286 a 3.8236849,4.1434846 0 0 1 -10e-4,0.004 l 3.78737,-0.01 a 7.5,7.5 0 0 0 0.0765,-1.06143 7.5,7.5 0 0 0 -7.50032,-7.4998 z m -0.0444,3.36982 a 3.8236849,4.1434846 0 0 1 3.42718,2.30528 h -6.83472 a 3.8236849,4.1434846 0 0 1 3.40754,-2.30528 z" /><path
|
||||
id="path30"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
d="m 31.445868,105.96392 v 19.18746 h 3.765145 v -7.02076 l 0.51418,-0.63873 5.338692,7.66259 h 4.588351 l -7.466728,-10.71821 6.821289,-8.47235 h -4.83433 l -4.961454,6.16293 v -6.16293 z" /><text
|
||||
xml:space="preserve"
|
||||
style="font-size:1.91816px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
x="86.808289"
|
||||
y="115.94128"
|
||||
id="text30"
|
||||
transform="scale(1.0595671,0.94378167)"><tspan
|
||||
id="tspan30"
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0"
|
||||
x="86.808289"
|
||||
y="115.94128">TM</tspan></text><path
|
||||
id="path31"
|
||||
style="display:inline;fill:#f16130;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0"
|
||||
d="m 22.49607,109.77016 a 6.548449,6.9453125 0 0 0 -6.583061,6.78201 h -0.0057 v 0.077 8.48682 h 3.835942 v -9.07128 a 2.7131952,2.3977864 0 0 1 -0.0036,-0.0403 2.7131952,2.3977864 0 0 1 0.0036,-0.0408 v -0.0393 c 0,-0.003 0.0011,-0.006 0.0036,-0.008 a 2.7131952,2.3977864 0 0 1 2.706295,-2.30994 v -5.1e-4 a 2.7131952,2.3977864 0 0 1 2.710946,2.31562 c 2.47e-4,10e-4 0.001,0.002 0.001,0.003 v 0.0403 a 2.7131952,2.3977864 0 0 1 10e-4,0.0398 2.7131952,2.3977864 0 0 1 -10e-4,0.0129 v 9.12968 h 3.835942 v -8.43153 h 0.0026 a 6.548449,6.9453125 0 0 0 -6.507613,-6.94531 z" /></g></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
BIN
assets/logged_in.png
Normal file
|
After Width: | Height: | Size: 278 KiB |
BIN
assets/login1.png
Normal file
|
After Width: | Height: | Size: 247 KiB |
BIN
assets/login2.png
Normal file
|
After Width: | Height: | Size: 247 KiB |
BIN
assets/n.png
Normal file
|
After Width: | Height: | Size: 963 B |
BIN
assets/pizza.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
assets/set_nkode.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
assets/signup.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
assets/wine.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
290
index.html
Normal file
@@ -0,0 +1,290 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="nKode Authentication Evolved">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>nKode</title>
|
||||
<link rel="icon" type="image/png" href="assets/n.png"/>
|
||||
<link rel="apple-touch-icon" href="assets/n.png">
|
||||
|
||||
<!-- Tailwind CSS CDN -->
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="bg-white">
|
||||
<header class="absolute inset-x-0 top-0 z-50">
|
||||
<nav class="fixed top-0 w-full z-50 flex items-center justify-between p-6 px-8 bg-white" aria-label="Global">
|
||||
<div class="flex flex-1">
|
||||
<a href="#" class="-m-1.5 p-1.5">
|
||||
<img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt="">
|
||||
</a>
|
||||
</div>
|
||||
<div class="md:flex md:hidden">
|
||||
<button id="open-menu" type="button" class="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-400">
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center gap-x-12">
|
||||
<div class="flex gap-x-6 text-lg font-semibold leading-6 text-black">
|
||||
<a href="#create-an-nkode">Create an nKode</a>
|
||||
<a href="#how-nkode-works">How nKode Works</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<button class="bg-orange-500 text-white py-2 px-4 rounded-full hover:bg-orange-600 transition duration-200 text-sm sm:text-lg">
|
||||
<a href="https://www.nkode.tech">Try nKode <span aria-hidden="true">→</span></a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Mobile menu, show/hide based on menu open state. -->
|
||||
<div id="mobile-menu" class="md:hidden hidden" role="dialog" aria-modal="true">
|
||||
<!-- Background backdrop, show/hide based on slide-over state. -->
|
||||
<div class="fixed inset-0 z-50"></div>
|
||||
<div class="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 md:max-w-sm md:ring-1 md:ring-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<a href="#" class="-m-1.5 p-1.5">
|
||||
<span class="sr-only">Your Company</span>
|
||||
<img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt="">
|
||||
</a>
|
||||
<button id="close-menu" type="button" class="-m-2.5 rounded-md p-2.5 text-black">
|
||||
<span class="sr-only">Close menu</span>
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-6 flow-root">
|
||||
<div class="-my-6 divide-y divide-white/25">
|
||||
<div class="space-y-2 py-6">
|
||||
<a href="#create-an-nkode" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-black hover:bg-gray-200 mobile-nav">Create an nKode</a>
|
||||
<a href="#how-nkode-works" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-black hover:bg-gray-200 mobile-nav" >How nKode Works</a>
|
||||
<a href="#faq" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-black hover:bg-gray-200 mobile-nav">FAQ</a>
|
||||
</div>
|
||||
|
||||
<button class="bg-orange-500 text-white py-2 px-4 rounded-full hover:bg-orange-600 transition duration-200 text-sm sm:text-large">
|
||||
<a href="https://www.nkode.tech">Try nKode <span aria-hidden="true">→</span></a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div class="mx-auto lg:max-w-3xl sm:max-w-xl max-w-sm mb-8">
|
||||
<h2 class="text-4xl tracking-tight text-black py-24">
|
||||
<span class="text-orange-600 font-semibold">n</span>Kode is <span class="font-semibold">easier</span> to remember and more <span class="font-semibold">secure</span> than a password
|
||||
</h2>
|
||||
<section id="create-an-nkode" class="scroll-mt-24">
|
||||
<h3 class="text-4xl">Create an nKode</h3>
|
||||
<p class="text-2xl mt-4">1. Enter your email</p>
|
||||
<img class="w-3/4 mx-auto mt-8" src="assets/signup.png">
|
||||
<h4 class="text-2xl">2. Set your nKode</h4>
|
||||
<p class="mt-8 text-xl">Select 4 icons that will be your nKode. Icons can not be repeated.</p>
|
||||
<p class="text-xl">Example: pizza, ladybug, wine, baseball</p>
|
||||
<div class="mt-8 flex flex-row">
|
||||
<img class="w-16" src="assets/pizza.png">
|
||||
<img class="w-16" src="assets/ladybug.png">
|
||||
<img class="w-16" src="assets/wine.png">
|
||||
<img class="w-16" src="assets/baseball.png">
|
||||
</div>
|
||||
<img class="w-3/4 mx-auto mt-8" src="assets/set_nkode.png">
|
||||
|
||||
<h4 class="text-2xl">3. Confirm your nKode</h4>
|
||||
<p class="mt-8 text-xl">Confirm your nKode by reentering it.</p>
|
||||
<img class="w-3/4 mx-auto mt-8" src="assets/confirm_nkode.png">
|
||||
|
||||
<h4 class="text-2xl">4. Login with nKode</h4>
|
||||
<p class="mt-8 text-xl">Once you've confirmed, the login screen will open. Enter your nKode to login</p>
|
||||
<img class="w-3/4 mx-auto mt-8" src="assets/login1.png">
|
||||
|
||||
</section>
|
||||
<section id="how-nkode-works" class="scroll-mt-24">
|
||||
<h3 class="text-4xl mt-8">How nKode Works</h3>
|
||||
<h4 class="text-2xl mt-4">Interface Settings</h4>
|
||||
<p>
|
||||
Your nKode interface is configurable.
|
||||
Under advanced settings, you can change the number of keys and the number of attributes per key.
|
||||
(from this point forward, this document will use the term attribute instead of icon)
|
||||
</p>
|
||||
<img class="w-3/4 mx-auto mt-8" src="assets/advanced_settings.png">
|
||||
<h4 class="text-2xl mt-4">Account Creation</h4>
|
||||
<p>
|
||||
The server is able to deduce your nKode from two entries.
|
||||
Notice how, in the set and confirm images below, no attribute in the set nKode interface share a key with any other attribute in the confirm.
|
||||
This is called an attribute dispersion.
|
||||
</p>
|
||||
<div class="flex flex-row">
|
||||
<img class="w-1/2 mx-auto mt-8" src="assets/set_nkode.png">
|
||||
<img class="w-1/2 mx-auto mt-8" src="assets/confirm_nkode.png">
|
||||
</div>
|
||||
<h4 class="text-2xl mt-4">Attribute Dispersion</h4>
|
||||
<p>
|
||||
The login interface looks different than the set and confirm interfaces.
|
||||
It has three more attributes per key.
|
||||
A dispersion is possible if the number of attributes per key is less than or equal to the total number of keys.
|
||||
Since the login interface has more attributes per key than keys, we call this a dispersion-resistant interface.
|
||||
If a malicious actor steals your interface, they can use your interface to phish for your nKode.
|
||||
If the login interface was dispersable, an attack might go like this:
|
||||
</p>
|
||||
|
||||
<ol class="list-decimal list-inside mt-2 space-y-2">
|
||||
<li>You click a malicious link from your email or text saying you need to authorize USPS to send you a package (or whatever the latest scam is today).</li>
|
||||
<li>You're redirected to a site with your nKode interface requesting authorization with your nKode.</li>
|
||||
<li>You enter your nKode, but you're informed you entered the wrong nKode.</li>
|
||||
<li>The attacker disperses your interface and requests you enter your nKode again.</li>
|
||||
<li>You enter it again, and your nKode is stolen.</li>
|
||||
</ol>
|
||||
<p>
|
||||
The greater the difference between the number of attributes per key and the number of keys, the greater the dispersion resistance, which comes with trade-offs.
|
||||
If there are too few keys, it becomes easier to randomly enter keys and accidentally get into your account without actually knowing your nKode.
|
||||
If you increase the number of keys without increasing the number of attributes per key, your interface becomes more dispersable.
|
||||
If you have too many attributes and keys, the interface is too busy, which makes it challenging to find your attributes.
|
||||
</p>
|
||||
<h4 class="text-2xl mt-4">Server-Side Attributes</h4>
|
||||
<p>
|
||||
A traditional password is composed of ASCII and sometimes Unicode characters.
|
||||
These are salted, hash, and stored in a database.
|
||||
nKode is similar.
|
||||
An unsigned 64-bit integer represents every attribute, though it can be a byte array of any size.
|
||||
These server-side attributes can be rotated daily, weekly, or any other cadence desired.
|
||||
Here's how it works:
|
||||
</p>
|
||||
<ol class="list-decimal list-inside mt-2 space-y-2">
|
||||
<li>An administrator or cron job starts the server-side attribute renewal.</li>
|
||||
<li>The server-side attributes are rotated, and an intermediate transformation is applied to the user's server-side keys</li>
|
||||
<li>Has a successful login, and the user's keys, salt, and hash are all replaced.</li>
|
||||
</ol>
|
||||
|
||||
<h4 class="text-2xl mt-4">Login</h4>
|
||||
<p>
|
||||
Every time you log in, your attributes are randomly shuffled.
|
||||
Attributes don't move to arbitrary locations within the key; attributes are a part of a set.
|
||||
You can identify the set by its position within the key.
|
||||
In the example below, you can see some attributes haven't moved, some moved to other keys as a group, and some moved to different keys alone.
|
||||
</p>
|
||||
<div class="flex flex-row">
|
||||
<img class="w-1/2 mx-auto mt-8" src="assets/login1.png">
|
||||
<img class="w-1/2 mx-auto mt-8" src="assets/login2.png">
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-8">
|
||||
<button class="bg-orange-500 text-white py-2 px-4 rounded-full hover:bg-orange-600 transition duration-200 text-sm sm:text-lg">
|
||||
<a href="https://www.nkode.tech">Try nKode <span aria-hidden="true">→</span></a>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<section class="scroll-mt-24" id="faq">
|
||||
|
||||
<h3 class="text-4xl mt-8">FAQ</h3>
|
||||
<h4 class="text-2xl mt-4">How does nKode defend against common attacks?</h4>
|
||||
<p>
|
||||
At the time of this writing, nKode is only a demo web application.
|
||||
Ideally, all nKode authentication is done through a mobile application.
|
||||
A mobile application can make nKode more secure by requiring passkeys and biometric authentication to get the nKode interface.
|
||||
This makes it very difficult to steal or use your nKode.
|
||||
</p>
|
||||
<h5 class="text-xl mt-4">1. MFA Prompt Bombing</h5>
|
||||
<p>
|
||||
Many MFA solutions try to make login as frictionless as possible.
|
||||
This kind of frictionless system makes prompt bombing a viable attack.
|
||||
Adding some friction to the login process, nKode mitigates prompt bombing, not so much that it's too time-consuming but not so little that a person could mindlessly accept an MFA request or accidentally fat-finger and accept an authentication request by mistake.
|
||||
The easiest attack vector for a nKode MFA bomb is session hijacking.
|
||||
Stealing nKode is more complex, making it an unlikely attack vector.
|
||||
nKode can mitigate this by adding a button, "I did not make this MFA request."
|
||||
The server can block fraudulent requests if the user presses this button.
|
||||
Otherwise, the user enters their nKode.
|
||||
Since a user has to look for their nKode, it prevents them from quickly typing in a passcode without thinking, giving them a chance to reconsider their decision. </p>
|
||||
<h5 class="text-xl mt-4">2. Service Desk Social Engineering: Scattered Spider</h5>
|
||||
<p>
|
||||
An nKode interface is made from any visual attribute.
|
||||
To make this more concrete, take a look at <a class="text-orange-600 underline" href="https://www.flaticon.com/search?word=abstract">Flaticon</a>.
|
||||
If every employee at the service desk has a randomly generated interface from abstract visual attributes like those found on Flaticon, an employee would have difficulty explaining their nKode.
|
||||
Moreover, this interface can be further protected with a 2FA keycard so only the employee can render their interface.
|
||||
For an attacker to get a target's nKode, they'd have to be with the target, and the targeted employee would have to point to the attributes on their screen since they're difficult to describe in words.
|
||||
The attacker must also steal the employee's 2FA keycard to render the login screen.
|
||||
</p>
|
||||
<h5 class="text-xl mt-4">3. Session Hijacking</h5>
|
||||
<p>
|
||||
To mitigate the damage from session hijacking, jwts or session tokens can be made read-only by default.
|
||||
When a user makes a sensitive write transaction, such as updating personal information or sending money, they must enter an nKode.
|
||||
</p>
|
||||
<h5 class="text-xl mt-4">3. Sim Swaps</h5>
|
||||
<p>
|
||||
If a user's device is damaged, lost, or stolen, they'll need a way to establish authentication keys with the new device without using the old device.
|
||||
|
||||
We are building two types of nKode offerings:
|
||||
</p>
|
||||
|
||||
<ol class="list-decimal list-inside mt-2 space-y-2">
|
||||
<li>Sign in with nKode is a B2C service nKode SSO is a B2B service.</li>
|
||||
<li>The solutions below will use the terms customers and mobile carriers, but these are interchangeable with employee and service desk.</li>
|
||||
</ol>
|
||||
<h6 class="mt-2 font-semibold">Temporary nKode Portal</h6>
|
||||
<p>
|
||||
The customer calls their mobile carrier to activate the sim for a new phone without the old device.
|
||||
The customer provides information like their name, dob, and ssn and answers security questions.
|
||||
The carrier will then activate a temporary web portal where the customer enters their nKode to authenticate the request.
|
||||
When the portal is activated, the customer with the authenticated phone will receive a notification on their nKode app alerting them to the activated portal.
|
||||
If the user has their device, they can close the portal by entering their nKode.
|
||||
The portal should only be opened if the user can't use their device to activate the new sim.
|
||||
If their phone is stolen, the thief can't stop this process if they don't know the user's nKode.
|
||||
Customers who want higher security can specify a wait period before a replacement device is activated.
|
||||
If the portal isn't closed before the end of this waiting period, the sim swap or new device enrollment can proceed.
|
||||
</p>
|
||||
<h6 class="mt-2 font-semibold">Authentication nKode Delegates</h6>
|
||||
<p>
|
||||
This solution is only suitable for Sign in with nKode.
|
||||
After a user has installed the nKode app and created their account, they can delegate authentication to trusted friends and family who also have a Sign in with nKode for device recovery.
|
||||
If a user delegates authentication recovery to a few trusted people and they've lost their device, the user can go to any of their trusted delegates to enroll a new device through their delegate's nKode app.
|
||||
Users can configure account delegation such that any authentication can be completed with only one delegate or require more than one delegate to authenticate on the user's behalf.
|
||||
Once a device has been enrolled, the carrier can rely on nKode to authenticate a sim swap.
|
||||
</p>
|
||||
|
||||
<h5 class="text-xl mt-4">4. Redline Stealer</h5>
|
||||
<p>
|
||||
Ideally, all nKode authentication goes through the mobile app. If authentication is done on a laptop, an attacker can steal a user's nKode after watching several nKode entries depending on the number of keys and attributes per key. This number can vary as the number of attributes and keys change.
|
||||
</p>
|
||||
<h5 class="text-xl mt-4">5. Exploiting SSO SAML</h5>
|
||||
<p>
|
||||
If an attacker finds a way to steal a user's nKode, they still need the user's device. The user's device contains their passkeys and biometrics. Without it, the adversary won't be able to authenticate.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Add your JavaScript just before the closing body tag -->
|
||||
<script>
|
||||
// Get the elements from the DOM
|
||||
const openMenuButton = document.getElementById('open-menu');
|
||||
const closeMenuButton = document.getElementById('close-menu');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
const mobileNavLinks = document.getElementsByClassName('mobile-nav');
|
||||
// Function to show the mobile menu
|
||||
openMenuButton.addEventListener('click', () => {
|
||||
mobileMenu.classList.remove('hidden');
|
||||
});
|
||||
|
||||
// Function to hide the mobile menu
|
||||
closeMenuButton.addEventListener('click', () => {
|
||||
mobileMenu.classList.add('hidden');
|
||||
});
|
||||
|
||||
Array.from(mobileNavLinks).forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
mobileMenu.classList.add('hidden');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
69
nginx.config
Normal file
@@ -0,0 +1,69 @@
|
||||
# Redirect all traffic from www.nkode.tech to nkode.tech
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.nkode.tech;
|
||||
|
||||
return 301 https://nkode.tech$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name www.nkode.tech;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/nkode.tech/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/nkode.tech/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/nkode.tech/chain.pem;
|
||||
|
||||
return 301 https://nkode.tech$request_uri;
|
||||
}
|
||||
|
||||
# Main server block for nkode.tech
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name nkode.tech;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/nkode.tech/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/nkode.tech/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/nkode.tech/chain.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade";
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
root /var/www/webapp;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
root /var/www/webapp;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /var/www/webapp;
|
||||
}
|
||||
}
|
||||
|
||||
# Redirect HTTP to HTTPS for nkode.tech
|
||||
server {
|
||||
listen 80;
|
||||
server_name nkode.tech;
|
||||
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||