The preface

It bothers me, too, that someone hacked my stupid website. And it was a fucking continuous attack. Originally a small website I think is to write their own blog, and then people give me comments. Help each other, solidarity and love. As a result, I was educated. Pretty bad memories.

It is the flow problem of individual stationmaster next.

One, Internet site points

1. Search engines

This is very important, that is, make sure the server renders.

For no other reason, if your site is search engine oriented you must be server rendering. Otherwise, it can’t be well searched and promoted.

My website is private, so I don’t do that stuff. I’ll have to try server rendering next time though, otherwise I haven’t had much experience so far.

2. Flow problem

The traffic problem here has nothing to do with search or anything like that, it’s just remember, don’t put pictures up there. Too much flow. You’re just a shitty station. Don’t do that.

I put the image on oss storage for image access speed and server resource savings, but I want to say. It’s still expensive.

3. Money (Picture problem)

I’m going to do a calculation for you

At present, the server (1G1M with 1 core) is Aliyun’s, 300 for three years, which is very cheap, isn’t it? But this is a special price. Normally, it needs 1,000 a year.

If your site development optimization can be done, then the first screen traffic can be controlled at about 1M. It’s actually pretty quick.

But mostly the picture part. If you put pictures on your own server, then the bandwidth can not be very low, or it will be jammed.

If oss is deployed, traffic is calculated by visits. Specific seems to be 1G2 hair, anyhow very expensive. If you have a lot of pictures, pay attention to the random page switch, refresh a single person can give you brush away hundreds of traffic. A little more… I knew a company before. In half a year, the traffic cost is 200,000 yuan (mainly used for video surveillance).

So individual bloggers, their own small broken station pictures less put.

The picture is best to do anti-theft chain. Otherwise the flow will be very painful.

Examples of defense mechanisms

Here I first copy ali in eggJS defense, the main you encounter these.

  • XSS attack: Inject scripts into Web pages and use JavaScript to steal user information and induce user operations.
  • CSRF attacks: Fake user requests to send malicious requests to a website.
  • Phishing attack: Create a phishing trap using a link or image from a website.
  • HTTP parameter contamination: Parameter injection attacks on servers that take advantage of incomplete validation of parameter formats.
  • Remote code execution: the user submits the execution command through the browser. The command is executed without specifying an absolute path because the server does not filter the execution function.

The attack I encountered this time was on the CSRF side.

Three, the process of website defense

1. Monitor your interface access

Back end: Records each invocation of each interface.

Front-end: Records the access records after each route changes

These are two very simple ways to keep track, but they give you the most intuitive sense of how much your site is visited. There is also monitoring your site is malicious call interface, malicious access and so on. It’s intuitive. It’s easy to use.

I didn’t add this feature per se. But I learned my lesson the hard way. Added corresponding records.

Through the analysis of the interface call, it is concluded that the other side is the software refresh page constantly malicious to send me comments

2. One round of confrontation, limiting the transmission frequency of each IP (failed)

Here I post my middleware code, the above is really meaningless, just write middleware, database record data. Very simple.

Here I added Redis, if database performance is not appropriate, and it does not need to be so bulky. The cache is good. As for why there are no global variables. I have to explain this to everyone, whether it’s NodeJS or Java backend. There are threads or processes. So once the load is on, the system switches to another process and the data is no longer accessible.

Here is the middleware code that restricts access.

'use strict';

module.exports = (options, app) => {
  return async function(ctx, next) {
    try {
      const ip = ctx.request.header['x-forwarded-for']; const req_url = ctx.request.url; Const url = requrl.indexof (const url = requrl.indexof ('? ') === -1 ?
        req_url :
        req_url.substring(0, req_url.indexOf('? ')); / / store the current interface to access information, the subsequent have statistic CTX. Service. The interface. ApiVisit. Add ({IP, url,}); // Current time const time = new Date().gettime (); Const usr_api = await app.redis. Get (IP + url); // Const intercept_api = options. API [url]; Await app.redis. Set (IP + URL, new Date().getTime()));if (intercept_api) {
        if (time - usr_api > 5000) {
          await next();
        } else {
          ctx.body = ctx.helper.result(' ', 1,'Restricted access' + intercept_api / 1000 + '秒', 0); }}else{ await next(); } } catch (e) { ctx.logger.warn(e); }}; };Copy the code

Configure the config.js section

/ / to'interfaceRestriction'Incoming parameters config. InterfaceRestriction = {/ / API banned API: {'/dream-admin/noauth/blog/discuss/add': 1000 * 8,}, // IP block, IP: [//'127.0.0.1',]};Copy the code

The IP block above is not written. Not needed at the moment

The functions can also be extended, such as limiting IP addresses, limiting the frequency of access to an interface, and so on.

3. Round 2 (add captcha) (win)

The main reason for the above failure is that IP can actually be forged. And the cost of IP forgery is low. So it’s not very effective for you to limit crawlers’ malicious attacks by IP, it only prevents people from flooding. Crawlers come at you by the tens of millions every minute, and they don’t work.

Then I wondered what would be appropriate.

The attack itself belongs to the CSRF, but using the CSRF to defend against the opponent is useless. Because CSRF itself is a password-based approach. With a crawler, it’s easy to steal your password.

I finally decided there was no good way to add captcha.

Finally, the SVG-CAPtCHA package was used.

Here is a simple way to use it:

The controller code:

const { ctx, app } = this; Try {/ / generated arithmetic captcha const. Verify = svgCaptcha createMathExpr ({size: 4, ignoreChars:'0o1i',
    noise: 5,
    color: true,
    background: '#7E7D78'}); Const IP = ctx.request.header[const IP = ctx.request.header'x-forwarded-for'];
  await app.redis.set(ip, verify.text);
  ctx.response.type = 'image/svg+xml'; Ctx. body = verify.data; } catch (e) { ctx.body = ctx.helper.result(' ', -1, e);
}Copy the code

Finally, add validation where the comments are created.

Four,

1. All of this is to increase the difficulty of decoding

2. Don’t open up the interface for creating data (the root of all evil)

3, do a good job of data monitoring, prevention. And allow you to identify problems as quickly as possible

4, if you open the interface to the outside world, then please be prepared to guard against villains. (Captcha is a really good thing.)

5. All verification codes are not as reliable as mobile verification codes.


In fact, the end is still a bit of a cliche. It’s just, you know, it was a victory. Have to send a dynamic.