update landing page

This commit is contained in:
2024-10-30 11:00:21 -05:00
parent e164c91990
commit 374c8f019d
5 changed files with 75 additions and 40 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 963 B

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -15,9 +15,12 @@ tar -cvf "$TMP_TAR_DIR" -C "$TMP_WEBAPP_DIR" .
rm -rf $TMP_WEBAPP_DIR rm -rf $TMP_WEBAPP_DIR
scp server_landing_page_deploy.sh dkelly@nkode.tech:/home/dkelly #scp server_landing_page_deploy.sh dkelly@nkode.tech:/home/dkelly
scp "$TMP_TAR_DIR" dkelly@nkode.tech:/home/dkelly #scp "$TMP_TAR_DIR" dkelly@nkode.tech:/home/dkelly
scp www.nkode.tech dkelly@217.21.78.137:/home/dkelly
scp server_landing_page_deploy.sh dkelly@217.21.78.137:/home/dkelly
scp "$TMP_TAR_DIR" dkelly@217.21.78.137:/home/dkelly
rm $TMP_TAR_DIR rm $TMP_TAR_DIR

View File

@@ -13,6 +13,15 @@
<!-- Tailwind CSS CDN --> <!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-SR0MLMR2MR"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-SR0MLMR2MR');
</script>
</head> </head>
<body> <body>
<div class="bg-white"> <div class="bg-white">
@@ -23,7 +32,7 @@
<img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt=""> <img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt="">
</a> </a>
</div> </div>
<div class="md:flex md:hidden"> <div class="lg:flex lg: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"> <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> <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"> <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">
@@ -31,11 +40,12 @@
</svg> </svg>
</button> </button>
</div> </div>
<div class="hidden md:flex items-center gap-x-12"> <div class="hidden lg:flex items-center gap-x-12">
<div class="flex gap-x-6 text-lg font-semibold leading-6 text-black"> <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="#create-an-nkode">How to create an nKode</a>
<a href="#how-nkode-works">How nKode Works</a> <a href="#how-nkode-works">How nKode Works</a>
<a href="#faq">FAQ</a> <a href="#faq">FAQ</a>
<a href="#contact-us">Contact Us</a>
</div> </div>
<div class="ml-auto"> <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"> <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">
@@ -45,18 +55,18 @@
</div> </div>
</nav> </nav>
<!-- Mobile menu, show/hide based on menu open state. --> <!-- Mobile menu, show/hide based on menu open state. -->
<div id="mobile-menu" class="md:hidden hidden" role="dialog" aria-modal="true"> <div id="mobile-menu" class="lg:hidden hidden" role="dialog" aria-modal="true">
<!-- Background backdrop, show/hide based on slide-over state. --> <!-- Background backdrop, show/hide based on slide-over state. -->
<div class="fixed inset-0 z-50"></div> <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="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 lg:max-w-sm lg:ring-1 lg:ring-white/10">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<a href="#" class="-m-1.5 p-1.5"> <a href="#" class="-m-1.5 p-1.5">
<span class="sr-only">Your Company</span> <span class="sr-only">Your Company</span>
<img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt=""> <img class="h-8 w-auto" src="assets/lightmodenkode.svg" alt="">
</a> </a>
<button id="close-menu" type="button" class="-m-2.5 rounded-md p-2.5 text-black"> <button id="close-menu" type="button" class="-m-3 rounded-md p-4 text-black">
<span class="sr-only">Close menu</span> <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"> <svg class="h-8 w-8" 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" /> <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
@@ -64,9 +74,10 @@
<div class="mt-6 flow-root"> <div class="mt-6 flow-root">
<div class="-my-6 divide-y divide-white/25"> <div class="-my-6 divide-y divide-white/25">
<div class="space-y-2 py-6"> <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="#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">How to 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="#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> <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>
<a href="#contact-us" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-black hover:bg-gray-200 mobile-nav">Contact Us</a>
</div> </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"> <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">
@@ -103,7 +114,7 @@
<img class="w-3/4 mx-auto mt-8" src="assets/set_nkode.png"> <img class="w-3/4 mx-auto mt-8" src="assets/set_nkode.png">
<h4 class="text-2xl">3. Confirm your nKode</h4> <h4 class="text-2xl">3. Confirm your nKode</h4>
<p class="mt-8 text-xl">Confirm your nKode by reentering it.</p> <p class="mt-8 text-xl">Confirm your nKode by re-entering it.</p>
<img class="w-3/4 mx-auto mt-8" src="assets/confirm_nkode.png"> <img class="w-3/4 mx-auto mt-8" src="assets/confirm_nkode.png">
<h4 class="text-2xl">4. Login with nKode</h4> <h4 class="text-2xl">4. Login with nKode</h4>
@@ -116,31 +127,30 @@
<h4 class="text-2xl mt-4">Keypad Settings</h4> <h4 class="text-2xl mt-4">Keypad Settings</h4>
<p> <p>
Your nKode keypad is configurable. Your nKode keypad is configurable.
Under advanced settings, you can change the number of keys and the number of attributes (icon) per key. Under advanced settings, you can change the number of keys and the number of icons per key.
From this point forward, we will use the term attribute instead of icon.
</p> </p>
<img class="w-3/4 mx-auto mt-8" src="assets/advanced_settings.png"> <img class="w-3/4 mx-auto mt-8" src="assets/advanced_settings.png">
<h4 class="text-2xl mt-4">Account Creation</h4> <h4 class="text-2xl mt-4">Account Creation</h4>
<p> <p>
The server is able to deduce your nKode from two entries. The server is able to deduce your nKode from two entries.
Notice how, in the set and confirm keypads below, no attribute in the set keypad share a key with any other attribute in the confirm keypad. In the set and confirm keypads below, no icon in the set keypad share a key with any other icon in the confirm keypad.
This is called an attribute dispersion. This is called an icon dispersion.
</p> </p>
<div class="flex flex-row"> <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/set_nkode.png">
<img class="w-1/2 mx-auto mt-8" src="assets/confirm_nkode.png"> <img class="w-1/2 mx-auto mt-8" src="assets/confirm_nkode.png">
</div> </div>
<h4 class="text-2xl mt-4">Attribute Dispersion</h4> <h4 class="text-2xl mt-4">Icon Dispersion</h4>
<p> <p>
The login keypad looks different from the set and confirm keypads. The login keypad looks different from the set and confirm keypads.
It has three more attributes per key. It has three more icons per key.
A dispersion is possible if the number of attributes per key is less than or equal to the total number of keys. A dispersion is possible if the number of icons per key is less than or equal to the total number of keys.
Since the login keypad has more attributes per key than keys, we call this a dispersion-resistant keypad. Since the login keypad has more icons per key than keys, we call this a dispersion-resistant keypad.
If a malicious actor steals your keypad, they can use your keypad to phish for your nKode. If a malicious actor steals your keypad, they can use your keypad to phish for your nKode.
If the login keypad was dispersable, an attack might go like this: If the login keypad was dispersable, an attack might go like this:
</p> </p>
<ol class="list-decimal list-inside mt-2 space-y-2"> <ol class="list-decimal list-inside mt-4 mb-4 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 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 keypad requesting authorization with your nKode.</li> <li>You're redirected to a site with your nKode keypad requesting authorization with your nKode.</li>
<li>You enter your nKode, but you're informed you entered the wrong nKode.</li> <li>You enter your nKode, but you're informed you entered the wrong nKode.</li>
@@ -148,32 +158,33 @@
<li>You enter it again, and your nKode is stolen.</li> <li>You enter it again, and your nKode is stolen.</li>
</ol> </ol>
<p> <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. The greater the difference between the number of icons per key and the number of keys, the greater the dispersion resistance.
This 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 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 keypad becomes more dispersable. If you increase the number of keys without increasing the number of icons per key, your keypad becomes more dispersable.
If you have too many attributes and keys, the keypad is too busy, which makes it challenging to find your attributes. If you have too many icons and keys, the keypad is too busy, making it challenging to find your icons.
</p> </p>
<h4 class="text-2xl mt-4">Server-Side Attributes</h4> <h4 class="text-2xl mt-4">Server-Side Attributes</h4>
<p> <p>
A traditional password is composed of ASCII and sometimes Unicode characters. A traditional password is composed of ASCII and sometimes Unicode characters.
These are salted, hash, and stored in a database. These are salted, hashed, and stored in a database.
nKode is similar. nKode is similar.
An unsigned 64-bit integer represents every attribute, though it can be a byte array of any size. An unsigned 64-bit integer represents every icon, though it can be a byte array of any size.
These server-side attributes can be rotated daily, weekly, or any other cadence desired. These server-side attributes can be rotated daily, weekly, or any other frequency desired.
Here's how it works: Here's how it works:
</p> </p>
<ol class="list-decimal list-inside mt-2 space-y-2"> <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>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>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> <li>After a successful login, and the user's keys, salt, and hash are all replaced.</li>
</ol> </ol>
<h4 class="text-2xl mt-4">Login</h4> <h4 class="text-2xl mt-4">Login</h4>
<p> <p>
Every time you log in, your attributes are randomly shuffled. Every time you log in, your icons are randomly shuffled.
Attributes don't move to arbitrary locations within the key; attributes are a part of a set. Icons don't move to arbitrary locations within the key; icons are a part of a set.
You can identify the set by its position within the key. 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. In the example below, you can see some icons haven't moved, some moved to other keys as a group, and some moved to different keys alone.
</p> </p>
<div class="flex flex-row"> <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/login1.png">
@@ -190,11 +201,17 @@
<section class="scroll-mt-24" id="faq"> <section class="scroll-mt-24" id="faq">
<h3 class="text-4xl mt-8">FAQ</h3> <h3 class="text-4xl mt-8">FAQ</h3>
<h4 class="text-2xl mt-4">When can I use nKode?</h4>
<p>
We're working to make nKode available through Auth0.
However, we are looking for a strategic partner in identity management.
If you are interested in working with nKode, please reach out.
</p>
<h4 class="text-2xl mt-4">How does nKode defend against common attacks?</h4> <h4 class="text-2xl mt-4">How does nKode defend against common attacks?</h4>
<p> <p>
At the time of this writing, nKode is only a demo web application. At the time of this writing, nKode is only a demo web application.
Ideally, all nKode authentication is done through a mobile 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 keypad. A mobile application can make nKode more secure by requiring passkeys and biometric authentication.
This makes it very difficult to steal or use your nKode. This makes it very difficult to steal or use your nKode.
</p> </p>
<h5 class="text-xl mt-4">1. MFA Prompt Bombing</h5> <h5 class="text-xl mt-4">1. MFA Prompt Bombing</h5>
@@ -210,11 +227,11 @@
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> 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> <h5 class="text-xl mt-4">2. Service Desk Social Engineering: Scattered Spider</h5>
<p> <p>
An nKode keypad is made from any visual attribute. An nKode keypad can be made from any type of image.
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>. 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 keypad from abstract visual attributes like those found on Flaticon, an employee would have difficulty explaining their nKode. If every employee at the service desk has a randomly generated keypad from abstract images like those found on Flaticon, an employee would have difficulty explaining their nKode.
Moreover, this keypad can be further protected with a 2FA keycard so only the employee can render their keypad. Moreover, this keypad can be further protected with a 2FA keycard so only the employee can render their keypad.
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. 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 icons 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. The attacker must also steal the employee's 2FA keycard to render the login screen.
</p> </p>
<h5 class="text-xl mt-4">3. Session Hijacking</h5> <h5 class="text-xl mt-4">3. Session Hijacking</h5>
@@ -256,12 +273,19 @@
<h5 class="text-xl mt-4">4. Redline Stealer</h5> <h5 class="text-xl mt-4">4. Redline Stealer</h5>
<p> <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. 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 icons per key. This number can vary as the number of icons and keys change.
</p> </p>
<h5 class="text-xl mt-4">5. Exploiting SSO SAML</h5> <h5 class="text-xl mt-4">5. Exploiting SSO SAML</h5>
<p> <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. 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> </p>
</section>
<section class="scroll-mt-24" id="contact-us">
<h3 class="text-4xl mt-8">Contact Us</h3>
<p class="mt-4 text-lg">We'd love to hear from you! Whether you have questions, or feedback, feel free to reach out to us at:</p>
<a href="mailto:hello@nkode.tech" class="text-blue-600 hover:underline mt-2 text-lg font-semibold">hello@nkode.tech</a>
</section> </section>
</div> </div>
</main> </main>
@@ -291,5 +315,6 @@
}); });
}); });
</script> </script>
</body> </body>
</html> </html>

View File

@@ -31,6 +31,7 @@ fi
# Move the newly extracted directory to /var/www # Move the newly extracted directory to /var/www
mv $APP_DIR /var/www mv $APP_DIR /var/www
# Restart Nginx to apply changes # Restart Nginx to apply changes
systemctl restart nginx systemctl restart nginx

View File

@@ -1,22 +1,28 @@
# Redirect all traffic from www.nkode.tech to nkode.tech # Redirect all traffic from www.nkode.tech to nkode.tech (HTTP and HTTPS)
server { server {
listen 80; listen 80;
listen 443 ssl http2;
server_name www.nkode.tech; server_name www.nkode.tech;
# SSL configuration for www.nkode.tech redirect
ssl_certificate /etc/letsencrypt/live/www.nkode.tech/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.nkode.tech/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/www.nkode.tech/chain.pem;
return 301 https://nkode.tech$request_uri; return 301 https://nkode.tech$request_uri;
} }
# Redirect HTTP to HTTPS for nkode.tech # Redirect HTTP to HTTPS for nkode.tech
server { server {
listen 80; listen 80 default_server;
server_name nkode.tech; server_name nkode.tech;
return 301 https://$host$request_uri; return 301 https://nkode.tech$request_uri;
} }
# Main server block for nkode.tech with SSL and content configuration # Main server block for nkode.tech with SSL and content configuration
server { server {
listen 443 ssl http2; listen 443 ssl http2 default_server;
server_name nkode.tech; server_name nkode.tech;
ssl_certificate /etc/letsencrypt/live/nkode.tech/fullchain.pem; ssl_certificate /etc/letsencrypt/live/nkode.tech/fullchain.pem;
@@ -42,7 +48,7 @@ server {
root /var/www/nkode_landing_page; root /var/www/nkode_landing_page;
index index.html; index index.html;
# Routing for Flutter SPA # Catch-all for any request, including `index.html`, to serve the landing page or 404
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }