avatarExploit The Edge

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

5801

Abstract

cookie.</li><li><code>secure: true</code> ensures that the cookie is only sent over secure, encrypted connections (HTTPS). but since most testing environments are on localhost, it is allowed</li></ul><p id="6bc1">then executing this action looks like:</p><div id="e2cb"><pre><span class="hljs-keyword">import</span> { storeToken } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/actions"</span>;

<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">onSubmit</span>(<span class="hljs-params">formData</span>) { <span class="hljs-title function_">setIsLoading</span>(<span class="hljs-literal">true</span>); <span class="hljs-keyword">try</span> { <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> http.<span class="hljs-title function_">post</span>(<span class="hljs-string">/auth/login</span>, formData);

  <span class="hljs-keyword">await</span> <span class="hljs-title function_">storeToken</span>(resp.<span class="hljs-property">data</span>);

  router.<span class="hljs-title function_">push</span>(<span class="hljs-string">"/dashboard"</span>);

  <span class="hljs-title function_">toast</span>({
    <span class="hljs-attr">title</span>: <span class="hljs-string">"Login Successful"</span>,
  });
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">"error logging in"</span>, error);
} <span class="hljs-keyword">finally</span> {
  <span class="hljs-title function_">setIsLoading</span>(<span class="hljs-literal">false</span>);
}

}</pre></div><p id="173a">After testing this check your cookie storage in devtools and the token should be set:</p><figure id="de3a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*VxsyZ7KTXg_XygebpIfq1Q.png"><figcaption></figcaption></figure><p id="7f8d">Now let’s move on to using the token to communicate with our API.</p><h1 id="ad3b">2. Accessing the Token</h1><p id="3425">So accessing the token is different depending on the context. If you are accessing it on the server it looks like:</p><div id="ba24"><pre>import {cookies} <span class="hljs-keyword">from</span> <span class="hljs-string">"next/headers"</span>;

<span class="hljs-keyword">const</span> authToken = cookies().<span class="hljs-keyword">get</span>(<span class="hljs-string">"accessToken"</span>)?.<span class="hljs-keyword">value</span> </pre></div><p id="636a">In the Client side, because we set <code>httpOnly: true</code> . How do we now access our jwt? That’s where creating an api route comes in. It would have been really cool to have a server action for retrieving the token but we don’t have that yet. “fix up Next.js team”!</p><p id="dc9e">Docs for api routes using the app router <a href="https://nextjs.org/docs/app/building-your-application/routing/route-handlers">here</a></p><p id="c93d">so the gist is a folder structure of <code>app/api/auth/token/route.ts</code> resolves to an endpoint with path of <code>/api/auth/token</code> . Now in the route.ts file we write:</p><div id="916b"><pre>import { cookies } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/headers'</span>

export async <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">GET</span>(<span class="hljs-params">request: Request</span>) </span>{ <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">authToken</span> = <span class="hljs-title function_ invoke__">cookies</span>().<span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'accessToken'</span>)?.value <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">headers</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Headers</span>(); headers.<span class="hljs-title function_ invoke__">append</span>(<span class="hljs-string">"Authorization"</span>, authToken);

<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">response</span> = await <span class="hljs-title function_ invoke__">fetch</span>(`${process.env.NEXT_PUBLIC_API_URL}/user`,{
  <span class="hljs-attr">headers</span>: headers
}
<span class="hljs-keyword">if</span> (response.status === <span class="hljs-number">401</span>) {
  <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">refreshPayload</span> = {
    <span class="hljs-string">"refresh_token"</span>: <span class="hljs-title function_ invoke__">cookies</span>().<span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'refreshToken'</span>)?.value
  }
  <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">res</span> = await <span class="hljs-title function_ invoke__">fetch</span>(`${process.env.NEXT_PUBLIC_API_URL}/refresh-token, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
     <span class="hljs-attr">body</span>: JSON.<span class="hljs-title function_ invoke__">stringify</span>(refreshPayload),
  }
  
  <span class="hljs-keyword">const</span> jsonData = await res.<span class="hljs-title function_ invoke__">json</span>()
  
  <span class="hljs-title function_ invoke__">cookies</span>().<span class="hljs-title function_ invoke__">set</span>({
    <span class="hljs-attr">name</span>: <span class="hljs-string">"acce

Options

ssToken"</span>, <span class="hljs-attr">value</span>: jsonData.token, <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">sameSite</span>: <span class="hljs-string">"strict"</span>, <span class="hljs-attr">secure</span>: <span class="hljs-literal">true</span>, })

  <span class="hljs-title function_ invoke__">cookies</span>().<span class="hljs-title function_ invoke__">set</span>({
      <span class="hljs-attr">name</span>: <span class="hljs-string">"refreshToken"</span>,
      <span class="hljs-attr">value</span>: jsonData.refresh_token,
      <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">sameSite</span>: <span class="hljs-string">"strict"</span>,
      <span class="hljs-attr">secure</span>: <span class="hljs-literal">true</span>,
  })
} 
<span class="hljs-keyword">const</span> resData = {
    <span class="hljs-attr">token</span>: <span class="hljs-title function_ invoke__">cookies</span>().<span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'accessToken'</span>)?.value
}



<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Response</span>(JSON.<span class="hljs-title function_ invoke__">stringify</span>(resData), {
    <span class="hljs-attr">status</span>: <span class="hljs-number">200</span>,
    <span class="hljs-attr">headers</span>: {
        <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
    },
})

}</pre></div><p id="66db">Now let’s break down what this api route does:</p><ul><li>we retrieve the jwt from the cookie store</li><li>we make a request to /user on our api to check if the token is still valid. /user can be replaced with any protected route on your api</li><li>if we receive the <code>unauthorized(401)</code> error code we send a request to get a new token pair with our refresh token.</li><li>then we return the valid token back to the client for use.</li></ul><p id="260f">Now, to make use of this API route we can write an axios interceptor like so:</p><div id="b457"><pre>axiosInstance.<span class="hljs-property">interceptors</span>.<span class="hljs-property">request</span>.<span class="hljs-title function_">use</span>(<span class="hljs-keyword">async</span> (config) => { <span class="hljs-keyword">if</span> (config.<span class="hljs-property">url</span>?.<span class="hljs-title function_">includes</span>(<span class="hljs-string">"auth"</span>)) { <span class="hljs-keyword">return</span> config }

    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">'/api/auth/token'</span>)
    <span class="hljs-keyword">const</span> resData = <span class="hljs-keyword">await</span> res.<span class="hljs-title function_">json</span>()
    <span class="hljs-keyword">const</span> token = resData?.<span class="hljs-property">token</span>

    config.<span class="hljs-property">headers</span>![<span class="hljs-string">'Authorization'</span>] = <span class="hljs-string">"Bearer "</span> + token
     <span class="hljs-keyword">return</span> config
},
<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">reject</span>(error)
}

)</pre></div><p id="8f27">What this interceptor does is: “if the app is making a request to an auth route like <code>/auth/login</code> , <code>/auth/signup</code> no token is sent along with the request but if it is to a protected route it fetches the access token from our api route and passes it in the <code>Authorization</code> header.</p><h2 id="c7b2">Further reading:</h2><p id="fb63">This article was greatly inspired by:</p><div id="b5f3" class="link-block"> <a href="https://javascript.plainenglish.io/next-js-secure-authentication-using-http-only-cookie-graphql-or-rest-a4ef94cec9e8"> <div> <div> <h2>Next.js Secure Authentication Using http-only Cookie (GraphQL or REST)</h2> <div><h3>When it comes to user authentication we need to make sure our application is secured from any potential threats. To…</h3></div> <div><p>javascript.plainenglish.io</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*FBBZ5ksEs057sEfEkcl42g.png)"></div> </div> </div> </a> </div><p id="7edc">If you want to see how to do this with graphql. or you are working on older versions of Next without server actions, I suggest the article.</p><p id="948d">Thanks for reading and if you have any questions, drop them in the comments.</p><p id="50be">Happy building!🚀</p><h1 id="d403">Stackademic</h1><p id="3a1b"><i>Thank you for reading until the end. Before you go:</i></p><ul><li><i>Please consider <b>clapping</b> and <b>following</b> the writer! 👏</i></li><li><i>Follow us on <a href="https://twitter.com/stackademichq"><b>Twitter(X)</b></a>, <a href="https://www.linkedin.com/company/stackademic"><b>LinkedIn</b></a>, and <a href="https://www.youtube.com/c/stackademic"><b>YouTube</b></a><b>.</b></i></li><li><i>Visit <a href="http://stackademic.com/"><b>Stackademic.com</b></a> to find out more about how we are democratizing free programming education around the world.</i></li></ul></article></body>

OhSINT TryHackMe Challenge

Using Open Source Intelligence

Photo from https://wecyberup.org/

Here we are trying to solve this Osint Challenge by TryHackMe.com. I hope this guide can help you learn something new!

Walkthrough

First, download the photo from the task file button.

You need to install ExifTool to see the correct info. So let’s go to the download page exiftool.org and download what you need.

Once done, open the terminal and type

ExifTool C:/pathOfTheImage

and we can see some useful info: - the nickname of the creator - the location

So let’s try to search on the internet for some information about this OWoodFlint guy. One one the first result is a twitter account:

He wrote 2 tweets and one of them is very interesting:

Let’s go ahead with the search result and we can find a GitHub page:

Cool! Now we have other 2 information about him: his email address and the place where he’s from.

Going through the search results, we can find a blog: https://oliverwoodflint.wordpress.com/author/owoodflint/

We can learn from here that he’s been in new york since march 3rd, 2019. But there’s something way more interesting here…

Looking at the page source, we can see that written in white there’s something like a password!

Now it’s time to use the GPS information we found at the beginning, so we know where the photo was taken.

and then we can search on wigle.net for the BSSID he wrote about in his tweet post.

Now we have all the info to solve the TryHackMe room!

Answers

Down below you will find the answers to complete the CTF:

Hacking
Tryhackme
Tryhackme Walkthrough
Ctf
Osint
Recommended from ReadMedium