<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title><![CDATA[ Engineering &amp; Data Science - Bamieh Tech blog ]]></title>
<description><![CDATA[ A collection of articles by software engineers &amp; data experts ]]></description>
<link>https://blog.bamieh.com</link>
<image>
    <url>https://blog.bamieh.com/favicon.png</url>
    <title>Engineering &amp; Data Science - Bamieh Tech blog</title>
    <link>https://blog.bamieh.com</link>
</image>
<lastBuildDate>Wed, 22 Apr 2026 03:15:13 +0300</lastBuildDate>
<atom:link href="https://blog.bamieh.com" rel="self" type="application/rss+xml"/>
<ttl>60</ttl>

    <item>
        <title><![CDATA[ Detect anomalies in your data with Elasticsearch &amp; Kibana ]]></title>
        <description><![CDATA[ A digestible introduction to anomaly detection using Elasticsearch and Kibana without diving too deep into data science ]]></description>
        <link>https://blog.bamieh.com/anomaly-detection-with-elasticsearch-kibana-part-1/</link>
        <guid isPermaLink="false">61c999d698cb8d003b71ca36</guid>
        <category><![CDATA[ Engineering ]]></category>
        <dc:creator><![CDATA[ Ahmad Bamieh ]]></dc:creator>
        <pubDate>Wed, 02 Feb 2022 19:20:15 +0200</pubDate>
        <media:content url="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/cover_ghost@2x-2.png" medium="image"/>
        <content:encoded><![CDATA[ <p>A three parts series to cover anomaly detection using Elasticsearch and Kibana. My goal is to provide a digestible introduction to anomaly detection without diving too deep into data science. I'll guide you through creating your first anomaly detection job through Kibana then adding alerts on top. Hoping to excite you to explore the incredible ML capabilities of the Elastic stack.</p><p>Part 1: Get started with anomaly detection <em>(you're here)</em><br>Part 2: Create your first anomaly detection job  <em>(coming next week)</em><br>Part 3: Add alerting to your ML jobs <em>(coming later)</em></p><hr><p>Not so long ago, machine learning (ML) and applications like anomaly detection were only accessible to ML specialists and seasoned data analysts. Lucky for us, solutions like Elasticsearch and Kibana allow data professionals and engineers to gain unique insights from their data through ML quickly and with ease.</p><p>I've recently read the book <a href="https://www.amazon.com/gp/product/B091V4GXLV/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B091V4GXLV&linkCode=as2&tag=bamieh-20&linkId=dc5895d34bed0a29c2bb36f9d11db18d&ref=blog.bamieh.com" rel="noopener">Machine learning with the Elastic Stack</a>, the main driver for writing this series. I highly recommend reading this book if this article piques your interest as it goes into great detail explaining Elastic's ML capabilities, configurations, and applications in practice.</p><h2 id="entering-anomaly-detection">Entering anomaly detection</h2><p>Anomaly detection is simply a way to find data points or patterns in your data that are different from usual. There are two heuristics that we could use to define the different kinds of anomalies:</p><ul><li><strong>Temporal: </strong>Something is unusual if its behavior diverges  significantly from an established pattern in its own behavior over time.</li><li><strong>Population:</strong> Something is unusual when it is drastically different from its peers in population.</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/anomaly_types@2x.png" class="kg-image" alt loading="lazy" width="2000" height="1124" srcset="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w600/2022/02/anomaly_types@2x.png 600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1000/2022/02/anomaly_types@2x.png 1000w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1600/2022/02/anomaly_types@2x.png 1600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w2400/2022/02/anomaly_types@2x.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>population vs. temporal anomalies</figcaption></figure><p>Elasticsearch uses <em>unsupervised learning</em> to detect anomalies in the data. The gist of unsupervised learning is that the algorithms learn the data patterns independently with no outside guidance or assistance from humans, which is a massive win for us!</p><h3 id="why-you-should-care">Why you should care</h3><p>It is not uncommon to see companies handle terabytes of critical information through continuous data streams from their solutions. Examples of such data vary from things like purchase logs,  user interactions, and all the way to system logs and network activity.</p><p>In general, there are three main approaches to sifting through this plethora of data:</p><ol><li><strong>Manually watch the data</strong> looking for anomalies through visualizations and analyses.</li><li><strong>Define rules or conditions</strong> to trigger under specific requirements.</li><li><strong>Use Machine learning to detect anomalies</strong> in data and proactively take action.</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/approaches@2x.png" class="kg-image" alt loading="lazy" width="1907" height="497" srcset="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w600/2022/02/approaches@2x.png 600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1000/2022/02/approaches@2x.png 1000w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1600/2022/02/approaches@2x.png 1600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/approaches@2x.png 1907w" sizes="(min-width: 720px) 720px"><figcaption>Approaches to sifting through data — Icons from Elastic’s <a href="https://elastic.github.io/eui/?ref=blog.bamieh.com#/display/icons" rel="noopener">EUI library</a></figcaption></figure><p>It goes without saying that <strong>manually watching</strong> incoming data to detect issues proactively is both costly and error-prone. A less obvious fault of this approach is that a human eye cannot detect all anomalies. There are a few key things to recognize about these less-than-obvious anomalies:</p><ul><li>A pattern is not anomalous by itself but is interestingly significant.</li><li>Lack of expected values  can be anomalous if there's an expectation that events should occur.</li><li>An  anomaly spans multiple entries rather than a single data point. These are called multi-bucket anomalies.</li></ul><p><strong>Setting Thresholds or rules</strong> to catch anomalies proactively is a lot better than manual labor. However, it is unlikely to define the entire ruleset needed to get reliable and accurate results. Plus, the velocity of changes in the applications and environments could quickly render any static ruleset useless. Analysts find themselves chasing down many false positive alerts, setting up a boy who cried wolf paradigm rendering the generated results useless.</p><p><strong>Using anomaly detection</strong> enables teams to act proactively on early signs only surfacing a small set of relevant data points to help in the identification of the root cause while filtering out the noise of irrelevant behaviors that might distract human analysts from the things that actually matter.</p><p><em>Detecting anomalies through the Elastic stack is fast, scalable, accurate, low-cost, and easy to use.</em></p><p>Many important use cases revolve around detecting anomalous events over time <em>(temporal anomalies)</em>, such as:</p><ul><li>Detect an unusual <strong>purchasing behavior</strong> of specific customers or a sudden change in overall sales.</li><li>Proactively detect unexpected <strong>piling up of messages</strong> in application log files.</li><li>Track down <strong>unauthorized access attempts</strong> or suspicious user activity.</li></ul><p>Finding outliers in a dataset <em>(population anomalies)</em> is critical in several applications such as fraud detection or detecting defects in manufacturing lines.</p><h3 id="how-does-it-work">How does it work?</h3><p>Anomaly detection works on  live data streams by ingesting <strong>time series data </strong>grouped  into discrete time units called buckets. The model allows users to specify <strong>a detector function such as average or sum</strong>,<strong> </strong>computed on each bucket. The model then calculates the <strong>probability distribution </strong>of each bucket and continuously updates this distribution as more data is ingested. <strong>The model scores the data points based on their probability</strong> <strong>distribution</strong>. The lower the probability of the data points, the more likely it'll be flagged as an anomaly.</p><p>A rather complex orchestration occurs to enable the ML models to continuously ingest and learn from live data streams. Elasticsearch automatically handles all the complex logistics required to make it all happen, from maintaining the model states to data ingestions and managing the cluster.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/process@2x.png" class="kg-image" alt loading="lazy" width="1945" height="876" srcset="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w600/2022/02/process@2x.png 600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1000/2022/02/process@2x.png 1000w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/size/w1600/2022/02/process@2x.png 1600w, https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2022/02/process@2x.png 1945w" sizes="(min-width: 720px) 720px"><figcaption>Machine learning jobs process — Icons from Elastic’s <a href="https://elastic.github.io/eui/?ref=blog.bamieh.com#/display/icons" rel="noopener">EUI library</a></figcaption></figure><p>The machine learning nodes in Elasticsearch are responsible for running the anomaly detection jobs, which analyze the incoming data against the ML model. While the models keep their state in memory, snapshots of the  latest states are also synced into Elasticsearch. This allows users to revert a job into a previous state in case something unexpected happens. The analysis results are stored in Elasticsearch to be consumed by Kibana or  through API access.</p><p>The anomaly job model comes with many powerful out-of-the-box features that are also highly configurable. I'll highlight a few here:</p><p><strong>De-trending: </strong>Elastic’s  ML models automatically factor out trends in the data such as linear and cyclical patterns. De-trending is essential for modeling real-world datasets to account for seasonal cycles and linear growth and shrinkage.</p><p><strong>Splitting jobs: </strong>Elastic’s ML allows splitting the analysis based on categories in the data. Splitting jobs helps the model find more detailed patterns in each category and run the analysis for each in parallel.</p><p><strong>Influencers: </strong>Elastic ML automatically identifies relevant fields in the dataset that have contributed significantly to anomalous behavior.</p><h2 id="final-thoughts">Final thoughts</h2><p>There are many more exciting details and advanced configurations <a href="https://www.amazon.com/gp/product/B091V4GXLV/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B091V4GXLV&linkCode=as2&tag=bamieh-20&linkId=dc5895d34bed0a29c2bb36f9d11db18d&ref=blog.bamieh.com" rel="noopener">Machine learning with the elastic stack</a> goes into detail about elastic's ML capabilities in both supervised and unsupervised learning.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.amazon.com/gp/product/B091V4GXLV/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B091V4GXLV&linkCode=as2&tag=bamieh-20&linkId=dc5895d34bed0a29c2bb36f9d11db18d&ref=blog.bamieh.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Amazon.com: Machine Learning with the Elastic Stack: Gain valuable insights from your data with Elastic Stack’s machine learning features, 2nd Edition eBook : Collier, Rich, Montonen, Camilla, Azarmi, Bahaaldine: Kindle Store</div><div class="kg-bookmark-description">Amazon.com: Machine Learning with the Elastic Stack: Gain valuable insights from your data with Elastic Stack’s machine learning features, 2nd Edition eBook : Collier, Rich, Montonen, Camilla, Azarmi, Bahaaldine: Kindle Store</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.amazon.com/favicon.ico" alt=""><span class="kg-bookmark-publisher">Visit Amazon’s Rich Collier Page</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://fls-na.amazon.com/1/batch/1/OP/ATVPDKIKX0DER:147-4417233-7991647:HFGFZJBVYWPT1JAN131H$uedata&#x3D;s:%2Frd%2Fuedata%3Fstaticb%26id%3DHFGFZJBVYWPT1JAN131H%26pty%3DError%26spty%3DPageNotFound%26pti%3D:1000" alt=""></div></a></figure><p>Next week I will publish the second part of this series:<strong> Create your first anomaly detection job: </strong>a step-by-step guide to write your first anomaly job through Kibana within 15 minutes! Stay tuned and follow to get notified.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ You’re missing out on ImmutableJS records ]]></title>
        <description><![CDATA[ ImmutableJS records are super simple to use and provide tremendous advantages over the regular Map. This post will introduce you to records, what are they, and how to start using them right now. ]]></description>
        <link>https://blog.bamieh.com/immutablejs-records/</link>
        <guid isPermaLink="false">61c87a4c1cc2e80048b88804</guid>
        <category><![CDATA[ Engineering ]]></category>
        <dc:creator><![CDATA[ Ahmad Bamieh ]]></dc:creator>
        <pubDate>Sun, 16 Jul 2017 16:26:00 +0300</pubDate>
        <media:content url="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2021/12/immutable-records.png" medium="image"/>
        <content:encoded><![CDATA[ <blockquote>ImmutableJS records are immutably beautiful! </blockquote><p>ImmutableJS records are super simple to use and provide tremendous advantages over the regular <code>Map</code> . This post will introduce you to records, what are they, and how to start using them right now.</p><h3 id="record-properties">Record Properties</h3><p>A <code>Record</code> is similar to ImmutableJS <code>Map</code> , however, it has the following unique features that make it special:</p><ol><li>You <strong>cannot add more keys</strong> to it once it has been constructed.</li><li>You can define <strong>default values</strong> for new record instances.</li><li>The properties of a Record Instance can be <strong>accessed like regular JS objects</strong> and can be <strong>destructed</strong> as well.</li><li>You can <strong>name</strong> a record, for better debugging and error handling.</li><li>You can extend the Record, to provide <strong>derived data</strong> from within the record.</li></ol><p>This post will discuss all the following properties, but first, let us create our first record!</p><h3 id="creating-a-record">Creating a record</h3><p>The <code>Record</code> method returns a constructor function in which new instances could be made out of it.</p><!--kg-card-begin: markdown--><pre><code class="language-ts">const LivingCreature = new Immutable.Record({
    name: 'Unknown',
    species: 'Human',
    age: 0,
});

const fooBar = new LivingCreature({name: 'Foo Bar', age: 24});
</code></pre>
<!--kg-card-end: markdown--><p>In this code snippet, we’ve created a Record of <code>LivingCreature</code> and made a new instance called <code>fooBar</code>. <strong>Note</strong> that this instance has the default species of <code>Human</code> .</p><h4 id="descriptive-name">Descriptive Name</h4><p>Records accept a second parameter for a descriptive name that appears when converting a Record to a string or in any error messages.</p><!--kg-card-begin: markdown--><pre><code class="language-ts">const NamedRecord = new Immutable.Record({ ... }, &quot;[NAME HERE]&quot;);
</code></pre>
<!--kg-card-end: markdown--><h4 id="retrieving-properties">Retrieving Properties</h4><p>Unlike other ImmutableJS objects, <strong>records can be accessed like normal JS objects.</strong></p><!--kg-card-begin: markdown--><pre><code class="language-js">const {name, species} = fooBar;

fooBar.name; // Foo Bar
fooBar['species']; // Human
</code></pre>
<!--kg-card-end: markdown--><h4 id="replacing-values">Replacing Values</h4><p>To replace <code>fooBar</code> living creature with another creature, simply *<em>swap records</em>*.</p><!--kg-card-begin: markdown--><pre><code>fooBar = new LivingCreature({
    name: 'Foo Bar Junior',
    species: 'Half Blood',
    age: 8,
});
</code></pre>
<!--kg-card-end: markdown--><h3 id="updating-values">Updating Values</h3><p>Using records, we can update <strong>multiple values at once</strong> using merge, in addition to using <code>set</code> to update a single value.</p><!--kg-card-begin: markdown--><pre><code>fooBar.set('age', 20);

// or

fooBar.merge({
 age: 25,
 species: 12,
});
</code></pre>
<!--kg-card-end: markdown--><h4 id="adding-new-keys">Adding new keys</h4><p>The record throws an error if you attempt to add non-initialized keys on it. The following examples will throw an error.</p><!--kg-card-begin: markdown--><pre><code>const newFooBar = new LivingCreature({ status: 'its complicated' });
const mergeFooBar = fooBar.merge({ status: 'its complicated' });
</code></pre>
<!--kg-card-end: markdown--><h4 id="removing-keys">Removing Keys</h4><p>Records always have a value for the keys they define. Removing a key from a record simply <strong>resets it to the default value </strong>for that key.</p><!--kg-card-begin: markdown--><pre><code>const newFooBar = fooBar.remove('name');
console.log(newFooBar.name); // → 'Unknown'
</code></pre>
<!--kg-card-end: markdown--><h4 id="derived-values">Derived Values</h4><p>One of the most powerful features that I personally love about records is their ability to derive data from within the record itself.</p><p>For example, let's say that we have a <em>'Cart'</em> of two items, and their <code>sum</code> . In normal cases, every time we update an item value, we have to update the sum as well. Soon you will feel that this is not the best practice;</p><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">👉</div><div class="kg-callout-text">Records come to the rescue!</div></div><!--kg-card-begin: markdown--><pre><code>class Cart extends Immutable.Record({ itemA: 1, itemB: 2 }) {
  get sum() {
    return this.itemA + this.itemB;
  }
}
var myCart = new Cart();
myCart.sum; // 3
</code></pre>
<!--kg-card-end: markdown--><p>Now we can update any value, and since the sum is derived from the record properties, there is no need to worry about updating it manually.</p><!--kg-card-begin: markdown--><pre><code>const updatedCart = myCart.set('itemA', 5);
updatedCart.sum; // 7
</code></pre>
<!--kg-card-end: markdown--><h3 id="conclusion">Conclusion</h3><p>Records provide an amazing advantage of allowing your immutable objects to be treated like normal objects, by having standard accessors and object de-structuring, hence any library or component that does not mutate objects will welcome the records like one of their own!</p><p>Additionally, since record keys must be specified when the record is created, reading the record will clarify its use and self-document its purpose. It also enforces a more strict code style since you cannot add any more keys to the record.</p><p>My team and I have been using ImmutableJS Records for a while now. I am surprised why it is usually overlooked and less popular than the standard <code>Map</code> .</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ NodeJS: Constant HashTable Seeds Vulnerability ]]></title>
        <description><![CDATA[ --------------------------------------------------------------------------------

You might have heard about the high-impact security vulnerability issue recently
fixed and announced by the NodeJS team. This post will attempt to explain the
issue, how and why it happened.

Thanks to the amazing effort of the team at NodeJS, this vulnerability has been
fixed immediately across releases ]]></description>
        <link>https://blog.bamieh.com/nodejs-constant-hashtable-seeds-vulnerability/</link>
        <guid isPermaLink="false">61c897d498cb8d003b71c9f4</guid>
        <category><![CDATA[ Engineering ]]></category>
        <dc:creator><![CDATA[ Ahmad Bamieh ]]></dc:creator>
        <pubDate>Thu, 13 Jul 2017 00:00:00 +0300</pubDate>
        <media:content url="https://storage.ghost.io/c/b3/cc/b3ccea49-516e-449d-9c96-af18740de17f/content/images/2021/12/Constant-HashTable-Seeds-Vulnerability.png" medium="image"/>
        <content:encoded><![CDATA[ <hr><p>You might have heard about the high-impact security vulnerability issue recently fixed and announced by the NodeJS team. This post will attempt to explain the issue, how and why it happened.</p><p>Thanks to the amazing effort of the team at NodeJS, this vulnerability has been fixed immediately across releases (4.x, 6.x, 7.x, and 8.x).</p><p>Make sure you upgrade your node version as soon as you can (preferably when you finish reading this post!). For upgrading your node head to the <a href="https://nodejs.org/en/blog/vulnerability/july-2017-security-releases/?ref=blog.bamieh.com" rel="noopener">official nodeJS blog</a> for details.</p><p>The vulnerability roots from Hash tables, so let us start with a quick recap on HashTables, just in case you missed your computer science classes.</p><h4 id="hashtables">HashTables</h4><p>HashTables fulfill the dream of *<em>constant time</em>* insertions and access.</p><p>Some of the places where HashTables are used:</p><ul><li>Method lookups.</li><li>Sets, Objects, and Maps.</li><li>HTTP headers.</li><li>JSON representations.</li><li>URL-encoded post form data.</li></ul><p>A HashTable is a group of linked lists, the linked lists must be small in order for the performance to be good.</p><p>The create HashTable function pre-allocates the number of linked lists it can contain, throughout this post, the number of linked lists the HashTable can hold is denoted by the word <code>l</code>.</p><blockquote>l = 2**n</blockquote><p>The best scenario for optimal performance is to have <code>n/l</code> entries in each linked list, where <code>n</code> is the number of entries in the HashTable. so if we have 256 entries in the HashTable, the perfect hash function would distribute them into the 256 lists, each holding only 1 entry.</p><h4 id="example-storing-strings-one-to-ten-in-a-hashtable">Example: Storing strings one to ten in a HashTable</h4><p>In this example, our hash function is the following:</p><blockquote>H(s) = first byte of s<br>l = 256</blockquote><p>In our “one” to “ten” example, inserting the values into the HashTable will result in something like the following:</p><!--kg-card-begin: markdown--><pre><code>{
  &quot;o&quot;: [&quot;one&quot;],
  &quot;t&quot;: [&quot;two&quot;, &quot;three&quot;, &quot;ten&quot;],
  &quot;f&quot;: [&quot;four&quot;, &quot;five&quot;],
  &quot;s&quot;: [&quot;six&quot;, &quot;seven&quot;],
  &quot;e&quot;: [&quot;eight&quot;],
  &quot;g&quot;: [],
  &quot;h&quot;: [],
  &quot;n&quot;: [&quot;nine&quot;],
  &quot;r&quot;: [],
  …
}
</code></pre>
<!--kg-card-end: markdown--><p>Notice that we have empty linked lists in the HashTable because they are not filled up by any value. Additionally, there is a pile-up on the <code>t</code> list in the HashTable. This is a <strong>bad</strong> hash function since it does not do a good job of distributing the strings through the linked lists. No matter how many linked lists you have, if the hash function does a bad job in the distribution among them you will get bad performance, since linked lists are slow, hash tables are fast by having only short linked lists in them.</p><p>To avoid overflowing the HashTable, since there are more <code>H(s)</code> results than <code>l</code>, the hash function is always reduced by <code>l</code> using <em>mod</em></p><blockquote>H(s) % l</blockquote><p><code>H(s) = first byte of s</code> is not a good hashing function. NodeJS implements a very good hash function that quickly looks through the whole string, and gives randomly looking results to spread the results across the HashTable.</p><p>Since we have a good hashing function, normal usage should *<em>never</em>* cause HashTables to over-flood. However, an attacker just might.</p><h4 id="hashing-malicious-strings">Hashing malicious strings.</h4><p>The attacker provides strings where <code>H(s)%l</code> will result in the same HashTable index, hence all these strings will be stored in the same linked list, making the app go super slow.</p><p>To solve such issues, programming languages looked at different solutions, some are the following:</p><h4 id="solution-1">Solution #1</h4><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">👉</div><div class="kg-callout-text">Replace linked lists with another structure, such as red black trees or any balanced tree structure.</div></div><p>However, most programs go with the simpler approach of using simple linked lists to avoid bugs, heavy re-writes, debugging issues, and implementation complexity.</p><h4 id="solution-2">Solution #2</h4><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">👉</div><div class="kg-callout-text"><em><em>Stop inserting into the linked list if it gets more than <code><em>n</em></code> entries.</em></em></div></div><p>This solution looks pleasant, but for real-world applications, you cannot just discard newly coming results, hence this solution is not viable for all situations. It can be only used in caching solutions.</p><h4 id="solution-3">Solution #3</h4><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">👉</div><div class="kg-callout-text">Use crypto hashing functions like <code>sha256</code>.</div></div><p>Crypto hash functions should be collision-resistant, you should not find any two strings with the same output.</p><p>But this solution is troublesome for two main reasons:</p><ol><li>The hash function should be fast, crypto hashes are not the fastest.</li><li>Even if the crypto hashes were fast enough, this does not solve the problem. The attacker does not need to find collisions in the crypto hashing function itself, instead, they need to find collisions in the output which is reduced to the number of <code>l</code> linked lists specified. <code>H(s)%l</code> is not collision-resistant based on the hashing function, since the output will always be reduced to the <code>2**n</code> lists. So the attacker might run a few million iterations to find critical amounts of collisions.</li></ol><h4 id="current-solution">Current Solution</h4><blockquote>Randomizing the hash function with a secret key.</blockquote><p>These attacks were repeated many times throughout the years under different names: low bandwidth denial of service attacks, hash flooding, algorithmic complexity attacks, etc.</p><p>Attacks were targeted at many programming languages, such as Perl, Redis, and python. Usually the response to these attacks is to secretly randomize the hash function on each application boot, or hashtable initialization, this way the attacker has no way to guess the hashing function hence they cannot find collisions because they do not know the secret key of the hashing function.</p><p>NodeJS uses the same approach, by randomizing its <strong>“HashTable seed”</strong>.</p><p>**<em>Whether this is actually secure or not is a debate for another time.</em></p><h3 id="the-nodejs-constant-hashtable-vulnerability">The NodeJS Constant HashTable vulnerability</h3><p>The vulnerability came along by a bug introduced in the <strong>randomizer</strong> of the HashTable seed where the seed was always the same for a given version of node.</p><blockquote>NodeJS was susceptible to hash flooding remote DoS attacks as the HashTable seed was constant across a given released version of NodeJS.</blockquote><p>For example, an HTTP node server is vulnerable to this attack since the URL-encoded post form data is stored in a HashTable on the heap. The attacker can send small payloads each with different input but yield the same hash key, across multiple post requests (say 10 bytes each), each request will accumulate the payload in the same HashTable linked list stored on the heap.</p><p>So after accumulating the requests and abusing the same linked list, the server will face huge delays in responses since it is synchronously trying to access the same linked list in the HashTable.</p><h3 id="the-cause">The Cause</h3><p>The JavaScript specification includes a lot of built-in functionality, from math functions to a full-featured regular expression engine. Every newly-created V8 context has these functions available from the start. For this to work, the global object (for example, the window object in a browser) and all the built-in functionality must be set up and initialized into V8’s heap at the time the context is created. It takes quite some time to do this from scratch.</p><p><strong>V8 uses 'snapshots' to solve this issue:</strong> A snapshot is basically a saved context that can be re-used in future boots.</p><blockquote>Fortunately, V8 uses a shortcut to speed things up: just like thawing a frozen pizza for a quick dinner, we deserialize a previously-prepared snapshot directly into the heap to get an initialized context. On a regular desktop computer, this can bring the time to create a context from 40 ms down to less than 2 ms. On an average mobile phone, this could mean a difference between 270 ms and 10 ms.</blockquote><p>Snapshots basically enabled NodeJS to reduce boot time by taking a snapshot of the pre-initialized boot context and using it for the next runs. Additionally, users are allowed to use custom snapshots to build on top of the original context.</p><p>The root cause of the vulnerability originates from having the v8 snapshots feature enabled by default, so the initial randomized hash table seeds are constant across each version of NodeJS. This minor error resulted in NodeJS being susceptible to remote DOS attacks via hash flooding.</p><h4 id="resources">Resources</h4><ul><li><a href="https://nodesource.com/blog/node-js-security-release-summary-july-2017?ref=blog.bamieh.com" rel="nofollow noopener noopener noopener">https://nodesource.com/blog/node-js-security-release-summary-july-2017</a></li><li><a href="https://v8project.blogspot.com/2015/09/custom-startup-snapshots.html?ref=blog.bamieh.com" rel="nofollow noopener noopener noopener">https://v8project.blogspot.com/2015/09/custom-startup-snapshots.html</a></li><li><a href="https://www.youtube.com/watch?v=Vdrab3sB7MU&t&ref=blog.bamieh.com" rel="nofollow noopener noopener noopener">https://www.youtube.com/watch?v=Vdrab3sB7MU&amp;t</a></li><li><a href="https://nodejs.org/en/blog/vulnerability/july-2017-security-releases/?ref=blog.bamieh.com" rel="nofollow noopener noopener noopener">https://nodejs.org/en/blog/vulnerability/july-2017-security-releases/</a></li><li><a href="https://github.com/antirez/redis/pull/718?ref=blog.bamieh.com" rel="nofollow noopener noopener noopener">https://github.com/antirez/redis/pull/718</a></li></ul> ]]></content:encoded>
    </item>

</channel>
</rss>