<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sarah Katz</title>
    <description>The latest articles on DEV Community by Sarah Katz (@sarahscode).</description>
    <link>https://dev.to/sarahscode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F162918%2F4635f3b5-0dcc-4f94-ac0e-16eee0b8c5b3.jpg</url>
      <title>DEV Community: Sarah Katz</title>
      <link>https://dev.to/sarahscode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sarahscode"/>
    <language>en</language>
    <item>
      <title>What I Worked On This Week: April 5th-9th, 2021</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Sun, 11 Apr 2021 21:09:14 +0000</pubDate>
      <link>https://dev.to/sarahscode/what-i-worked-on-this-week-april-5th-9th-2021-3737</link>
      <guid>https://dev.to/sarahscode/what-i-worked-on-this-week-april-5th-9th-2021-3737</guid>
      <description>&lt;p&gt;My company is currently in a performance review period, and as I was completing my self-review, I realized that I don't really take enough time to celebrate the small things I accomplish every week. I decided that I wanted to spend more time thinking about what I accomplish every week, and what better way to do that than write a short recap at the end of the week of what I worked on.&lt;/p&gt;

&lt;p&gt;And on that note, here are some of the things I did this week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Onboarded to a new codebase&lt;/strong&gt;. My team is onboarding to a new project, which involves working in a codebase that I've never worked in before (which is written in a language that I've never worked in before...). So far all I've done is run the tests and run the codebase, but I'm excited to dig further into this codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My first experiences with mob programming&lt;/strong&gt;. This week I participated in a few mob programming sessions. Mob programming is similar to pair programming, but with a larger group. One person drives (and this person should probably switch more frequently than we actually did) with everyone else assisting and offering suggestions. I enjoyed the mob programming and working as a group, but some of the sessions were very long, and it got to be very draining, so I don't think it's something I could do all the time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Got to take my first steps into mentorship&lt;/strong&gt;. We have someone new joining my team next sprint, and I'm helping onboard her. I a bit dropped the ball on reaching out to her and starting the process, but once I got started, I enjoyed preparing some information and I'm looking forward to sharing it with her and helping her get set up over the next few days.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Yet Another Article About React Server Components</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 11 Jan 2021 14:09:25 +0000</pubDate>
      <link>https://dev.to/sarahscode/yet-another-article-about-react-server-components-4f20</link>
      <guid>https://dev.to/sarahscode/yet-another-article-about-react-server-components-4f20</guid>
      <description>&lt;p&gt;A few weeks ago, the React team gave the community a surprise gift - an introduction to &lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html" rel="noopener noreferrer"&gt;React Server Components&lt;/a&gt;. React Server Components are pretty much what they sound like - React components that render on the server (rather than in the browser like traditional React components). Using React server components, developers can write components that render on the server in addition to rendering components in the browser. Components that render on the server can directly access data sources (such as databases and filesystems) without the need to query an API and can pass data to a client component as a prop (minimizing the need for the client to call an API).&lt;/p&gt;

&lt;p&gt;There have been many great articles written about React Server Components, and this article will not be introducing any new concepts, but as part of my commitment to learning in 2021, I wanted to write a summary of what I've learned about this exciting new addition to React.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why React Server Components?
&lt;/h3&gt;

&lt;p&gt;There were several motivating factors behind the creation of React Server Components (the &lt;a href="https://github.com/josephsavona/rfcs/blob/server-components/text/0000-server-components.md#motivation" rel="noopener noreferrer"&gt;RFC&lt;/a&gt; lists them all), but I wanted to focus on two of the problems that I see in my work that React Server Components solves: large bundle size and waterfalls in fetching data from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large bundle size&lt;/strong&gt;. &lt;br&gt;
When the browser is downloading a lot (which it does in large react applications or applications that import a lot of large third-party libraries), it can take a while to load the page, especially over slower connections. One of the struggles developers often face is how to improve the performance of their apps without sacrificing features. React server components helps solve this problem by sending less code to the browser.&lt;/p&gt;

&lt;p&gt;Here's a concrete example of this:&lt;br&gt;&lt;br&gt;
Let's say you're working on an app that displays a note added by the user (which we do a version of in my team's product). You may want to display the date the note was created or last updated (which we also do). We use moment.js (&lt;a href="https://momentjs.com/docs/#/-project-status/" rel="noopener noreferrer"&gt;which is currently in maintenance mode&lt;/a&gt;), which has a bundle size of 232 kB (66 kB gzipped). That's a lot of code for the browser to download. Since we're only displaying a date and not interacting with it at all, we could render that part of the note on the server and save the browser from having to download that large package.&lt;/p&gt;

&lt;p&gt;However, this wouldn't work for all situations. My team's app also has some date inputs, where the user inputs a date (either by typing it in or using a date picker) and we need to validate that date - which we do using moment.js. Because these components are interactive, we would have to render them on the client and would have to load this large package in the browser. React server components allows us to minimize the instances where we have to load this particular library but does not completely eliminate it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Waterfalls in fetching data from the server&lt;/strong&gt;. &lt;br&gt;
Waterfalls occur when data takes a long time to load, slowing down your applications. There can be many potential areas for waterfalls to occur, but one of the most common ones is on requests from the client to the server (and the server sending its response to the client). This back and forth communication between the server and client can cause significant latency and noticeably slow down your app, particularly if you have sequential requests coming from parent and child components. React server components solves this problem by fetching data on the server, eliminating that latency.&lt;/p&gt;

&lt;p&gt;I actually would have benefited from React server components on a ticket I recently completed. I needed to retrieve data from one endpoint and based on that data, determine if I needed to fetch additional data by calling a second endpoint. I had to wait for the server to send me the response of the first API call, and then if the feature flag told me that I needed the additional info, I needed to make another API call. If I was rendering these components on the server, I would have saved myself a lot of time on the API calls. &lt;/p&gt;

&lt;p&gt;Removing the waterfall between the client and server will significantly improve performance, but there can still be waterfalls on the server-side. The React team has indicated that there is a plan to provide an API to preload data requests as an optimization, which will help with the server-side waterfalls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Components
&lt;/h3&gt;

&lt;p&gt;Under this new system, components can be rendered on the server, on the client (ie in the browser), or both. To differentiate between the different types of components, server components are named &lt;code&gt;*.server.js&lt;/code&gt; (or .jsx or .ts or whatever extension you're using), client components are named &lt;code&gt;*.client.js&lt;/code&gt;, and shared components are &lt;code&gt;*.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Any component that requires interactivity or uses state must render on the client, and any component that directly accesses a database or filesystem must render on the server. Server components can import client components, but client components cannot import server components. Both server and client components can render shared components. The browser will only render client components and any shared components that they import, which greatly reduces the amount of data that is being rendered in the browser.&lt;/p&gt;

&lt;p&gt;Here's a quick primer on what each type of component can and cannot do:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Client Components&lt;/th&gt;
&lt;th&gt;Server Components&lt;/th&gt;
&lt;th&gt;Shared Components&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Render in the Browser&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render on the Server&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can Use State&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can Use Rendering Lifecycle/effects&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can Use browser-ony APIs (such as the DOM)&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can User server-only data sources (such as databases, internal microservices, filesystems)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can Render Server Components&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Some Things To Note
&lt;/h3&gt;

&lt;p&gt;While I'd love to say that React server components will actually get your bundle size down to zero, it's important to remember that any component that requires state or interactivity will need to render in the browser, so if you have a highly interactive app, that will increase your bundle size. However, reorganizing your app in a way that makes the interactive sections smaller client components that can be rendered by server components will help reduce bundle size.&lt;/p&gt;

&lt;p&gt;Another important thing to note is that server components can only be used with a JavaScript backend. You don't necessarily need to be using a JavaScript API, but at the very least you will need some sort of Node layer on which to render these server components.&lt;/p&gt;

&lt;p&gt;There will also be a steep learning curve, especially initially, and I recommend taking this slowly and practicing using server components in a non-production environment (especially right now, as server components are not production-ready) while you adjust to how they work.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Future With React Server Components
&lt;/h3&gt;

&lt;p&gt;I'm looking forward to trying out React server components (I plan to fork &lt;a href="https://github.com/reactjs/server-components-demo" rel="noopener noreferrer"&gt;the React team's demo&lt;/a&gt; and play with it), but I don't see myself having a heavy use for it in my everyday life. I'm not currently working on any personal projects that require interactivity, and for the projects I'm working on, server-side rendering is probably a better way to reduce my bundle size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will I recommend it at work?&lt;/strong&gt;&lt;br&gt;
Probably not. I do think we could benefit from server components, but they wouldn't really work with our current architecture, and I don't think the benefit would be worth the cost involved. I would be interested in trying it if we were building a new product that was totally separate from our existing architecture. However, I don't see that happening at work any time soon, so for now, I think any chance I get to use React Server Components will be through playing around with the demo project.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Information
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introductory Talk from Dan Abramov and Lauren Tan - &lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html" rel="noopener noreferrer"&gt;https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RFC from the React core team - &lt;a href="https://github.com/reactjs/rfcs/pull/188" rel="noopener noreferrer"&gt;https://github.com/reactjs/rfcs/pull/188&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Server Components Demo - &lt;a href="https://github.com/reactjs/server-components-demo" rel="noopener noreferrer"&gt;https://github.com/reactjs/server-components-demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>reactservercomponents</category>
    </item>
    <item>
      <title>Props Are Not Forever: Preventing Props From Being Passed to the DOM with styled-components v5.1</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 23 Nov 2020 12:06:47 +0000</pubDate>
      <link>https://dev.to/sarahscode/props-are-not-forever-preventing-props-from-being-passed-to-the-dom-with-styled-components-v5-1-l47</link>
      <guid>https://dev.to/sarahscode/props-are-not-forever-preventing-props-from-being-passed-to-the-dom-with-styled-components-v5-1-l47</guid>
      <description>&lt;p&gt;At work, my team uses styled-components as our CSS-in-JS solution. I've enjoyed working with styled-components and have found it to be a very powerful solution for our needs, but one issue I've encountered a few times is needing to pass props to a styled component for conditional styling and then having those props show up on the DOM and lead to a console error. I recently discovered (thanks to a teammate's comment on a PR I was reviewing) two new functionalities added to styled-components v5.1.0 that I think will reduce these errors in the future, and today I'd like to give a brief overview of this new functionality and how I plan to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;shouldForwardProp&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;shouldForwardProp&lt;/code&gt; is a config option that determines if a given prop should be forwarded to the DOM. For example, you may want to pass "height" and "width" properties to the DOM, but if you have a property called &lt;code&gt;shouldBePurple&lt;/code&gt; that determines whether or not the styled component has a purple background, that likely does not need to be passed to the DOM.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shouldForwardProp&lt;/code&gt; accepts a prop and optionally the &lt;code&gt;defaultValidatorFn&lt;/code&gt;, a function that is used by styled-components as the default function to determine if a prop should be passed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Include&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;withConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="na"&gt;shouldForwardProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValidatorFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;height&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;width&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="s2"&gt;`
 height: props.height;
 width: props.width;
 color: props.deeppink;
`&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Include&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deeppink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Renders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can also be used to specify props to not include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;withConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="na"&gt;shouldForwardProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValidatorFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Exclude&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deeppink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Renders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whatever&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a lot of areas in my team's codebase where I could see the use of this new config option. One area in particular where it could be helpful, and where I'd like to have an opportunity to apply it, is in our design system. We have a number of components in our design system that receive props used exclusively for styling, and I'm hoping to get a chance to take a deeper look at these components and see if we can use the &lt;code&gt;shouldForwardProp&lt;/code&gt; config to minimize the props we pass through to the DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;transient props&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Transient props are props that don't get passed to the DOM. Similar to &lt;code&gt;shouldForwardProp&lt;/code&gt;, this is a way for styled-components to know that a prop is only used for styling and should not make its way to the DOM.&lt;/p&gt;

&lt;p&gt;Transient props achieve the same end as &lt;code&gt;shouldForwardProp&lt;/code&gt;, and often the two can be used interchangeably, but there are situations where one may be more useful than the other. Personally, I feel that transient props are more useful when there are many props to filter out and listing those props in &lt;code&gt;shouldForwardProp&lt;/code&gt; could create unnecessary confusion or extra code.&lt;/p&gt;

&lt;p&gt;Transient props start with the &lt;code&gt;$&lt;/code&gt; symbol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Paragraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="s2"&gt;`
  padding-bottom: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$bottomPad&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Paragraph&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;bottomPad&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I Have Bottom Padding&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Paragraph&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Renders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;padding-bottom: 24px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;Have&lt;/span&gt; &lt;span class="nx"&gt;Bottom&lt;/span&gt; &lt;span class="nx"&gt;Padding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Paragraph&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;Have&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;Bottom&lt;/span&gt; &lt;span class="nx"&gt;Padding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Paragraph&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
#&lt;/span&gt; &lt;span class="nx"&gt;Renders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;Have&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;Bottom&lt;/span&gt; &lt;span class="nx"&gt;Padding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've already started using transient props in my company's codebase (see PR mentioned above), and I have one specific use in mind. As part of a recent project, I introduced a prop that is used for styling, but I have since noticed that this prop is creating a console error on the DOM (oops). I'm hoping that I get a chance soon to replace this prop with a transient prop and fix that DOM error.&lt;/p&gt;

&lt;p&gt;Most of the libraries and frameworks that are commonly used add new functionalities from time to time. It can be hard to keep up with these new functionalities (I'm pretty bad at it - probably would not have discovered these new styled-components functionalities without a teammate explicitly calling them out), but if you're running into a problem with a particular library, it may be worth looking to see if it has introduced new functionality that can help. As someone whose company uses styled-components fairly heavily, I'm excited to have discovered &lt;code&gt;shouldForwardProp&lt;/code&gt; and &lt;code&gt;transient props&lt;/code&gt;, and I know I will be using them in my future development work.&lt;/p&gt;

</description>
      <category>styledcomponents</category>
      <category>javascript</category>
    </item>
    <item>
      <title>In Which Sarah Learns Web Security: Part Four, The Most Common Attacks, Part Two</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 05 Oct 2020 12:54:15 +0000</pubDate>
      <link>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-four-the-most-common-attacks-part-two-mp1</link>
      <guid>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-four-the-most-common-attacks-part-two-mp1</guid>
      <description>&lt;p&gt;In the previous article, I discussed a number of common attacks, including credential theft, SQL injection, cross-site scripting, and many others, as well as some tips for preventing those attacks. This article discusses the remainder of the common security attacks covered in the &lt;a href="https://www.linkedin.com/learning/programming-foundations-web-security-2/the-importance-of-security" rel="noopener noreferrer"&gt;web security course I recently completed&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cookie Visibility and Theft
&lt;/h2&gt;

&lt;p&gt;Be careful with what you store in cookies. While browser cookies may seem like private data, they are not quite as private as you might think. Not only can users inspect their own cookies, but their data can be visible to attackers while in transit. Cookie data is sent in the header of requests to the server, and if an attacker can see network traffic (which could easily happen on an unsecured network), they can see the cookie data. XSS attacks can also be used to get cookie data.&lt;/p&gt;

&lt;p&gt;"Stealing" a cookie refers to a situation where an attack takes the information from a user's cookie and inserts those values into their own browser's cookie. It can also refer to a situation where the attacker sends a forged request with the user's cookie data. Alternatively, an attacker could modify the user's existing cookie to serve their own purposes.&lt;/p&gt;

&lt;p&gt;While cookie theft can be serious, there are some methods that the course suggests to protect against damage from cookie theft:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The best prevention is to not put anything of value in the cookie data. Storing harmless information in a cookie, such as a user's language preference, is perfectly safe. Storing an access token in the cookie that allows the user to access privileged data is not so safe. Session data should also not be stored in the cookie (although a session ID can be stored there to be sent to the server when you need to confirm that a session is valid).&lt;/li&gt;
&lt;li&gt;Websites should be set up using SSL certificates so that HTTPS can be used. This encrypts all communication between the browser and the server and prevents attackers from seeing the cookie data in transit. Secure cookies, which are only sent over HTTPS (and would not be sent if the user manually typed in HTTP), should be used together with SSL for extra security.&lt;/li&gt;
&lt;li&gt;Cookies should be given expiration dates, set either using &lt;code&gt;Expires&lt;/code&gt; or &lt;code&gt;Max-Age&lt;/code&gt; (if both are set, Max-Age has precedence over Expires). When the cookie reaches its expiration date, it will be deleted by the browser, which helps in cleaning up old cookies.&lt;/li&gt;
&lt;li&gt;By default, a cookie is available throughout a domain, including on all subdomains and all pages. If a cookie will only be needed in a certain subdomain or within one directory, then it should be restricted to that directory using the &lt;code&gt;Domain&lt;/code&gt; or &lt;code&gt;Path&lt;/code&gt; attributes. This may not be appropriate for all situations, but it is always worth considering whether the principle of least privilege should apply to cookies.&lt;/li&gt;
&lt;li&gt;If sensitive data is being stored in the cookie, then it should be encrypted. Encrypted cookies are never in plain text, whether in transit or in storage.&lt;/li&gt;
&lt;li&gt;Cookies can be digitally signed (which means running it through an algorithm to get a checksum that is added to the end of the cookie data) to prevent modification. When the cookie data is received by the app, the value will be run through the same algorithm, and it will only be accepted if the checksums match.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Session Hijacking
&lt;/h2&gt;

&lt;p&gt;Session hijacking is when an attacker steals ("hijacks") a user's active session to gain unauthorized access to restricted parts of a website. While sessions should store user data in a file or database on the server, a session identifier is often stored in the browser cookie and is vulnerable to theft. If an attacker gains access to the user's session, they can access all of the data stored in that session, or worse, they can impersonate a logged-in user. Once the attacker gains access to a logged-in user's session, the server treats the attacker as that logged in user. The attacker can do anything that the user can do - transfer money, view personal information, edit account credentials, send messages as the user, etc.&lt;/p&gt;

&lt;p&gt;Several defenses can be employed to protect against session hijacking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep cookie data (and the session IDs stored in cookies) secure (see above for some examples of that). Cookies can be stolen through XSS attacks, so it's important to also have protections against cross-site scripting. Using HTTPS is an easy way to add security to your website, and is essential for login pages or any pages that should have restricted access.&lt;/li&gt;
&lt;li&gt;Expire and remove old session files. Fewer sessions stored means fewer sessions that can be hijacked.&lt;/li&gt;
&lt;li&gt;Regenerate session identifiers periodically and at key access points in the app. Regenerating a session ID invalidates any previous session IDs, which means that a stolen session is only valid until the next time the session ID is regenerated. One instance in which it is key to regenerate the session ID is after a successful login - we do not want to give a user with access to a logged out session access to the session once the user logs back in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Session Fixation
&lt;/h2&gt;

&lt;p&gt;Session fixation is essentially the reverse of session hijacking - rather than hijacking a user's session, in a session fixation attack, the attacker gives the user a valid session ID that is controlled by the attacker. In both scenarios, the end result is the attacker and the user using the same session. However, in a session fixation attack, the session provided by the attacker is not yet authenticated, and the attacker has to wait for the user to log in to gain access to restricted pages.&lt;/p&gt;

&lt;p&gt;Early session fixation attacks relied on websites which accepted session ID's sent in the URL or form data, but this is no longer common practice. However, session fixation is still a concern, as an attacker can set the user's browser cookie to their session ID through an XSS attack or a "person-in-the-middle" attack. In a person-in-the-middle attack, an attacker positions themselves in the line of communication between the browser and the web server, using malware or a hacked router (or some other technique). The attacker relays information from the browser to the server (and vice versa) but can manipulate that data without either party knowing.&lt;/p&gt;

&lt;p&gt;How can we prevent session fixation?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only accept session IDs from cookies - never accept them as GET or POST variables. This is generally the default setting but is worth checking to be sure.&lt;/li&gt;
&lt;li&gt;Use XSS defenses (as listed above) to prevent an attacker from setting a user's session ID through an XSS attack.&lt;/li&gt;
&lt;li&gt;Automatically regenerate the session identifier after the user logs in - discard the old session ID and assign a new one. This renders the attacker's session ID useless, as it will never be attached to an authenticated session.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Remote Code Execution
&lt;/h2&gt;

&lt;p&gt;Remote code execution (RCE) is one of the worst types of attacks. RCE is when an attacker can remotely execute internal operating system commands on a server. To put it simply, an attacker can run commands on your server as if they were sitting at the keyboard acting as a logged-in user. Once an attacker has access to your server, they can read, add, modify or delete files, change access privileges or passwords, edit configurations, or communicate to other servers.&lt;/p&gt;

&lt;p&gt;RCE is one of the worst attacks, but thankfully, it's also one of the hardest to pull off. Operating systems keep a wall between the operating system and the software running the web server, which is difficult to get through. Most programming languages have functions which allow them to communicate directly with the underlying OS (for example, &lt;code&gt;console.log()&lt;/code&gt; in NodeJS), and hackers can use these function to send their own data to the OS. It's best to not use these functions at all (often there's another solution using less risky code) or to disable them entirely (if your programming language of choice allows it). If you have no other option but to use one of these functions, avoid pairing it with user-submitted or dynamic data, and if that is not possible, ensure that you validate all data and use allow-lists to limit the range of data that can be entered.&lt;/p&gt;

&lt;p&gt;Remote code execution attacks are very bad, but fortunately are not very common, and most occur because of developer carelessness.&lt;/p&gt;

&lt;h2&gt;
  
  
  File Upload Abuse
&lt;/h2&gt;

&lt;p&gt;File upload abuse is when an attacker abuses a website's upload feature in some way. The most common forms of abuse are uploading too many files, uploading files that are too large, or uploading files too frequently. Too many files or files that are too large can use up all of a server's storage space. Files uploaded too frequently can slow down server processing or monopolize server connections. File upload abuse can also take the form of uploading the wrong content type.&lt;/p&gt;

&lt;p&gt;The most serious type of file upload abuse involves malware. Malware can pretend to be a different file type or can be embedded in files that otherwise seem legitimate. An attacker may upload malware and then use other techniques to move it to a different location or launch it. Malware can be used for many different goals, and ransomware (such as the attack on Garmin a few months ago which affected flight systems, as well as my ability to sync my runs) has become a major threat in recent years. Most ransomware encrypts all files and then demands a ransom to obtain the key needed to decrypt the files.&lt;/p&gt;

&lt;p&gt;The instructor in this course recommended a few measures to protect against file upload abuse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The best way is to require users to log in before they can upload files - don't allow anonymous uploads. This won't prevent a determined attacker, but at least you'll have account information for the attacker and can revoke their access to prevent future attacks from that user.&lt;/li&gt;
&lt;li&gt;Don't make user-uploaded files available for public download (so that if malware is uploaded, you don't spread it). Store uploaded files in directories that are not publicly readable, and if they do need to become public, scan them for viruses and have a human review them for extra protection.&lt;/li&gt;
&lt;li&gt;Validate that the file has the correct content type or MIME type, and validate the file extension against a list of allowed extensions. You can also validate that the file size is below a set maximum file size.&lt;/li&gt;
&lt;li&gt;Using large hard drives or cloud servers can help ensure that there's always adequate drive space available, rendering some file upload abuse attacks (particularly ones that are intended to use up your server space) useless.&lt;/li&gt;
&lt;li&gt;Frequent file uploads can be limited or throttled by the server, the web application, or a firewall.&lt;/li&gt;
&lt;li&gt;Scan servers with antivirus software to look for malware that you may have missed through your other defenses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Denial of Service
&lt;/h2&gt;

&lt;p&gt;Denial of service (DoS) attacks deny authorized users access to a server, service, or resource to which they would normally expect to have access. In a DoS attack, the underlying resource is generally not impacted, but the user's ability to access that resource is impacted. This attack is intended to impact the availability of data, not the data itself. Denial of service attacks usually use flooding or crashing to make data unavailable. &lt;em&gt;Flooding&lt;/em&gt; is when a system is overwhelmed with too many requests, and &lt;em&gt;crashing&lt;/em&gt; is when software or hardware stops operating&lt;/p&gt;

&lt;p&gt;Denial of service attacks are rarely performed by a single computer, as most computers cannot muster up the amount of traffic necessary to shut down a well-designed server or router. More commonly, a distributed denial of service (DDoS) attack, which involves hundreds or even thousands of computers, will be used to bring down a resource. DDoS attacks can be controlled by humans, but are more often executed by zombie botnets, collections of internet-enabled devices with malware installed on them. An attacker sends commands to the botnet and can use all of the connected devices to launch simultaneous attacks. The biggest DDoS attack to date took place in February 2020 and was unsuccessful, as AWS was able to &lt;a href="https://www.zdnet.com/article/aws-said-it-mitigated-a-2-3-tbps-ddos-attack-the-largest-ever/" rel="noopener noreferrer"&gt;successfully mitigate the 2.3 Tbps attack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Preventing DDoS attacks is challenging. The first question to ask is whether a DDoS attack is in your threat model. In most cases, the answer is no.&lt;br&gt;&lt;br&gt;
If your website is likely to be the target of retaliation, hacktivism, or extortion attempts (for example, a government agency website), the instructor of this course suggests outsourcing the problem and hiring a company that offers DDoS mitigation services. These companies will route all incoming traffic to your website through their servers, which are better equipped to handle the traffic.&lt;/p&gt;

&lt;p&gt;If you see a spike in your website traffic, it may be legitimate traffic based on recent good press or changes in the need for your service. Increasing available RAM and deploying additional servers behind your load balancer are two ways to handle this increased load.&lt;/p&gt;

&lt;p&gt;If you do discover an increase in malicious traffic, the instructor of this course recommends a few methods to deal with that traffic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Throttling your traffic, also known as rate limiting, regulates the flow of input to keep it below a maximum level, which slows down the attack.&lt;/li&gt;
&lt;li&gt;Filtering traffic applies a set of rules to that traffic, and only allows requests of a certain type or with certain characteristics.&lt;/li&gt;
&lt;li&gt;Sinkholing redirects traffic to a new destination.&lt;/li&gt;
&lt;li&gt;Blackholing is a more extreme version of sinkholing, where the traffic is rerouted to nowhere (also known as the null resource). Blackholing, along with sinkholing, filtering, and throttling, can all be done with the user of a firewall.&lt;/li&gt;
&lt;li&gt;Contact your ISP, who may be able to start blackholing traffic on their end immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Knowing what attacks are commonly executed helps in developing a threat model and deciding on security defenses. Most websites will not be subject to all of the attacks listed in this article, but knowing which ones may impact your website is a great first step in deciding what security to employ.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>In Which Sarah Learns Web Security: Part Three, The Most Common Attacks, Part One</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Tue, 29 Sep 2020 01:46:12 +0000</pubDate>
      <link>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-three-the-most-common-attacks-part-one-cb9</link>
      <guid>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-three-the-most-common-attacks-part-one-cb9</guid>
      <description>&lt;p&gt;So far in this series, I've discussed general security principles and some considerations around handling inputted and outputted data. In this article, I want to give an overview of the last segment of the &lt;a href="https://www.linkedin.com/learning/programming-foundations-web-security-2/the-importance-of-security" rel="noopener noreferrer"&gt;web security course I recently completed&lt;/a&gt;, a list of the most common security attacks (and some tips on how to protect against them). The list included in this article is the attacks covered in this one course. This is by no means a comprehensive list of all attacks or defenses against them. For the last information on the current top ten application security risks, a great resource is The OWASP Foundation's &lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;Top Ten List&lt;/a&gt;. I particularly enjoyed this part of the course because I felt that it tied everything together, showing how the principles and concepts covered in previous sections can be applied to your application's threat model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credential Attacks
&lt;/h2&gt;

&lt;p&gt;Credential attacks occur when an attacker gains access to a user's login credentials and uses that to access the user's account. There are several different types of credential attacks, but this course covered three in depth: credential theft, brute force attacks, and dictionary attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credential Theft
&lt;/h3&gt;

&lt;p&gt;Credential theft is when attackers gain access to a user's username and password. This can happen through human error, such as leaving usernames and passwords lying around unprotected (admit it, you've done that once or twice ... I know I have), but most often it happens through a data breach. When a company's database is breached, usernames and passwords are available to hackers, and while the data is safer if it is encrypted, hackers can often get past the encryption given enough time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brute Force Attack
&lt;/h3&gt;

&lt;p&gt;A brute force attack is when a hacker uses software to try every possible password - attempting to discover a password through trial-and-error. It is impossible to know how long it will take a brute force attack to discover a password because there's no way to know when the software will hit on the right password. Using longer passwords increases the maximum time that the attack could take, but because we don't know the order in which the software will attempt character combinations, even a long password could potentially be discovered quickly by a brute force attack.&lt;br&gt;&lt;br&gt;
Wouldn't it be crazy if your password was &lt;code&gt;bsUa8752!@nhJp039&lt;/code&gt; and the software guessed it on the first try? With a brute force attack it's not likely, but it is possible because the order of attempts is random.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dictionary Attack
&lt;/h3&gt;

&lt;p&gt;A dictionary attack is a type of brute force attack that prioritizes dictionary words. Working off the assumption that most people will use dictionary words in their passwords (mostly because they're easier to remember and nobody likes having to remember long, bizarre passwords), these attacks try character combinations including dictionary words before moving on to non-word combinations. While &lt;code&gt;bsUa8752!@nhJp039&lt;/code&gt; is safer from a dictionary attack than a password that uses dictionary words (for example, &lt;code&gt;Yellow20!&lt;/code&gt;), it still can be discovered eventually.&lt;/p&gt;

&lt;p&gt;While the maximum time for a dictionary attack to discover a password is the same as a brute force attack (after all, they are working from the same set of potential passwords), in real-world situations dictionary attacks tend to find passwords faster because they are prioritizing common and known passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credential Stuffing
&lt;/h2&gt;

&lt;p&gt;Credential stuffing uses username/password combinations that have been exposed through data breaches and tries them on other websites. This is why it is so important to make passwords unique - if your password for one website is exposed, as long as you don't reuse that password on a different website, any attempt to access your accounts through credential stuffing will fail.&lt;/p&gt;

&lt;p&gt;The best way to protect against credential attacks is to have a safe password (and to not reuse that safe password). The most secure passwords are at least 12 characters long, with 15 or more characters being ideal. Having variety in your password, including uppercase/lowercase, numbers, and special characters, is helpful but should be used in combination with a long password. Avoid using dictionary words or common patterns, as those are likely to be discovered in a dictionary attack. For extra security, include multi-factor authentication in your app to ensure that hackers need more than just a username and password to access the account. Your users may not always love it (I know it drives me crazy sometimes), but they'll appreciate you making their account more secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL Manipulation
&lt;/h2&gt;

&lt;p&gt;URL Manipulation is when an attacker edits the URL in the browser's location bar to probe a website. Editing the URL can lead an attacker to a private page that should not be accessible to that user, could reveal database information, or could give the attacker more information about the technology behind the website (for example, if an attacker discovers an &lt;code&gt;admin.php&lt;/code&gt; page, even if they learn nothing from the content of that page, they now know that the website is using PHP and can target their attacks using known PHP vulnerabilities). If you suddenly notice a lot of hits to URLs that don't exist on your site (or that have no way for the user to reach them), an attacker may be trying a URL manipulation attack on your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insecure Direct Object Reference (IDOR)
&lt;/h2&gt;

&lt;p&gt;One of the most dangerous consequences of URL manipulation is &lt;strong&gt;insecure direct object reference (IDOR)&lt;/strong&gt;, when code accesses a restricted resource based on user input without verifying the user's authorization to access that resource. If an attacker can find the URL for an insecure resource, they may be able to access private information or access resources they should not have access to.&lt;/p&gt;

&lt;p&gt;IDOR is one of the most dangerous consequences of URL manipulation, but there are ways to prevent it. Some of the prevention measures discussed in this course include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When developing a website, take into consideration the fact that URLs are exposed and easily editable. Even if you never link to a particular URL, it could still be found by an attacker.&lt;/li&gt;
&lt;li&gt;Consider all edge cases and expect the unexpected (this is a good general security principle that also applies here).&lt;/li&gt;
&lt;li&gt;Define an allow list for accepted URL parameters and reject all other input.&lt;/li&gt;
&lt;li&gt;Handle errors and unfound URLs gracefully and vaguely - having an error page is important, but don't display any specific feedback on the error page that could be helpful to a potential attacker.&lt;/li&gt;
&lt;li&gt;Validate a user's information before allowing access to protected resources - make the user log in and then verify that they are logged in and allowed to access that resource.&lt;/li&gt;
&lt;li&gt;Change direct object reference to indirect. One way to do this is to provide a list of options for the users to choose from and then use an option number for the URL (and have code that maps the option number to the item you're trying to reference). For example, on an e-commerce website's order history page, list 4 orders for which the user can view invoices, and have the URLs be something like "/order-3", and then in your code map "order-3" to the third of the four invoices that could be chosen (which may, in fact, have been invoice #89578 - but we don't want an attacker to know that because that gives them too much information about how we structure and use order numbers). By not directly linking to invoice #89578, we ensure that only someone who has access to the order history page will have access to that invoice (which could contain personal data such as name, address, or phone number).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SQL Injection
&lt;/h2&gt;

&lt;p&gt;SQL injection is an attack that occurs when untrusted data is used to construct a SQL query. When raw data is inserted into a SQL query string (for example, if SQL is inserted as part of an email address during login), it allows the attacker to execute arbitrary requests to a SQL database. These attacks can be used to probe the structure of the database, to steal data, to add or change database information, to destroy data, or to bypass authentication. One of my favorite examples of SQL injection is a popular &lt;a href="https://xkcd.com/327/" rel="noopener noreferrer"&gt;xkcd comic&lt;/a&gt; where young Bobby Tables's school loses an entire year's worth of records because they inserted an unsanitized student name into the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blind SQL Injection
&lt;/h3&gt;

&lt;p&gt;Blind SQL injection is a type of SQL injection where a vulnerability exists but it does not affect the browser. An attacker who attempts to exploit this vulnerability will not receive any visual confirmation that their attack was successful. Because attackers have no visual confirmation of the success of an attack, one technique that is often used is injecting a SQL query that will cause the database to pause or slow return times (one common way to do this is with SQL's sleep command). If the attacker sees a slowed or paused response, that indicates a successful attack, and the attacker will often attempt to further exploit that same vulnerability.&lt;/p&gt;

&lt;p&gt;Several strategies can be used to protect against SQL injection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the principle of least privilege when deciding what access your database should have. Your database will most likely need to read and write, so those actions should be permitted. It probably doesn't need to modify schema or drop tables, so it should not have access to those actions.&lt;/li&gt;
&lt;li&gt;Sanitize data. As we learned from Bobby Tables, unsanitized query strings can have unintended consequences. Sanitizing your input before passing it to the database (by either escaping or replacing powerful characters) prevents rogue code from causing damage.&lt;/li&gt;
&lt;li&gt;Use a SQL prepared statement. A SQL prepared statement is a SQL query that is prepared in advance with placeholders for dynamic data. The data being inputted must match certain requirements, and there's no concern about modifying the query because it has already been written. For example, using a PostgreSQL database, you may have a prepared statement that says &lt;code&gt;PREPARE finduser AS SELECT name FROM users WHERE id=$1&lt;/code&gt;. You could then execute it using &lt;code&gt;EXECUTE finduser('1234-5678-9098-7654')&lt;/code&gt;. Other databases may have slightly different syntaxes, but the general principle is the same - because you're inserting variables, not the full command, you can be more restrictive about what data is accepted and know that the query is not being altered.&lt;/li&gt;
&lt;li&gt;Allow lists and validation can be used together with the strategies listed above as an extra layer of protection (defense in depth).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cross-site Scripting (XSS)
&lt;/h2&gt;

&lt;p&gt;A cross-site scripting attack occurs when an attacker sends scripts across your website to someone else's browser. The attacker injects code (primarily HTML and JavaScript) into your website that another user's browser will execute. This becomes possible when a website displays user-submitted input without first sanitizing it.&lt;/p&gt;

&lt;p&gt;XSS is often ranked as one of the top 10 web security threats.&lt;/p&gt;

&lt;p&gt;There are several types of cross-site scripting attacks. The ones covered in this course are reflected XSS attacks, stored XSS attacks, and DOM-based XSS attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflected XSS Attacks
&lt;/h3&gt;

&lt;p&gt;This is the most common type of XSS attack. A reflected attack is one where an attacker includes JavaScript code to be run in a URL string or in the form data sent with a request. For example, an attacker can post a link on twitter that looks like it's just a link to register for their website, but with the URL it includes a script that will run when the page loads. When a user clicks on that link, the script runs immediately in the user's browser. It is called a reflected attack because it bounces right back. Phishing emails often include reflected XSS attacks.&lt;/p&gt;

&lt;p&gt;Stored and DOM-based attacks use the same principle as reflected attacks, but are not immediate and do not originate from links.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stored XSS Attacks
&lt;/h3&gt;

&lt;p&gt;A stored XSS attack occurs when malicious JavaScript is planted in a database, files, cookies, a session, or other storage. When the data containing the code is retrieved and inserted into the HTML, the script executes. For example, if an attacker leaves a comment on a blog that contains a stored XSS attack, that code will be triggered when the comment is retrieved from the database and displayed on the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  DOM-Based XSS Attacks
&lt;/h3&gt;

&lt;p&gt;A DOM-based XSS attack embeds a script into the existing page. This differs from a reflected attack in that it impacts code that is already loaded and does not return a response from a server. DOM-based attacks are effective on single-page applications that load all of the JavaScript necessary for user interactions on the client side.&lt;/p&gt;

&lt;p&gt;Cross-site scripting attacks are common, but there are ways to protect against them. A good place to start is by mapping data passageways and exposure points to understand where your site could be vulnerable to an XSS attack. Pay particular attention to areas where data is outputted (as this is where the script will do the most damage), but its important to also look at areas where data is inputted, transferred, and stored to ensure that you're seeing the complete picture. Once you've determined where your website and data is vulnerable, protect your data by following best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate that all data matches expectations. Use allow lists (when possible) to confirm that the data is allowed - for example, if your user is inputting a PIN, you may want to validate that the data is a four-digit number, no more, no less, and no other types.&lt;/li&gt;
&lt;li&gt;Sanitize all data before output. The exact sanitization you use will differ from case to case, but your language of choice should have sanitization options.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;HTTPOnly&lt;/code&gt; cookies. These cookies protect the cookie from being accessed by client-side scripts. &lt;code&gt;HTTPOnly&lt;/code&gt; should also be used on cookies used for session management.&lt;/li&gt;
&lt;li&gt;Define a content security policy (CSP). A CSP provides instructions to the browser about what types of resources can be used and where those resources can come from. Best practice is to send the policy in the header of an HTTP response. The CSP is essentially an allow list for the browser, telling it what content is allowed on the page and what content is not allowed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cross-site Request Forgery (CSRF)
&lt;/h2&gt;

&lt;p&gt;A cross-site request forgery attack (CSRF) occurs when an attacker tricks a user's browser into sending a request to a different site. A CSRF attack is not dependent on a user clicking a link, rather, the URL for the request is in the HTML of the page (often the &lt;code&gt;src&lt;/code&gt; attribute of an image), and when the page loads, a request is made to that URL. The user may see a broken image link, but would not know that the forged request was sent.&lt;/p&gt;

&lt;p&gt;A CSRF attack could also take advantage of a user's logged-in state on a website. If a CSRF attack sends a request to a website where the user is logged in, the request may include their authenticated status and could give the attacker access to their account. Attackers generally do not see the direct results of the attack (they don't see the user's browser making the request), but they may see an indirect result, depending on what the attack was used for (for example, an attack that made fraudulent votes in a poll would lead the attacker to see an increase in votes, but they wouldn't see each individual vote happen).&lt;/p&gt;

&lt;p&gt;There are several ways to protect against CSRF attacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The simplest defense against a CSRF attack is to limit what requests can be made from a page. A page that is just loading data without submitting anything should only allow &lt;code&gt;GET&lt;/code&gt; requests. &lt;code&gt;POST&lt;/code&gt; requests should be allowed only on pages that are submitting forms or performing other actions that make changes.&lt;/li&gt;
&lt;li&gt;A more effective defense is to use CSRF tokens. A token can be generated and stored in the user's session data, and when the user submits a form, verify that the token is authentic before allowing the request. If the token sent with the request does not match the stored token, then the request is rejected. However, if your site is subject to XSS attacks, this defense would not work, as the attacker could be able to access the token.&lt;/li&gt;
&lt;li&gt;Other defenses that can be used as part of defense in depth include matching the referrer in a form submission, setting a custom header in the XMLHttpRequest and verifying that the header is present, or using the SameSite cookie attribute (which is not fully supported in all browsers).&lt;/li&gt;
&lt;li&gt;For very sensitive actions, such as changing usernames and passwords, the best protection is to require a second action to confirm the change, which could be a confirmation page (something you often see in online shopping), a CAPTCHA image, or re-authentication, all of which a CSRF attack could not respond to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These attacks are just a small number of potential attacks that could be part of your threat model. In my next article, I will discuss a number of additional threats to consider, as discussed in the last portion of this course.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>In Which Sarah Learns Web Security: Part Two, Input and Output</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 14 Sep 2020 13:14:30 +0000</pubDate>
      <link>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-two-input-and-output-5e7a</link>
      <guid>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-two-input-and-output-5e7a</guid>
      <description>&lt;p&gt;In the previous article, I discussed how and why I started learning about web security, as well as some general security principles I learned from &lt;a href="https://www.lynda.com/IT-tutorials/Programming-Foundations-Web-Security/5005066-2.html" rel="noopener noreferrer"&gt;the LinkedIn Learning course&lt;/a&gt; that I completed. In this article, I want to review the next section of the course, from which I learned some important principles for dealing with input and output. When input enters your app, you want to follow certain steps to ensure that the input is appropriate and that no security risks or vulnerabilities are being introduced with this input. Similarly, when displaying output on your app, you want to ensure that the output is safe (and will not cause unexpected side effects in the user's browser) and that you are only displaying output that is appropriate for the user to see.&lt;/p&gt;

&lt;p&gt;Let's go into a little more detail about how this course recommends regulating your inputs and outputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regulating Requests
&lt;/h2&gt;

&lt;p&gt;Your website should be selective about which requests it accepts. The four most common types of requests are &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, and &lt;code&gt;DELETE&lt;/code&gt;, and most websites generally accept &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt; requests. &lt;code&gt;POST&lt;/code&gt; requests should only be accepted when a form is being submitted (for example, logging in or adding a comment on a blog post). Most (or often all) other requests should be &lt;code&gt;GET&lt;/code&gt; requests. It's also important to inspect the format of the request - is it the format you are expecting? If not, you should not be sending a successful response.&lt;/p&gt;

&lt;p&gt;Regulating requests is not itself enough to protect against attacks, but it's an important first layer of defense in depth (which we discussed in the last article).&lt;/p&gt;

&lt;h2&gt;
  
  
  Validating Input
&lt;/h2&gt;

&lt;p&gt;In a situation where a user is submitting data, we can't just assume that all of the input is acceptable - we must validate the input. "Acceptable" can include any number of criteria, from the presence of the data to its uniqueness. Some common qualities to validate include the presence length of the data, the type of data (ie string, number, file type, etc), and the format of the data (which often involves using regular expressions to determine if the data matches an expected pattern). If you're expecting data to be a member of a particular set of data (for example, is it one of the values on your allowed data list), you should be validating that as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanitize Data
&lt;/h2&gt;

&lt;p&gt;Validating data is not the last step - once data has passed validation, it should then be sanitized to remove anything potentially harmful. Many common attacks start with malicious input (something which will be covered in part 3 of this series), and it's important to sanitize all data because you don't know when the data will contain something harmful.&lt;/p&gt;

&lt;p&gt;The instructor in this course recommended &lt;em&gt;typecasting&lt;/em&gt; as a good first step in sanitizing data. Typecasting refers to ensuring that the data you received matches the expected type. Each programming language handles data types differently, and its best to typecast your data yourself to ensure that it is handled as expected. Typecasting should be done early so that it is not forgotten.&lt;/p&gt;

&lt;p&gt;What sanitization you apply next will depend on where the data is going. Different languages and data pathways have different sanitization processes (because what is harmful differs across languages). Many languages have special characters as part of the language that can be used to insert harmful code (for example, HTML tags use &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;, so an attacker could send input that starts with &lt;code&gt;&amp;gt;&lt;/code&gt; and then add their own HTML). Two ways to sanitize data to ensure that these special characters cannot cause harm are encoding and escaping the characters. &lt;em&gt;Encoding&lt;/em&gt; replaces harmful characters with harmless equivalents (for example, &lt;code&gt;&amp;amp;lt;&lt;/code&gt; for &lt;code&gt;&amp;lt;&lt;/code&gt; in HTML input). &lt;em&gt;Escaping&lt;/em&gt; adds an escape character before the powerful character, which renders the character harmless. You can get functions to encode and escape data from either the language's built-in function or a well-vetted library (you may be tempted to write these functions yourself, but it's more secure to use the existing well-tested functions).&lt;/p&gt;

&lt;h2&gt;
  
  
  Label Variables
&lt;/h2&gt;

&lt;p&gt;One of the recommendations made in this course is keeping track of which data has been sanitized and which has not. I wasn't aware of this consideration before watching this video, but it makes sense - you don't want to display unsanitized data in a place where it could cause harm just because you mixed up your data. The instructor recommends labeling variables to indicate whether or not the data has been sanitized. For example, data that comes in from an input can be labeled as &lt;code&gt;rawVariableName&lt;/code&gt;, and once it has been sanitized, it can be assigned to a variable named &lt;code&gt;safeVariableName&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Code Private
&lt;/h2&gt;

&lt;p&gt;The code for your website should never be made publicly available. If hackers can see your code, they may be able to determine what security defenses you're using (and figure out how to circumvent them). It is important to separate your app into a public directory that is accessible to the browser and a private directory that handles the code behind the scenes. Most web frameworks do this, and your server should be configured to serve files from the public directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Credentials Private
&lt;/h2&gt;

&lt;p&gt;We all know that it's a bad idea to share your password or write it somewhere where it is available to others. This applies to applications as well - if your app uses any credentials or access keys (for example, to access APIs, code repositories, or databases), these credentials should not be put directly in your code. The best practice is to separate all of your configuration from your code. Store these access keys in a separate file and use constants to refer to them (for example, you may want to configure a variable for your &lt;code&gt;DATABASE_URL&lt;/code&gt; and only reference the variable name in your app).&lt;/p&gt;

&lt;p&gt;Credentials should never be stored in version control (such as git or svn). Once something is in version control, it's hard to remove all traces of it, so if you currently have credentials in your version control, once you've removed those credentials (and excluded any files that contain credentials), the instructor of this course recommends changing those credentials.&lt;/p&gt;

&lt;p&gt;One last recommendation that this course made was to use an SSH key to handle credentials for connecting to a remote server. An SSH key has two parts, a public key and a private key, and only when the keys match is access granted. Your public key can be stored in plain text in your code because it will only work properly when it interacts with the appropriate private key (which is not stored in your code).&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Error Messages Vague
&lt;/h2&gt;

&lt;p&gt;When I'm working on developing a new app (or a new feature or a bug fix), I like having descriptive error messages. The more I know about what goes wrong, the easier it will be for me to identify a way to fix it. That is not at all a security concern - as long as those descriptive error messages don't make it into a production app. Developers aren't the only people who like descriptive error messages - hackers like them too. When they encounter an error as part of an attack, hackers can use details from the error messages to help them figure out what attack to try next. Best practice is to return 404 or 500 errors in production (with no more information than that and possibly a generic "something went wrong" error message) and save displaying detailed error logs for a development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Logging
&lt;/h2&gt;

&lt;p&gt;If a hacker attempts to penetrate your app, it's useful to have detailed logs to help you identify what happened and determine where there may be a vulnerability that needs to be fixed. However, too much logging can become a liability (see above), so it's important to be smart about what you log. A good general principle is to log any errors that occur (including as many details as you can), any sensitive actions (such as logging in or changing user permissions), and any suspicious activity.&lt;/p&gt;

&lt;p&gt;When logging an event, some details you may want to log include the date and time of the event, whatever information you have about the source of the event (IP address, user account info), the URL where the event occurred (including request parameters and cookies if applicable), and a backtrace (if your programming language of choice allows it). Because they contain a lot of sensitive data, these logs should be kept in a restricted area, such as a database or a private folder.&lt;/p&gt;

&lt;p&gt;Knowing general security principles and how to securely handle your input and output is important, but it's not enough to secure your application. To properly develop a threat model and act on it, you need to know what kind of attacks are out there and how to protect against each attack. In the next post in this series, I will share some common attacks covered in this course and the instructor's suggestions for how to protect against these attacks.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>In Which Sarah Learns Web Security: Part One, Introduction and General Principles</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Tue, 08 Sep 2020 00:08:08 +0000</pubDate>
      <link>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-one-3ad4</link>
      <guid>https://dev.to/sarahscode/in-which-sarah-learns-web-security-part-one-3ad4</guid>
      <description>&lt;h1&gt;
  
  
  Introduction to the Series
&lt;/h1&gt;

&lt;p&gt;Part of being a developer - part of being a human being, really - is lifelong learning. The idea that there's always more to learn, and that you'll become a better developer (and a better person) if you take the time to learn new things. In the spirit of growth through learning, I've been trying to take half an hour out of every workday for professional development, focusing on something I want to learn that's not directly related to my current work priorities. At first, this professional development time was spent learning more about things I touched in my work. Topics I studied included typescript, redux (which I've been using for 3 years and I still struggle with), and our app's session management. While I appreciated the opportunity to learn more about these topics, I wasn't entirely sure how studying the same things I was working on every day was contributing to my overall professional growth. My manager shared our department's competency framework with me, and after reviewing that framework, I noted a few areas where I felt that I had a lot to learn.&lt;/p&gt;

&lt;p&gt;One of the gaps that I identified in my knowledge was web security. I know that security is important, and while many companies (including mine) hire dedicated cybersecurity engineers, as a developer, I knew that it was important for me to learn the basics of web security to get a better sense of where I could run up against security vulnerabilities (and when to reach out to my company's security team to review my options with them). To help me learn more about this area, I decided to watch a &lt;a href="https://www.lynda.com/IT-tutorials/Programming-Foundations-Web-Security/5005066-2.html" rel="noopener noreferrer"&gt;course on LinkedIn Learning&lt;/a&gt; called Programming Foundations: Web Security.&lt;/p&gt;

&lt;p&gt;I learned a lot from this course, and in the spirit of sharing my knowledge and helping others find areas where they want to grow, I decided to write a series of articles recapping what I learned through that course.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Is Web Security?
&lt;/h1&gt;

&lt;p&gt;Web security is when we are aware of the potential threats and have adequate protection against them. As a web developer, this means detecting potential vulnerabilities in code and addressing them. The process of detecting these threats is called &lt;strong&gt;developing a threat model&lt;/strong&gt;, and is an important part not only of launching a new web application but also of maintaining an existing app.&lt;/p&gt;

&lt;p&gt;Total security is unachievable, but it's important to use your threat model to discover the most important vulnerabilities and protect against those. Effective security is not a one-time thing - it requires constantly reassessing the threats against your website and protecting against new threats.&lt;/p&gt;

&lt;h1&gt;
  
  
  General Security Principles
&lt;/h1&gt;

&lt;p&gt;After introducing the concept of web security, the course covered some general security principles. It described each of the principles and how to apply them. Some of these principles were things I had heard of before, but many of them were new to me, and I learned a great deal from this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principle of Least Privilege
&lt;/h2&gt;

&lt;p&gt;This principle says that every user of the system should operate with the least amount of privilege necessary to complete the job. In a system that applies the principle of least privilege, a user only has access to the resources that they absolutely must be able to access. In such a system, a user also cannot have access to edit their level of privilege or to give themselves access to something to which the do not need access.&lt;/p&gt;

&lt;p&gt;This principle should also be applied to code. Code should only be accessible to other code that needs to use it. One example of this is private and public functions. If a function will not be used outside of the scope where it is declared, it should be private (and therefore not accessible outside that scope). Only when you need to reuse a function outside the scope where it is declared should that function be made public.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple is More Secure
&lt;/h2&gt;

&lt;p&gt;The simpler a system is, the more likely it is to be secure. Adding complexity to a system increases the likelihood of introducing bugs or mistakes that could lead to a security vulnerability.&lt;/p&gt;

&lt;p&gt;The video on this topic offered several suggestions to reduce complexity in an app, and I'd like to mention two of these suggestions in particular. One is to leave code comments, particularly pertaining to security concerns. When a code decision is made with security concerns in mind, it's important to ensure that all other devs who see that code are aware of the security concern and don't refactor that code in a way that could create a new vulnerability. The other suggestion I wanted to mention was using functions built-in to the programming language rather than custom solutions. As devs, sometimes we feel that we can create a custom solution that fits our needs better than a language's built-in functionality. But these built-in functions tend to be better tested and have often already taken into account security concerns, which means that in writing custom code, we're losing the security that would have come from the built-in functionality. If we choose to use custom code instead of a built-in solution, there should be a good reason for it, and security concerns should be part of the development and review process for this custom code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust No One
&lt;/h2&gt;

&lt;p&gt;Trust should only extend as far as absolutely necessary. While you may want to believe that all of your users have good intentions, this likely won't be true (after all, insider threats, where a user with legitimate access abuses that access, are a real concern). To ensure good security for your system, it's a good idea to be a little paranoid and treat every user as if they are a potential hacker.&lt;/p&gt;

&lt;p&gt;One example of an attack that exploited legitimate user access was a recent hack involving several verified Twitter accounts. The affected accounts posted a message promising to send back twice as many bitcoins if users sent bitcoins to a particular address - but no return bitcoin was sent. The attackers were able to access these verified accounts because they had gained access to a Twitter admin account - an account that had legitimate access to user information was used for a malicious attack. Even if you know your user won't be launching an attack, you never know who else may be able to gain access to their account (more on that later).&lt;/p&gt;

&lt;h2&gt;
  
  
  Always Expect The Unexpected
&lt;/h2&gt;

&lt;p&gt;Security should be proactive, not reactive. Assume that you will be hacked (or at least that attempts will be made), and figure out how it's most likely to happen so that you can work to prevent it. A good place to look for vulnerabilities is in edge cases, which are often overlooked and can contain unexpected security vulnerabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defense In Depth
&lt;/h2&gt;

&lt;p&gt;It's important to have multiple defenses in place. This decreases your reliance on any one defense, while at the same time increasing the difficulty of getting into your system.&lt;/p&gt;

&lt;p&gt;The three main categories of defenses to consider are physical, technical, and administrative. Physical defenses are defenses applied to your servers and hardware to prevent unauthorized access, which can include limiting building access, having proper security protocols, and locking up important hardware. Technical defenses, which include firewalls, antivirus, logging attempted hacking events, and data backups, provide defense for the software and network. Encrypting data, forcing multi-factor authentication for user login, and applying the principle of least privilege to your code are all part of creating technical defenses. Administrative defenses are policies and procedures put in place to enforce security and can include writing a formal security policy, training and security reviews, and penetration testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Through Obscurity
&lt;/h2&gt;

&lt;p&gt;The less information you give out, the better. Information is valuable, and giving out information on a need-to-know basis helps keep your app secure. As a web developer, you want to be careful what information you make visible - hide any file extensions or version information that the app does not need to run. The more information a hacker can find about what languages and software you use, the easier it is for them to focus their attack. The instructor gave an example of a PHP app, which creates pages with a &lt;code&gt;.php&lt;/code&gt; extension. If you have such an application, you should configure your server to remove that extension before displaying the page so that hackers do not know that you are using PHP (and therefore may not know to focus their attack on known PHP vulnerabilities).&lt;/p&gt;

&lt;p&gt;Security through obscurity is not itself the best defense, but it works well as part of defense in depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deny Lists and Allow Lists
&lt;/h2&gt;

&lt;p&gt;"Deny lists" and "allow lists" are exactly what they sound like - lists of objects or actions that are either forbidden or allowed. Allow lists are a better choice for maintaining security because they assume by default that actions are forbidden, and actions are only allowed if they are explicitly listed. Deny lists assume that everything is permitted unless it is on the deny list. When adding a new option or object that should be restricted, if you're using a deny list, it will assume that that new thing is permitted, whereas an allow list will assume it is forbidden. Allow lists provide better default security for the same reason that "trust no one" is a good policy - the best security assumes that all intentions are malicious and all actions are bad unless explicitly told otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map Exposure Points and Data Pathways
&lt;/h2&gt;

&lt;p&gt;Mapping the movement of data and where it could be exposed will help increase awareness of the areas where your data is vulnerable, which then helps you protect against those vulnerabilities.&lt;/p&gt;

&lt;p&gt;Data security goals can be summarized with the acronym CIA, which stands for confidentiality, integrity, and availability. Confidentiality means that our data is only available to privileged users. Integrity means that data is correct and can be trusted. Availability means that data is available when needed.&lt;/p&gt;

&lt;p&gt;Understanding the general principles of web security is important to developing a secure app, but it's only the first step. Stay tuned for future articles in this series as I share what I've learned about filtering input, regulating output, and some common attacks (and defenses against them).&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Three Years In</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 17 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/sarahscode/three-years-in-1d0i</link>
      <guid>https://dev.to/sarahscode/three-years-in-1d0i</guid>
      <description>&lt;p&gt;August 14th, 2017. I suppose I could call that the first day of the rest of my life (or at least this part of my life). It was the day I officially started the Web Development Fellowship at Fullstack Academy of Code.&lt;/p&gt;

&lt;p&gt;I've written pretty extensively about that experience (&lt;a href="https://medium.com/@sarahscode/the-end-and-beginning-of-a-journey-my-time-at-fullstack-academy-d2912e407eab" rel="noopener noreferrer"&gt;here's one recap post I wrote&lt;/a&gt;), but to summarize, it was a positive experience. I learned a lot, met some wonderful people, and really started to love being immersed in the tech ecosystem. These five months were not all sunshine and roses, as I found certain concepts more difficult than I expected. But more than that, I struggled to find my place in the community, and I worried that if I couldn't find my place in my bootcamp, I would never find a place in the greater developer community. I graduated from Fullstack in December 2017 excited to go forth and start my career in software engineering.&lt;/p&gt;

&lt;p&gt;After a relatively short search, I found my first actual real life developer job. I was hired by a consulting firm as a fullstack developer (my official title was "Fullstack UI Developer"), working full-time onsite for one of their clients. I was originally told that the job would start with an automation testing project and then transition into feature work, but that transition to feature work never came, and I was unhappy about the fact that I wasn't given much opportunity to do the work I enjoy. There were some good things about that job - I met some great people and had an opportunity to learn a lot from (and with) them. One major lesson I learned at that job was the importance of thorough testing. But ultimately, this job was not an ideal opportunity for me. Not only did I eventually realize that I wasn't what the company really needed (I was hired as a javascript developer and only had experience in that area, and what they really needed was a SDET who had education and experience in automated testing and could have better guided that project), I really did not feel well-supported, either by the consulting firm that I officially worked for or by the client where I was spending all of my time. While it was ultimately the company's decision to let me go, I'm happy that our relationship ended when it did and that I can still look back on some of the good from that job.&lt;/p&gt;

&lt;p&gt;The end of that job brought on one of the hardest parts of my career to this point - my second job search. I went into the search excited and optimistic. This was a chance to learn from my mistakes and find a job that would be right for me from the start. I knew there were a lot of great jobs out there, and now that I had a year of experience under my belt, I was in a better position to find that right job. But the interviews didn't come, and when they did, they didn't lead to offers. I tried to be optimistic, but as the search dragged on, I became very discouraged. I considered leaving the industry several times. To be honest, I think the only reason I didn't quit is because I didn't see any non-tech options (that I was comfortable with based on my life and financial needs) open to me. I even ended up "lowering" my standards and applying for entry-level jobs with no experience required, but that didn't work out either. I had several companies tell me that they liked me as a potential teammate but I didn't fit their technical needs, which made me wonder if I should be applying for non-technical positions at these companies. Eventually, after nine long and frustrating months of searching, I got the offer I was looking for, and I started preparing for my second software engineering job.&lt;/p&gt;

&lt;p&gt;On November 4th, 2019, I started my current job, as a full stack software engineer working at a healthtech company. I've been here for nine months, and while it's not 100% perfect (nothing ever is), things are going fairly well. From the start, I've had the opportunity to work on projects I enjoy, ranging from creating new frontend components to fixing small bugs to refactoring existing components (and lots of big and small tasks in between). I've noticed a large amount of growth in my technical skills. However, I haven't seen the career growth I was hoping for, and based on the discussions I've had, a large part of that is because of interpersonal skills. Working with others, while it is sometimes something I enjoy, has always been difficult for me. I'm not comfortable reaching out to others to ask for help, and when I do receive help (either in the form of pairing with a teammate or through comments left on my PRs), it can be hard for me to fully understand what my teammate is trying to say and to see constructive comments in the midst of what often looks like criticism. I've always struggled with communication, and knowing that my struggles are holding me back at the company has made me feel like my technical growth has not been worth it. Thankfully, I've gotten a lot of good feedback and suggestions on how to grow my communication and collaboration skills, and I know I can use that feedback to guide my continued growth.&lt;/p&gt;

&lt;p&gt;That brings us to the present. Three years in the industry and I do feel like I've grown my technical skills, but I'm not sure how much I've progressed in my career. When I started off my career, I never had an exact path of growth that I wanted to follow, so it's hard for me to gauge where I am in my career growth. Thankfully, I recently rediscovered a &lt;a href="https://medium.com/@sarahscode/gooooooooooooooals-514a9c6fcc28" rel="noopener noreferrer"&gt;blog post I wrote at my first job&lt;/a&gt; that listed my goals for the next three years. Here are the very broad goals I wrote:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Year One: Developer&lt;/li&gt;
&lt;li&gt;Year Two: Developer and Mentor&lt;/li&gt;
&lt;li&gt;Year Three: Team/Project Lead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though I've been in the industry for three years, between education, a suboptimal work situation, and job searching, I feel like I have about the amount of knowledge and hands-on experience that you'd expect from someone with 1-1.5 years of experience in the field. Using that barometer, I'm about where I want to be, maybe behind schedule. In the next year, I'd like an opportunity to help mentor and guide some newer devs at my company, or possibly dedicate a little bit of time to mentoring someone looking to get into the industry (although I'm not sure I'm comfortable committing that much time outside of work). I'd also like to be at the engineer II level in a year from now, either at my current company or starting a new position at that level.&lt;/p&gt;

&lt;p&gt;To reach the next level in my career, I know I need to focus on growing my interpersonal skills. I've received some great feedback on where to start, and I've already started to search out opportunities to grow my communication and collaboration skills. I know it's going to be a struggle and I may never get to the level I need to be at to advance at my current company, I know I can make some improvement in this area and I will be a better developer the more I learn to collaborate with others and to interpret their comments on my work in a positive way. While I am currently focusing on growing my interpersonal skills, I want to continue to grow my technical skills. I know there will always be more to learn, and even if it is not my focus, I want to always be learning new technical skills. While my technical skills are enough and I shouldn't feel bad about the skills I have not yet acquired, there is always room to grow and acquire new technical skills and knowledge.&lt;/p&gt;

&lt;p&gt;I don't think I ever had specific expectations for myself when starting my career in tech, so I don't know if I am where I expected myself to be three years into the journey. I do know that I have contributed a lot to my current company (and hopefully a little to my former company), and I still have a lot left to give to my company and to the industry. I may still struggle with interpersonal communication, and I may not feel like I've found my place in the developer community (either as a whole or the dev team at my company), but I know that I want to continue sharing my thoughts, sharing my knowledge, and just being present and contributing in any way I can - including in collaboration with my teammates.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Don't Do Personal Projects Outside of Work</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 20 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/sarahscode/i-don-t-do-personal-projects-outside-of-work-480e</link>
      <guid>https://dev.to/sarahscode/i-don-t-do-personal-projects-outside-of-work-480e</guid>
      <description>&lt;p&gt;Since starting my career in tech, I've seen and heard many people emphasize the importance of working on projects outside of work, either personal projects or contributing to open source software. At first I bought into that idea - I tried to start personal projects or find places to contribute to open-source - but eventually I realized that it wasn't right for me. I've learned that am at my best when I don't work on personal projects (or anything else coding-related) outside of work.&lt;/p&gt;

&lt;p&gt;The main reason why I don't work on personal projects is because when I "leave" work for the day, I want to do just that - leave my work behind me. I enjoy writing code to solve problems, but I don't want it to be my entire life. I have other interests, and I'd rather spend my time after work pursuing those interests. I don't want to go straight from writing code for work to writing code for a personal project - I want a break from writing code and using code to solve problems. My brain (or at least that part of my brain) needs a chance to turn off. I need a chance to focus on something else and do something that doesn't involve staring at a screen and typing.&lt;/p&gt;

&lt;p&gt;It took me a while to get to the point where I didn't see personal projects as essential. Early in my career I felt that the best way for me to learn how to be a developer and to learn things that I might not be heavily exposed to at work was to work on personal projects. But I often ended up starting a project and not finishing it, or not really learning as much as I expected. What I've started doing over the last few months (and my manager has encouraged this, which I very much appreciate) is setting aside 30 minutes during the work day to learn something new, generally by reading documentation or watching videos (and taking notes on those videos). If I come across something that I think I will learn better by coding (and I have a few things in mind where that will be the case), I am okay with starting a project and writing some code - but I plan to do most of it during that 30 minute period I set aside. I want to learn new things and still preserve a work-life balance.&lt;/p&gt;

&lt;p&gt;Another reason why I had originally planned to do personal projects was to keep my a certain level of activity on my GitHub profile. At my last company, I used my regular GitHub account, so while all of our repositories were private, the contributions still showed on my GitHub profile. My current company uses Enterprise GitHub, which means that my contributions don't show up on my personal GitHub profile. At first I was afraid of how having a not-so-busy GitHub profile would make me look in future job searches, but after some reflection, I realized that any future employer that I wanted to work for would understand that my GitHub profile does not reflect my abilities and would find another way to test my coding skill.&lt;/p&gt;

&lt;p&gt;While I choose not to do personal projects, I don't see choosing to spend time on personal projects as any sort of problem. Some people love writing code so much that they want to do it as a hobby and a job, and I truly admire those people. But that's not me. If I'm in a situation where whipping up a quick personal project or contributing to an open source repository feels like my best option to solve a problem, then I'm happy to do it, but in most situations, coding outside of work is just not something I'm interested in doing. And that's okay.&lt;/p&gt;

&lt;p&gt;In the tech industry, there can sometimes be an expectation that you continue to code even after the work day is done. Personal projects, resume boosters, and even just learning experiences can be an expected part of your time off. I know that some people love working on personal projects in their free time, and that's awesome, but it's just not for me. I prefer to separate what I do at work from what I do after work - and part of that is putting away the coding and focusing on other interests when I'm not on the clock.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>A Tale of A Refactor</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 29 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/sarahscode/a-tale-of-a-refactor-4epc</link>
      <guid>https://dev.to/sarahscode/a-tale-of-a-refactor-4epc</guid>
      <description>&lt;p&gt;Today I'd like to tell you a story. I call this the story of the refactor, or how I ended up breaking (and then fixing) one functionality while trying to add another functionality.&lt;/p&gt;

&lt;p&gt;Last week I started working with a new team (same company, but different part of the product), and my first ticket is a doozy. On the surface, it seems simple - adding a new functionality to an existing feature. To make it even easier ... this functionality already exists elsewhere in the app. I figured it would be fairly easy, at least at the beginning - find the component where the functionality already exists, then copy the code for the functionality into the feature where it needs to be. I tracked down what code controlled the feature I was working with and where the functionality I was adding existed in a different feature, and it turns out that functionality had its own component, so I started by importing the component. And that's where things stopped being simple.&lt;/p&gt;

&lt;p&gt;The component that controls this functionality received a number of props. Those props were passed down through several levels of components ... and I got lost trying to trace it. Our team tech lead had offered to help out, so we took some time to go through and figure out a good approach. We got a little confused trying to trace everything, but eventually we found where the props were originally coming from. And it seemed like there was no easy way to get them to where we needed the functionality to be added.&lt;/p&gt;

&lt;p&gt;It seemed like some serious refactoring would need to happen. We discussed some ideas of what needed to be done, and then I decided to spend some time moving things around to figure out the best way to add this new functionality. I even floated the idea of writing something from scratch and fitting the existing functionality into that, but it seemed like that might be too much effort and refactoring was a better way to go. And so, I opened my code editor and began to work.&lt;/p&gt;

&lt;p&gt;I moved some things. I got the new functionality working, but some of the existing functionality was not working. So then I tried moving other things. I tried creating new components and then deleted those new components. I got to the point where everything but the functionality that I moved around the most was working, and eventually I got that working too. But even once I had the functionality working (and only a few cosmetic changes to make), I still knew there was more to be done.&lt;/p&gt;

&lt;p&gt;With all of the functionality working, the next step is to refactor my refactor. I plan to start by going through all of the files I've touched and deleting any props or functions that are not being used anymore. I also want to separate some blocks of code into their own components, as I know that would improve readability. I may even try to simplify some of the functions that are used to validate form data, as that was one of the areas where I ran into a lot of difficulty getting functionality to work.&lt;/p&gt;

&lt;p&gt;The last major work that needs to be done is fixing the tests I broke (and writing new tests for the new functionality). Unfortunately, our current tests are testing implementation details, not just functionality, so in changing the implementation details, I broke a lot of tests. We are in the process of converting the tests in our codebase to use a library that focuses on testing user behavior, not implementation details, but the tests for the code I was working on have not yet been converted. I'm considering rewriting the tests to no longer test implementation details, but I'm not sure if that's outside the scope of the ticket, so I will discuss it with one of my teammates and get his take on the best way to approach the tests.&lt;/p&gt;

&lt;p&gt;All of the functionality may be working, but there's still work to be done on my refactor. I'm hoping that with all of my work to refactor I end up deleting more code than I added (which would be really cool when adding functionality), but we'll see how it goes. That's a secondary goal - the primary goal is still to have all of the functionality done and the code written in an understandable and readable way.&lt;/p&gt;

&lt;p&gt;When faced with existing code and a task that doesn't seem easy to fit into the code, it can be hard to figure out where to get started. Sometimes it's easier to just start the new task from scratch and then fit it into the existing code, but often it's less complex to just refactor the existing code. With this particular task, I had a hard time figuring out where to get started with the refactor, but the great part about working with a team is that I had a teammate who was available to help me figure it out. Refactoring code can be tough, but it's a great way to make sure your code is doing what it's expected to do (and only what it's expected to do), and as a new person on this team, I appreciated the opportunity to work on a ticket that exposed me to more than just the functionality I was adding.&lt;/p&gt;

</description>
      <category>story</category>
    </item>
    <item>
      <title>React-Router Hooks: A Brief Introduction</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Sun, 24 May 2020 21:40:09 +0000</pubDate>
      <link>https://dev.to/sarahscode/react-router-hooks-a-brief-introduction-173n</link>
      <guid>https://dev.to/sarahscode/react-router-hooks-a-brief-introduction-173n</guid>
      <description>&lt;p&gt;React-Router, a popular declarative routing library for React, &lt;a href="https://reacttraining.com/blog/react-router-v5-1/"&gt;recently released hooks as part of their API&lt;/a&gt;. I came across one of these hooks as part of my work, and I thought it would be interesting to dig into them a little bit more.&lt;/p&gt;

&lt;p&gt;This article provides a very basic overview of the four hooks that were included with React Router v5.1. This is by no means a comprehensive article, but my goal is to provide information to help you decide whether it would be worth trying to implement these hooks in your app.&lt;/p&gt;

&lt;p&gt;Four hooks were introduced with this release - &lt;code&gt;useParams&lt;/code&gt;, &lt;code&gt;useHistory&lt;/code&gt;, &lt;code&gt;useLocation&lt;/code&gt;, and &lt;code&gt;useRouteMatch&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useParams&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This hook is intended for use in any situation where you would have used &lt;code&gt;match.params&lt;/code&gt;. For example, if you're looking to get the id in the url &lt;code&gt;www.mysite.com/page/:id&lt;/code&gt;, here's how your code could change:&lt;/p&gt;

&lt;p&gt;Old Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;New Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useParams&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;While the cleaner-looking code would be enough of a reason for me to use it, &lt;code&gt;useParams&lt;/code&gt; actually has one even bigger advantage - it allows you to access params anywhere in the component tree without explicitly passing them down. For example, if you have &lt;code&gt;ComponentA&lt;/code&gt; which calls &lt;code&gt;ComponentB&lt;/code&gt;, here's how your code might change:&lt;/p&gt;

&lt;p&gt;Old Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Component A:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ComponentB&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RoutedComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ComponentA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Component B:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My ID is: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;New Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ComponentB&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Component B:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useParams&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My ID is: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm always appreciative of an opportunity to not pass down props, so I anticipate using &lt;code&gt;useParams&lt;/code&gt; quite a bit in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useHistory&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This hook provides access to the history object. &lt;code&gt;useHistory&lt;/code&gt; is not intended as a long term solution - it will eventually be replaced by another hook called &lt;code&gt;useNavigation&lt;/code&gt; - but it was included in this release to make it easier for teams to move away from &lt;code&gt;withRouter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This would be used in the same way as you would use &lt;code&gt;props.history&lt;/code&gt;. For example, if you want to make a button that redirects the user to the home page any time they click it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BackButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useHistory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Paradise City&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Any action that can be performed with the history API can also be performed with the history object returned from &lt;code&gt;useHistory()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useLocation&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This hook provides access to the location object, which is useful for any component that needs to know the current URL. &lt;br&gt;
For example, if your app has several "FAQ" pages and you want to navigate to the FAQ page for your current location, here's how your code might change:&lt;/p&gt;

&lt;p&gt;Old Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LinkToFaqComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/faq`&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Read&lt;/span&gt; &lt;span class="nx"&gt;Our&lt;/span&gt; &lt;span class="nx"&gt;FAQ&lt;/span&gt; &lt;span class="nx"&gt;Here&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LinkToFaq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LinkToFaqComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;New Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LinkToFaq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="err"&gt;`$&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;faq&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Read Our FAQ Here!
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The difference in this example isn't that large, but the more complex your location-related logic is, the more you will see a difference with the use of the &lt;code&gt;useLocation&lt;/code&gt; hook.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useRouteMatch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This hook is used when you just want route match data without actually having to render the route. I haven't seen this hook used in action, so I'll direct you to the &lt;a href="https://reacttraining.com/react-router/web/api/Hooks/useroutematch"&gt;official documentation&lt;/a&gt; for an example of its use for this purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;Seeing React-Router introduce hooks is a great thing, but it doesn't mean that everyone should rush to put these hooks in all of your apps right now. &lt;code&gt;withRouter&lt;/code&gt; is still supported and will continue to be supported in React Router v6 (whenever that comes). If your app isn't designed in a way that you can easily convert to using hooks, that may be a good use case for continuing to use &lt;code&gt;withRouter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That said ... if you're creating a new functional component (or you're refactoring a class component that can easily be converted into a functional component) and you need access to route props, this would be a great opportunity to start using these new hooks. Hooks are the future of React and several other libraries that are popular in React applications (including react-redux and react-router), so the more you make hooks part of your regular development, the easier it will be to adapt to future changes.&lt;/p&gt;

</description>
      <category>reactrouter</category>
      <category>hooks</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>It's Not Always Impostor Syndrome</title>
      <dc:creator>Sarah Katz</dc:creator>
      <pubDate>Mon, 27 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/sarahscode/it-s-not-always-impostor-syndrome-c36</link>
      <guid>https://dev.to/sarahscode/it-s-not-always-impostor-syndrome-c36</guid>
      <description>&lt;p&gt;Impostor syndrome is a hot topic in the tech world. I've written about it in the past, and it was a huge struggle for me when I started my current job. Almost six months later, I know I'm doing better and don't feel quite like an impostor, but I am still struggling at work, and I sometimes find myself (and others) labeling my struggles as "impostor syndrome", when I know that's not the case.&lt;/p&gt;

&lt;p&gt;Early in my time at this company, I was worried that my teammates would find out that I'm not quite as capable as they thought I was. I was afraid my boss would discover that I can't really do the things I was hired to do. That feeling has subsided somewhat. At this point, I think my team has a fairly good assessment of what I can and can't do, and I'm not quite as afraid that my team will come across something that I can't do, because I know that they'll accept it and help me figure out where to go from there.&lt;/p&gt;

&lt;p&gt;For the past few weeks, I've been feeling extremely frustrated at work. At first, I thought it was a return of my impostor syndromebut then I realized ... the things I think I can do, I can do decently. Maybe my work isn't perfect, but I think it's at an acceptable level for an early-career junior developer. The problem is ... the things I'm comfortable doing are the same things I felt comfortable doing 6 months ago. I came into this role knowing that it would be a great opportunity for me to learn and grow, and I just don't feel like I've learned very much. And that frustrates me, because I know the opportunities are there, and I wish I was taking advantage of them. Maybe if I looked more carefully at the work I've done over the past few months I'd see improvements, but the fact that I don't feel like I've grown at all and that the things I've learned haven't had an impact on me is extremely frustrating.&lt;/p&gt;

&lt;p&gt;As much as I hate then fact that I'm so frustrated by my self-perceived lack of learning and growth in my current position, I am glad that I've spent the time figuring out what has caused all (well, most) of my recent frustration. Now that I know what's frustrating me, I can start working on lessening that frustration. I can look back at some of my old work and old PRs and see if there's anything I can do better based on what I know now. I can talk to my manager and get her advice on how to handle my frustration. I can ask my teammates to specifically call out my improvements when they see them (because sometimes they will notice improvements that I don't). I've always had trouble leaning on the people around me for support, and that trouble is magnified when I don't even know what support I need. Now that I know what the problem is, it will be easier for me to understand how my team can support me.&lt;/p&gt;

&lt;p&gt;Impostor syndrome can be very detrimental to someone's career. If it is not discovered and discussed, very capable and talented people may hold themselves back in their careers because they don't feel worthy of advancement. But impostor syndrome is not the only thing that can cause frustration and hold people back. When someone is feeling frustrated or unworthy at work, it's important to investigate the true cause. There are ways to help someone deal with impostor syndrome, but those methods may not help if the cause of someone's frustration is in fact not feeling like an impostor or fraud. It's important to understand that impostor syndrome is not the cause of every difficulty.&lt;/p&gt;

&lt;p&gt;I have suffered from impostor syndrome in the past, and I'm sure I'll encounter it again in the future. But right now that's not what is causing my frustration at work, and I know that I'd be hurting my chances of feeling more comfortable at work if I mislabeled my frustrations as impostor syndrome. There's a time for everything, and right now it's time for me to figure out why I'm not learning as much as I had hoped at work and how to solve that specific problem.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
