Does any OpenID identity provider allow site-unique arbitrary email addresses? Since OpenID officially furnishes email address to sites (with the user's permission) as a convenience rather than an attestation, is there any OpenID identity provider who'll allow you to authenticate to THEM for an unlimited number of sites with one email address, but upon registration with a new site, allow you to enter an arbitrary email address specific to that one site in a textbox before it kicks you back to the site you're registering for?

Why?

Over the years, I've discovered the hard way that there's really only one nearly-foolproof way to avoid spam: I have my mail server configured to allow adhoc aliases, and I use a different email address for every site and sender. Those email addresses are in the form mymailbox-senderspecificalias@mydomain.net.

The advantages are many:

If I start getting spammed, I can look at the address, and add a Procmail rule to instantly nuke it thereafter at the mail server.
It's the only method that actually works if a site or friend/family member/whomever gets compromised by hackers/malware and the address gets harvested.

At the end of the day, it's a lot easier to tell one person or site, "use mymailbox-senderspecificalias2@mydomain.net from now on" than to keep nuking email address after email address as they succumb to spammers.

It makes a huge difference. Today alone, I received approximately 12,380 inbound emails addressed to alleged recipients at my domain. 19 of them were non-spam. I actually had to write a cron job to rotate and delete my Procmail logs, because if I didn't, they'd be several gigabytes within a matter of days.

Here's the problem: most sites I've seen that authenticate through OpenID wrongfully treat the address they receive from OpenID as immutable thereafter. If I'm logging in to some OpenID provider as mymailbox-myopenidprovider@mydomain.net, and ultimately passing that same email address along to every site I use, my whole strategy would quickly fall apart the moment one of those sites starts spamming me or gets harvested by spammers.

What I'd like to happen is, after authenticating to the OpenID provider, when it gets to the page where it would normally ask me for permission to share my email address with the other site, I'd like to be presented with a dialog box that will allow me to enter whatever unique email address I want to use for that particular site.

So, are there any?

No.

Open authentication works on the premise that it knows who you are. If you could just change who you are after authentication, the whole system wouldn't work as an authentication method.

Try using something like SpamHaus to deal with your problem.


In a LAN environment, can you fake the IP address while also being able to receive the response? Looks like nmap could fake source IP address, and getting a valid response, but only in LAN environment. I'm not sure how it works, here's my thought,

You created a packet with fake IP address and a fake MAC address (associated with the fake IP), so that you both spoofed the packet source and being able to get the response data.

But it's unlikely to work in a switched-based LAN environment or with VLAN enabled.

So, anyone know about that?

A network switch works by inspecting packets as they come and go. When a switch sees that a packet arrives on a given port, bearing the source MAC address X, then the switch remembers that the machine with MAC address X lies at some point beyond that port, and packets destined to the MAC address X will be sent to that port. Note that switches don't care about IP addresses (well, some switches double as traffic inspectors and know what IP addresses are, but the switch behaviour occurs at the ethernet level and deals with MAC addresses, not IP addresses).

If the attacker is sending packets with X as source address, and expects responses which are destined to address X, then, by any reasonable definition, X is not a "fake address": it is the address that the attacker is assuming, and, from a network point of view, it is very real.

The real trouble comes when the attacker tries to steal an IP address. The attacker observes that there is an active machine, with some IP address U and MAC address Y, and the attacker wants to emit packets which will look as if they come from that machine, and also see the response from another machine V. The attacker has two possible ways:

The attacker may try to use an address X distinct from Y, but yet steal address U. The trouble is that the machine V is aware that the genuine machine U has MAC address Y; this awareness comes from the ARP protocol. To achieve his goals, the attacker will have to spam machine V with fake ARP responses so that V becomes convinced that the MAC address for address U is X. This is known as ARP spoofing or "ARP poisoning".

Note that the switch sees only MAC addresses Y and X, duly distinct from each other, and has no impact here. The attacker has nothing special to do to fool the switch if he chooses this way.
The attacker may try to use both the IP address U and the MAC address X. The good point of this method is that there is nothing to do with regards to machine V: that machine remembers that U maps to X, and, as far as the attacker is concerned, this is fine. On the other hand, the switch becomes a problem: that switch has already seen some packets with source address X, coming from a port other than the one used by the attacker. The attacker may not see the response.

To counter that, the attacker will first spam the switch with thousands of packets, full of random junk, allegedly coming from thousands of random MAC addresses. The switch has only limited RAM to remember all the mappings of MAC addresses to ports, so the spamming onslaught will make it forget where address X is. At that point, given a packet with destination address X, the switch will degrade to hub mode and broadcast the packet on all ports -- including the one leading to the attacker.

The situation can be made more complex with modern switches which employ more complex routing algorithms to support redundant networks. The base principle is still that the MAC addresses are unknown to the switches, who discover them dynamically by observing packets in transit. A countermeasure which can be employed with some switches is ton configure them, statically, with known associations of MAC addresses with ports. This loses in flexibility (a specific machine will be rejected if not plugged on the right port), but can make switches more robust against such attacks.

(Not letting evil people connect directly to your switch would be better, though.)


Is it possible for an open-source website be secure? Lets say I want to develop a website with a community, and so I want it to be open source.  However, this website isn't going to be static.

However, it seems that revealing the database connections and the queries made is insecure, as the database name, username, and password are all part of the code.

How is sensitive information kept secure on an open-source website?

The database login credentials should not be part of your sourcecode. They should be part of the configuration files. The production version of these configuration files should not be part of the official codebase. You should only publish an example configuration with example parameters.

This is not just recommended from a security perspective, it also makes it much easier for others to use your project. They will definitely have other login credentials than you do, so providing a config file where they can enter them is much more comfortable than digging through the source and replacing all references to them.

For more information, check the question "Strategy for keeping secret info such as API keys out of source control?" on programmers stackexchange


Is it a good idea to use an input by the user as SALT? I have read many Q&As here on IT Security about password hashing and salting.

I am building a simple registration form for our community website which will be used by our members to create their accounts. I am seriously debating the idea of asking users a security question that will require a single word answer and then using the answer as a salt. Or maybe even answers with two or more words/numbers etc.

Of course, I will need to devise something with very little likelihood of repetition - say - the user's mother's maiden name. The likelihood of the exact same name in our 2000 strong community is extremely little. And the likelihood of a chosen password and the answer to the security question being identical is even more remote. However, such a question will necessarily have at least one space in the answer. Another idea is asking for the mother's date of birth and stripping the date separators.

Question 1: Is this a decent enough salting?

Question 2: Can a salt have a space? Or a slash? Or a hyphen?

Question 3: In case spaces (or slashes and hyphens) are not allowed in Salts, is it OK to perform some sort of a space (or slashes and hyphens)stripping on the input before the input is used as a salt?

Question 4: Are there any glaring security loop-holes this can open?

You want the salt to be unique. You also do not want the salt to be "revealing" because you will store it "as is", as clear text, on the database server. A salt needs not be secret, but people may get nervous if you store, unprotected, some value which they feel ought to be secret -- and this includes their mother's maiden name, which is apparently used by some US banks as an authentication mechanism.

Ensuring uniqueness of salts is easy on the server side: just generate a long enough sequence of random bytes. Randomness is not uniqueness, but it works just as well with overwhelming probability. Good password hashing functions can use any sequence of bytes as salt. Good implementations of password hashing functions will even generate the salt properly for you, and include it in their output, so you don't have to care about it (that's what normally occurs with bcrypt); in that case, forget all about this answer and your question, and just let the library do its job.

Asking the user to answer his own salt is a bad idea. First, it is technical, and most users can be assumed not to grasp anything about what a salt is; a lot of them will become nervous. Also, when users do understand what a salt is, then they know that a good salt is a random salt; human users are not well equipped at generating randomness (it is not part of what a human brain is good at). On the other hand, your server can do randomness. Finally, you cannot count on human users to enforce uniqueness -- and, in particular, when a user changes his password, he does not change his mother's maiden name, so that's an unavoidable failure at uniqueness.

Edit: if your programming language offers UUID, otherwise known as GUID (distinction is Byzantine), then these are good for salts. For instance, in .NET, just call System.Guid.NewGuid(). There are various methods for creating such values, but they all aim at worldwide uniqueness (they might be predictable, but that's not a problem for salts). "Method 4" is actually 122 bits of randomness. Best method for salt generation is to let the password hashing library code do it, but if you have to use a library which does not do it itself, then using a system-provided UUID is a decent low-effort method.


Does the presence of XSRF token and per-request session cookie mitigates the security risk of brute-forcing login credentials? I am having no success on brute-forcing HTTPS form (username and password), that has XSRF token and per-request session cookie, using Hydra.

I want to know if the presence of XSRF token and per-request session cookie mitigates the security risk of brute-forcing login credentials?

Disallowing login attempts that don't have a valid cookie/token (indicating that the client loaded the page before submitting the request) and having that cookie/token be single-use (so you can't just load the page once and then submit a bunch of requests with those credentials) is, in theory, a valid way to slow down login brute-force attempts. A tool can still automate the process, but it needs to make a request and receive the response for each attempt, rather than firing off requests as fast as possible, usually leading to having multiple requests in flight at once.

There are problems with this approach, though. For one thing, it's hard to scale. You can't easily load-balance your login attempts - which is important to do if you have a lot of traffic and an appropriately-expensive password hashing function - because the single-use-ness of the token breaks down if multiple "valid" requests get balanced across multiple servers and the servers' list of valid tokens isn't kept perfectly in sync. For another, it's not actually going to prevent automated brute-force - at worst, the tool simply needs to scrape the responses for the values it includes in its next request - the way a CAPTCHA will. It also becomes harder to create a tool that authenticates (with valid credentials) automatically, which is sometimes valuable to enable.


What personally identifying data does does command line Git send? What identifying data (such as hostname) does command line Git send when:

cloning
commiting/pushing

I expect git config data (specified email and full name) to be sent when commiting/pushing. Does git send anything else and/or when cloning?

This is really easy to test out.  GIT uses CURL for the clone and push/pull operations, and it uses one environment variable that will make it tell us everything what it is doing, so first let's do:

export GIT_TRACE_CURL=1

(That is the *nix way of doing it, but it works in the git shell that comes on windows as well)

The only problem with that configuration is that pretty much all free public git repositories (github, bitbucket, gitlab) require you to use HTTPS, which is a little hard to debug.  To avoid an extra proxy I simply created my own git server on localhost (that's not hard at all, even the official git documentation has examples of doing it).

git clone

I have cloned a repository that I call rc and got the following output (thanks to the exported variable above):

git clone http://localhost/git/rc > log 2>&1

The content of the log is:

Cloning into 'rc'...
21:30:48.175889 http.c:558              == Info: Couldn't find host localhost in the .netrc file; using defaults
21:30:48.177516 http.c:558              == Info:   Trying ::1...
21:30:48.177542 http.c:558              == Info: TCP_NODELAY set
21:30:48.177698 http.c:558              == Info: connect to ::1 port 80 failed: Connection refused
21:30:48.177722 http.c:558              == Info:   Trying 127.0.0.1...
21:30:48.177732 http.c:558              == Info: TCP_NODELAY set
21:30:48.178015 http.c:558              == Info: Connected to localhost (127.0.0.1) port 80 (#0)
21:30:48.178266 http.c:505              => Send header, 0000000186 bytes (0x000000ba)
21:30:48.178316 http.c:517              => Send header: GET /git/rc/info/refs?service=git-upload-pack HTTP/1.1
21:30:48.178327 http.c:517              => Send header: Host: localhost
21:30:48.178335 http.c:517              => Send header: User-Agent: git/2.10.0
21:30:48.178342 http.c:517              => Send header: Accept: */*
21:30:48.178349 http.c:517              => Send header: Accept-Encoding: gzip
21:30:48.178356 http.c:517              => Send header: Accept-Language: en-GB, *;q=0.9
21:30:48.178364 http.c:517              => Send header: Pragma: no-cache
21:30:48.178371 http.c:517              => Send header:
21:30:48.196881 http.c:505              <= Recv header, 0000000017 bytes (0x00000011)
21:30:48.196914 http.c:517              <= Recv header: HTTP/1.1 200 OK
21:30:48.196928 http.c:505              <= Recv header, 0000000022 bytes (0x00000016)
21:30:48.196936 http.c:517              <= Recv header: Server: nginx/1.10.1
21:30:48.196946 http.c:505              <= Recv header, 0000000037 bytes (0x00000025)
21:30:48.196954 http.c:517              <= Recv header: Date: Sun, 16 Oct 2016 20:30:48 GMT
21:30:48.196964 http.c:505              <= Recv header, 0000000059 bytes (0x0000003b)
21:30:48.196972 http.c:517              <= Recv header: Content-Type: application/x-git-upload-pack-advertisement
21:30:48.196982 http.c:505              <= Recv header, 0000000028 bytes (0x0000001c)
21:30:48.196990 http.c:517              <= Recv header: Transfer-Encoding: chunked
21:30:48.197000 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:30:48.197008 http.c:517              <= Recv header: Connection: keep-alive
21:30:48.197016 http.c:505              <= Recv header, 0000000040 bytes (0x00000028)
21:30:48.197024 http.c:517              <= Recv header: Expires: Fri, 01 Jan 1980 00:00:00 GMT
21:30:48.197033 http.c:505              <= Recv header, 0000000018 bytes (0x00000012)
21:30:48.197041 http.c:517              <= Recv header: Pragma: no-cache
21:30:48.197050 http.c:505              <= Recv header, 0000000053 bytes (0x00000035)
21:30:48.197057 http.c:517              <= Recv header: Cache-Control: no-cache, max-age=0, must-revalidate
21:30:48.197067 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:30:48.197075 http.c:517              <= Recv header:
21:30:48.197085 http.c:531              <= Recv data, 0000000323 bytes (0x00000143)
21:30:48.197093 http.c:546              <= Recv data: 137..001e# service=git-upload-pack.000000d2af75078c1b6bb5ff6
21:30:48.197100 http.c:546              <= Recv data: 30e0acf2f9e94d934a025aa HEAD.multi_ack thin-pack side-band s
21:30:48.197108 http.c:546              <= Recv data: ide-band-64k ofs-delta shallow no-progress include-tag multi
21:30:48.197115 http.c:546              <= Recv data: _ack_detailed no-done symref=HEAD:refs/heads/master agent=gi
21:30:48.197123 http.c:546              <= Recv data: t/2.10.0.003faf75078c1b6bb5ff630e0acf2f9e94d934a025aa refs/h
21:30:48.197130 http.c:546              <= Recv data: eads/master.0000..0....
21:30:48.197166 http.c:558              == Info: Curl_http_done: called premature == 0
21:30:48.197182 http.c:558              == Info: Connection #0 to host localhost left intact
21:30:48.207536 http.c:558              == Info: Couldn't find host localhost in the .netrc file; using defaults
21:30:48.207600 http.c:558              == Info: Found bundle for host localhost: 0x1c7db00 [can pipeline]
21:30:48.207650 http.c:558              == Info: Re-using existing connection! (#0) with host localhost
21:30:48.207677 http.c:558              == Info: Connected to localhost (127.0.0.1) port 80 (#0)
21:30:48.216731 http.c:505              => Send header, 0000000225 bytes (0x000000e1)
21:30:48.216789 http.c:517              => Send header: POST /git/rc/git-upload-pack HTTP/1.1
21:30:48.216798 http.c:517              => Send header: Host: localhost
21:30:48.216805 http.c:517              => Send header: User-Agent: git/2.10.0
21:30:48.216813 http.c:517              => Send header: Accept-Encoding: gzip
21:30:48.216820 http.c:517              => Send header: Content-Type: application/x-git-upload-pack-request
21:30:48.216827 http.c:517              => Send header: Accept: application/x-git-upload-pack-result
21:30:48.216835 http.c:517              => Send header: Content-Length: 153
21:30:48.216841 http.c:517              => Send header:
21:30:48.216853 http.c:531              => Send data, 0000000153 bytes (0x00000099)
21:30:48.216861 http.c:546              => Send data: 008cwant af75078c1b6bb5ff630e0acf2f9e94d934a025aa multi_ack_
21:30:48.216868 http.c:546              => Send data: detailed no-done side-band-64k thin-pack no-progress ofs-del
21:30:48.216876 http.c:546              => Send data: ta agent=git/2.10.0.00000009done.
21:30:48.216899 http.c:558              == Info: upload completely sent off: 153 out of 153 bytes
21:30:48.235637 http.c:505              <= Recv header, 0000000017 bytes (0x00000011)
21:30:48.235702 http.c:517              <= Recv header: HTTP/1.1 200 OK
21:30:48.235719 http.c:505              <= Recv header, 0000000022 bytes (0x00000016)
21:30:48.235726 http.c:517              <= Recv header: Server: nginx/1.10.1
21:30:48.235736 http.c:505              <= Recv header, 0000000037 bytes (0x00000025)
21:30:48.235745 http.c:517              <= Recv header: Date: Sun, 16 Oct 2016 20:30:48 GMT
21:30:48.235755 http.c:505              <= Recv header, 0000000052 bytes (0x00000034)
21:30:48.235763 http.c:517              <= Recv header: Content-Type: application/x-git-upload-pack-result
21:30:48.235774 http.c:505              <= Recv header, 0000000028 bytes (0x0000001c)
21:30:48.235781 http.c:517              <= Recv header: Transfer-Encoding: chunked
21:30:48.235791 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:30:48.235799 http.c:517              <= Recv header: Connection: keep-alive
21:30:48.235808 http.c:505              <= Recv header, 0000000040 bytes (0x00000028)
21:30:48.235817 http.c:517              <= Recv header: Expires: Fri, 01 Jan 1980 00:00:00 GMT
21:30:48.235826 http.c:505              <= Recv header, 0000000018 bytes (0x00000012)
21:30:48.235833 http.c:517              <= Recv header: Pragma: no-cache
21:30:48.235843 http.c:505              <= Recv header, 0000000053 bytes (0x00000035)
21:30:48.235850 http.c:517              <= Recv header: Cache-Control: no-cache, max-age=0, must-revalidate
21:30:48.235861 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:30:48.235869 http.c:517              <= Recv header:
21:30:48.235879 http.c:531              <= Recv data, 0000008027 bytes (0x00001f5b)
21:30:48.235888 http.c:546              <= Recv data: 1f53..0008NAK.2004.PACK..........x...I..0...zE............#

#### And the rest is simply gzipped repo files

The interesting part of all that output is that we can see that GIT is performing one HTTP GET and one HTTP POST to achieve the clone operation:

GET /git/rc/info/refs?service=git-upload-pack HTTP/1.1
Host: localhost
User-Agent: git/2.10.0
Accept: */*
Accept-Encoding: gzip
Accept-Language: en-GB, *;q=0.9
Pragma: no-cache

POST /git/rc/git-upload-pack HTTP/1.1
Host: localhost
User-Agent: git/2.10.0
Accept-Encoding: gzip
Content-Type: application/x-git-upload-pack-request
Accept: application/x-git-upload-pack-result
Content-Length: 153

008cwant af75078c1b6bb5ff630e0acf2f9e94d934a025aa multi_ack_
detailed no-done side-band-64k thin-pack no-progress ofs-del
ta agent=git/2.10.0.00000009done.

Nothing particularly worrying here.  That hex string comes from what GIT got in the body returned by GET, and so are all the other options.

git commit

Well, this is a local operation.  Nothing is transferred over the network here.

Still, the commit operation, submits some data (GIT objects) into the repository (.git directory) which is synced to all other copies of the repo with push/pull operations.  See the extra notes at the end for some files in the commit that are relevant to information disclosure.

git push

Here things are a little different.  I only tested this until the point where I saw the start of the PUT (on the server side) but it does give us good info.

I changed a file, added it, committed, and now I'm going to push it back to the origin.  I configured use.name and user.email to ensure they appear in the logs (see below):

$ git config user.name grochmal
$ git config user.email grochmal@example.com
$ git commit -m 'yay'
$ git push origin master > log2 2>&1
Username for 'http://localhost': grochmal
Password for 'http://grochmal@localhost':

For GIT to allow me to push over HTTP I needed to configure basic authentication on the server, since (by default) it only allows for a push if the server performs authentication.  Anyhow, the output:

21:53:54.779437 http.c:558              == Info: Couldn't find host localhost in the .netrc file; using defaults
21:53:54.781338 http.c:558              == Info:   Trying ::1...
21:53:54.781423 http.c:558              == Info: TCP_NODELAY set
21:53:54.781618 http.c:558              == Info: connect to ::1 port 80 failed: Connection refused
21:53:54.781643 http.c:558              == Info:   Trying 127.0.0.1...
21:53:54.781654 http.c:558              == Info: TCP_NODELAY set
21:53:54.781851 http.c:558              == Info: Connected to localhost (127.0.0.1) port 80 (#0)
21:53:54.781998 http.c:505              => Send header, 0000000187 bytes (0x000000bb)
21:53:54.782028 http.c:517              => Send header: GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
21:53:54.782038 http.c:517              => Send header: Host: localhost
21:53:54.782047 http.c:517              => Send header: User-Agent: git/2.10.0
21:53:54.782056 http.c:517              => Send header: Accept: */*
21:53:54.782065 http.c:517              => Send header: Accept-Encoding: gzip
21:53:54.782073 http.c:517              => Send header: Accept-Language: en-GB, *;q=0.9
21:53:54.782082 http.c:517              => Send header: Pragma: no-cache
21:53:54.782090 http.c:517              => Send header:
21:53:54.782555 http.c:505              <= Recv header, 0000000027 bytes (0x0000001b)
21:53:54.782569 http.c:517              <= Recv header: HTTP/1.1 401 Unauthorized
21:53:54.782586 http.c:505              <= Recv header, 0000000022 bytes (0x00000016)
21:53:54.782595 http.c:517              <= Recv header: Server: nginx/1.10.1
21:53:54.782605 http.c:505              <= Recv header, 0000000037 bytes (0x00000025)
21:53:54.782613 http.c:517              <= Recv header: Date: Sun, 16 Oct 2016 20:53:54 GMT
21:53:54.782623 http.c:505              <= Recv header, 0000000025 bytes (0x00000019)
21:53:54.782632 http.c:517              <= Recv header: Content-Type: text/html
21:53:54.782645 http.c:505              <= Recv header, 0000000021 bytes (0x00000015)
21:53:54.782654 http.c:517              <= Recv header: Content-Length: 195
21:53:54.782664 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:53:54.782673 http.c:517              <= Recv header: Connection: keep-alive
21:53:54.782685 http.c:505              <= Recv header, 0000000044 bytes (0x0000002c)
21:53:54.782693 http.c:517              <= Recv header: WWW-Authenticate: Basic realm="Restricted"
21:53:54.782704 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:53:54.782713 http.c:517              <= Recv header:
21:53:54.782723 http.c:531              <= Recv data, 0000000195 bytes (0x000000c3)
21:53:54.782732 http.c:546              <= Recv data: ..<title>401 Authorization Required</title></hea
21:53:54.782740 http.c:546              <= Recv data: d>....
401 Authorization Re
21:53:54.782748 http.c:546              <= Recv data: quired
..
nginx/1.10.1..</b
21:53:54.782756 http.c:546              <= Recv data: ody>....
21:53:54.782778 http.c:558              == Info: Curl_http_done: called premature == 0
21:53:54.782848 http.c:558              == Info: Connection #0 to host localhost left intact
21:53:59.617614 http.c:558              == Info: Couldn't find host localhost in the .netrc file; using defaults
21:53:59.617755 http.c:558              == Info: Found bundle for host localhost: 0x136d680 [can pipeline]
21:53:59.617806 http.c:558              == Info: Hostname localhost was found in DNS cache
21:53:59.617870 http.c:558              == Info:   Trying ::1...
21:53:59.617894 http.c:558              == Info: TCP_NODELAY set
21:53:59.618064 http.c:558              == Info: connect to ::1 port 80 failed: Connection refused
21:53:59.618102 http.c:558              == Info:   Trying 127.0.0.1...
21:53:59.618122 http.c:558              == Info: TCP_NODELAY set
21:53:59.618332 http.c:558              == Info: Connected to localhost (127.0.0.1) port 80 (#1)
21:53:59.618453 http.c:505              => Send header, 0000000187 bytes (0x000000bb)
21:53:59.618559 http.c:517              => Send header: GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
21:53:59.618575 http.c:517              => Send header: Host: localhost
21:53:59.618591 http.c:517              => Send header: User-Agent: git/2.10.0
21:53:59.618607 http.c:517              => Send header: Accept: */*
21:53:59.618621 http.c:517              => Send header: Accept-Encoding: gzip
21:53:59.618637 http.c:517              => Send header: Accept-Language: en-GB, *;q=0.9
21:53:59.618652 http.c:517              => Send header: Pragma: no-cache
21:53:59.618667 http.c:517              => Send header:
21:53:59.618731 http.c:505              <= Recv header, 0000000027 bytes (0x0000001b)
21:53:59.618750 http.c:517              <= Recv header: HTTP/1.1 401 Unauthorized
21:53:59.618772 http.c:505              <= Recv header, 0000000022 bytes (0x00000016)
21:53:59.618788 http.c:517              <= Recv header: Server: nginx/1.10.1
21:53:59.618807 http.c:505              <= Recv header, 0000000037 bytes (0x00000025)
21:53:59.618822 http.c:517              <= Recv header: Date: Sun, 16 Oct 2016 20:53:59 GMT
21:53:59.618841 http.c:505              <= Recv header, 0000000025 bytes (0x00000019)
21:53:59.618857 http.c:517              <= Recv header: Content-Type: text/html
21:53:59.618876 http.c:505              <= Recv header, 0000000021 bytes (0x00000015)
21:53:59.618892 http.c:517              <= Recv header: Content-Length: 195
21:53:59.618912 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:53:59.618927 http.c:517              <= Recv header: Connection: keep-alive
21:53:59.618949 http.c:505              <= Recv header, 0000000044 bytes (0x0000002c)
21:53:59.618965 http.c:517              <= Recv header: WWW-Authenticate: Basic realm="Restricted"
21:53:59.618986 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:53:59.619001 http.c:517              <= Recv header:
21:53:59.619017 http.c:558              == Info: Ignoring the response-body
21:53:59.619037 http.c:531              <= Recv data, 0000000195 bytes (0x000000c3)
21:53:59.619052 http.c:546              <= Recv data: ..<title>401 Authorization Required</title></hea
21:53:59.619068 http.c:546              <= Recv data: d>....
401 Authorization Re
21:53:59.619083 http.c:546              <= Recv data: quired
..
nginx/1.10.1..</b
21:53:59.619098 http.c:546              <= Recv data: ody>....
21:53:59.619127 http.c:558              == Info: Curl_http_done: called premature == 0
21:53:59.619150 http.c:558              == Info: Connection #1 to host localhost left intact
21:53:59.619178 http.c:558              == Info: Issue another request to this URL: 'http://localhost/git/rc/info/refs?service
=git-receive-pack'
21:53:59.619289 http.c:558              == Info: Couldn't find host localhost in the .netrc file; using defaults
21:53:59.619322 http.c:558              == Info: Found bundle for host localhost: 0x136d680 [can pipeline]
21:53:59.619351 http.c:558              == Info: Re-using existing connection! (#1) with host localhost
21:53:59.619387 http.c:558              == Info: Connected to localhost (127.0.0.1) port 80 (#1)
21:53:59.619426 http.c:558              == Info: Server auth using Basic with user 'grochmal'
21:53:59.619600 http.c:505              => Send header, 0000000226 bytes (0x000000e2)
21:53:59.619631 http.c:517              => Send header: GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
21:53:59.619646 http.c:517              => Send header: Host: localhost
21:53:59.619661 http.c:517              => Send header: Authorization: Basic <redacted>
21:53:59.619677 http.c:517              => Send header: User-Agent: git/2.10.0
21:53:59.619691 http.c:517              => Send header: Accept: */*
21:53:59.619706 http.c:517              => Send header: Accept-Encoding: gzip
21:53:59.619720 http.c:517              => Send header: Accept-Language: en-GB, *;q=0.9
21:53:59.619753 http.c:517              => Send header: Pragma: no-cache
21:53:59.619768 http.c:517              => Send header:
21:53:59.633633 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:53:59.633669 http.c:517              <= Recv header: HTTP/1.1 403 Forbidden
21:53:59.633683 http.c:505              <= Recv header, 0000000022 bytes (0x00000016)
21:53:59.633692 http.c:517              <= Recv header: Server: nginx/1.10.1
21:53:59.633702 http.c:505              <= Recv header, 0000000037 bytes (0x00000025)
21:53:59.633711 http.c:517              <= Recv header: Date: Sun, 16 Oct 2016 20:53:59 GMT
21:53:59.633722 http.c:505              <= Recv header, 0000000028 bytes (0x0000001c)
21:53:59.633730 http.c:517              <= Recv header: Transfer-Encoding: chunked
21:53:59.633740 http.c:505              <= Recv header, 0000000024 bytes (0x00000018)
21:53:59.633749 http.c:517              <= Recv header: Connection: keep-alive
21:53:59.633758 http.c:505              <= Recv header, 0000000040 bytes (0x00000028)
21:53:59.633767 http.c:517              <= Recv header: Expires: Fri, 01 Jan 1980 00:00:00 GMT
21:53:59.633776 http.c:505              <= Recv header, 0000000018 bytes (0x00000012)
21:53:59.633785 http.c:517              <= Recv header: Pragma: no-cache
21:53:59.633795 http.c:505              <= Recv header, 0000000053 bytes (0x00000035)
21:53:59.633803 http.c:517              <= Recv header: Cache-Control: no-cache, max-age=0, must-revalidate
21:53:59.633813 http.c:505              <= Recv header, 0000000040 bytes (0x00000028)
21:53:59.633822 http.c:517              <= Recv header: Expires: Fri, 01 Jan 1980 00:00:00 GMT
21:53:59.633831 http.c:505              <= Recv header, 0000000018 bytes (0x00000012)
21:53:59.633840 http.c:517              <= Recv header: Pragma: no-cache
21:53:59.633849 http.c:505              <= Recv header, 0000000053 bytes (0x00000035)
21:53:59.633858 http.c:517              <= Recv header: Cache-Control: no-cache, max-age=0, must-revalidate
21:53:59.633868 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:53:59.633858 http.c:517              <= Recv header: Cache-Control: no-cache, max-age=0, must-revalidate
21:53:59.633868 http.c:505              <= Recv header, 0000000002 bytes (0x00000002)
21:53:59.633876 http.c:517              <= Recv header:
21:53:59.633887 http.c:531              <= Recv data, 0000000005 bytes (0x00000005)
21:53:59.633895 http.c:546              <= Recv data: 0....
21:53:59.633923 http.c:558              == Info: Curl_http_done: called premature == 0
21:53:59.633940 http.c:558              == Info: Connection #1 to host localhost left intact
fatal: unable to access 'http://localhost/git/rc/': The requested URL returned error: 403

HTTP 403!  Oh well, I could not be arsed to configure a proper htpaswd file.  But this gives us already enough info about what GIT does on a push, the interesting parts are:

GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
Host: localhost
User-Agent: git/2.10.0
Accept: */*
Accept-Encoding: gzip
Accept-Language: en-GB, *;q=0.9
Pragma: no-cache

GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
Host: localhost
User-Agent: git/2.10.0
Accept: */*
Accept-Encoding: gzip
Accept-Language: en-GB, *;q=0.9
Pragma: no-cache

These two GETs are the ones that trigger the user prompt and the password prompt, all fine until now.  Forward:

GET /git/rc/info/refs?service=git-receive-pack HTTP/1.1
Host: localhost
Authorization: Basic <redacted>
User-Agent: git/2.10.0
Accept: */*
Accept-Encoding: gzip
Accept-Language: en-GB, *;q=0.9
Pragma: no-cache

Ouch!  That <redacted> part (CURL redacts it even in trace mode!) is a Basic Authentication header, and its content is equivalent to:

echo -n username:password | base64

In essence, the password is sent in (almost) clear text.  That's expected since GIT wants the server to perform the authentication and an HTTP server will perform simple HTTP authentication.

It is really a very good thing that pretty much all repositories available through the internet use HTTPS.  Don't use an HTTP authenticated repository over plain HTTP over the internet, anything can be spoofed and you password is compromised straight away.

Extra note

But wait, where the hell those user.name and user.email configuration options ended?  Answer: in the log:

$ git log
commit 4aa5546090030c4d9196b6a4a2547b77a8c5a394
Author: grochmal <grochmal@example.com>
Date:   Sun Oct 16 21:52:22 2016 +0100

    yay

commit af75078c1b6bb5ff630e0acf2f9e94d934a025aa
Author: grochmal <grochmal@somewhere.org>
Date:   Mon Oct 27 00:39:41 2014 +0000

    some simple configs plus dummy email configuration

commit 421b7dce992a67940422e5a0612f0d2d253d1a55
Author: Michal Grochmal <grochmal@fuji.bluepenguin>
Date:   Sun Feb 17 01:01:12 2013 +0000

    remove stuff

commit 3e2d568bb260d12a31b76141c782a655e44eef64
Author: Michal Grochmal <grochmal@fuji.bluepenguin>
Date:   Fri Feb 15 22:36:30 2013 +0000

    create depot

These come form the files in .git/logs combined with files in .git/objects, and contain whatever was configured as the email and username at the time.  This is an old repo, older than GIT 2, which started frowning upon commits without the two parameters.  During that time the username was takes as the system username and the email as the host.

And since the log files are in every clone (or sync) of a repo, these files are actually the biggest information disclosure vectors.  One file may look for example as (.git/objects/42/1b7dce992a67940422e5a0612f0d2d253d1a55):

$ git cat-file -p 421b7dce992a67940422e5a0612f0d2d253d1a55
tree 222cb8fbbddc6d6d79d9ec6a83bd95228994a46c
parent 3e2d568bb260d12a31b76141c782a655e44eef64
author Michal Grochmal <grochmal@fuji.bluepenguin> 1361062872 +0000
committer Michal Grochmal <grochmal@fuji.bluepenguin> 1361062872 +0000

remove stuff

Which discloses the system username and hostname, because I did not configure user.name or user.email before commit+push.

New GIT versions (notably all 2.x ones) solve the disclosure by giving up on commits that do not have a properly configured repo.  Yet, there are still systems using old GIT binaries out there.


Is it safe to use rng-tools on a virtual machine? I am currently working on an app that needs to create GPG key pairs using the gpg tool. Unfortunately, this tool takes a long time to generate a key pair if there is insufficient entropy/randomness available on the system to do so. A common workaround for this is to install the rng-tools package as it is called on Debian systems. This allows gpg to take advantage of true hardware random number generators. Is this safe to use (from a security perspective) on a virtual machine/virtual private server where the OS only has access to virtualized hardware? Will the generated keys be sufficiently random?

All of this depends on the hardware (physical or virtual) available to your VM. rng-tools can only get entropy from the sources available to it. If your virtual machine has no available sources of entropy for rng-tools to use then you'll be no better off.

Some virtualization systems are however able to make hardware sourced entropy available to guests through a number of mechanisms. In some cases you can pass a hardware device directly to your guest (USB, PCI, whatever) and have rng-tools use this device. In most cases this won't be possible.

The virtio paravirtual drivers expose various IO devices to guest VMs from the hardware controlling domain (Linux kernel running KVM, dom0 in Xen). There's a virtio-rng device that allows for an entropy source to be exposed to guests. From what I can find this is pretty mature on KVM but Xen support looks to be a work in progress: http://wiki.xen.org/wiki/Virtio_On_Xen

While virtio is great, it requires the guest have virtio drivers and thus be aware of the fact that it's a VM (paravirtualized). Newer hardware like Intel IVB and HSW chips have specific CPU instructions that provide random numbers from an on-chip RNG and these can be exposed to guest VMs. You can probe for the availability of these instructions by using CPUID.

This is a brief overview and likely information enough.  If you're interested in more details there's an excellent discussion of this topic here: http://log.amitshah.net/2013/01/about-random-numbers-and-virtual-machines/

EDIT:
Sorry, I guess I provided a lot of data but never really answered the question.  Anyways here's my take on the actual question:

  Is this safe to use (from a security perspective) on a virtual machine/virtual private server where the OS only has access to virtualized hardware? Will the generated keys be sufficiently random?

When it comes to security there's nothing more damaging than thinking your configuration is secure when it isn't. Using rng-tools when it provides you with no benefit (has no hardware entropy source source to draw from) has the distinct possibility of making you think you are generating high quality random numbers (keying material?) when in fact you aren't. So I don't think using rng-tools without having an entropy source for it in your VM will make the numbers generated any less random but it may make cause you to think you're generating high quality keys when you actually aren't.

My advice would be to use the rng-tools daemon but only after verifying that you've got an entropy source available for it to use.


Storing opened mail attachments unencrypted in /tmp is a normal thing? So there is an E-mail client. I can encrypt its database with a few clicks in its menu. But it's storing the opened attachments unencrypted in /tmp/foo/bla.xls. The bla.xls has 644 UNIX permission (since user's umask is 0022) and the /tmp/foo/ directory has permission of 750. The owner:group is the user that uses the desktop, the mail client.

My question: Is it normal to store opened attachments in unencrypted format?

At some point the program needs to store the documents somewhere in an unecrypted format if the document is to be shown to the user. If you want to show the document to the user you need to decrypt it, there is no other way. It can either be stored on disk or in memory in its unencrypted form (although the latter can have severe issues once the filesize starts growing). Hence often the unencrypted file is stored temporarily in a folder where only the owner of the file can view it.

If the permissions are indeed 750 on the folder then it means that only the owner and group members will be able to view the file. This is normal practice as long as all files are removed from the tmp folder after viewing.


Escaping out of a select query to run a statement that modifies data in the database Lets say you use SELECT * FROM ($query) sub where you can swap $query to any query you wish. Is there a way to escape this select and run a command that modifies data in the database?

There is an SQL attack called Stacked Queries, this type of attack is done by adding an semicolon -> ; to terminate an SQL statement. Example:
/*Malicious user input by attacker*/
        1; DELETE FROM sub

/*This example executes multiple statements*/
SELECT * FROM sub WHERE subid=1; DELETE FROM sub

Not all SQL injections attack may allow that, you can give it an try via sqlmap (if possible) and prompt an sql shell and try to run an query that will alter the data.


Examples of "Runtime application self-protection" (RASP) in action? I'm having a hard time figuring out what "Runtime Application Self-Protection" (RASP) really is, though I see it mentioned in the press.  The best description I've seen of the possible benefits, along with some limitations, is in this article Is runtime application self-protection a shortcut to secure software?

But that still doesn't really give practical examples.

Is there any open-source software that does this?  Any frameworks that provide it?
Would something like Cross Site Request Forgery protection in Django be an example?

RASP takes a naive application and enables it to identify attacks and block them. There are a number of different approaches including filters, sandboxes, and full instrumentation. Here's a good independent article on RASP describing the use cases and approaches: https://securosis.com/blog/understanding-and-selecting-rasp-technology-overview.

Let's look at a simple SQL injection example. A naive application simply has no defense and gets exploited.  An application that uses PreparedStatements is safe against injection, but has no idea whether it is being attacked or not. Let's see how this works with RASP. I'm describing Contrast's instrumentation approach here.

First, the RASP is installed into the application. In this case, simply adding the RASP agent to the environment is enough. When the code loads, the RASP uses dynamic binary instrumentation to add new security sensors and analysis capability to the application. This process is very similar to how NewRelic or AppDynamics work to instrument an application for performance.

When the attack arrives at the application, RASP uses gathers data about the request, the user, the session, and any other contextual information. The attacker's request data is tracked through the application. If it looks like an attack, but never reaches a SQL query, it gets reported as a probe. This is a major difference from what a WAF can do, as WAFs are not able to see what happens inside the application and must overblock.

If the attack actually reaches a SQL query and modifies the meaning of that query, only then does RASP block the attack.  This is essentially enforcing the definition of SQL Injection, as only attacks that successfully modify the meaning of SQL queries are blocked.  This is why RASP implementation can be deployed without much configuration or training.

Ultimately, the user gets visibility into who is attacking their applications, where the attacks are coming from, the techniques being used, the exact line of code that is being targeted, and the full SQL query containing the attack.  The number of viable attacks is only a tiny fraction of the overall probes that never hit a matching vulnerability.  So the results are quite different than what a WAF can provide.

The process is roughly the same for other vulnerabilities. Although, RASP may add specific protections for known vulnerabilities in libraries and components.  RASP may also add security logging or other security features to applications.


What are the security benefits to a separate user database? In the app I'm writing I separated the user and main databases a long time ago for "security reasons". However its getting harder and harder to justify the overhead and the difficulty of managing such a setup.

For some quick detail this is a PHP web app. There are 2 separate mysqli connections, one for each database. Each database has its own user with its own credentials. This means you can't get to the main database with the user database credentials

In theory this prevents SQL injection damage, separation of concerns, security through obscurity, etc. However in a costs vs rewards I loose easy interoperability with the user table and the rest of the database, eg joins.

Are there more concrete reasons that such a database setup makes sense? Is this even common?

Rather than two separate connections working together, you can use separate user accounts with access to specific columns. Most of your statements can use the user account that has access only to the username (not password) column of the users table, and the less important data from your main db.

In MySQL, you can do this with nice granularity. This will allow you to show everyone's usernames, and only access passwords in login pages, and only access sessions in session management, only access email addresses in notifiers, etc.

With this model, SQL Injections will generally be limited to the public info, or the single section that they reach.

Of course, what is public, how your users are set up, how many, what they get is all specific to your use case.

Check the GRANT documentation for your version of MySQL.

Disclaimer: This is not a fix to SQL Injection, only an effort to help minimize the impact.


How to apply a pepper correctly to bcrypt? Update: There is a better way to add a server side key, than using it as a pepper. With a pepper an attacker must gain additional privileges on the server to get the key. The same advantage we get by calculating the hash first, and afterwards encrypting the hash with the server side key (two way encryption). This gives us the option to exchange the key whenever this is necessary.

For hashing passwords in a database, i would like to add a pepper to the hash function. Of course this pepper will be additionally to the unique salt.

The reason why i want to add a pepper is, that it prevents a dictionary attack, in case that the attacker has only access to the database, but not to the server (typical for Sql-Injection). In my opinion this is better than a hash without pepper, even if the pepper is only hardcoded (to avoid code complexity).

Now i wonder, how the pepper should be applied correctly, is it correct to just append the pepper to the password before hashing?

1. Concatenating password and pepper

$passwordHash = bcrypt($password . $pepper, $salt);

A reason against this could be, that passwords bigger than the bcrypt limit (55 characters) will not get the pepper, although passwords of this length are propably not in a dictionary anyway. Because of this limit, the pepper is added after the password and not before. Another reason could be, that if the attacker knows the pepper, he also knows the ending of all our peppered passwords.

2. Combine password and pepper with hash

$passwordHash = bcrypt(hash('sha256', $password . $pepper), $salt);

So we could use a hash function to combine password and pepper, before hashing. Is it appropriate to use sha256, or which hash function would be ideal, when we want to use bcrypt afterwards?

3. Combine password and pepper with hmac

$passwordHash = bcrypt(hash_hmac('sha256', $password, $pepper), $salt);

Often a hmac is the recommended solution, is there any advantage over using SHA256 directly? Since we only want to combine password and pepper, and the security comes later from the bcrypt, i cannot see any apparent advantage.

Any helpful hints are much appreciated.

Your three methods are correct. The third (with HMAC) might be a tad more "elegant", mathematically speaking: it would make it easier to prove the security of the construction, relatively to those of bcrypt and HMAC.

Beware, though, of null bytes. A given bcrypt implementation might expect a character string and stop at the first byte of value 0, which may occur in the output of either SHA-256 or HMAC (or as part of the binary key you use as pepper), ignoring all subsequent bytes. It would be a grave problem, and you would not notice it. To avoid that problem, you might want to Base64-encode the SHA-256 or HMAC output before giving it to bcrypt (Base64-encoded SHA-256 output is 44 characters, still below the bcrypt limit).


VPN service - change of ip Imagine I connect to example.com, change my IP address using my VPN service, and then remain on example.com in my browser.  Meanwhile I open some other sites and eventually switch off my VPN service.  Therefore I start using my initial IP again and continue using example.com.  Can example.com detect the change of IP address? Does it matter if I received any activity from example.com (incoming message, likes, ...) while I was connected to my VPN?

When you enable/disable a VPN your IP address changes but your browser doesn't. A web application can easily track you regardless of your IP address by using cookies and a variety of other methods. In fact, the IP address doesn't matter at all for tracking purposes - a user on a mobile phone will have their IP address change frequently by simply walking out of their home and switching from WIFI to mobile data.

As a result switching to a VPN won't do anything to hide your previous history from a web application unless you take additional steps. The only thing that a VPN gives you some privacy from is your ISP.

You can easily confirm this yourself.  Login to a website, connect to your VPN, and then continue using the website.  If you are still logged in then they still know how you are despite turning on your VPN.  Then turn your VPN off again and I'm sure you'll find you are still logged in.


Storage of SSL private key in load balancer VS HSM I have a setup whereby the SSL certificates are terminated at the load balancer (i.e. Load balancer to web server is in plaintext). In order to do the SSL termination, the private key is stored on the load balancer itself. I do have a HSM in a data center.

I was told by security guys that best practice is to store the private key in a HSM.

I have read Should SSL be terminated at a load balancer? and I understand that there is nothing wrong in terminating SSL encryption at the load balancer.

However, should the private keys be stored in the load balancer itself (from a security perspective)? Are there any technical challenges in storing the SSL private keys in a central HSM instead?

From the security point of view, keeping the private key inside HSM is an ultimate solution. However, HSM has a throughput limitation, which brings a question of what rate of handshake requests do you expect to your web service and is it guaranteed to be lower than the max number that HSM can process.

If storing private keys in the HSM is not an option, then I still wouldn't store them in plain text. Every cloud solution offers tools for keys management, for example, if your service where run AWS - AWS Key Management Service (AWS KMS). Azure and gcloud will have their own tools.


Reverse-engineering one-time passwords for two-factor authentication systems Given a one-time password generator that is time-based (such as Google Authenticator), how many instances of (time, PIN) pairs would one need to significantly weaken the algorithm to a point where one would be able to narrow down possible seeds to the original function? If one were to send out PINs to clients via SMS or email (instead of using a keyfob or the actual Google Authenticator app which does not let one see past PINs), would a compromise that reveals past PINs be a significant threat to the system (note that both emails and SMS carry relatively precise time information)?

The question is related to the design of a two-factor authentication system on whether it should involve any timestamped storage of the one-time passwords generated. If this significantly weakens the security of the system, then one would argue that the design should not include any storage of past OTPs (emails, SMS or otherwise).

Details of the OTP Algorithm: http://www.ietf.org/rfc/rfc4226.txt
Reference Java Implementation: http://rfc-ref.org/RFC-TEXTS/4226/chapter16.html

Per advice by folks on stackoverflow, this is re-asked here: https://stackoverflow.com/questions/9041162/reverse-engineering-one-time-passwords-for-two-factor-authentication-systems (question there will point to this one here)

If the OTP generation algorithm is any good (and HOTP is good):

the best attack when knowing one generated password, and trying to guess the next one, should be exhaustive search on the key (and exhaustive search is not doable if the key is large enough, e.g. a 128-bit key);
knowing many previous passwords should not give any additional advantage to the attacker.

Appendix A of RFC 4226 details the security analysis of HOTP; at its core lies the hypothesis that HMAC/SHA-1 is a key-selected random function:

  To be more precise, let Maps(c,n) denote the set of all functions
     mapping from {0,1}^c to {0,1}^n.  The idealized algorithm has key
     space Maps(c,n), so that a "key" for such an algorithm is a function
     h from {0,1}^c to {0,1}^n.  We imagine this key (function) to be
     drawn at random.

This is the random oracle model. HMAC with a secure hash function, or even HMAC with a slightly weak hash function like SHA-1, is about the best practical approximation of a random oracle that cryptographers have in store.

To sum up the security proof of HOTP:

with a random oracle, you know nothing of the output for a given input until you try it on that exact input;
the generated passwords are (derived from) the output of HMAC/SHA-1, believed to be indistinguishable from a random oracle, over a counter value;
thus, nobody knows anything of a password which will be generated until the corresponding counter value is actually entered as input of HMAC/SHA-1, something which did not occur previously (for the older generated passwords) because that's a counter and it does not "wrap around".

There are details to take care of, of course, but the RFC writers are known cryptographers and the proof detailed in appendix A is sound and clear (and has been reviewed by many other cryptographers, which is the real test of security).


Why does changing physical router not warn of possible man in the middle attack? Situation

I swapped out a dead router at home today.  I setup the new router with the same SSID and encryption settings.  The devices on my network acted like nothing had happened and are happily connected to the new router.

Question

If I swap out a physical host or VM using the same IP and using SSH for example, connect to that host, the thumbprints are different and problems ensue.  Why does this not happen when switching out a router?  I could think of a few cases where this could be done maliciously, so I'm surprised it works like this.

WiFi access points have no secret. They use a SSID, but they otherwise offer or know nothing that the client can validate. Every time a device (say, a laptop) connects to a WiFi router, it uses it as if it was a new router and expects nothing in particular from that router. Secrets are more on the client side: the router will require the device to demonstrate knowledge of the WiFi password.

With a SSH server, the server has a private/public key pair, and shows the public key, and the client records that public key. If the client reconnects, then it will require that the server uses the same public key as previously; otherwise, it will complain loudly (as you observe).

There is no such public key in a WiFi router. Clients are not actually interesting in knowing whether the router has changed or not, because the router is only meant to route data to the Internet, not to provide access to some sensitive data or receive sensitive data.

When you talk to your banker, you want to be sure that you have a genuine banker with you, because you will give him your money. When you talk to the cashier at a supermarket you don't care whether he is a real cashier or not, as long as you get to exit the supermarket with the food and security guards don't begin to shout at you.


Can neighbour hear my bluetooth headset? I'd like to buy a wireless bluetooth headset to not disturbing others by my TV sound but I'm wondering how private the transmission will be?

Can a neighbour with a bluetooth headset hear my TV's bluetooth emission through a wooden wall? If so, how can I avoid it?

Can a neighbour with a bluetooth headset hear my TV's bluetooth
  emission through a wooden wall?

If you're asking about if the signal can get through, then the answer is yes. To block a bluetooth signal you'd need very thick and dense walls (something like thick concrete walls) or something that acts as a Faraday cage.

Usually bluetooth transmissions are encrypted by default, the security on this mainly relies on the pairing method.

But as forest commented, you shouldn't be worried about anything. Statistically speaking I think that it's quite unlikely that your neighbour would have the cryptographic expertise to hear your transmissions.


Difference between IPSEC SA and CHILD SA Let us consider two network entities.
            Linux1 (eth0)=============IPSEC=============Linux2(eth0)
            192.168.1.1                                 192.168.1.2

The IPSEC Tunnel is V4 over V4. When i set up this tunnel through IKE Strongswan, when i do "ipsec statusall", it shows a connection between Inner IP's.
In this setup

I think there is only 1 tunnel. I am confused on what is IPSEC SA and CHILD SA. I think the packets from Linux1 to Linux2 will be ESP encapsulated (if it is chosen) and the packets are supposed to go through the IPSEC tunnel.
Suppose there is rekeying, what is the difference between ikelifetime and ipseclifetime?

Before I start, I need to explain how IKE and IPSec work together.  It's not like TLS (where there is one set of logical keys that protect everything); instead (using the language of the RFCs), you have 3 Security Associations within this one tunnel:

You have an IKE SA, that is used to protect negotiation traffic between Linux1 and Linux2 (such as negotiating traffic SAs).
You have an IPSec SA that is used to protect data traffic from Linux1 to Linux2
You have an IPSec SA that is used to protect data traffic from Linux2 to Linux1

Now, for your questions:

What is a CHILD SA?

A Child SA is any SA that was negotiated via the IKE SA.  An IKE SA can be used to negotiate either SAs to protect the traffic (IPSec SAs), or it can be used to create another IKE SA.  In the context you're seeing it, it's most likely a synonym for the IPSec SAs.

What is the difference between ikelifetime and ipseclifetime

No SA is eternal; they all have a best-by date; and when that expires, they go away (and hopefully replacement SAs are also negotiated, unless you're actually done with the tunnel).  ikelifetime would be the lifetime of the IKE SA; ipseclifetime would be the lifetime of the IPSec SAs.


eCPPT vs. OSCP Certification I am a soon to be college student. I am looking to become certified in pentesting for both personal interest as well as to be able to have something that would look good to future employers. Both courses are just barely in my price range, so I need to be sure that I get my money's worth.

My question is: Are either of these certifications recognizable and accredited? Will I be able to put these certificates on my resume? Will either of these look good to an employer?

The answer to this question largely depends on the country you're in and the companies that you apply to and the roles that you're looking at.

The eCPPT looks to be more focused on web app. testing, I've not specifically heard of the cert. before, but elearnsecurity have some good training materials.

The OSCP looks to be a decent cert for the exploitation/infrastructure testing side of things, so if that's the type of role that you're looking at then I'd expect that it could be a factor.

If you're just going in to college and won't be looking at getting a job for a while, I'd be inclined to hold of on professional certs if I was you as the field may well have changed in a couple of years.


How long is too long being out of InfoSec This is a question related to the information security field but it is not technical in nature, more opinion based. I would really like some constructive but honest feedback.

I just recently left my job in Infosec as a member of a CERT team for 6 years, in order to move country so I can be with my wife who is going to have our first baby. I am planning to stay at home for the next 7-8 months (longest i will have been out of work) to help my wife raise the baby during the start as I know it can be hard.

The issue is that some people I talk to are of the opinion that 8 months being out from InfoSec is too long and it will be a manor obstacle to finding a new join the industry. I do hold some major certs like CISSP and CEH. I would love the opinion of some of you who are in the industry on this.

Thanks fort your time

I've had spurts where I've been out of infosec for years. Was it too long? No, it was very easy to catch up. If you're competent, infosec, like many other skills, is like riding a bike.

The biggest thing you have to worry about is explaining the gap in your resume, as WhiteWinterWolf states. Employers don't want to know you were out of work because you wanted to help raise a baby. What if your wife gets pregnant again? Off you go, huh?! You said you're changing countries, though... that is a perfectly valid excuse.

But this is opinion-based...


Issues with preserving $HOME on sudo On Ubuntu, the default behavior with sudo is to preserve the user's $HOME environment variable, which means that sudo will be able to read the dot files in the user's home directory.  I enjoy this most notably because, when I need to edit a text file, sudo vim will read my vimrc.

On some other systems, the sudoers file has Defaults always_set_home, which sets the home to /root, so it does not use my vimrc.  I could disable this, but since that option is, presumably, set for security reasons, I was wondering how serious they were and whether or not I should simply deal with the annoyance of the home being /root.

The only security vulnerability that I can think of this introducing is if I run an untrusted executable or script which edits one of my startup scripts.  Then, the next time I sudo, that script could get control.  However, if we're assuming my account has been compromised without my knowledge, the malicious script could have changed my path to point to a fake sudo command anyways, so this doesn't seem like an additional vulnerability.

What security vulnerabilities does preserving $HOME in sudo open up?

Edit: I realize now that sudoedit solves my main use case, but I wonder about the security issue nonetheless.

For a user who may run arbitrary commands with sudo, changing environments variables is not a direct security issue. If you like, you can run tmp=$(mktemp); export >$tmp; sudo bash -c ". $tmp; exec bash" — in other words, save the environment and restore it inside the root shell.

As you note, a trojan in a configuration file is not a concern, since the trojan could put a wrapper around sudo anyway (and grab your password while it's at it).

The topic has come up a few times in the Ubuntu mailing lists (1 2). Ubuntu doesn't reset HOME. David Mandelberg's arguments cover most of the case for resetting HOME.

Resetting HOME protects against exploitation of mistakes you might make. For example, one of your configuration file might contain a temporary file vulnerability that could be exploited to gain access to the root account. This example is, as before, not really a concern since the exploit could equally affect your account first and then hook into your call of sudo.

Resetting HOME also protects against mistakes you might make, and this is where the case for doing it has a point — but not a very convincing one.

There's an extreme view that says that you should stick to the default configuration as root. This way, anything done as root is easily distinguishable from what to do under your own customized account, so you won't forget that you're acting as root. Also doing things as root is painful so that you are incited to use the root account as little as possible. I don't buy this: doing things “the hard way” instead of the way you're comfortable with makes it more likely to make mistakes, not less. It's normally easy enough to know whether you're acting as root: if you're editing a file under /etc, you're root¹. If you're running a shell and the prompt ends with # instead of $ or % (following the usual convention), you're root — and you can use things like colors to make the distinction more visible. If you're running a package management program, you're root.
You might mistakenly leave a confidential file lying around in a publicly readable location in your home directory, believing it to be in /root. Or you might leave it in /tmp… This argument seems really far-fetched to me. Sure, it's a mistake you might make, but it's not any more likely than, say, mistakenly adding a firewall rule that leaves everything open, or making /bin/* world-writable.
One of your configuration files might cause confidential information to pop up in your home directory. This is plausible − it could be a history file or an autosave file — but these files would presumably be in a private location anyway, otherwise people could snoop on you.
Applications that automatically save their configuration might write to your home directory. This is not so much a security concern as a matter of convenience for you, and it's more than offset by the convenience of having your usual configuration when acting as root.
You might mistakenly edit files under ~, thinking that this is root's home directory when it is actually you home directory. Yes, but if $HOME is your home directory, then you'll also have your usual configuration, so you're less likely to think that you're running as the root user and more likely to think that you're running in a privileged mode. This argument is hoisted by its own petard.

Scott James Remnant put it this way:

  "sudo -s" is for lazy people who don't want to duplicate config files, "sudo -i" is for forgetful people.

But sudo -i (run a root shell) seems like a bad idea for forgetful people. And duplicating configuration files as root is only possible on a single-user machine, in which case running as root isn't such a big deal in the first place.

Conclusion: no, there aren't any serious security concern, and the case for resetting HOME is pretty weak. The purpose of always_set_home is to protect you against yourself, but it protects so little that it isn't worth it.

¹  Except that you shouldn't be running an editor as root: use sudoedit or Emacs (Tramp)'s sudo method to run the editor as your normal user.


When salting and hashing passwords, any advantage to including password length? In this answer, Gilles says (emphasis mine):

  There's no need to hide the salt from the attacker: it needs to be unique (and not derived from the password) but it doesn't need to be more secret than the hash.

I'm wondering whether there's any additional advantage to be gained by modifying the salting based on some characteristic derived from the password.

As an example:

Database:  Username | Hash | Salt

Code:
var passwd = "foo";
var len = passwd.Length();
var hash = hash(passwd + len + salt);

Does this have any advantage over the standard logic of

var passwd = "foo";
var hash = hash(passwd + salt);

aside from making the "password" portion longer?

One scenario where I feel like it might make a difference is a brute-force lookup based on common passwords.  If password1 is actually hashed as if it were password1|9, for instance, then attempting to hash password1 with the known salt wouldn't provide a match.  But I don't know if this is a common way of attacking password hashes, or whether it would actually matter.

The point of a salt is that it is unique, so that an attacker who wants to crack multiple hashes has to do all the work afresh for each hash. If you include a characteristic that is derived from the password, it doesn't help the salt. It doesn't hurt, either, but it doesn't strengthen the salt in any way.

In effect, by taking hash(password+length+salt) instead of hash(password+salt), you're using a different hash function hash2(password+salt) where hash2(x) = hash(x+length(x)). You are effectively inventing your own cryptographic primitive. That in itself is a bad sign. I don't think the result is actually insecure in any way, but I'd still veto it as an unnecessary risk.

hash2 is very marginally slower than hash. Slower is good for a password hash, but there are better ways of making the hash slow — password hashing functions have a tunable parameter to configure the slowness of the hash. Using a variant hash isn't worth the added complexity.

The normal method to generate the salt is to make it random. If you're going to add anything to it, the only point would be to mitigate a bug in the random number generator. If you're going to do that, take something that does not depend on the password, such as the user ID or the time.

Be careful with taking the hash of a concatenation of two strings: it's ambiguous: hash("bob" + "swordfish") = hash("bobsword" + "fish"). Whenever you take the concatenation of some strings and hash them or otherwise use them in a cryptographic protocol, make sure that the strings can be decomposed unambiguously. If there's a byte value that can't occur in either string (null bytes are often suitable), use that as a separator. If there is a bound on the length of the first string (264 is often suitable), prepend the length (itself in a fixed-size encoding, e.g. 8 bytes for a 264 length limit). If you're building complex data structures, use your library's ASN.1 module.

In any case, when you need to store a password hash, you shouldn't think about cryptography. Use your programming environment's bcrypt or PBKDF2 or scrypt library.

For everything you wanted to know about hashing passwords, everything you didn't want to know about hashing passwords, and everything you didn't even know you might know about hashing passwords, read How to securely hash passwords?


Symmetric key management I am currently employing GNU Crypto in Java and I am now deciding on the best way to store the keys.

The question Storage of 'secrets', keystores, HSMs and the rest has led me to believe the best course of action, without purchasing expensive hardware, is to use a password protected key store.

I plan to enter a password on system start-up to allow the system access to the key store and eliminate the need to store the password in the same location as the key store. However at this time the key store will be located on the same system as the database with the files and IV.

One answer to the question https://stackoverflow.com/questions/723653/storing-encryption-keys-best-practices suggests splitting up a key and spreading it around. I have thought of doing this where I may locate part of the key in my keystore, part in my database and perhaps parts elsewhere. Would this add any security?

As for the key store my preference would be to use the GNU Crypto keyring, however it does explicitly appear to accept symmetric keys. Is there way to use it for this purpose? I can't seem to find any useful examples.
An alternative would be Java KeyStore which seems to accept 'SecretKeys.'

Many thanks for your help.

Bonus question: I decided to use the GNU Cryptos ciphers as I had read, and perceived it to be quicker than the alternatives partly due to it not having to use any native C code. Is this assumption correct?

Instead of rolling your own crypto scheme, use Keyczar for your cryptography. It is an opinionated framework that handles everything for you (including key management) and has been extensively reviewed by cryptographers and security researchers.

To encrypt the Keyczar keystore, use OS-level full-disk encryption.


SSHguard: Does one to change any configuration for basic usage of the program? I use Ubuntu 16.04 and I've installed SSHGuard (sudo apt-get install sshguard -y) to protect from Brute Force Attacks (BFAs) on whatever user.

From reading about the program in ArchLinux wikipedia and in the SSHguard website, it is unclear to me if one needs to add/change any SSHguard configuration, to enjoy its basic functionality, in Ubuntu/Debian distros in particular (one user told me something like "just install and use").

By "basic usage" I mean: Have protection from SSH brute force attacks of whatever user of a given system, per the default SSHguard rules.

Does one have to change any configuration for basic usage of the program?

I've manually verified this trying to login to my remote machine and it seems that SSHguard works OOB (Out Of Box), without me changing anything in the configuration:

Indeed, after 6 tries, I got a Putty fatal error, with this message:

  Server sent disconnect message type 2 (protocol error): "Too many
  authentication failures"

Update

I likely was wrong and it comes from Putty. Will further test later.


How might the Chinese government be blocking only specific types of WhatsApp traffic? There are currently media reports that the Chinese government are blocking some types of messages sent via WhatsApp ("pictures, voice messages and video").

Given that WhatsApp traffic has end-to-end encryption, what mechanisms is it likely that the Chinese government could be using to do this?

Given that Whatsapp traffic has end-to-end encryption, ...

End-to-end encryption neither implies anonymity nor that the underlying protocol is unrecognizable to an eavesdropper and doesn't reveal any meta information at all.

In fact, obscuring protocols to hide them from firewalls is notoriously difficult and finding out enough to block the traffic can be fairly easy. In the case of WhatsApp, it's also irrelevant that E2EE is used, because WhatsApp adds an extra layer of encryption between client and WhatsApp servers anyway (formerly via TLS, now Noise Pipes). So the fact that users additionally get E2EE via the Signal protocol has limited impact on traffic analysis.

There are some obvious ways to block WhatsApp traffic without having to bother with encryption:

Block the servers. WhatsApp publishes the IP pool of their messaging servers. (The IPs used to be listed here and have since been moved to the Facebook Mobile Partner Portal.) But even without a ready-made list of IPs it would be fairly easy to reverse-engineer a list of servers by just using the app and observing the traffic. (That's an entirely common technique - similarly, the Tor network has suffered in the past years from China blocking the majority of their public relays.)
Block the protocol. The government could use heuristics to recognize and block the transport protocol. Blocking based on traffic patterns has worked in the past for BitTorrent, Tor and others but might come with a notable overhead. (I can't comment on whether this approach is practical.)

One way to block media files in particular would be by identifying large uploads. It might also come in handy that WhatsApp doesn't send images the same way as ordinary text. Instead, clients encrypt and upload attachments separately and then just send a message containing the key to the upload.

Since the news report states that no files could be sent at all, it's plausible that the government just temporarily blocked the attachment upload servers (which would leave plain messages unaffected).

The process for sending attachments is detailed in the WhatsApp Security Whitepaper:

  Transmitting Media and Other
  Attachments

  Large attachments of any type (video, audio, images,
  or files) are also end-to-end encrypted:

  The WhatsApp user sending a message (“sender”) generates an
  ephemeral 32 byte AES256 key, and an ephemeral 32 byte HMAC-
  SHA256 key.
  The sender encrypts the attachment with the AES256 key in CBC
  mode with a random IV, then appends a MAC of the ciphertext using
  HMAC-SHA256.
  The sender uploads the encrypted attachment to a blob store.
  The sender transmits a normal encrypted message to the recipient
  that contains the encryption key, the HMAC key, a SHA256 hash of
  the encrypted blob, and a pointer to the blob in the blob store.
  The recipient decrypts the message, retrieves the encrypted blob
  from the blob store, verifies the SHA256 hash of it, verifies the MAC,
  and decrypts the plaintext.


E-Mail privacy proxy for hiding real e-mail? Do E-Mail proxy services exists to improve privacy and security?

Privacy in the sense that one wouldn't need to give a website his/her username (possibly even in the firstname.lastname@domain.tld form) and in a security sense that the used e-mail couldn't be used to log into the e-mail service (thereby making it useless for a leaked password, because the e-mail address couldn't be used to login).

Example:

john.doe@gmail.com could be someone's e-mail. If there were a Google Privacy/Proxy service then one could generate as many random e-mails as possible and if one would be sent spam to, or leaked, it could be disabled:

abcdef@gmail.proxy
290dcef@gmail.proxy

could both redirect mail to john.doe@gmail.com.

One could be blocked/disabled/removed if wanted without abandoning the real account (e.g. because 290dcef@gmail.proxy has been compromised or spam is being sent to it).

Would it really improve security and privacy? Or am I missing something?

And does such a service exist? (as a bonus, replying from such proxy e-mails would be even better, converting the real account from field to the proxy mail address)

In GMail, you can use disposable emails of your own by just adding "+" and any string following it.

Eg:

john.doe+newsletters@gmail.com
john.doe+forums@gmail.com


How to perform a security test/review/penetration testing of Ethernet ports? I have been engaged by a client who wants its Ethernet ports checked to determine whether port security is functioning effectively.

What can be the approach or steps to do check Ethernet port security?
What tools can be used to do the same?
In the scenario that I am third party who enters an
organization with his/her laptop and sees that there are Ethernet
ports around. Then I decide to plug in a wire and try to get into the
network. What can I do to achieve that?

This is a broad question, as there are several different ways to assess the security of Ethernet ports. However, there are a few things that are usually covered in this type of scope.

The first (and most straightforward) thing to test is whether any sort of Network Access Control is in place. If you're being asked to assess the security of a port, there is presumably some security control that the client wants tested. It might be a good idea to ask the client what, specifically, they want assessed.

The easiest way to test whether Network Access Control is functioning correctly is to simply plug into the Ethernet port and see what happens. Are you given an IP? If you set a static IP (vs. using DHCP), does that work? Or is there some agent-based access control that's stopping you from connecting? Is there a "walled garden" once you connect to the network?

Once you're connected, what can you see? Can you port scan (nmap) the local network? Are you in some sort of a segregated environment? What else is running nearby on the network? Is the network controlling your DNS, or can you resolve anything you want? Is there egress filtering to the Internet?

Lastly, there's always the physical security element: is the port in question in a public area, like a lobby or waiting room? Is that intended? Do untrusted actors have physical access to the port?

From the answers to these questions, you should hopefully be able to determine how secure the Ethernet setup is -- and hopefully write recommendations to improve security based on what you find. Like I said earlier, though, you should definitely check with the client before doing any of this stuff -- they'll know what their goals are, and should be able to tell you what they want to learn.

Good luck!


Whether PGP is send over MIME? If I am using PGP to encrypt mails whther it is send as a MIME (Multipurpose Internet Mail Extensions) message, and S/MIME and PGP are used for providing email security.

When I send PGP message using a email client to my another web based account, what I got was a an attachment.

There are two ways of signing/encrypting email with PGP:
Inline-PGP and PGP/MIME.

Inline PGP takes a plain text message, and signs it or encrypts it, and the signed or encrypted message is sent as a single plain text message.

PGP/MIME uses a MIME-type of either multipart/signed (or for encrypted mails multipart/encrypted.)  The original unsigned message is left alone, and an additional MIME part is added which contains the signature. This would MIME part would be seen by any non-PGP-aware MUA as being just some random attachment.

The difference between PGP and S/MIME is more in the formatting of the certificates, and the trust model used. PGP uses a web-of-trust, and S/MIME uses a PKI based on Certification Authorities.  A PGP public key file is formatted very differently from an X.509 certificate.

In terms of mixing PGP and S/MIME, its possible to do, if you use inline-PGP, and then S/MIME sign the message.  (Why one would want to is another question.)


How to check if the decryption is correct? I'm working on chat room that encrypt messages for more than one users and each user might have different encryption and key/password. The user's key won't work with all the message, therefore; return errors.

var message ="secret message";
var encrypted = CryptoJS.AES.encrypt(message, "Secret Passphrase");
try {
    var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase123").toString(CryptoJS.enc.Utf8);
    if (decrypted.length > 0) {
        alert(decrypted);
    } else {
        alert("false");
    }
} catch(e) {
    alert("false");
}

I'm currently catching the error, but sometimes the decryption returns with jumbled up letters and symbols. The current way I'm doing this is not efficient. Is there a better way?

I ask this question earilier on stackoverflow, but they suggested that I might have bette luck here.

Just use an authenticated mode like GCM. Not only will this tell you whether or not the correct key was used to decrypt, but it prevents message-tampering attacks, the worst of which can allow attackers to completely decrypt encrypted messages.


Duo Security forgot password workflow I'm updating my company's forgot password workflow. Currently we use Duo Security as our second factor on login (but for the purposes of my question this can be any such service). I've been walking through Owasp best practices and they make sense.

My confusion comes with what I see other sites implement forgot password workflow. I tend to see side channels like SMS/Email used to send one time tokens with security questions and whatnot even if they use a service like Duo. I never for example see a site do a DUO push notification along with a security question(or other 'what you know' item).

Am I missing something obvious?

The attacks you mention are real problems to threat model.

I like to think email is the master key to most online accounts. SMS is arguably better, but similar risk. They let you bypass the password to login. If I can access your email, then I can get into most of your accounts.

Sites that support MFA or 2factor should still ask for your second factor after a pw reset. If they don't then they are effectively only checking a single factor - that the user can access the associated email account.

If you have seen this, it's a vulnerability in the web app and you could report the vulnerable flow to the webmaster.


Data collection when responding to malware alerts When investigating malware alerts I would like to collect some information from the system before the decision gets made to take the system off of the network and re-imaged, or if further forensics is necessary.

I am envisioning a batch script that collected all the basic information about the system (e.g. open network connections, IP addresses, host name, logged on user, local administrators, etc.) and then takes a memory dump using Memorize or similar tool for later analysis.

It would be more efficient if we would run these scripts remotely rather than connecting a thumb drive to the machine with the tools loaded but my concern is that copying the tools to the suspect machine would modify the file system and would be bad for forensics purposes.

Are there any other good options for collecting this information remotely without compromising the forensic data? I am aware of PSexec but tools like memorize will still have to be copied to the remote machine. Perhaps putting all the tools on a read-only share, and redirecting the data back to the analysis workstation with netcat or cryptcat?

Thanks!

Live response is a common and accepted practice today. A number of commercial and open source tools can gather volatile data, because immediately pulling the system off of the network can also be disruptive to the forensic validity of your evidence. The key is not "don't change anything", but rather "be able to explain and have documentation for any changes".

For example, SANS best practices explain fairly well how to proceed in this sort of case. NIST 800-86 also documents this in sections 5.1 and 5.2.

I recommend looking into tools like GRR or OSQuery. I don't know of remote live response tools for Windows other than commercial ones like MIR or Carbon Black. (I have no affiliation with any of those tools or organizations.)


How do I know exactly what type of information Github collects from a visitor? I keep track of the upload bandwidth on every site that I visit, and I've noticed that the most site that uses upload bandwidth is Github.com
every single page that I visit uploads 1.06MB of data.

visiting 3 Github pages results in a total of 3.18MB data uploaded:

Github's remote name:

it says in their Privacy Policy that they collect my cookies. I don't know what type of data they collect, but is there a way to know what exactly gets uploaded, stop it or take control of what I upload?

This is the heaviest POST command taken from dev tools, as you can see 40 seconds:

I saved that as HAR with content as requested, here is the file

To see what exactly the site is doing and the details of the sessions, you can use many free tools such as Glasswire.

I use it to track every network connection on my systems and what files change or what is being uploaded by apps such as Chrome, IE, MS Word or sites. Check it out, it may help you here. This applies to your mobile device as well.

You would be surprised as to what other things the site is doing while you are browsing.

Another tool you can use is a proxy tool (Burp Suite, WireShark, Fiddler etc) that will enable you to intercept requests and responses by the site and you can watch the traffic when you visit the site and forward each request/response individually (some tools will allow you to do that).


Number of Column Enumeration in PHP / MySQL I am currently studying SQLi from a book which I won't mention to avoid any copyright issues. The book contains many examples of strings / code from MSSQL, MySQL, Oracle etc.

I am currently stumped as to what the equivalent syntax would be in PHP/MySQL for this example, given only in .asp (assuming a DB of MSSQL). This is an injection string as used in the browser's address bar, using ORDER BY to enumerate the number of columns in a table, iterating through ORDER BY 1, ORDER BY 2 etc. until producing an error:

hxxp://someserver.com/products.asp?id=12+order+by+1

So, would the equivalent syntax in PHP/MySQL be something like:

hxxp://someserver.com/products.php?id=12 order by 1

I'm thinking whitespace is OK here? Or perhaps:

hxxp://someserver.com/products.php?id=12%20order%20by%201

I have written an application for XAMPP in order to test, but an unable to produce an error, so I'm checking to make sure that I'm using the correct syntax.

To be clear, for the present post, I'm really only asking about syntax.

Edit: I thought I was very clear that I was only asking about whitespace in a URL... I did produce the error I was looking for.

I have found an instance where a space vs %20 do not produce the same results - as the very last character in a URL.

This (note the single space after the two hyphens):

/victim/products.php?val=100' ORDER BY 4 --

produces this:

  Database access failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1.

While this:

/victim/products.php?val=100' ORDER BY 4 --%20

produces:

  Database access failed: Unknown column '4' in 'order clause'.

Interesting...

I know that the very same build of XAMPP has no problem with a space after 2 hyphens at the end of an injection when it's in a login field using the POST method...

So you have three different way of expressing a space: , + and %20. When you enter an URL, your browser will first trim it and then URL encode it. You can see this in action by taking a look at the network tab in the developer tools in Chrome. There you can see the URL that is actually being sent, as opposed to the one you enter in the URL bar.

From this we can conclude that a space and %20 are equivalent, except at the end where the space will be ignored while the %20 will not. As for + all standard compliant URL decoder (including PHP's urldecode()) will convert it to a space, so it can also be treated as equivalent (again, except if it is on the end).

So why is the space at the end important? Read the MySQL documentation:

  From a --  sequence to the end of the line. In MySQL, the --  (double-dash) comment style requires the second dash to be followed by at least one whitespace or control character (such as a space, tab, newline, and so on). This syntax differs slightly from standard SQL comment syntax, as discussed in Section 1.8.2.4, “'--' as the Start of a Comment”.

Without a whitespace after the -- you don't get a comment. Hence the error.


What is the current status of trust management? It is almost 30 years now since Ken Thompson presented his widely known ACM Turing Award Lecture "Reflections on Trusting Trust". What is the current status of practice and research on trust management?

Biggest problem in trust management is that it involves people who don't act like machines.

Public-Key Infrastructures can be seen as a big exercise in trust management. The two main deployed solutions, X.509 and OpenPGP, implement two strategies which can be described as "let's add all the needed features that application won't bother to implement properly, or at all" and "let's do nothing and pray for the best", respectively. By right they should both fail in horrible (but spectacular) ways. In practice, there are not so many issues because people are still basically honest.

But really, security does not make dollars; you will never be able to say that stricter controls resulted in 10% sales increase. Therefore, trust management will be underbudgeted, badly done, and rely on luck. That is the biggest unsolved issue: how could we make trust management, and security in general, be recognized as important enough to, generally, warrant a bit of care ?

(The one known way to make trust management safe is to make it known that offenders will be shot. This is what they do in war-time armies.)


Encryption algorithm selection in IPsec Phase 2 My question is, in which payload (transform or proposal) does the initiator specify the encryption algorithm to be used in Phase 2. Let us assume that PFS is turned off in this case for simplicity of explanation.

I understand that for Phase 1, the encryption algorithm is specified in the transform payload and that the encryption mechanism used in Phase 1 and Phase 2 can be different.

I spent some time trying to find this, but I failed.

The mechanisms differ for IKEv1 and IKEv2 and whether the initial Phase 2 (CHILD_SA) is created or one is created/rekeyed later.

With IKEv1/ISAKMP every IPsec SA is created with a Quick Mode exchange, which contains the SA, Proposal and Transform payloads used to negotiate the algorithms (see RFC 2408, section 4.2). These algorithms don't have to be the same as those used for the ISAKMP SA. PRF is enabled by negotiating a DH group and establishing a shared secret with a DH exchange. Thus, already the first Phase 2 SA can negotiate key material independent of the Phase 1 SA.

With IKEv2 an initial CHILD_SA is created already with the IKE_AUTH exchange. The algorithms are negotiated with SA payloads that contain proposal and transform substructures (not full payloads). As with IKEv1 the algorithms negotiated don't have to be the same as those for the IKE_SA. However, since the key material for this initial SA is derived from the IKE keys, negotiated with a DH exchange during the IKE_SA_INIT exchange, there will never be a DH group negotiated for this SA (see RFC 7296, end of section 1.2). To establish additional CHILD_SAs or to rekey existing ones CREATE_CHILD_SA exchanges are used. The payload used to transport the proposals/algorithms is the same SA payload used during the initial exchanges. In these exchanges a DH group may be negotiated and a DH exchange can be used to create key material that is independent of the IKE keys.


Unencrypted proxy connection with encrypted backend connection Is it secure to allow unencrypted connections to a proxy server but encrypt all connections to the backend servers?

Essentially, reversing this pattern: https://assets.digitalocean.com/articles/nginx_ssl_termination_load_balancing/nginx_ssl.png

It depends on what you mean by 'secure'.

It would mean that the traffic to the proxy is not encrypted and thus the confidentiality of said traffic is not garantueed, nor is any integrity. Someone could be sitting as a man in the middle (MitM) and change requests.

Usually it is a good idea to make connections to proxies encrypted if you care about the confidentiality and integrity of the data being fed to your backend servers. If, for whatever reason, that is not important for your business case, then you could consider no encryption.

The connection to the backend servers also goes over a network (between the proxy and the backend server), but usually the idea behind not encrypting that traffic is that you control said network and the threat of a MitM is much less.


RSA Signing Key Rotation I understand the details of RSA encryption/decryption in that a public key can be distributed in the clear since all it can really do anyway is encrypt data. I also understand that this public key can be signed with a different public/private key pair. This is great to validate that the key came from a reliable source and you are not encrypting your sensitive data with with a malicious public key so that an attacker could decrypt with the paired malicious private key. I also understand that it is important to rotate public encryption keys since after a number of uses, the private key becomes mathematically exposed with fewer computational cycles. What I do not understand is if you need to rotate your public signing key. It seems to me that after enough key rotations your private signing key would become exposed and then a malicious public encryption key could be signed by an attacker with the private signing key they have exploited. Issuing a new public signing key, however, becomes susceptible to a man in the middle attack.
What piece of this am I missing?

I also understand that it is important to rotate public encryption keys since after a number of uses, the private key becomes mathematically exposed with fewer computational cycles.

Well, you understood wrong. This is a widespread myth, but myth nonetheless. Keys don't wear upon usage -- especially not signature keys. Keys used to require regular rotation, but that was back in the days before computers, when cryptographic algorithms had to be done with a pen and paper, or possibly some assembly of whirring cogs. Times have changed.

A decent signature algorithm is supposed to remain safe even if you produce a billion of billions of signatures. An algorithm which does not achieve at least that level of security is said to be "broken" and cryptographers shun it. RSA (used properly, i.e. as explained in PKCS#1) is not broken.