Tanceuticals and Skin Drop

This is a brain-dump of what I believe is an online scam of three review sites. But maybe it’s perfectly legal. I don’t know, you tell me. I am just going to write down my findings.

Hi guys,

I stumbled upon a set of review sites that provide scammy “reviews” and steer potential buyers to specific products. I don’t know if this is legal, certainly not ethical, but I also don’t know where to go from here. So, for now, I decided to write a blog post about it.

This one if going to be really long. I am sorry in advance. There is a tl;dr at the end if you want to skip the fluff.

Backstory – the first review site

One day, when I searched for a self-tanner, I stumbled upon a website called SelfTanning.com. A self-tanner is a lotion or mousse that you can wipe on your skin and it makes you look tan for 5-7 days. There are no known side effects, it’s considered safe, and a lot of people do it. The only downside is, some self-tanners smell “ok”, some make you look orange instead of tan, some dry patchy or stain all your clothes. It’s a big market out there, and it’s easy to get lost in it.

Selftanning.com is ran by a nice blonde lady who posts Youtube videos of her reviewing all the self-tanners out there. Exactly what I needed. She considers price, smell, color, how long each application lasts and she even had a page for the top 10 tanners for 2018, then she rates them on a scale of 5. Her top recommendation, Tanceuticals Extra Dark, was available an Amazon. I checked the reviews and bought a bottle for myself.

It worked great! The smell was great, the color was uncannily real, and it lasted for a good 7 days. I was pleased. I used up that bottle and ordered another one. Then, once I used up that one too, I ordered a third one.

The third bottle was runny, watery, and I sent it back to Amazon. I got a refund and ordered another brand that Amazon recommended for me. It wasn’t as good as Tanceuticals, but it was fine, and I’ve been using it ever since.

Three years later

It’s 2020, and I am in search for a good face cream that contains retinol. Without going into too much detail, retinol can be purchased with a prescription, and there are also OTC versions available. It’s one of the few ingredients that are proven to be efficient in keeping your skin in good shape if you continuously use it for years. There are a lot of products out there, and some are better than others. Some are completely useless. It’s a big market out there, and it’s easy to get lost in it.

I google “creams with retinol,” click on the top result: Retinol.com, and immediately get a strange feeling.

Retinol.com and Selftanning.com are the same review sites

But they are not the same. The sites’ structure is the same. They both have hundreds of video reviews, but the reviews are posted by different women. Products are reviewed the same way: price, how well it works, texture and feel. Both have a submenu for the top 10 products for the year.

I watched a few of the videos and they sound … legit. The woman’s tone doesn’t sound scripted, and she makes sense in the details she mentions. But then I notice the dates the videos were published: every 1-7 days.

Now, in case of self-tanning lotions I can see how 7 days are enough to test a product. But with facial creams, you need a good 30-90 days for each test. So these videos are fake. Or are they? She sounds honest and knowledgeable.

Who is sponsoring these sites?

I compared the “top” products on the two review sites and immediately saw an overlap. Three companies products received the highest ratings: Tanceuticals, Skinceuticals, and Skin Drop.

Skin Drop’s self tanner on Selftanning.com
Skin Drop’s retinol cream on Retinol.com

I searched for “Skin Drop” and “Skinceuticals”, and found a third website: Cellulite.com. Another website with the same structure, and same type of reviews by yet another woman. But this time I also noticed something else: the backdrop in some of the videos of Retinol.com and Cellulite.com were the same. I also noticed that over time they rotated some of the “review experts” and hired new ones.

Here are the playlists of each of the review sites on Youtube. They have uploaded hundreds of videos since mid-2015:

They don’t trash other products, but I also don’t believe these are honest reviews. In case of Cellulite creams (which are a complete scam, by the way, Cellulite creams don’t work), you would need to use them for weeks before you see results. And the thing with retinol is, it can be highly irritating to the skin. I am hesitant to even try one, let alone a hundred. What I am trying to say is, these women are very likely not talking about their own experiences, but they make it seem like they are.

About Us

Each of the review sites has an “About” page that contains a picture of one (or more) women who are the Chief Editors and reviewers. Selftanning.com is ran by a group of women. I googled each of the names, but couldn’t find any of the matching name + face combinations.

Selftanning.com’s team
Cellulite.com’s host

Retinol.com is allegedly ran by a Jessica Jones. I did not even bother to attempt to google that name, I knew the results would be saturated with images from the Marvel show. Cellulite.com is ran by a women whose name is Elizabeth Adams. I did try to google her .. couldn’t find anything.

Contact Us

Each site has a “Contact Us” page as well. They recommend that you write them via email, but they also list a mailing address.

Retinol.com’s mailing address
Selftanning.com’s mailing address
Cellulite.com’s mailing address

These addresses look fairly alike, no? Turns out, they are various UPS stores around the greater Phoenix area. I also tried to look at the ICANN’s registrar to find out who do these addresses belong to. They are all registered to and live on godaddy.com’s servers and no other names were provided.

Skin Drop and Tanceuticals

The two companies’ websites look entirely similar, clearly they were built on the same framework. But I also discovered something else on skindrop.com: The Terms of Use page refers to Skin Drop as part of Tanceuticals. In addition, per the “Contact Us” page, both Skin Drop and Tanceuticals are also located in the Greater Phoenix Area. Their addresses are UPS boxes, just like the three review sites’.

Skin Drop’s Terms and Conditions

I pinged all five URL’s. Tanceuticals.com and Skindrop.com came back from the same IP.

ping tanceuticals.com -c 1
PING tanceuticals.com ( 56 data bytes
64 bytes from icmp_seq=0 ttl=55 time=139.663 ms

ping skindrop.com -c 1
PING skindrop.com ( 56 data bytes
64 bytes from icmp_seq=0 ttl=55 time=71.291 ms


  • Selftanning.com, Retinol.com, and Cellulite.com and three sites offering seemingly independent product reviews.
  • The sites’ reviews are detailed, but posted all too often to believe that the reviews are based on real-life experiences.
  • The women posting these reviews seem to be local to the site. Their names (associated with this market) don’t appear anywhere else. In some cases in the past they occasionally switched the reviewers to new women.
  • The three sites’ top recommendations are products from two companies: Tanceuticals and Skin Drop.
  • Tanceuticals and Skin Drop are affiliated with each other.
  • Nowhere on Selftanning.com, Retinol.com, and Cellulite.com is it mentioned that they are affiliated with Tanceuticals on Skin Drop.
  • Selftanning.com, Retinol.com, and Cellulite.com, Skin Drop, and Tanceuticals’ physical addresses are UPS boxes around the Greater Phoenix Area.
  • All five URL’s are registered and hosted on Godaddy.com. Tanceuticals.com and Skindrop.com are on the same server.

In my opinion, at the very least the reviews are dishonest and the top products are purposefully listed to steer potential buyers to two particular sites (which are also affiliated, so, same company). This by itself is not against the law, I believe. But this whole thing feels scammy to me. Maybe some of you can offer some insight.

Zero to OSCP Chapter 1 – CompTIA S+ and N+

Hi guys,

One year ago I decided to switch careers and get into cybersecurity. Don’t get me wrong, I love my DBA career. But maybe I would love a cybersecurity even more, who knows? 

Therefore, today I am going to start a new series on my blog, describing my path from zero to OSCP.

This is chapter one.

If you hate fluff, skip to the conclusions at the end of this post.

Background: I am a fantastic DBA. I love working with SQL Server, and as a result of my new position at CoverMyMeds, I am also becoming quite proficient in Postgres. However, I am one of those “Accidental DBA’s” and I never completed a formal CS education.

Therefore, I recognized that I have gaps in my knowledge that I must fill sooner or later, and I decided to use the CompTIA exams for that: A+, N+, and S+.


In case you are a complete newbie to the topic, here is a link to CompTIA’s A+ page, but this is their beginner certifications and covers basic computer technician concepts: how do internal parts work, how does the BIOS work, how to service a laptop and a computer. I had a good understanding of 70% of the concepts and I didn’t feel the need to sit for this exam. However, I also wanted to get a refresher, so I signed up to Cybrary.it (it’s free) and watched Anthony Harris’s A+ course. Unfortunately since then the course was retired, but Cybrary offers other, updated A+ courses instead.


I purchased Jason Dion’s N+ course on Udemy as well as the six practice exams, bought the CompTIA voucher and signed up for an exam one month out. I then promptly forgot about the whole thing for about 27 days until I got the reminder email. I rescheduled for another month. A month later I got another reminder email, and rescheduled again. And again. Finally I got tired of procrastinating and decided to just go for it.

Two weeks before the exam I started to watch the course on Udemy. The weekend before the exam I finished the course and moved on to the sample tests and promptly failed all of them. However, I noticed that quite a few people on Reddit also mentioned that they passed the exam and never got a passing score on the practice tests. 

Monday morning I successfully passed the test with a fairly low score. But hey, a pass is a pass ;)

For the record, here are my practice test results: 68%, 77%, 80%, 68%.


I did not learn from my previous mistakes, and after scheduling the S+ exam I, again, forgot about it until for about a week before the exam. However, this time the universe decided to play a sick joke on me and there were no dates left for two months out in my area! So, I had no choice but to study for the exam with just 6 days left. I passed. 

I used Jason Dion’s course and practice exams again. I speed-watched the entire course in four days, and each day I took another test to measure my progress. My baseline (pre-course) test was 60%. The practice test results were 62%, 67%, 72%, 78%. A lot of the concepts associated with this course were extremely familiar to me due to the cybersec podcasts I would listen to. For example, I scored 100% on most practice tests in the “Threat, Attacks, Vulnerabilites” module.

The day of the exam I was super unsure if I would pass. I was sweating hard by the end of the exam and barely passed – by a pass is a pass ;)

My personal understanding of CompTIA tests

They are not hard (so far). They are multiple choice questions and they are entirely theoretical. I don’t think they add much value to my career other than a nice little badge on LinkedIn. BUT! They are well-structured and help you organize your study material.

If your goal is to get valid work experience, don’t use the CompTIA exams. 

If your goal is to fill gaps in your knowledge, I would suggest them. If you have a couple $100 dollars to spare, or your employer pays for your continuous education, use them.


  • If you have a basic understanding of IT concepts, you can skip A+.
  • If you like to use online courses for studying, I recommend Jason Dion’s N+ and S+ online courses on Udemy.
  • I also recommend purchasing the practice tests. Some of the questions were verbatim the same.
  • There is always a sale going on on Udemy. Never spend more than $10-12 on a course or practice tests.
  •  I was able to pass these tests without using anything else. Jason Dion’s courses and practice tests together are enough.
  • If you get 70% on the practice exams, you are ready for the real ones. People who pass the real exam don’t always get 85% (passing score) on the test exams.
  • Skip the PBQ’s on the exam. Flag them, then move on to the multiple choice questions, and once you’re done with those you can read and solve the PBQ’s.
  • Flag everything that you are unsure of. After my first round, I flagged about 50% of the questions. Then I went back and reviewed everything I flagged and answered what I could. Sometimes later questions might jog your memory. 
  • Cybrary.it has exam vouchers with 10% off

Use Query Store to help with SQL Server upgrades

The Query Store is a feature that helps you evaluating query performance. It captures execution information asl well as up to 200 plans for a single query. For a thorough overview on the Query Store you can read Enrico van de Laar’s article here. Query Store is also available for Azure since V12. To turn on Query Store you would run the following command:


You can also use the GUI in SQL Server to turn on Query Store:


Query Store GUI 1
Turn on and tune Query Store conveniently


I learned the following neat trick last week when I attended SQL Saturday. We know upgrading between SQL Server versions may lead to slow queries, as our queries are optimized for, well, the SQL Server we use. That means if your production server is a 2008 R2, and you upgrade to a 2016, you might end up with a few queries that in fact execute slower than what you are used to. If you are a smart DBA (and you are a smart DBA), you put a few test databases on the target server and let them run for a while. You evaluate performance, growth, make some changes, and when everything looks peachy you move on to upgrade your servers.

This is where the Query Store can help you in that process. Say, I want to upgrade from my current 2008R2 server. I would grab a database from my current 2008R2 server, restore it on the 2016 server, but leave the compatibility level at 2008R2. I turn on Query Store here, and allow it to capture all execution plans for all queries. These data will stay in the memory for 900 seconds by definition, then will be flushed to disk. You hear that right — Query Store saves all this information to disk. When I restart the server, the execution plans are still going to be there for me. I will let that database happily spin around for, say, a month. I can always check on its progress by accessing Query Store in SSMS.


Query Store in SSMS
Query Store in SSMS


At that time I change the compatibility mode to SQL Server 2016. What do you think will happen? You guessed it right, nothing will change for the most part, except for a few queries that would suddenly run slower. Way slower. I have heard stories of queries that used to run in mere seconds on 2008R2, but would take up to 15 minutes on 2016. That is because the Cardinality Estimator has undergone major changes over the past few years, especially with the introduction of SQL Server 2014.

At this point I turn to my new best friend, Query Store, and look at the executions plans it saved for that particular query. I would see something like this:

Query Store GUI
Execution plans in the Query Store


I can see that plan 146 was the best performing execution plan. I can now select that plan and click the ‘Force Plan’ button right under the scatter plot.


Force and Unforce Plan buttons in Query Store
Force and Unforce Plan buttons


I would do this to all my slow-performing queries. Tah-dah! I now crossed off one item on my ‘upgrade to SQL Server 2016’ list, and I don’t have to worry about execution plans anymore. Isn’t that neat?!


For more information on the Query Store, I recommend Microsoft’s surprisingly reader-friendly page here, as well as the aforementioned Enrico van de Laar’s extensive article over on Simple Talk. Credit goes to these two articles for their images as well.

When the client asks for a unique ID based on name and address but gives you dirty data

when len(
PARTITION BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3)
ORDER BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3)
) < 2

then (UPPER
(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3) + '0' + convert(varchar(3),ROW_NUMBER() OVER( PARTITION BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3) ORDER BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3)))

else (UPPER(left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3) + convert(varchar(3),ROW_NUMBER() OVER( PARTITION BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3) ORDER BY left(replace(name,' ',''), 3) + left(replace(addrsscty,' ',''),3)))))

end as ID

my work is done.

Setting database to trustworthy will let you deploy assemblies in unsafe mode

The title says it all, but let me expand on this a little bit.

I have an assembly that I wanted to emulate in SQL server. The first, obvious choice is to use safe mode, which results in the following message:

Msg 6212, Level 16, State 1, Line 2
CREATE ASSEMBLY failed because method ‘x’ on type ‘x.x’ in safe assembly ‘x’ is storing to a static field. Storing to a static field is not allowed in safe assemblies.

Be quiet my racing heart. Sassy SQL Server be sassy. So evidently I’d go ahead and deploy it in unsafe mode, just so that we can run into another error message:

Msg 10327, Level 14, State 1, Line 2
CREATE ASSEMBLY for assembly ‘CTXCRMEncryption’ failed because assembly ‘CTXCRMEncryption’ is not authorized for PERMISSION_SET = UNSAFE. The assembly is authorized when either of the following is true: the database owner (DBO) has UNSAFE ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission.

SQL Server is actually trying to help in her quite, sassy way here, so let’s give her what she wants.


And now we can emulate the assembly in unsafe mode. I wish I had known that sooner.
I wish I had known that

SSIS – SQL Server data type

This blog post here on BI Developer Network contains a nice list on data conversion between SSIS and SQL server, something that gets my blood pressure going due to SSIS’s ‘check your metadata’ error message. Good cheat sheet that list the data types.


SSIS Data Type

SSIS Expression

SQL Server

single-byte signed integer



two-byte signed integer



four-byte signed integer



eight-byte signed integer



single-byte unsigned integer



two-byte unsigned integer



four-byte unsigned integer



eight-byte unsigned integer






double-precision float




(DT_STR, «length», «code_page»)

char, varchar

Unicode text stream

(DT_WSTR, «length»)

nchar, nvarchar, sql_variant, xml








(DT_NUMERIC, «precision», «scale»)

decimal, numeric


(DT_DECIMAL, «scale»)




smallmoney, money

unique identifier



byte stream

(DT_BYTES, «length»)

binary, varbinary, timestamp

database date



database time



database time with precision

(DT_DBTIME2, «scale»)


database timestamp


datetime, smalldatetime

database timestamp with precision

(DT_DBTIMESTAMP2, «scale»)


database timestamp with timezone



file timestamp






text stream

(DT_TEXT, «code_page»)


Unicode string




Credit goes to their user, DevinKnight.


DBCC DBReindex

I ran into some ‘Message 823’ issues on my development DB, and upon running DBCC CheckDB() I saw that my indexes were the ones throwing the errors.
I got this handy cursor from SQL Server Performance, and decided to save it here for me, and for you, so that I don’t have to search for it over and over again. The script by the way is from the talented Brad McGehee, and I suggest checking out the article because it has more information and more cursors for failing indexes.

Without further ado:
USE DatabaseName –Enter the name of the database you want to reindex

DECLARE @TableName varchar(255)

SELECT table_name FROM information_schema.tables
WHERE table_type = ‘base table’

OPEN TableCursor

FETCH NEXT FROM TableCursor INTO @TableName
DBCC DBREINDEX(@TableName,’ ‘,90)
FETCH NEXT FROM TableCursor INTO @TableName

CLOSE TableCursor


Conclusion: you, too, can fix your indexes with a cursor now.


I will make this short and sweet for you.
If there is something you want to do to all tables in your database, there is a command for you.

I will demonstrate, watch my hands because I cheat. To add a column to every table:
exec sp_msforeachtable 'alter table ? add intGoat int NULL'
To delete a column from each table
exec sp_msforeachtable 'alter table ? drop column intGoat'

And this is how you use this undocumented little gem.

Small print: emphasis on undocumented, aka can go away or change in nature without any warning. Test it on your dev DB before using it.
Willy Wonka is telling you to watch with undocumented features.

The thing with cursors

So our aggregated databases have experienced some loading errors lately, and until that gets fixed, I have to collect the data straight from the field databases for each report.
That is, go in the database, pull the data, load into temp.
Go in the next database, pull the data, load into temp.
Go in next, pull, process. Go in next, pull, process.

Sounds familiar? That’s a classic cursor right there.


CREATE TABLE pureHatred (
[DBName] varchar(50),
[text] varchar(max)
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
While @@FETCH_STATUS = 0
SET @sql = N'USE ['+@name+']
INSERT INTO pureHatred(DBName, [text])
SELECT DB_NAME(), v.name
from sys.[syscomments] sc
JOIN sys.views v ON v.object_id = sc.id
WHERE sc.text like ''%fill my sproc with hatred%'''
exec (@SQL)
FETCH NEXT FROM db_cursor INTO @name
Close db_cursor
DEALLOCATE db_cursor
select * from pureHatred
drop table pureHatred

Now you’ve heard a million times that cursors are a bad approach, and I won’t even deny that fact. They are. They lock rows and load everything into the memory. Cursors also include multiple steps, that is selecting the data, then processing the data, and the lock remains there for the duration of all steps. Also, the server has to execute the plan for each row, each database. (case in point: pull 10K orders each from 500 databases. Oh look! Large numbers.)

I have the luxury to do so in our environment, because we are loaded with memory already. My box still completes the 5 million pull-process cursors in less than 10 seconds, but imagine the peak in memory processes as it does so!* However, we could actually use that memory for other processes, so my solution is only for ad-hoc reports, and only until I fix the data imports. I slap my wrist every time I write up a cursor and hope that the lord of database administrators doesn’t find out about my sin.

But! I don’t know of any other way to jump databases. Feel free to suggest a solution, if you. If you have to repeat the same process in 500-1000-5000 databases, you need a cursor to repeat said process.

So again, should someone toss in the question on your next interview: cursors are bad for using up resources and locking rows.
There are times you can’t avoid them (jumping databases), but if you want to, read up on set-based approaches. I’ll write another article on the matter soon.

Conclusion: If you have to jump databases, you will use UNION ALL 5000 times, or you will load the data in a temp table with a cursor. In this one case I approve of using a cursor, else I you should avoid it.

*You know what? Let me run a query on sys.dm_exec_query_memory_grants next time I set up a mildly complicated cursor, and I tell you just how much memory it costs indeed to use it.